Mercurial > pidgin
comparison libpurple/plugins/log_reader.c @ 17979:c8d2e131cc37
QIP logger was implemented
author | Michael Shkutkov <mshkutkov@soc.pidgin.im> |
---|---|
date | Wed, 13 Jun 2007 12:26:17 +0000 |
parents | 21773944db4b |
children | b5e9a814b711 |
comparison
equal
deleted
inserted
replaced
17978:fa4b70c5ea9d | 17979:c8d2e131cc37 |
---|---|
1722 g_free(data->path); | 1722 g_free(data->path); |
1723 g_free(data->their_nickname); | 1723 g_free(data->their_nickname); |
1724 | 1724 |
1725 } | 1725 } |
1726 | 1726 |
1727 /***************************************************************************** | |
1728 * QIP Logger * | |
1729 *****************************************************************************/ | |
1730 | |
1731 /* The QIP logger doesn't write logs, only reads them. This is to include | |
1732 * QIP logs in the log viewer transparently. | |
1733 */ | |
1734 #define QIP_LOG_DELIMITER "--------------------------------------" | |
1735 #define QIP_LOG_IN_MESSAGE (QIP_LOG_DELIMITER "<-") | |
1736 #define QIP_LOG_OUT_MESSAGE (QIP_LOG_DELIMITER ">-") | |
1737 #define QIP_LOG_IN_MESSAGE_ESC (QIP_LOG_DELIMITER "<-") | |
1738 #define QIP_LOG_OUT_MESSAGE_ESC (QIP_LOG_DELIMITER ">-") | |
1739 | |
1740 #define DEBUG_MESSAGE(var, sign, value, title) if(var sign value) \ | |
1741 purple_debug(PURPLE_DEBUG_ERROR, title, \ | |
1742 #var " " #sign " " #value "\n"); | |
1743 | |
1744 static PurpleLogLogger *qip_logger; | |
1745 static void qip_logger_finalize(PurpleLog *log); | |
1746 | |
1747 struct qip_logger_data { | |
1748 | |
1749 char *path; /* FIXME: Change this to use PurpleStringref like log.c:old_logger_list */ | |
1750 int offset; | |
1751 int length; | |
1752 }; | |
1753 | |
1754 static GList *qip_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account) | |
1755 { | |
1756 GList *list = NULL; | |
1757 const char *logdir; | |
1758 PurplePlugin *plugin; | |
1759 PurplePluginProtocolInfo *prpl_info; | |
1760 const char *buddy_name; | |
1761 char *username; | |
1762 char *filename; | |
1763 char *path; | |
1764 GError *error = NULL; | |
1765 gchar *contents = NULL; | |
1766 gsize length; | |
1767 gchar *c; | |
1768 | |
1769 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1770 "start\n"); | |
1771 | |
1772 g_return_val_if_fail(sn != NULL, list); | |
1773 g_return_val_if_fail(account != NULL, list); | |
1774 | |
1775 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1776 "arguments not NULL\n"); | |
1777 | |
1778 /* QIP is ICQ messenger. Should we add prpl-aim? */ | |
1779 if (strcmp(account->protocol_id, "prpl-icq")) | |
1780 return list; | |
1781 | |
1782 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1783 "protocol is 'prpl-icq'\n"); | |
1784 | |
1785 logdir = purple_prefs_get_string("/plugins/core/log_reader/qip/log_directory"); | |
1786 | |
1787 /* By clearing the log directory path, this logger can be (effectively) disabled. */ | |
1788 if (!*logdir) | |
1789 return list; | |
1790 | |
1791 plugin = purple_find_prpl(purple_account_get_protocol_id(account)); | |
1792 if (!plugin) | |
1793 return NULL; | |
1794 | |
1795 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); | |
1796 if (!prpl_info->list_icon) | |
1797 return NULL; | |
1798 | |
1799 buddy_name = g_strdup(purple_normalize(account, sn)); | |
1800 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1801 "buddy_name %s\n", buddy_name); | |
1802 | |
1803 username = g_strdup(purple_normalize(account, account->username)); | |
1804 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1805 "username %s\n", username); | |
1806 | |
1807 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1808 "sn %s\n", sn); | |
1809 | |
1810 filename = g_strdup_printf("%s.txt", buddy_name); | |
1811 path = g_build_filename( | |
1812 logdir, username, "History", filename, NULL); | |
1813 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1814 "Reading %s\n", path); | |
1815 if (!g_file_get_contents(path, &contents, &length, &error)) | |
1816 if (error) | |
1817 g_error_free(error); | |
1818 | |
1819 if (contents) { | |
1820 struct qip_logger_data *data = NULL; | |
1821 | |
1822 purple_debug(PURPLE_DEBUG_INFO, "QIP logger list", | |
1823 "File %s is found\n", filename); | |
1824 c = contents; | |
1825 if (purple_str_has_prefix(c, QIP_LOG_IN_MESSAGE) || | |
1826 purple_str_has_prefix(c, QIP_LOG_OUT_MESSAGE)) { | |
1827 | |
1828 /* find next line */ | |
1829 while(*c && *c != '\n') { | |
1830 c++; | |
1831 } | |
1832 | |
1833 if (*c) { | |
1834 char *timestamp = c; | |
1835 | |
1836 while (*timestamp && (*timestamp !='(')) | |
1837 timestamp++; | |
1838 | |
1839 if (*timestamp == '(') { | |
1840 struct tm tm; | |
1841 | |
1842 timestamp++; | |
1843 | |
1844 /* Parse the time, day, month and year */ | |
1845 if (sscanf(timestamp, "%u:%u:%u %u/%u/%u", | |
1846 &tm.tm_hour, &tm.tm_min, &tm.tm_sec, | |
1847 &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 6) { | |
1848 purple_debug(PURPLE_DEBUG_ERROR, "QIP logger list", | |
1849 "Parsing timestamp error\n"); | |
1850 } else { | |
1851 PurpleLog *log; | |
1852 | |
1853 | |
1854 /* cos month of year in [0,11] */ | |
1855 tm.tm_mon -= 1; | |
1856 /* cos years since 1900 */ | |
1857 tm.tm_year -= 1900; | |
1858 | |
1859 purple_debug(PURPLE_DEBUG_INFO, | |
1860 "QIP logger list", | |
1861 "Parsing timestamp: %u/%u/%u %u:%u:%u\n", | |
1862 tm.tm_year, tm.tm_mon, tm.tm_mday, | |
1863 tm.tm_hour, tm.tm_min, tm.tm_sec); | |
1864 | |
1865 /* Let the C library deal with | |
1866 * daylight savings time. | |
1867 */ | |
1868 tm.tm_isdst = -1; | |
1869 | |
1870 data = g_new0( | |
1871 struct qip_logger_data, 1); | |
1872 data->path = g_strdup(path); | |
1873 data->offset = 0; | |
1874 data->length = strlen(contents); | |
1875 | |
1876 /* XXX: Look into this later... Should we pass in a struct tm? */ | |
1877 log = purple_log_new(PURPLE_LOG_IM, | |
1878 sn, account, NULL, mktime(&tm), NULL); | |
1879 | |
1880 log->logger = qip_logger; | |
1881 log->logger_data = data; | |
1882 | |
1883 list = g_list_append(list, log); | |
1884 } | |
1885 } | |
1886 } | |
1887 } | |
1888 | |
1889 g_free(contents); | |
1890 } | |
1891 | |
1892 g_free(username); | |
1893 g_free(path); | |
1894 g_free(filename); | |
1895 | |
1896 return list; | |
1897 } | |
1898 | |
1899 static char * qip_logger_read (PurpleLog *log, PurpleLogReadFlags *flags) | |
1900 { | |
1901 struct qip_logger_data *data; | |
1902 char *read; | |
1903 FILE *file; | |
1904 PurpleBuddy *buddy; | |
1905 char *escaped; | |
1906 GString *formatted; | |
1907 char *c; | |
1908 const char *line; | |
1909 | |
1910 purple_debug(PURPLE_DEBUG_INFO, "QIP logger read", | |
1911 "start\n"); | |
1912 | |
1913 DEBUG_MESSAGE(log, ==, NULL, "QIP logger read"); | |
1914 g_return_val_if_fail(log != NULL, g_strdup("")); | |
1915 | |
1916 data = log->logger_data; | |
1917 | |
1918 DEBUG_MESSAGE(data->path, ==, NULL, "QIP logger read"); | |
1919 g_return_val_if_fail(data->path != NULL, g_strdup("")); | |
1920 | |
1921 DEBUG_MESSAGE(data->length, <=, 0, "QIP logger read"); | |
1922 g_return_val_if_fail(data->length > 0, g_strdup("")); | |
1923 | |
1924 | |
1925 purple_debug(PURPLE_DEBUG_INFO, "QIP logger read", | |
1926 "Reading %s\n", data->path); | |
1927 | |
1928 read = g_malloc(data->length + 2); | |
1929 | |
1930 file = g_fopen(data->path, "rb"); | |
1931 fseek(file, data->offset, SEEK_SET); | |
1932 fread(read, data->length, 1, file); | |
1933 fclose(file); | |
1934 | |
1935 if (read[data->length-1] == '\n') { | |
1936 read[data->length] = '\0'; | |
1937 } else { | |
1938 read[data->length] = '\n'; | |
1939 read[data->length+1] = '\0'; | |
1940 } | |
1941 | |
1942 /* Load miscellaneous data. */ | |
1943 buddy = purple_find_buddy(log->account, log->name); | |
1944 | |
1945 escaped = g_markup_escape_text(read, -1); | |
1946 g_free(read); | |
1947 read = escaped; | |
1948 | |
1949 /* Apply formatting... */ | |
1950 formatted = g_string_sized_new(strlen(read)); | |
1951 c = read; | |
1952 line = read; | |
1953 | |
1954 while (*c) | |
1955 { | |
1956 gboolean is_in_message = FALSE; | |
1957 | |
1958 if (purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC) || | |
1959 purple_str_has_prefix(line, QIP_LOG_OUT_MESSAGE_ESC)) { | |
1960 const char *buddy_name; | |
1961 is_in_message = purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC); | |
1962 | |
1963 purple_debug(PURPLE_DEBUG_INFO, "QIP loggger read", | |
1964 "%s message\n", (is_in_message) ? "incoming" : "Outgoing"); | |
1965 | |
1966 /* find next line */ | |
1967 while(*c && *c!= '\n') | |
1968 c++; | |
1969 /* XXX: Do we need buddy_name when we have buddy->alias? */ | |
1970 buddy_name = c; | |
1971 | |
1972 /* we hope that nickname hasn't '(' symbol */ | |
1973 while (*c && *c != '(') | |
1974 c++; | |
1975 | |
1976 if (*c == '(') { | |
1977 const char *timestamp = c; | |
1978 int hour; | |
1979 int min; | |
1980 int sec; | |
1981 | |
1982 timestamp++; | |
1983 | |
1984 /* Parse the time, day, month and year */ | |
1985 if (sscanf(timestamp, "%u:%u:%u", | |
1986 &hour, &min, &sec) != 3) | |
1987 purple_debug(PURPLE_DEBUG_ERROR, "QIP logger read", | |
1988 "Parsing timestamp error\n"); | |
1989 else { | |
1990 g_string_append(formatted, "<font size=\"2\">"); | |
1991 g_string_append_printf(formatted, | |
1992 "(%u:%02u:%02u) %cM ", hour % 12, | |
1993 min, sec, (hour >= 12) ? 'P': 'A'); | |
1994 g_string_append(formatted, "</font> "); | |
1995 | |
1996 if (is_in_message) { | |
1997 if (buddy_name != NULL && buddy->alias) { | |
1998 g_string_append_printf(formatted, | |
1999 "<span style=\"color: #A82F2F;\">" | |
2000 "<b>%s</b></span>: ", buddy->alias); | |
2001 } | |
2002 } else { | |
2003 const char *acct_name; | |
2004 acct_name = purple_account_get_alias(log->account); | |
2005 if (!acct_name) | |
2006 acct_name = purple_account_get_username(log->account); | |
2007 | |
2008 g_string_append_printf(formatted, | |
2009 "<span style=\"color: #16569E;\">" | |
2010 "<b>%s</b></span>: ", acct_name); | |
2011 } | |
2012 | |
2013 /* find next line */ | |
2014 while(c && *c != '\n') | |
2015 c++; | |
2016 | |
2017 line = ++c; | |
2018 | |
2019 if ((c = strstr(c, "\n"))) | |
2020 *c = '\0'; | |
2021 | |
2022 purple_debug(PURPLE_DEBUG_INFO, "QIP logger read", | |
2023 "writing message: \"%s\"\n", line); | |
2024 | |
2025 g_string_append(formatted, line); | |
2026 line = ++c; | |
2027 g_string_append_c(formatted, '\n'); | |
2028 } | |
2029 } | |
2030 } else { | |
2031 if ((c = strchr(c, '\n'))) | |
2032 *c = '\0'; | |
2033 | |
2034 if (line[0] != '\n' && line[0] != '\r') { | |
2035 purple_debug(PURPLE_DEBUG_INFO, "QIP logger read", | |
2036 "line is not delimiter \"%s\"\n", line); | |
2037 | |
2038 g_string_append(formatted, line); | |
2039 g_string_append_c(formatted, '\n'); | |
2040 } | |
2041 line = ++c; | |
2042 } | |
2043 } | |
2044 g_free(read); | |
2045 /* XXX: TODO: Avoid this g_strchomp() */ | |
2046 return g_strchomp(g_string_free(formatted, FALSE)); | |
2047 } | |
2048 | |
2049 static int qip_logger_size (PurpleLog *log) | |
2050 { | |
2051 struct qip_logger_data *data; | |
2052 char *text; | |
2053 size_t size; | |
2054 | |
2055 g_return_val_if_fail(log != NULL, 0); | |
2056 | |
2057 data = log->logger_data; | |
2058 | |
2059 if (purple_prefs_get_bool("/plugins/core/log_reader/fast_sizes")) { | |
2060 return data ? data->length : 0; | |
2061 } | |
2062 | |
2063 text = qip_logger_read(log, NULL); | |
2064 size = strlen(text); | |
2065 g_free(text); | |
2066 | |
2067 return size; | |
2068 } | |
2069 | |
2070 static void qip_logger_finalize(PurpleLog *log) | |
2071 { | |
2072 struct qip_logger_data *data; | |
2073 | |
2074 g_return_if_fail(log != NULL); | |
2075 | |
2076 data = log->logger_data; | |
2077 | |
2078 g_free(data->path); | |
2079 } | |
1727 | 2080 |
1728 /***************************************************************************** | 2081 /***************************************************************************** |
1729 * Plugin Code * | 2082 * Plugin Code * |
1730 *****************************************************************************/ | 2083 *****************************************************************************/ |
1731 | 2084 |
1968 g_free(folder); | 2321 g_free(folder); |
1969 } else /* !folder */ | 2322 } else /* !folder */ |
1970 path = g_strdup(""); | 2323 path = g_strdup(""); |
1971 #endif | 2324 #endif |
1972 | 2325 |
1973 purple_prefs_add_string("/plugins/core/log_reader/trillian/log_directory", path); | |
1974 g_free(path); | |
1975 | |
1976 #ifdef _WIN32 | 2326 #ifdef _WIN32 |
1977 } /* !found */ | 2327 } /* !found */ |
1978 #endif | 2328 #endif |
2329 | |
2330 /* Add QIP log directory preference. */ | |
2331 purple_prefs_add_none("/plugins/core/log_reader/qip"); | |
2332 | |
2333 #ifdef _WIN32 | |
2334 /* Calculate default Messenger Plus! log directory. */ | |
2335 folder = wpurple_get_special_folder(CSIDL_PROGRAM_FILES); | |
2336 if (folder) { | |
2337 #endif | |
2338 path = g_build_filename( | |
2339 #ifdef _WIN32 | |
2340 folder, | |
2341 #else | |
2342 PURPLE_LOG_READER_WINDOWS_MOUNT_POINT, "Program Files", | |
2343 #endif | |
2344 "QIP", "Users", NULL); | |
2345 #ifdef _WIN32 | |
2346 g_free(folder); | |
2347 } else /* !folder */ | |
2348 path = g_strdup(""); | |
2349 #endif | |
2350 | |
2351 purple_debug(PURPLE_DEBUG_INFO, "QIP log reader", "QIP log directory %s\n", path); | |
2352 | |
2353 purple_prefs_add_string("/plugins/core/log_reader/qip/log_directory", path); | |
2354 g_free(path); | |
1979 } | 2355 } |
1980 | 2356 |
1981 static gboolean | 2357 static gboolean |
1982 plugin_load(PurplePlugin *plugin) | 2358 plugin_load(PurplePlugin *plugin) |
1983 { | 2359 { |
2017 messenger_plus_logger_finalize, | 2393 messenger_plus_logger_finalize, |
2018 messenger_plus_logger_list, | 2394 messenger_plus_logger_list, |
2019 messenger_plus_logger_read, | 2395 messenger_plus_logger_read, |
2020 messenger_plus_logger_size); | 2396 messenger_plus_logger_size); |
2021 purple_log_logger_add(messenger_plus_logger); | 2397 purple_log_logger_add(messenger_plus_logger); |
2022 #endif | 2398 |
2023 | 2399 #endif |
2400 | |
2401 /* The names of IM clients are marked for translation at the request of | |
2402 translators who wanted to transliterate them. Many translators | |
2403 choose to leave them alone. Choose what's best for your language. */ | |
2404 qip_logger = purple_log_logger_new("qip", _("QIP"), 6, | |
2405 NULL, | |
2406 NULL, | |
2407 qip_logger_finalize, | |
2408 qip_logger_list, | |
2409 qip_logger_read, | |
2410 qip_logger_size); | |
2411 purple_log_logger_add(qip_logger); | |
2412 | |
2024 /* The names of IM clients are marked for translation at the request of | 2413 /* The names of IM clients are marked for translation at the request of |
2025 translators who wanted to transliterate them. Many translators | 2414 translators who wanted to transliterate them. Many translators |
2026 choose to leave them alone. Choose what's best for your language. */ | 2415 choose to leave them alone. Choose what's best for your language. */ |
2027 msn_logger = purple_log_logger_new("msn", _("MSN Messenger"), 6, | 2416 msn_logger = purple_log_logger_new("msn", _("MSN Messenger"), 6, |
2028 NULL, | 2417 NULL, |
2058 purple_log_logger_remove(fire_logger); | 2447 purple_log_logger_remove(fire_logger); |
2059 purple_log_logger_remove(messenger_plus_logger); | 2448 purple_log_logger_remove(messenger_plus_logger); |
2060 #endif | 2449 #endif |
2061 purple_log_logger_remove(msn_logger); | 2450 purple_log_logger_remove(msn_logger); |
2062 purple_log_logger_remove(trillian_logger); | 2451 purple_log_logger_remove(trillian_logger); |
2452 purple_log_logger_remove(qip_logger); | |
2063 | 2453 |
2064 return TRUE; | 2454 return TRUE; |
2065 } | 2455 } |
2066 | 2456 |
2067 static PurplePluginPrefFrame * | 2457 static PurplePluginPrefFrame * |
2105 | 2495 |
2106 ppref = purple_plugin_pref_new_with_name_and_label( | 2496 ppref = purple_plugin_pref_new_with_name_and_label( |
2107 "/plugins/core/log_reader/messenger_plus/log_directory", _("Messenger Plus!")); | 2497 "/plugins/core/log_reader/messenger_plus/log_directory", _("Messenger Plus!")); |
2108 purple_plugin_pref_frame_add(frame, ppref); | 2498 purple_plugin_pref_frame_add(frame, ppref); |
2109 #endif | 2499 #endif |
2500 | |
2501 ppref = purple_plugin_pref_new_with_name_and_label( | |
2502 "/plugins/core/log_reader/qip/log_directory", _("QIP")); | |
2503 purple_plugin_pref_frame_add(frame, ppref); | |
2504 purple_debug(PURPLE_DEBUG_INFO, "QIP log reader", "QIP creating directory\n"); | |
2110 | 2505 |
2111 ppref = purple_plugin_pref_new_with_name_and_label( | 2506 ppref = purple_plugin_pref_new_with_name_and_label( |
2112 "/plugins/core/log_reader/msn/log_directory", _("MSN Messenger")); | 2507 "/plugins/core/log_reader/msn/log_directory", _("MSN Messenger")); |
2113 purple_plugin_pref_frame_add(frame, ppref); | 2508 purple_plugin_pref_frame_add(frame, ppref); |
2114 | 2509 |