Mercurial > pidgin
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) |
