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