comparison libpurple/plugins/log_reader.c @ 18251:8908e9ec2420

Optimize this QIP code some more.
author Richard Laager <rlaager@wiktel.com>
date Mon, 25 Jun 2007 00:47:02 +0000
parents 7a6a1da4121b
children 6722bbd698ff
comparison
equal deleted inserted replaced
18250:7a6a1da4121b 18251:8908e9ec2420
1 #include <stdio.h> 1 #include <stdio.h>
2
3 #ifndef PURPLE_PLUGINS
4 # define PURPLE_PLUGINS
5 #endif
6 2
7 #include "internal.h" 3 #include "internal.h"
8 4
9 #include "debug.h" 5 #include "debug.h"
10 #include "log.h" 6 #include "log.h"
1743 char *path; /* FIXME: Change this to use PurpleStringref like log.c:old_logger_list */ 1739 char *path; /* FIXME: Change this to use PurpleStringref like log.c:old_logger_list */
1744 int offset; 1740 int offset;
1745 int length; 1741 int length;
1746 }; 1742 };
1747 1743
1744 static char *qip_get_file_contents(const char *path)
1745 {
1746 GError *error;
1747 char *contents;
1748 char *utf8_string;
1749
1750 purple_debug_info("QIP logger", "Reading %s\n", path);
1751
1752 error = NULL;
1753 if (!g_file_get_contents(path, &contents, NULL, &error)) {
1754 purple_debug_error("QIP logger",
1755 "Couldn't read file %s: %s \n", path, error->message);
1756 g_error_free(error);
1757 return NULL;
1758 }
1759
1760 g_return_val_if_fail(contents != NULL, NULL);
1761
1762 /* Convert file contents from Cp1251 to UTF-8 codeset */
1763 error = NULL;
1764 if (!(utf8_string = g_convert(contents, -1, "UTF-8", "Cp1251", NULL, NULL, &error))) {
1765 purple_debug_error("QIP logger",
1766 "Couldn't convert file %s to UTF-8: %s\n", path, error->message);
1767 g_error_free(error);
1768
1769 g_free(contents);
1770 return NULL;
1771 }
1772
1773 g_free(contents);
1774 contents = g_markup_escape_text(utf8_string, -1);
1775 g_free(utf8_string);
1776
1777 return contents;
1778 }
1779
1748 static GList *qip_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account) 1780 static GList *qip_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account)
1749 { 1781 {
1750 GList *list = NULL; 1782 GList *list = NULL;
1751 const char *logdir; 1783 const char *logdir;
1752 PurplePlugin *plugin; 1784 PurplePlugin *plugin;
1753 PurplePluginProtocolInfo *prpl_info; 1785 PurplePluginProtocolInfo *prpl_info;
1754 char *username; 1786 char *username;
1755 char *filename; 1787 char *filename;
1756 char *path; 1788 char *path;
1757 gsize length; 1789 char *contents;
1758 GError *error = NULL;
1759 char *contents = NULL;
1760 struct qip_logger_data *data = NULL; 1790 struct qip_logger_data *data = NULL;
1761 char *utf8_string = NULL;
1762 struct tm prev_tm; 1791 struct tm prev_tm;
1763 gboolean prev_tm_init = FALSE; 1792 gboolean prev_tm_init = FALSE;
1764 char *c; 1793 char *c;
1765 char *start_log; 1794 char *start_log;
1766 char *escaped;
1767 int offset = 0; 1795 int offset = 0;
1768 1796
1769 g_return_val_if_fail(sn != NULL, list); 1797 g_return_val_if_fail(sn != NULL, list);
1770 g_return_val_if_fail(account != NULL, list); 1798 g_return_val_if_fail(account != NULL, list);
1771 1799
1791 filename = g_strdup_printf("%s.txt", purple_normalize(account, sn)); 1819 filename = g_strdup_printf("%s.txt", purple_normalize(account, sn));
1792 path = g_build_filename(logdir, username, "History", filename, NULL); 1820 path = g_build_filename(logdir, username, "History", filename, NULL);
1793 g_free(username); 1821 g_free(username);
1794 g_free(filename); 1822 g_free(filename);
1795 1823
1796 purple_debug_info("QIP logger list", "Reading %s\n", path); 1824 if ((contents = qip_get_file_contents(path)) == NULL)
1797 1825 {
1798 error = NULL;
1799 if (!g_file_get_contents(path, &contents, &length, &error)) {
1800 purple_debug_error("QIP logger list",
1801 "Couldn't read file %s: %s \n", path, error->message);
1802 g_error_free(error);
1803
1804 g_free(path); 1826 g_free(path);
1805 return list; 1827 return list;
1806 } 1828 }
1807
1808 g_return_val_if_fail(contents != NULL, list);
1809
1810 purple_debug_info("QIP logger list", "File %s is found\n", path);
1811
1812 /* Convert file contents from Cp1251 to UTF-8 codeset */
1813 error = NULL;
1814 if (!(utf8_string = g_convert(contents, length, "UTF-8", "Cp1251", NULL, NULL, &error))) {
1815 purple_debug_error("QIP logger list",
1816 "Couldn't convert file %s to UTF-8: %s\n", path, error->message);
1817 g_error_free(error);
1818
1819 g_free(path);
1820 g_free(contents);
1821 return list;
1822 }
1823
1824 g_free(contents);
1825 contents = g_markup_escape_text(utf8_string, -1);
1826 g_free(utf8_string);
1827 1829
1828 c = contents; 1830 c = contents;
1829 start_log = contents; 1831 start_log = contents;
1830 while (*c) { 1832 while (*c) {
1831 if (purple_str_has_prefix(c, QIP_LOG_IN_MESSAGE_ESC) || 1833 if (purple_str_has_prefix(c, QIP_LOG_IN_MESSAGE_ESC) ||
1832 purple_str_has_prefix(c, QIP_LOG_OUT_MESSAGE_ESC)) { 1834 purple_str_has_prefix(c, QIP_LOG_OUT_MESSAGE_ESC)) {
1833 1835
1834 gchar *new_line = c; 1836 char *tmp;
1837 char *new_line = c;
1835 1838
1836 /* find EOL */ 1839 /* find EOL */
1837 c = strstr(c, "\n"); 1840 c = strstr(c, "\n");
1838 c++; 1841 c++;
1839 1842
1937 g_free(contents); 1940 g_free(contents);
1938 g_free(path); 1941 g_free(path);
1939 return g_list_reverse(list); 1942 return g_list_reverse(list);
1940 } 1943 }
1941 1944
1942 static char * qip_logger_read (PurpleLog *log, PurpleLogReadFlags *flags) 1945 static char *qip_logger_read(PurpleLog *log, PurpleLogReadFlags *flags)
1943 { 1946 {
1944 struct qip_logger_data *data; 1947 struct qip_logger_data *data;
1945 PurpleBuddy *buddy; 1948 PurpleBuddy *buddy;
1946 GString *formatted; 1949 GString *formatted;
1947 char *c; 1950 char *c;
1948 const char *line; 1951 const char *line;
1949 GError *error = NULL; 1952 gchar *contents;
1950 gchar *contents = NULL; 1953 char *selected;
1951 gsize length;
1952 1954
1953 g_return_val_if_fail(log != NULL, g_strdup("")); 1955 g_return_val_if_fail(log != NULL, g_strdup(""));
1954 1956
1955 data = log->logger_data; 1957 data = log->logger_data;
1956 1958
1957 g_return_val_if_fail(data->path != NULL, g_strdup("")); 1959 g_return_val_if_fail(data->path != NULL, g_strdup(""));
1958 g_return_val_if_fail(data->length > 0, g_strdup("")); 1960 g_return_val_if_fail(data->length > 0, g_strdup(""));
1959 1961
1960 purple_debug_info("QIP logger read", "Reading %s\n", data->path); 1962 if ((contents = qip_get_file_contents(data->path)) == NULL)
1961 1963 {
1962 error = NULL; 1964 return g_strdup("");
1963 if (!g_file_get_contents(data->path, &contents, &length, &error)) 1965 }
1964 if (error) { 1966
1965 purple_debug_error("QIP logger list", 1967 buddy = purple_find_buddy(log->account, log->name);
1966 "Couldn't read file %s \n", data->path); 1968
1967 1969 selected = g_strndup(contents + data->offset, data->length + 2);
1968 g_error_free(error); 1970 selected[data->length] = '\n';
1969 } 1971 selected[data->length + 1] = '\0';
1970 if (contents) { 1972
1971 gchar * utf8_string; 1973 g_free(contents);
1972 1974 contents = selected;
1973 /* We should convert file contents from Cp1251 to UTF-8 codeset */ 1975
1974 error = NULL; 1976 /* Apply formatting... */
1975 if (!(utf8_string = g_convert (contents, length, "UTF-8", "Cp1251", NULL, NULL, &error))) { 1977 formatted = g_string_sized_new(data->length + 2);
1976 if (error) { 1978 c = contents;
1977 purple_debug_error("QIP logger read", 1979 line = contents;
1978 "Couldn't convert file %s to UTF-8\n", data->path); 1980
1979 g_error_free(error); 1981 while (*c) {
1982 gboolean is_in_message = FALSE;
1983
1984 if (purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC) ||
1985 purple_str_has_prefix(line, QIP_LOG_OUT_MESSAGE_ESC)) {
1986
1987 char *tmp;
1988 const char *buddy_name;
1989
1990 is_in_message = purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC);
1991
1992 /* find EOL */
1993 c = strstr(c, "\n");
1994
1995 /* XXX: Do we need buddy_name when we have buddy->alias? */
1996 buddy_name = ++c;
1997
1998 /* Find the last '(' character. */
1999 if ((tmp = strstr(c, "\n")) != NULL)
2000 c = g_strrstr(tmp, "(");
2001 else {
2002 while (*c)
2003 c++;
2004 c--;
2005 c = g_strrstr(c, "(");
1980 } 2006 }
1981 } else { 2007
1982 char *escaped; 2008 if (c != NULL) {
1983 char *selected; 2009 const char *timestamp = c;
1984 2010 int hour;
1985 purple_debug_info("QIP logger read", 2011 int min;
1986 "File %s converted successfully\n", data->path); 2012 int sec;
1987 2013
1988 g_free(contents); 2014 timestamp++;
1989 contents = utf8_string; 2015
1990 2016 /* Parse the time, day, month and year */
1991 /* Load miscellaneous data. */ 2017 if (sscanf(timestamp, "%u:%u:%u",
1992 buddy = purple_find_buddy(log->account, log->name); 2018 &hour, &min, &sec) != 3) {
1993 2019 purple_debug_error("QIP logger read",
1994 escaped = g_markup_escape_text(contents, -1); 2020 "Parsing timestamp error\n");
1995 g_free(contents); 2021 } else {
1996 contents = escaped; 2022 g_string_append(formatted, "<font size=\"2\">");
1997 2023 /* TODO: Figure out if we can do anything more locale-independent. */
1998 selected = g_strndup(contents + data->offset, data->length + 2); 2024 g_string_append_printf(formatted,
1999 selected[data->length] = '\n'; 2025 "(%u:%02u:%02u) %cM ", hour % 12,
2000 selected[data->length + 1] = '\0'; 2026 min, sec, (hour >= 12) ? 'P': 'A');
2001 2027 g_string_append(formatted, "</font> ");
2002 g_free(contents); 2028
2003 contents = selected; 2029 if (is_in_message) {
2004 2030 if (buddy_name != NULL && buddy->alias) {
2005 /* Apply formatting... */ 2031 g_string_append_printf(formatted,
2006 formatted = g_string_sized_new(strlen(contents)); 2032 "<span style=\"color: #A82F2F;\">"
2007 c = contents; 2033 "<b>%s</b></span>: ", buddy->alias);
2008 line = contents; 2034 }
2009 2035 } else {
2010 while (*c) { 2036 const char *acct_name;
2011 gboolean is_in_message = FALSE; 2037 acct_name = purple_account_get_alias(log->account);
2012 2038 if (!acct_name)
2013 if (purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC) || 2039 acct_name = purple_account_get_username(log->account);
2014 purple_str_has_prefix(line, QIP_LOG_OUT_MESSAGE_ESC)) { 2040
2015 const char *buddy_name; 2041 g_string_append_printf(formatted,
2016 is_in_message = purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC); 2042 "<span style=\"color: #16569E;\">"
2017 2043 "<b>%s</b></span>: ", acct_name);
2018 /* find EOL */ 2044 }
2045
2046 /* find EOF */
2019 c = strstr(c, "\n"); 2047 c = strstr(c, "\n");
2020
2021 /* XXX: Do we need buddy_name when we have buddy->alias? */
2022 buddy_name = ++c;
2023
2024 /* searching '(' character from the end of the line */
2025 c = strstr(c, "\n");
2026 while (*c && *c != '(')
2027 --c;
2028
2029 if (*c == '(') {
2030 const char *timestamp = c;
2031 int hour;
2032 int min;
2033 int sec;
2034
2035 timestamp++;
2036
2037 /* Parse the time, day, month and year */
2038 if (sscanf(timestamp, "%u:%u:%u",
2039 &hour, &min, &sec) != 3) {
2040 purple_debug_error("QIP logger read",
2041 "Parsing timestamp error\n");
2042 } else {
2043 g_string_append(formatted, "<font size=\"2\">");
2044 g_string_append_printf(formatted,
2045 "(%u:%02u:%02u) %cM ", hour % 12,
2046 min, sec, (hour >= 12) ? 'P': 'A');
2047 g_string_append(formatted, "</font> ");
2048
2049 if (is_in_message) {
2050 if (buddy_name != NULL && buddy->alias) {
2051 g_string_append_printf(formatted,
2052 "<span style=\"color: #A82F2F;\">"
2053 "<b>%s</b></span>: ", buddy->alias);
2054 }
2055 } else {
2056 const char *acct_name;
2057 acct_name = purple_account_get_alias(log->account);
2058 if (!acct_name)
2059 acct_name = purple_account_get_username(log->account);
2060
2061 g_string_append_printf(formatted,
2062 "<span style=\"color: #16569E;\">"
2063 "<b>%s</b></span>: ", acct_name);
2064 }
2065
2066 /* find EOF */
2067 c = strstr(c, "\n");
2068 line = ++c;
2069 }
2070 }
2071 } else {
2072 if ((c = strstr(c, "\n")))
2073 *c = '\0';
2074
2075 if (line[0] != '\n' && line[0] != '\r') {
2076
2077 g_string_append(formatted, line);
2078 g_string_append_c(formatted, '\n');
2079 }
2080 line = ++c; 2048 line = ++c;
2081 } 2049 }
2082 } 2050 }
2051 } else {
2052 if ((c = strstr(c, "\n")))
2053 *c = '\0';
2054
2055 if (line[0] != '\n' && line[0] != '\r') {
2056
2057 g_string_append(formatted, line);
2058 g_string_append_c(formatted, '\n');
2059 }
2060 line = ++c;
2083 } 2061 }
2084 } 2062 }
2085 g_free(contents); 2063 g_free(contents);
2064
2086 /* XXX: TODO: Avoid this g_strchomp() */ 2065 /* XXX: TODO: Avoid this g_strchomp() */
2087 return g_strchomp(g_string_free(formatted, FALSE)); 2066 return g_strchomp(g_string_free(formatted, FALSE));
2088 } 2067 }
2089 2068
2090 static int qip_logger_size (PurpleLog *log) 2069 static int qip_logger_size (PurpleLog *log)