Tue, 29 Aug 2006 02:22:08 +0000
[gaim-migrate @ 17076]
SF Patch #1547720 from Hilbert
Fixes SF Bug #1541097
If you search, leave the Find dialog open, switch tabs, and search again, the search happens in the original tab. This patch fixes that bug. Now when you search, it searches in the active conversation window.
committer: Richard Laager <rlaager@pidgin.im>
| 11459 | 1 | #ifdef HAVE_CONFIG_H |
| 2 | # include <config.h> | |
| 3 | #endif | |
| 4 | ||
| 5 | #include <stdio.h> | |
| 6 | ||
| 7 | #ifndef GAIM_PLUGINS | |
| 8 | # define GAIM_PLUGINS | |
| 9 | #endif | |
| 10 | ||
| 11 | #include "internal.h" | |
| 12 | ||
| 13 | #include "debug.h" | |
| 14 | #include "log.h" | |
| 15 | #include "plugin.h" | |
| 16 | #include "pluginpref.h" | |
| 17 | #include "prefs.h" | |
| 18 | #include "stringref.h" | |
| 19 | #include "util.h" | |
| 20 | #include "version.h" | |
| 21 | #include "xmlnode.h" | |
| 22 | ||
| 23 | /* This must be the last Gaim header included. */ | |
| 24 | #ifdef _WIN32 | |
| 25 | #include "win32dep.h" | |
| 26 | #endif | |
| 27 | ||
| 28 | /* Where is the Windows partition mounted? */ | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
29 | #ifndef GAIM_LOG_READER_WINDOWS_MOUNT_POINT |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
30 | #define GAIM_LOG_READER_WINDOWS_MOUNT_POINT "/mnt/windows" |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
31 | #endif |
| 11459 | 32 | |
| 33 | enum name_guesses { | |
| 34 | NAME_GUESS_UNKNOWN, | |
| 35 | NAME_GUESS_ME, | |
| 36 | NAME_GUESS_THEM | |
| 37 | }; | |
| 38 | ||
| 39 | ||
| 40 | /***************************************************************************** | |
| 41 | * Adium Logger * | |
| 42 | *****************************************************************************/ | |
| 43 | ||
| 44 | /* The adium logger doesn't write logs, only reads them. This is to include | |
| 45 | * Adium logs in the log viewer transparently. | |
| 46 | */ | |
| 47 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
48 | static GaimLogLogger *adium_logger; |
| 11459 | 49 | |
| 50 | enum adium_log_type { | |
| 51 | ADIUM_HTML, | |
| 52 | ADIUM_TEXT, | |
| 53 | }; | |
| 54 | ||
| 55 | struct adium_logger_data { | |
| 56 | char *path; | |
| 57 | enum adium_log_type type; | |
| 58 | }; | |
| 59 | ||
| 60 | static GList *adium_logger_list(GaimLogType type, const char *sn, GaimAccount *account) | |
| 61 | { | |
| 62 | GList *list = NULL; | |
| 63 | const char *logdir; | |
| 64 | GaimPlugin *plugin; | |
| 65 | GaimPluginProtocolInfo *prpl_info; | |
| 66 | char *prpl_name; | |
| 67 | char *temp; | |
| 68 | char *path; | |
| 69 | GDir *dir; | |
| 70 | ||
| 71 | g_return_val_if_fail(sn != NULL, list); | |
| 72 | g_return_val_if_fail(account != NULL, list); | |
| 73 | ||
| 74 | logdir = gaim_prefs_get_string("/plugins/core/log_reader/adium/log_directory"); | |
| 75 | ||
| 76 | /* By clearing the log directory path, this logger can be (effectively) disabled. */ | |
| 77 | if (!*logdir) | |
| 78 | return list; | |
| 79 | ||
| 80 | plugin = gaim_find_prpl(gaim_account_get_protocol_id(account)); | |
| 81 | if (!plugin) | |
| 82 | return NULL; | |
| 83 | ||
| 84 | prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 85 | if (!prpl_info->list_icon) | |
| 86 | return NULL; | |
| 87 | ||
| 88 | prpl_name = g_ascii_strup(prpl_info->list_icon(account, NULL), -1); | |
| 89 | ||
| 90 | temp = g_strdup_printf("%s.%s", prpl_name, account->username); | |
| 91 | path = g_build_filename(logdir, temp, sn, NULL); | |
| 92 | g_free(temp); | |
| 93 | ||
| 94 | dir = g_dir_open(path, 0, NULL); | |
| 95 | if (dir) { | |
| 96 | const gchar *file; | |
| 97 | ||
| 98 | while ((file = g_dir_read_name(dir))) { | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
99 | if (!gaim_str_has_prefix(file, sn)) |
| 11459 | 100 | continue; |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
101 | if (gaim_str_has_suffix(file, ".html") || gaim_str_has_suffix(file, ".AdiumHTMLLog")) { |
| 11459 | 102 | struct tm tm; |
| 103 | const char *date = file; | |
| 104 | ||
| 105 | date += strlen(sn) + 2; | |
| 106 | if (sscanf(date, "%u|%u|%u", | |
| 107 | &tm.tm_year, &tm.tm_mon, &tm.tm_mday) != 3) { | |
| 108 | ||
| 109 | gaim_debug(GAIM_DEBUG_ERROR, "Adium log parse", | |
| 110 | "Filename timestamp parsing error\n"); | |
| 111 | } else { | |
| 112 | char *filename = g_build_filename(path, file, NULL); | |
|
13158
3b4295931fd6
[gaim-migrate @ 15520]
Richard Laager <rlaager@pidgin.im>
parents:
13120
diff
changeset
|
113 | FILE *handle = g_fopen(filename, "rb"); |
| 11459 | 114 | char *contents; |
| 115 | char *contents2; | |
| 116 | struct adium_logger_data *data; | |
| 117 | GaimLog *log; | |
| 118 | ||
| 119 | if (!handle) { | |
| 120 | g_free(filename); | |
| 121 | continue; | |
| 122 | } | |
| 123 | ||
| 124 | /* XXX: This is really inflexible. */ | |
| 125 | contents = g_malloc(57); | |
| 126 | fread(contents, 56, 1, handle); | |
| 127 | fclose(handle); | |
| 128 | contents[56] = '\0'; | |
| 129 | ||
| 130 | /* XXX: This is fairly inflexible. */ | |
| 131 | contents2 = contents; | |
| 132 | while (*contents2 && *contents2 != '>') | |
| 133 | contents2++; | |
| 134 | if (*contents2) | |
| 135 | contents2++; | |
| 136 | while (*contents2 && *contents2 != '>') | |
| 137 | contents2++; | |
| 138 | if (*contents2) | |
| 139 | contents2++; | |
| 140 | ||
| 141 | if (sscanf(contents2, "%u.%u.%u", | |
| 142 | &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 3) { | |
| 143 | ||
| 144 | gaim_debug(GAIM_DEBUG_ERROR, "Adium log parse", | |
| 145 | "Contents timestamp parsing error\n"); | |
| 146 | g_free(contents); | |
| 147 | g_free(filename); | |
| 148 | continue; | |
| 149 | } | |
| 150 | g_free(contents); | |
| 151 | ||
| 152 | data = g_new0(struct adium_logger_data, 1); | |
| 153 | data->path = filename; | |
| 154 | data->type = ADIUM_HTML; | |
| 155 | ||
| 156 | tm.tm_year -= 1900; | |
| 157 | tm.tm_mon -= 1; | |
| 158 | ||
|
13120
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
159 | /* XXX: Look into this later... Should we pass in a struct tm? */ |
|
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
160 | log = gaim_log_new(GAIM_LOG_IM, sn, account, NULL, mktime(&tm), NULL); |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
161 | log->logger = adium_logger; |
| 11459 | 162 | log->logger_data = data; |
| 163 | ||
| 164 | list = g_list_append(list, log); | |
| 165 | } | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
166 | } else if (gaim_str_has_suffix(file, ".adiumLog")) { |
| 11459 | 167 | struct tm tm; |
| 168 | const char *date = file; | |
| 169 | ||
| 170 | date += strlen(sn) + 2; | |
| 171 | if (sscanf(date, "%u|%u|%u", | |
| 172 | &tm.tm_year, &tm.tm_mon, &tm.tm_mday) != 3) { | |
| 173 | ||
| 174 | gaim_debug(GAIM_DEBUG_ERROR, "Adium log parse", | |
| 175 | "Filename timestamp parsing error\n"); | |
| 176 | } else { | |
| 177 | char *filename = g_build_filename(path, file, NULL); | |
|
13158
3b4295931fd6
[gaim-migrate @ 15520]
Richard Laager <rlaager@pidgin.im>
parents:
13120
diff
changeset
|
178 | FILE *handle = g_fopen(filename, "rb"); |
| 11459 | 179 | char *contents; |
| 180 | char *contents2; | |
| 181 | struct adium_logger_data *data; | |
| 182 | GaimLog *log; | |
| 183 | ||
| 184 | if (!handle) { | |
| 185 | g_free(filename); | |
| 186 | continue; | |
| 187 | } | |
| 188 | ||
| 189 | /* XXX: This is really inflexible. */ | |
| 190 | contents = g_malloc(14); | |
| 191 | fread(contents, 13, 1, handle); | |
| 192 | fclose(handle); | |
| 193 | contents[13] = '\0'; | |
| 194 | ||
| 195 | contents2 = contents; | |
| 196 | while (*contents2 && *contents2 != '(') | |
| 197 | contents2++; | |
| 198 | if (*contents2) | |
| 199 | contents2++; | |
| 200 | ||
| 201 | if (sscanf(contents2, "%u.%u.%u", | |
| 202 | &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 3) { | |
| 203 | ||
| 204 | gaim_debug(GAIM_DEBUG_ERROR, "Adium log parse", | |
| 205 | "Contents timestamp parsing error\n"); | |
| 206 | g_free(contents); | |
| 207 | g_free(filename); | |
| 208 | continue; | |
| 209 | } | |
| 210 | ||
| 211 | g_free(contents); | |
| 212 | ||
| 213 | tm.tm_year -= 1900; | |
| 214 | tm.tm_mon -= 1; | |
| 215 | ||
| 216 | data = g_new0(struct adium_logger_data, 1); | |
| 217 | data->path = filename; | |
| 218 | data->type = ADIUM_TEXT; | |
| 219 | ||
|
13120
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
220 | /* XXX: Look into this later... Should we pass in a struct tm? */ |
|
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
221 | log = gaim_log_new(GAIM_LOG_IM, sn, account, NULL, mktime(&tm), NULL); |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
222 | log->logger = adium_logger; |
| 11459 | 223 | log->logger_data = data; |
| 224 | ||
| 225 | list = g_list_append(list, log); | |
| 226 | } | |
| 227 | } | |
| 228 | } | |
| 229 | g_dir_close(dir); | |
| 230 | } | |
| 231 | ||
| 232 | g_free(prpl_name); | |
| 233 | g_free(path); | |
| 234 | ||
| 235 | return list; | |
| 236 | } | |
| 237 | ||
| 238 | static char *adium_logger_read (GaimLog *log, GaimLogReadFlags *flags) | |
| 239 | { | |
| 240 | struct adium_logger_data *data; | |
| 241 | GError *error = NULL; | |
| 242 | gchar *read = NULL; | |
| 243 | gsize length; | |
| 244 | ||
| 245 | g_return_val_if_fail(log != NULL, g_strdup("")); | |
| 246 | ||
| 247 | data = log->logger_data; | |
| 248 | ||
| 249 | g_return_val_if_fail(data->path != NULL, g_strdup("")); | |
| 250 | ||
| 251 | gaim_debug(GAIM_DEBUG_INFO, "Adium log read", | |
| 252 | "Reading %s\n", data->path); | |
| 253 | if (!g_file_get_contents(data->path, &read, &length, &error)) { | |
| 254 | gaim_debug(GAIM_DEBUG_ERROR, "Adium log read", | |
| 255 | "Error reading log\n"); | |
| 256 | if (error) | |
| 257 | g_error_free(error); | |
| 258 | return g_strdup(""); | |
| 259 | } | |
| 260 | ||
| 261 | if (data->type != ADIUM_HTML) { | |
| 262 | char *escaped = g_markup_escape_text(read, -1); | |
| 263 | g_free(read); | |
| 264 | read = escaped; | |
| 265 | } | |
| 266 | ||
| 267 | #ifdef WIN32 | |
| 268 | /* This problem only seems to show up on Windows. | |
| 269 | * The BOM is displaying as a space at the beginning of the log. | |
| 270 | */ | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
271 | if (gaim_str_has_prefix(read, "\xef\xbb\xbf")) |
| 11459 | 272 | { |
| 273 | /* FIXME: This feels so wrong... */ | |
| 274 | char *temp = g_strdup(&(read[3])); | |
| 275 | g_free(read); | |
| 276 | read = temp; | |
| 277 | } | |
| 278 | #endif | |
| 279 | ||
| 280 | /* TODO: Apply formatting. | |
| 281 | * Replace the above hack with something better, since we'll | |
| 282 | * be looping over the entire log file contents anyway. | |
| 283 | */ | |
| 284 | ||
| 285 | return read; | |
| 286 | } | |
| 287 | ||
| 288 | static int adium_logger_size (GaimLog *log) | |
| 289 | { | |
| 290 | struct adium_logger_data *data; | |
| 291 | char *text; | |
| 292 | size_t size; | |
| 293 | ||
| 294 | g_return_val_if_fail(log != NULL, 0); | |
| 295 | ||
| 296 | data = log->logger_data; | |
| 297 | ||
| 298 | if (gaim_prefs_get_bool("/plugins/core/log_reader/fast_sizes")) { | |
| 299 | struct stat st; | |
| 300 | ||
| 301 | if (!data->path || stat(data->path, &st)) | |
| 302 | st.st_size = 0; | |
|
14097
0c340861ab79
[gaim-migrate @ 16638]
Mark Doliner <markdoliner@pidgin.im>
parents:
13702
diff
changeset
|
303 | |
| 11459 | 304 | return st.st_size; |
| 305 | } | |
| 306 | ||
| 307 | text = adium_logger_read(log, NULL); | |
| 308 | size = strlen(text); | |
| 309 | g_free(text); | |
| 310 | ||
| 311 | return size; | |
| 312 | } | |
| 313 | ||
| 314 | static void adium_logger_finalize(GaimLog *log) | |
| 315 | { | |
| 316 | struct adium_logger_data *data; | |
| 317 | ||
| 318 | g_return_if_fail(log != NULL); | |
| 319 | ||
| 320 | data = log->logger_data; | |
| 321 | ||
| 322 | g_free(data->path); | |
| 323 | } | |
| 324 | ||
| 325 | ||
| 326 | /***************************************************************************** | |
| 327 | * Fire Logger * | |
| 328 | *****************************************************************************/ | |
| 329 | ||
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
330 | #if 0 |
| 11459 | 331 | /* The fire logger doesn't write logs, only reads them. This is to include |
| 332 | * Fire logs in the log viewer transparently. | |
| 333 | */ | |
| 334 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
335 | static GaimLogLogger *fire_logger; |
| 11459 | 336 | |
| 337 | struct fire_logger_data { | |
| 338 | }; | |
| 339 | ||
| 340 | static GList *fire_logger_list(GaimLogType type, const char *sn, GaimAccount *account) | |
| 341 | { | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
342 | /* TODO: Do something here. */ |
| 11459 | 343 | return NULL; |
| 344 | } | |
| 345 | ||
| 346 | static char * fire_logger_read (GaimLog *log, GaimLogReadFlags *flags) | |
| 347 | { | |
| 348 | struct fire_logger_data *data; | |
| 349 | ||
| 350 | g_return_val_if_fail(log != NULL, g_strdup("")); | |
| 351 | ||
| 352 | data = log->logger_data; | |
| 353 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
354 | /* TODO: Do something here. */ |
| 11459 | 355 | return g_strdup(""); |
| 356 | } | |
| 357 | ||
| 358 | static int fire_logger_size (GaimLog *log) | |
| 359 | { | |
| 360 | g_return_val_if_fail(log != NULL, 0); | |
| 361 | ||
| 362 | if (gaim_prefs_get_bool("/plugins/core/log_reader/fast_sizes")) | |
| 363 | return 0; | |
| 364 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
365 | /* TODO: Do something here. */ |
| 11459 | 366 | return 0; |
| 367 | } | |
| 368 | ||
| 369 | static void fire_logger_finalize(GaimLog *log) | |
| 370 | { | |
| 371 | g_return_if_fail(log != NULL); | |
| 372 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
373 | /* TODO: Do something here. */ |
| 11459 | 374 | } |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
375 | #endif |
| 11459 | 376 | |
| 377 | ||
| 378 | /***************************************************************************** | |
| 379 | * Messenger Plus! Logger * | |
| 380 | *****************************************************************************/ | |
| 381 | ||
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
382 | #if 0 |
| 11459 | 383 | /* The messenger_plus logger doesn't write logs, only reads them. This is to include |
| 384 | * Messenger Plus! logs in the log viewer transparently. | |
| 385 | */ | |
| 386 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
387 | static GaimLogLogger *messenger_plus_logger; |
| 11459 | 388 | |
| 389 | struct messenger_plus_logger_data { | |
| 390 | }; | |
| 391 | ||
| 392 | static GList *messenger_plus_logger_list(GaimLogType type, const char *sn, GaimAccount *account) | |
| 393 | { | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
394 | /* TODO: Do something here. */ |
| 11459 | 395 | return NULL; |
| 396 | } | |
| 397 | ||
| 398 | static char * messenger_plus_logger_read (GaimLog *log, GaimLogReadFlags *flags) | |
| 399 | { | |
| 400 | struct messenger_plus_logger_data *data = log->logger_data; | |
| 401 | ||
| 402 | g_return_val_if_fail(log != NULL, g_strdup("")); | |
| 403 | ||
| 404 | data = log->logger_data; | |
|
14097
0c340861ab79
[gaim-migrate @ 16638]
Mark Doliner <markdoliner@pidgin.im>
parents:
13702
diff
changeset
|
405 | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
406 | /* TODO: Do something here. */ |
| 11459 | 407 | return g_strdup(""); |
| 408 | } | |
| 409 | ||
| 410 | static int messenger_plus_logger_size (GaimLog *log) | |
| 411 | { | |
| 412 | g_return_val_if_fail(log != NULL, 0); | |
| 413 | ||
| 414 | if (gaim_prefs_get_bool("/plugins/core/log_reader/fast_sizes")) | |
| 415 | return 0; | |
| 416 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
417 | /* TODO: Do something here. */ |
| 11459 | 418 | return 0; |
| 419 | } | |
| 420 | ||
| 421 | static void messenger_plus_logger_finalize(GaimLog *log) | |
| 422 | { | |
| 423 | g_return_if_fail(log != NULL); | |
| 424 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
425 | /* TODO: Do something here. */ |
| 11459 | 426 | } |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
427 | #endif |
| 11459 | 428 | |
| 429 | ||
| 430 | /***************************************************************************** | |
| 431 | * MSN Messenger Logger * | |
| 432 | *****************************************************************************/ | |
| 433 | ||
| 434 | /* The msn logger doesn't write logs, only reads them. This is to include | |
| 435 | * MSN Messenger message histories in the log viewer transparently. | |
| 436 | */ | |
| 437 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
438 | static GaimLogLogger *msn_logger; |
| 11459 | 439 | |
| 440 | struct msn_logger_data { | |
| 441 | xmlnode *root; | |
| 442 | xmlnode *message; | |
| 443 | const char *session_id; | |
| 444 | int last_log; | |
| 445 | GString *text; | |
| 446 | }; | |
| 447 | ||
| 448 | static time_t msn_logger_parse_timestamp(xmlnode *message) | |
| 449 | { | |
| 450 | const char *date; | |
| 451 | const char *time; | |
| 452 | struct tm tm; | |
| 453 | char am_pm; | |
| 454 | ||
| 455 | g_return_val_if_fail(message != NULL, (time_t)0); | |
| 456 | ||
| 457 | date = xmlnode_get_attrib(message, "Date"); | |
| 458 | if (!(date && *date)) { | |
| 459 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log timestamp parse", | |
| 460 | "Attribute missing: %s\n", "Date"); | |
| 461 | return (time_t)0; | |
| 462 | } | |
| 463 | ||
| 464 | time = xmlnode_get_attrib(message, "Time"); | |
| 465 | if (!(time && *time)) { | |
| 466 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log timestamp parse", | |
| 467 | "Attribute missing: %s\n", "Time"); | |
| 468 | return (time_t)0; | |
| 469 | } | |
| 470 | ||
| 471 | if (sscanf(date, "%u/%u/%u", &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) | |
| 472 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log timestamp parse", | |
| 473 | "%s parsing error\n", "Date"); | |
| 474 | ||
| 475 | if (sscanf(time, "%u:%u:%u %c", &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &am_pm) != 4) | |
| 476 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log timestamp parse", | |
| 477 | "%s parsing error\n", "Time"); | |
| 478 | ||
| 479 | tm.tm_year -= 1900; | |
| 480 | tm.tm_mon -= 1; | |
| 481 | if (am_pm == 'P') { | |
| 482 | tm.tm_hour += 12; | |
| 483 | } else if (tm.tm_hour == 12) { | |
| 484 | /* 12 AM = 00 hr */ | |
| 485 | tm.tm_hour = 0; | |
| 486 | } | |
| 487 | /* Let the C library deal with daylight savings time. */ | |
| 488 | tm.tm_isdst = -1; | |
| 489 | ||
| 490 | return mktime(&tm); | |
| 491 | } | |
| 492 | ||
| 493 | ||
| 494 | static GList *msn_logger_list(GaimLogType type, const char *sn, GaimAccount *account) | |
| 495 | { | |
| 496 | GList *list = NULL; | |
| 497 | char *username; | |
| 498 | GaimBuddy *buddy; | |
| 499 | const char *logdir; | |
| 500 | const char *savedfilename = NULL; | |
| 501 | char *logfile; | |
| 502 | char *path; | |
| 503 | GError *error = NULL; | |
| 504 | gchar *contents = NULL; | |
| 505 | gsize length; | |
| 506 | xmlnode *root; | |
| 507 | xmlnode *message; | |
| 508 | const char *old_session_id = ""; | |
| 509 | struct msn_logger_data *data = NULL; | |
| 510 | ||
| 511 | g_return_val_if_fail(sn != NULL, list); | |
| 512 | g_return_val_if_fail(account != NULL, list); | |
| 513 | ||
| 514 | if (strcmp(account->protocol_id, "prpl-msn")) | |
| 515 | return list; | |
| 516 | ||
| 517 | logdir = gaim_prefs_get_string("/plugins/core/log_reader/msn/log_directory"); | |
| 518 | ||
| 519 | /* By clearing the log directory path, this logger can be (effectively) disabled. */ | |
| 520 | if (!*logdir) | |
| 521 | return list; | |
| 522 | ||
| 523 | buddy = gaim_find_buddy(account, sn); | |
| 524 | ||
| 525 | if ((username = g_strdup(gaim_account_get_string( | |
| 526 | account, "log_reader_msn_log_folder", NULL)))) { | |
| 527 | /* As a special case, we allow the null string to kill the parsing | |
| 528 | * straight away. This would allow the user to deal with the case | |
| 529 | * when two account have the same username at different domains and | |
| 530 | * only one has logs stored. | |
| 531 | */ | |
| 532 | if (!*username) { | |
| 533 | g_free(username); | |
| 534 | return list; | |
| 535 | } | |
| 536 | } else { | |
| 537 | username = g_strdup(gaim_normalize(account, account->username)); | |
| 538 | } | |
| 539 | ||
| 540 | if (buddy) | |
| 541 | savedfilename = gaim_blist_node_get_string(&buddy->node, "log_reader_msn_log_filename"); | |
| 542 | ||
| 543 | if (savedfilename) { | |
| 544 | /* As a special case, we allow the null string to kill the parsing | |
| 545 | * straight away. This would allow the user to deal with the case | |
| 546 | * when two buddies have the same username at different domains and | |
| 547 | * only one has logs stored. | |
| 548 | */ | |
| 549 | if (!*savedfilename) { | |
| 550 | g_free(username); | |
| 551 | return list; | |
| 552 | } | |
| 553 | ||
| 554 | logfile = g_strdup(savedfilename); | |
| 555 | } else { | |
| 556 | logfile = g_strdup_printf("%s.xml", gaim_normalize(account, sn)); | |
| 557 | } | |
| 558 | ||
| 559 | path = g_build_filename(logdir, username, "History", logfile, NULL); | |
| 560 | ||
| 561 | if (!g_file_test(path, G_FILE_TEST_EXISTS)) { | |
| 562 | gboolean found = FALSE; | |
| 563 | char *at_sign; | |
| 564 | GDir *dir; | |
| 565 | ||
| 566 | g_free(path); | |
| 567 | ||
| 568 | if (savedfilename) { | |
| 569 | /* We had a saved filename, but it doesn't exist. | |
| 570 | * Returning now is the right course of action because we don't | |
| 571 | * want to detect another file incorrectly. | |
| 572 | */ | |
| 573 | g_free(username); | |
| 574 | g_free(logfile); | |
| 575 | return list; | |
| 576 | } | |
| 577 | ||
| 578 | /* Perhaps we're using a new version of MSN with the weird numbered folders. | |
| 579 | * I don't know how the numbers are calculated, so I'm going to attempt to | |
| 580 | * find logs by pattern matching... | |
| 581 | */ | |
| 582 | ||
| 583 | at_sign = g_strrstr(username, "@"); | |
| 584 | if (at_sign) | |
| 585 | *at_sign = '\0'; | |
| 586 | ||
| 587 | dir = g_dir_open(logdir, 0, NULL); | |
| 588 | if (dir) { | |
| 589 | const gchar *name; | |
| 590 | ||
| 591 | while ((name = g_dir_read_name(dir))) { | |
| 592 | const char *c = name; | |
| 593 | ||
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
594 | if (!gaim_str_has_prefix(c, username)) |
| 11459 | 595 | continue; |
| 596 | ||
| 597 | c += strlen(username); | |
| 598 | while (*c) { | |
| 599 | if (!g_ascii_isdigit(*c)) | |
| 600 | break; | |
| 601 | ||
| 602 | c++; | |
| 603 | } | |
| 604 | ||
| 605 | path = g_build_filename(logdir, name, NULL); | |
| 606 | /* The !c makes sure we got to the end of the while loop above. */ | |
| 607 | if (!*c && g_file_test(path, G_FILE_TEST_IS_DIR)) { | |
| 608 | char *history_path = g_build_filename( | |
| 609 | path, "History", NULL); | |
| 610 | if (g_file_test(history_path, G_FILE_TEST_IS_DIR)) { | |
| 611 | gaim_account_set_string(account, | |
| 612 | "log_reader_msn_log_folder", name); | |
| 613 | g_free(path); | |
| 614 | path = history_path; | |
| 615 | found = TRUE; | |
| 616 | break; | |
| 617 | } | |
| 618 | g_free(path); | |
| 619 | g_free(history_path); | |
| 620 | } | |
| 621 | else | |
| 622 | g_free(path); | |
| 623 | } | |
| 624 | g_dir_close(dir); | |
| 625 | } | |
| 626 | g_free(username); | |
| 627 | ||
| 628 | if (!found) { | |
| 629 | g_free(logfile); | |
| 630 | return list; | |
| 631 | } | |
| 632 | ||
| 633 | /* If we've reached this point, we've found a History folder. */ | |
| 634 | ||
| 635 | username = g_strdup(gaim_normalize(account, sn)); | |
| 636 | at_sign = g_strrstr(username, "@"); | |
| 637 | if (at_sign) | |
| 638 | *at_sign = '\0'; | |
| 639 | ||
| 640 | found = FALSE; | |
| 641 | dir = g_dir_open(path, 0, NULL); | |
| 642 | if (dir) { | |
| 643 | const gchar *name; | |
| 644 | ||
| 645 | while ((name = g_dir_read_name(dir))) { | |
| 646 | const char *c = name; | |
| 647 | ||
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
648 | if (!gaim_str_has_prefix(c, username)) |
| 11459 | 649 | continue; |
| 650 | ||
| 651 | c += strlen(username); | |
| 652 | while (*c) { | |
| 653 | if (!g_ascii_isdigit(*c)) | |
| 654 | break; | |
| 655 | ||
| 656 | c++; | |
| 657 | } | |
| 658 | ||
| 659 | path = g_build_filename(path, name, NULL); | |
| 660 | if (!strcmp(c, ".xml") && | |
| 661 | g_file_test(path, G_FILE_TEST_EXISTS)) { | |
| 662 | found = TRUE; | |
| 663 | g_free(logfile); | |
| 664 | logfile = g_strdup(name); | |
| 665 | break; | |
| 666 | } | |
| 667 | else | |
| 668 | g_free(path); | |
| 669 | } | |
| 670 | g_dir_close(dir); | |
| 671 | } | |
| 672 | g_free(username); | |
| 673 | ||
| 674 | if (!found) { | |
| 675 | g_free(logfile); | |
| 676 | return list; | |
| 677 | } | |
| 678 | } else { | |
| 679 | g_free(username); | |
| 680 | g_free(logfile); | |
| 681 | logfile = NULL; /* No sense saving the obvious buddy@domain.com. */ | |
| 682 | } | |
| 683 | ||
| 684 | gaim_debug(GAIM_DEBUG_INFO, "MSN log read", | |
| 685 | "Reading %s\n", path); | |
| 686 | if (!g_file_get_contents(path, &contents, &length, &error)) { | |
| 687 | g_free(path); | |
| 688 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log read", | |
| 689 | "Error reading log\n"); | |
| 690 | if (error) | |
| 691 | g_error_free(error); | |
| 692 | return list; | |
| 693 | } | |
| 694 | g_free(path); | |
| 695 | ||
| 696 | /* Reading the file was successful... | |
| 697 | * Save its name if it involves the crazy numbers. The idea here is that you could | |
| 698 | * then tweak the blist.xml file by hand if need be. This would be the case if two | |
| 699 | * buddies have the same username at different domains. One set of logs would get | |
| 700 | * detected for both buddies. | |
| 701 | */ | |
| 702 | if (buddy && logfile) { | |
| 703 | gaim_blist_node_set_string(&buddy->node, "log_reader_msn_log_filename", logfile); | |
| 704 | g_free(logfile); | |
| 705 | } | |
| 706 | ||
| 707 | root = xmlnode_from_str(contents, length); | |
| 708 | g_free(contents); | |
| 709 | if (!root) | |
| 710 | return list; | |
| 711 | ||
| 712 | for (message = xmlnode_get_child(root, "Message"); message; | |
| 713 | message = xmlnode_get_next_twin(message)) { | |
| 714 | const char *session_id; | |
| 715 | ||
| 716 | session_id = xmlnode_get_attrib(message, "SessionID"); | |
| 717 | if (!session_id) { | |
| 718 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log parse", | |
| 719 | "Error parsing message: %s\n", "SessionID missing"); | |
| 720 | continue; | |
| 721 | } | |
| 722 | ||
| 723 | if (strcmp(session_id, old_session_id)) { | |
| 724 | /* | |
| 725 | * The session ID differs from the last message. | |
| 726 | * Thus, this is the start of a new conversation. | |
| 727 | */ | |
| 728 | GaimLog *log; | |
| 729 | ||
| 730 | data = g_new0(struct msn_logger_data, 1); | |
| 731 | data->root = root; | |
| 732 | data->message = message; | |
| 733 | data->session_id = session_id; | |
| 734 | data->text = NULL; | |
| 735 | data->last_log = FALSE; | |
| 736 | ||
|
13120
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
737 | /* XXX: Look into this later... Should we pass in a struct tm? */ |
|
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
738 | log = gaim_log_new(GAIM_LOG_IM, sn, account, NULL, msn_logger_parse_timestamp(message), NULL); |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
739 | log->logger = msn_logger; |
| 11459 | 740 | log->logger_data = data; |
| 741 | ||
| 742 | list = g_list_append(list, log); | |
| 743 | } | |
| 744 | old_session_id = session_id; | |
| 745 | } | |
| 746 | ||
| 747 | if (data) | |
| 748 | data->last_log = TRUE; | |
| 749 | ||
| 750 | return list; | |
| 751 | } | |
| 752 | ||
| 753 | static char * msn_logger_read (GaimLog *log, GaimLogReadFlags *flags) | |
| 754 | { | |
| 755 | struct msn_logger_data *data; | |
| 756 | GString *text = NULL; | |
| 757 | xmlnode *message; | |
| 758 | ||
| 759 | g_return_val_if_fail(log != NULL, g_strdup("")); | |
| 760 | ||
| 761 | data = log->logger_data; | |
| 762 | ||
| 763 | if (data->text) { | |
| 764 | /* The GTK code which displays the logs g_free()s whatever is | |
| 765 | * returned from this function. Thus, we can't reuse the str | |
| 766 | * part of the GString. The only solution is to free it and | |
| 767 | * start over. | |
| 768 | */ | |
| 769 | g_string_free(data->text, FALSE); | |
| 770 | } | |
| 771 | ||
| 772 | text = g_string_new(""); | |
| 773 | ||
| 774 | if (!data->root || !data->message || !data->session_id) { | |
| 775 | /* Something isn't allocated correctly. */ | |
| 776 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log parse", | |
| 777 | "Error parsing message: %s\n", "Internal variables inconsistent"); | |
| 778 | data->text = text; | |
| 779 | ||
| 780 | return text->str; | |
| 781 | } | |
| 782 | ||
| 783 | for (message = data->message; message; | |
| 784 | message = xmlnode_get_next_twin(message)) { | |
| 785 | ||
| 786 | const char *new_session_id; | |
| 787 | xmlnode *text_node; | |
| 788 | const char *from_name = NULL; | |
| 789 | const char *to_name = NULL; | |
| 790 | xmlnode *from; | |
| 791 | xmlnode *to; | |
| 792 | enum name_guesses name_guessed = NAME_GUESS_UNKNOWN; | |
| 793 | const char *their_name; | |
| 794 | time_t time_unix; | |
| 795 | struct tm *tm_new; | |
| 796 | char *timestamp; | |
|
14142
97cb27b1093f
[gaim-migrate @ 16701]
Daniel Atallah <datallah@pidgin.im>
parents:
14139
diff
changeset
|
797 | char *tmp; |
| 11459 | 798 | const char *style; |
| 799 | ||
| 800 | new_session_id = xmlnode_get_attrib(message, "SessionID"); | |
| 801 | ||
| 802 | /* If this triggers, something is wrong with the XML. */ | |
| 803 | if (!new_session_id) { | |
| 804 | gaim_debug(GAIM_DEBUG_ERROR, "MSN log parse", | |
| 805 | "Error parsing message: %s\n", "New SessionID missing"); | |
| 806 | break; | |
| 807 | } | |
| 808 | ||
| 809 | if (strcmp(new_session_id, data->session_id)) { | |
| 810 | /* The session ID differs from the first message. | |
| 811 | * Thus, this is the start of a new conversation. | |
| 812 | */ | |
| 813 | break; | |
| 814 | } | |
| 815 | ||
| 816 | text_node = xmlnode_get_child(message, "Text"); | |
| 817 | if (!text_node) | |
| 818 | continue; | |
| 819 | ||
| 820 | from = xmlnode_get_child(message, "From"); | |
| 821 | if (from) { | |
| 822 | xmlnode *user = xmlnode_get_child(from, "User"); | |
| 823 | ||
| 824 | if (user) { | |
| 825 | from_name = xmlnode_get_attrib(user, "FriendlyName"); | |
| 826 | ||
| 827 | /* This saves a check later. */ | |
| 828 | if (!*from_name) | |
| 829 | from_name = NULL; | |
| 830 | } | |
| 831 | } | |
| 832 | ||
| 833 | to = xmlnode_get_child(message, "To"); | |
| 834 | if (to) { | |
| 835 | xmlnode *user = xmlnode_get_child(to, "User"); | |
| 836 | if (user) { | |
| 837 | to_name = xmlnode_get_attrib(user, "FriendlyName"); | |
| 838 | ||
| 839 | /* This saves a check later. */ | |
| 840 | if (!*to_name) | |
| 841 | to_name = NULL; | |
| 842 | } | |
| 843 | } | |
| 844 | ||
| 845 | their_name = from_name; | |
| 846 | if (from_name && gaim_prefs_get_bool("/plugins/core/log_reader/use_name_heuristics")) { | |
| 847 | const char *friendly_name = gaim_connection_get_display_name(log->account->gc); | |
| 848 | ||
|
11702
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
849 | if (friendly_name != NULL) { |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
850 | int friendly_name_length = strlen(friendly_name); |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
851 | int alias_length = strlen(log->account->alias); |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
852 | GaimBuddy *buddy = gaim_find_buddy(log->account, log->name); |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
853 | gboolean from_name_matches; |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
854 | gboolean to_name_matches; |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
855 | |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
856 | if (buddy && buddy->alias) |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
857 | their_name = buddy->alias; |
| 11459 | 858 | |
|
11702
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
859 | /* Try to guess which user is me. |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
860 | * The first step is to determine if either of the names matches either my |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
861 | * friendly name or alias. For this test, "match" is defined as: |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
862 | * ^(friendly_name|alias)([^a-zA-Z0-9].*)?$ |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
863 | */ |
|
14168
b844e3d268ca
[gaim-migrate @ 16740]
Daniel Atallah <datallah@pidgin.im>
parents:
14142
diff
changeset
|
864 | from_name_matches = (gaim_str_has_prefix(from_name, friendly_name) && |
|
13494
413c793bd39f
[gaim-migrate @ 15869]
Richard Laager <rlaager@pidgin.im>
parents:
13492
diff
changeset
|
865 | !isalnum(*(from_name + friendly_name_length))) || |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
866 | (gaim_str_has_prefix(from_name, log->account->alias) && |
|
14168
b844e3d268ca
[gaim-migrate @ 16740]
Daniel Atallah <datallah@pidgin.im>
parents:
14142
diff
changeset
|
867 | !isalnum(*(from_name + alias_length))); |
| 11459 | 868 | |
|
13494
413c793bd39f
[gaim-migrate @ 15869]
Richard Laager <rlaager@pidgin.im>
parents:
13492
diff
changeset
|
869 | to_name_matches = to_name != NULL && ( |
|
413c793bd39f
[gaim-migrate @ 15869]
Richard Laager <rlaager@pidgin.im>
parents:
13492
diff
changeset
|
870 | (gaim_str_has_prefix(to_name, friendly_name) && |
|
413c793bd39f
[gaim-migrate @ 15869]
Richard Laager <rlaager@pidgin.im>
parents:
13492
diff
changeset
|
871 | !isalnum(*(to_name + friendly_name_length))) || |
|
413c793bd39f
[gaim-migrate @ 15869]
Richard Laager <rlaager@pidgin.im>
parents:
13492
diff
changeset
|
872 | (gaim_str_has_prefix(to_name, log->account->alias) && |
|
413c793bd39f
[gaim-migrate @ 15869]
Richard Laager <rlaager@pidgin.im>
parents:
13492
diff
changeset
|
873 | !isalnum(*(to_name + alias_length)))); |
| 11459 | 874 | |
|
11702
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
875 | if (from_name_matches) { |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
876 | if (!to_name_matches) { |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
877 | name_guessed = NAME_GUESS_ME; |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
878 | } |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
879 | } else if (to_name_matches) { |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
880 | name_guessed = NAME_GUESS_THEM; |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
881 | } else { |
|
4977bb9807d0
[gaim-migrate @ 13993]
Richard Laager <rlaager@pidgin.im>
parents:
11503
diff
changeset
|
882 | if (buddy && buddy->alias) { |
| 11459 | 883 | char *alias = g_strdup(buddy->alias); |
| 884 | ||
| 885 | /* "Truncate" the string at the first non-alphanumeric | |
| 886 | * character. The idea is to relax the comparison. | |
| 887 | */ | |
| 888 | char *temp; | |
| 889 | for (temp = alias; *temp ; temp++) { | |
| 890 | if (!isalnum(*temp)) { | |
| 891 | *temp = '\0'; | |
| 892 | break; | |
| 893 | } | |
| 894 | } | |
| 895 | alias_length = strlen(alias); | |
| 896 | ||
| 897 | /* Try to guess which user is them. | |
| 898 | * The first step is to determine if either of the names | |
| 899 | * matches their alias. For this test, "match" is | |
| 900 | * defined as: ^alias([^a-zA-Z0-9].*)?$ | |
| 901 | */ | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
902 | from_name_matches = (gaim_str_has_prefix( |
| 11459 | 903 | from_name, alias) && |
| 904 | !isalnum(*(from_name + | |
| 905 | alias_length))); | |
| 906 | ||
|
14139
22ee84e0002b
[gaim-migrate @ 16698]
Daniel Atallah <datallah@pidgin.im>
parents:
14097
diff
changeset
|
907 | to_name_matches = to_name && (gaim_str_has_prefix( |
| 11459 | 908 | to_name, alias) && |
| 909 | !isalnum(*(to_name + | |
| 910 | alias_length))); | |
| 911 | ||
| 912 | g_free(alias); | |
| 913 | ||
| 914 | if (from_name_matches) { | |
| 915 | if (!to_name_matches) { | |
| 916 | name_guessed = NAME_GUESS_THEM; | |
| 917 | } | |
| 918 | } else if (to_name_matches) { | |
| 919 | name_guessed = NAME_GUESS_ME; | |
| 920 | } else if (buddy->server_alias) { | |
| 921 | friendly_name_length = | |
| 922 | strlen(buddy->server_alias); | |
| 923 | ||
| 924 | /* Try to guess which user is them. | |
| 925 | * The first step is to determine if either of | |
| 926 | * the names matches their friendly name. For | |
| 927 | * this test, "match" is defined as: | |
| 928 | * ^friendly_name([^a-zA-Z0-9].*)?$ | |
| 929 | */ | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
930 | from_name_matches = (gaim_str_has_prefix( |
| 11459 | 931 | from_name, |
| 932 | buddy->server_alias) && | |
| 933 | !isalnum(*(from_name + | |
| 934 | friendly_name_length))); | |
| 935 | ||
|
14168
b844e3d268ca
[gaim-migrate @ 16740]
Daniel Atallah <datallah@pidgin.im>
parents:
14142
diff
changeset
|
936 | to_name_matches = to_name && ( |
|
b844e3d268ca
[gaim-migrate @ 16740]
Daniel Atallah <datallah@pidgin.im>
parents:
14142
diff
changeset
|
937 | (gaim_str_has_prefix( |
| 11459 | 938 | to_name, buddy->server_alias) && |
| 939 | !isalnum(*(to_name + | |
|
14168
b844e3d268ca
[gaim-migrate @ 16740]
Daniel Atallah <datallah@pidgin.im>
parents:
14142
diff
changeset
|
940 | friendly_name_length)))); |
| 11459 | 941 | |
| 942 | if (from_name_matches) { | |
| 943 | if (!to_name_matches) { | |
| 944 | name_guessed = NAME_GUESS_THEM; | |
| 945 | } | |
| 946 | } else if (to_name_matches) { | |
| 947 | name_guessed = NAME_GUESS_ME; | |
| 948 | } | |
| 949 | } | |
| 950 | } | |
| 951 | } | |
| 952 | } | |
| 953 | } | |
| 954 | ||
| 955 | if (name_guessed != NAME_GUESS_UNKNOWN) { | |
| 956 | text = g_string_append(text, "<span style=\"color: #"); | |
| 957 | if (name_guessed == NAME_GUESS_ME) | |
| 958 | text = g_string_append(text, "16569E"); | |
| 959 | else | |
| 960 | text = g_string_append(text, "A82F2F"); | |
| 961 | text = g_string_append(text, ";\">"); | |
| 962 | } | |
| 963 | ||
| 964 | time_unix = msn_logger_parse_timestamp(message); | |
| 965 | tm_new = localtime(&time_unix); | |
| 966 | ||
| 967 | timestamp = g_strdup_printf("<font size=\"2\">(%02u:%02u:%02u)</font> ", | |
| 968 | tm_new->tm_hour, tm_new->tm_min, tm_new->tm_sec); | |
| 969 | text = g_string_append(text, timestamp); | |
| 970 | g_free(timestamp); | |
| 971 | ||
| 972 | if (from_name) { | |
| 973 | text = g_string_append(text, "<b>"); | |
| 974 | ||
| 975 | if (name_guessed == NAME_GUESS_ME) | |
| 976 | text = g_string_append(text, log->account->alias); | |
| 977 | else if (name_guessed == NAME_GUESS_THEM) | |
| 978 | text = g_string_append(text, their_name); | |
| 979 | else | |
| 980 | text = g_string_append(text, from_name); | |
| 981 | ||
| 982 | text = g_string_append(text, ":</b> "); | |
| 983 | } | |
| 984 | ||
| 985 | if (name_guessed != NAME_GUESS_UNKNOWN) | |
| 986 | text = g_string_append(text, "</span>"); | |
| 987 | ||
| 988 | style = xmlnode_get_attrib(text_node, "Style"); | |
| 989 | ||
|
14142
97cb27b1093f
[gaim-migrate @ 16701]
Daniel Atallah <datallah@pidgin.im>
parents:
14139
diff
changeset
|
990 | tmp = xmlnode_get_data(text_node); |
| 11459 | 991 | if (style && *style) { |
| 992 | text = g_string_append(text, "<span style=\""); | |
| 993 | text = g_string_append(text, style); | |
| 994 | text = g_string_append(text, "\">"); | |
|
14142
97cb27b1093f
[gaim-migrate @ 16701]
Daniel Atallah <datallah@pidgin.im>
parents:
14139
diff
changeset
|
995 | text = g_string_append(text, tmp); |
| 11459 | 996 | text = g_string_append(text, "</span>\n"); |
| 997 | } else { | |
|
14142
97cb27b1093f
[gaim-migrate @ 16701]
Daniel Atallah <datallah@pidgin.im>
parents:
14139
diff
changeset
|
998 | text = g_string_append(text, tmp); |
| 11459 | 999 | text = g_string_append(text, "\n"); |
| 1000 | } | |
|
14142
97cb27b1093f
[gaim-migrate @ 16701]
Daniel Atallah <datallah@pidgin.im>
parents:
14139
diff
changeset
|
1001 | g_free(tmp); |
| 11459 | 1002 | } |
| 1003 | ||
| 1004 | data->text = text; | |
| 1005 | ||
| 1006 | return text->str; | |
| 1007 | } | |
| 1008 | ||
| 1009 | static int msn_logger_size (GaimLog *log) | |
| 1010 | { | |
| 1011 | char *text; | |
| 1012 | size_t size; | |
| 1013 | ||
| 1014 | g_return_val_if_fail(log != NULL, 0); | |
| 1015 | ||
| 1016 | if (gaim_prefs_get_bool("/plugins/core/log_reader/fast_sizes")) | |
| 1017 | return 0; | |
| 1018 | ||
| 1019 | text = msn_logger_read(log, NULL); | |
| 1020 | size = strlen(text); | |
| 1021 | g_free(text); | |
| 1022 | ||
| 1023 | return size; | |
| 1024 | } | |
| 1025 | ||
| 1026 | static void msn_logger_finalize(GaimLog *log) | |
| 1027 | { | |
| 1028 | struct msn_logger_data *data; | |
| 1029 | ||
| 1030 | g_return_if_fail(log != NULL); | |
| 1031 | ||
| 1032 | data = log->logger_data; | |
| 1033 | ||
| 1034 | if (data->last_log) | |
| 1035 | xmlnode_free(data->root); | |
| 1036 | ||
| 1037 | if (data->text) | |
| 1038 | g_string_free(data->text, FALSE); | |
| 1039 | } | |
| 1040 | ||
| 1041 | ||
| 1042 | /***************************************************************************** | |
| 1043 | * Trillian Logger * | |
| 1044 | *****************************************************************************/ | |
| 1045 | ||
| 1046 | /* The trillian logger doesn't write logs, only reads them. This is to include | |
| 1047 | * Trillian logs in the log viewer transparently. | |
| 1048 | */ | |
| 1049 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1050 | static GaimLogLogger *trillian_logger; |
| 11459 | 1051 | static void trillian_logger_finalize(GaimLog *log); |
| 1052 | ||
| 1053 | struct trillian_logger_data { | |
| 1054 | char *path; /* FIXME: Change this to use GaimStringref like log.c:old_logger_list */ | |
| 1055 | int offset; | |
| 1056 | int length; | |
| 1057 | char *their_nickname; | |
| 1058 | }; | |
| 1059 | ||
| 1060 | static GList *trillian_logger_list(GaimLogType type, const char *sn, GaimAccount *account) | |
| 1061 | { | |
| 1062 | GList *list = NULL; | |
| 1063 | const char *logdir; | |
| 1064 | GaimPlugin *plugin; | |
| 1065 | GaimPluginProtocolInfo *prpl_info; | |
| 1066 | char *prpl_name; | |
| 1067 | const char *buddy_name; | |
| 1068 | char *filename; | |
| 1069 | char *path; | |
| 1070 | GError *error = NULL; | |
| 1071 | gchar *contents = NULL; | |
| 1072 | gsize length; | |
| 1073 | gchar *line; | |
| 1074 | gchar *c; | |
| 1075 | ||
| 1076 | g_return_val_if_fail(sn != NULL, list); | |
| 1077 | g_return_val_if_fail(account != NULL, list); | |
| 1078 | ||
| 1079 | logdir = gaim_prefs_get_string("/plugins/core/log_reader/trillian/log_directory"); | |
| 1080 | ||
| 1081 | /* By clearing the log directory path, this logger can be (effectively) disabled. */ | |
| 1082 | if (!*logdir) | |
| 1083 | return list; | |
| 1084 | ||
| 1085 | plugin = gaim_find_prpl(gaim_account_get_protocol_id(account)); | |
| 1086 | if (!plugin) | |
| 1087 | return NULL; | |
| 1088 | ||
| 1089 | prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 1090 | if (!prpl_info->list_icon) | |
| 1091 | return NULL; | |
| 1092 | ||
| 1093 | prpl_name = g_ascii_strup(prpl_info->list_icon(account, NULL), -1); | |
| 1094 | ||
| 1095 | buddy_name = gaim_normalize(account, sn); | |
| 1096 | ||
| 1097 | filename = g_strdup_printf("%s.log", buddy_name); | |
| 1098 | path = g_build_filename( | |
| 1099 | logdir, prpl_name, filename, NULL); | |
| 1100 | ||
| 1101 | gaim_debug(GAIM_DEBUG_INFO, "Trillian log list", | |
| 1102 | "Reading %s\n", path); | |
| 1103 | /* FIXME: There's really no need to read the entire file at once. | |
| 1104 | * See src/log.c:old_logger_list for a better approach. | |
| 1105 | */ | |
| 1106 | if (!g_file_get_contents(path, &contents, &length, &error)) { | |
| 1107 | if (error) { | |
| 1108 | g_error_free(error); | |
| 1109 | error = NULL; | |
| 1110 | } | |
| 1111 | g_free(path); | |
| 1112 | ||
| 1113 | path = g_build_filename( | |
| 1114 | logdir, prpl_name, "Query", filename, NULL); | |
| 1115 | gaim_debug(GAIM_DEBUG_INFO, "Trillian log list", | |
| 1116 | "Reading %s\n", path); | |
| 1117 | if (!g_file_get_contents(path, &contents, &length, &error)) { | |
| 1118 | if (error) | |
| 1119 | g_error_free(error); | |
| 1120 | } | |
| 1121 | } | |
| 1122 | g_free(filename); | |
| 1123 | ||
| 1124 | if (contents) { | |
| 1125 | struct trillian_logger_data *data = NULL; | |
| 1126 | int offset = 0; | |
| 1127 | int last_line_offset = 0; | |
| 1128 | ||
| 1129 | line = contents; | |
| 1130 | c = contents; | |
| 1131 | while (*c) { | |
| 1132 | offset++; | |
| 1133 | ||
| 1134 | if (*c != '\n') { | |
| 1135 | c++; | |
| 1136 | continue; | |
| 1137 | } | |
| 1138 | ||
| 1139 | *c = '\0'; | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1140 | if (gaim_str_has_prefix(line, "Session Close ")) { |
|
13669
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1141 | if (data && !data->length) { |
|
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1142 | if (!(data->length = last_line_offset - data->offset)) { |
|
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1143 | /* This log had no data, so we remove it. */ |
|
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1144 | GList *last = g_list_last(list); |
| 11459 | 1145 | |
|
13669
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1146 | gaim_debug(GAIM_DEBUG_INFO, "Trillian log list", |
|
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1147 | "Empty log. Offset %i\n", data->offset); |
| 11459 | 1148 | |
|
13669
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1149 | trillian_logger_finalize((GaimLog *)last->data); |
|
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1150 | list = g_list_delete_link(list, last); |
|
ffcdd1227906
[gaim-migrate @ 16070]
Richard Laager <rlaager@pidgin.im>
parents:
13498
diff
changeset
|
1151 | } |
| 11459 | 1152 | } |
| 1153 | } else if (line[0] && line[1] && line [3] && | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1154 | gaim_str_has_prefix(&line[3], "sion Start ")) { |
| 11459 | 1155 | |
| 1156 | char *their_nickname = line; | |
| 1157 | char *timestamp; | |
| 1158 | ||
| 1159 | if (data && !data->length) | |
| 1160 | data->length = last_line_offset - data->offset; | |
| 1161 | ||
| 1162 | while (*their_nickname && (*their_nickname != ':')) | |
| 1163 | their_nickname++; | |
| 1164 | their_nickname++; | |
| 1165 | ||
| 1166 | /* This code actually has nothing to do with | |
| 1167 | * the timestamp YET. I'm simply using this | |
| 1168 | * variable for now to NUL-terminate the | |
| 1169 | * their_nickname string. | |
| 1170 | */ | |
| 1171 | timestamp = their_nickname; | |
| 1172 | while (*timestamp && *timestamp != ')') | |
| 1173 | timestamp++; | |
| 1174 | ||
| 1175 | if (*timestamp == ')') { | |
| 1176 | char *month; | |
| 1177 | struct tm tm; | |
| 1178 | ||
| 1179 | *timestamp = '\0'; | |
| 1180 | if (line[0] && line[1] && line[2]) | |
| 1181 | timestamp += 3; | |
| 1182 | ||
| 1183 | /* Now we start dealing with the timestamp. */ | |
| 1184 | ||
| 1185 | /* Skip over the day name. */ | |
| 1186 | while (*timestamp && (*timestamp != ' ')) | |
| 1187 | timestamp++; | |
| 1188 | *timestamp = '\0'; | |
| 1189 | timestamp++; | |
| 1190 | ||
| 1191 | /* Parse out the month. */ | |
| 1192 | month = timestamp; | |
| 1193 | while (*timestamp && (*timestamp != ' ')) | |
| 1194 | timestamp++; | |
| 1195 | *timestamp = '\0'; | |
| 1196 | timestamp++; | |
| 1197 | ||
| 1198 | /* Parse the day, time, and year. */ | |
| 1199 | if (sscanf(timestamp, "%u %u:%u:%u %u", | |
| 1200 | &tm.tm_mday, &tm.tm_hour, | |
| 1201 | &tm.tm_min, &tm.tm_sec, | |
| 1202 | &tm.tm_year) != 5) { | |
| 1203 | ||
| 1204 | gaim_debug(GAIM_DEBUG_ERROR, | |
| 1205 | "Trillian log timestamp parse", | |
| 1206 | "Session Start parsing error\n"); | |
| 1207 | } else { | |
| 1208 | GaimLog *log; | |
| 1209 | ||
| 1210 | tm.tm_year -= 1900; | |
| 1211 | ||
| 1212 | /* Let the C library deal with | |
| 1213 | * daylight savings time. | |
| 1214 | */ | |
| 1215 | tm.tm_isdst = -1; | |
| 1216 | ||
| 1217 | /* Ugly hack, in case current locale | |
| 1218 | * is not English. This code is taken | |
| 1219 | * from log.c. | |
| 1220 | */ | |
| 1221 | if (strcmp(month, "Jan") == 0) { | |
| 1222 | tm.tm_mon= 0; | |
| 1223 | } else if (strcmp(month, "Feb") == 0) { | |
| 1224 | tm.tm_mon = 1; | |
| 1225 | } else if (strcmp(month, "Mar") == 0) { | |
| 1226 | tm.tm_mon = 2; | |
| 1227 | } else if (strcmp(month, "Apr") == 0) { | |
| 1228 | tm.tm_mon = 3; | |
| 1229 | } else if (strcmp(month, "May") == 0) { | |
| 1230 | tm.tm_mon = 4; | |
| 1231 | } else if (strcmp(month, "Jun") == 0) { | |
| 1232 | tm.tm_mon = 5; | |
| 1233 | } else if (strcmp(month, "Jul") == 0) { | |
| 1234 | tm.tm_mon = 6; | |
| 1235 | } else if (strcmp(month, "Aug") == 0) { | |
| 1236 | tm.tm_mon = 7; | |
| 1237 | } else if (strcmp(month, "Sep") == 0) { | |
| 1238 | tm.tm_mon = 8; | |
| 1239 | } else if (strcmp(month, "Oct") == 0) { | |
| 1240 | tm.tm_mon = 9; | |
| 1241 | } else if (strcmp(month, "Nov") == 0) { | |
| 1242 | tm.tm_mon = 10; | |
| 1243 | } else if (strcmp(month, "Dec") == 0) { | |
| 1244 | tm.tm_mon = 11; | |
| 1245 | } | |
| 1246 | ||
| 1247 | data = g_new0( | |
| 1248 | struct trillian_logger_data, 1); | |
| 1249 | data->path = g_strdup(path); | |
| 1250 | data->offset = offset; | |
| 1251 | data->length = 0; | |
| 1252 | data->their_nickname = | |
| 1253 | g_strdup(their_nickname); | |
| 1254 | ||
|
13120
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
1255 | /* XXX: Look into this later... Should we pass in a struct tm? */ |
| 11459 | 1256 | log = gaim_log_new(GAIM_LOG_IM, |
|
13120
c25222322810
[gaim-migrate @ 15481]
Richard Laager <rlaager@pidgin.im>
parents:
12727
diff
changeset
|
1257 | sn, account, NULL, mktime(&tm), NULL); |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1258 | log->logger = trillian_logger; |
| 11459 | 1259 | log->logger_data = data; |
| 1260 | ||
| 1261 | list = g_list_append(list, log); | |
| 1262 | } | |
| 1263 | } | |
| 1264 | } | |
| 1265 | c++; | |
| 1266 | line = c; | |
| 1267 | last_line_offset = offset; | |
| 1268 | } | |
| 1269 | ||
| 1270 | g_free(contents); | |
| 1271 | } | |
| 1272 | g_free(path); | |
| 1273 | ||
| 1274 | g_free(prpl_name); | |
| 1275 | ||
| 1276 | return list; | |
| 1277 | } | |
| 1278 | ||
| 1279 | static char * trillian_logger_read (GaimLog *log, GaimLogReadFlags *flags) | |
| 1280 | { | |
| 1281 | struct trillian_logger_data *data; | |
| 1282 | char *read; | |
| 1283 | FILE *file; | |
| 1284 | GaimBuddy *buddy; | |
| 1285 | char *escaped; | |
| 1286 | GString *formatted; | |
| 1287 | char *c; | |
| 1288 | char *line; | |
| 1289 | ||
| 1290 | g_return_val_if_fail(log != NULL, g_strdup("")); | |
| 1291 | ||
| 1292 | data = log->logger_data; | |
| 1293 | ||
| 1294 | g_return_val_if_fail(data->path != NULL, g_strdup("")); | |
| 1295 | g_return_val_if_fail(data->length > 0, g_strdup("")); | |
| 1296 | g_return_val_if_fail(data->their_nickname != NULL, g_strdup("")); | |
| 1297 | ||
| 1298 | gaim_debug(GAIM_DEBUG_INFO, "Trillian log read", | |
| 1299 | "Reading %s\n", data->path); | |
| 1300 | ||
| 1301 | read = g_malloc(data->length + 2); | |
| 1302 | ||
|
13158
3b4295931fd6
[gaim-migrate @ 15520]
Richard Laager <rlaager@pidgin.im>
parents:
13120
diff
changeset
|
1303 | file = g_fopen(data->path, "rb"); |
| 11459 | 1304 | fseek(file, data->offset, SEEK_SET); |
| 1305 | fread(read, data->length, 1, file); | |
| 1306 | fclose(file); | |
| 1307 | ||
| 1308 | if (read[data->length-1] == '\n') { | |
| 1309 | read[data->length] = '\0'; | |
| 1310 | } else { | |
| 1311 | read[data->length] = '\n'; | |
| 1312 | read[data->length+1] = '\0'; | |
| 1313 | } | |
| 1314 | ||
| 1315 | /* Load miscellaneous data. */ | |
| 1316 | buddy = gaim_find_buddy(log->account, log->name); | |
| 1317 | ||
| 1318 | escaped = g_markup_escape_text(read, -1); | |
| 1319 | g_free(read); | |
| 1320 | read = escaped; | |
| 1321 | ||
| 1322 | /* Apply formatting... */ | |
| 1323 | formatted = g_string_new(""); | |
| 1324 | c = read; | |
| 1325 | line = read; | |
| 1326 | while (*c) | |
| 1327 | { | |
| 1328 | if (*c == '\n') | |
| 1329 | { | |
| 1330 | char *link_temp_line; | |
| 1331 | char *link; | |
| 1332 | char *timestamp; | |
| 1333 | char *footer = NULL; | |
| 1334 | *c = '\0'; | |
| 1335 | ||
| 1336 | /* Convert links. | |
| 1337 | * | |
| 1338 | * The format is (Link: URL)URL | |
| 1339 | * So, I want to find each occurance of "(Link: " and replace that chunk with: | |
| 1340 | * <a href=" | |
| 1341 | * Then, replace the next ")" with: | |
| 1342 | * "> | |
| 1343 | * Then, replace the next " " (or add this if the end-of-line is reached) with: | |
| 1344 | * </a> | |
| 1345 | */ | |
| 1346 | link_temp_line = NULL; | |
| 1347 | while ((link = g_strstr_len(line, strlen(line), "(Link: "))) { | |
| 1348 | GString *temp; | |
| 1349 | ||
| 1350 | if (!*link) | |
| 1351 | continue; | |
| 1352 | ||
| 1353 | *link = '\0'; | |
| 1354 | link++; | |
| 1355 | ||
| 1356 | temp = g_string_new(line); | |
| 1357 | g_string_append(temp, "<a href=\""); | |
| 1358 | ||
| 1359 | if (strlen(link) >= 6) { | |
| 1360 | link += (sizeof("(Link: ") - 1); | |
| 1361 | ||
| 1362 | while (*link && *link != ')') { | |
| 1363 | g_string_append_c(temp, *link); | |
| 1364 | link++; | |
| 1365 | } | |
| 1366 | if (link) { | |
| 1367 | link++; | |
| 1368 | ||
| 1369 | g_string_append(temp, "\">"); | |
| 1370 | while (*link && *link != ' ') { | |
| 1371 | g_string_append_c(temp, *link); | |
| 1372 | link++; | |
| 1373 | } | |
| 1374 | g_string_append(temp, "</a>"); | |
| 1375 | } | |
| 1376 | ||
| 1377 | g_string_append(temp, link); | |
| 1378 | ||
| 1379 | /* Free the last round's line. */ | |
| 1380 | if (link_temp_line) | |
| 1381 | g_free(line); | |
| 1382 | ||
| 1383 | line = temp->str; | |
| 1384 | g_string_free(temp, FALSE); | |
| 1385 | ||
| 1386 | /* Save this memory location so we can free it later. */ | |
| 1387 | link_temp_line = line; | |
| 1388 | } | |
| 1389 | } | |
| 1390 | ||
| 1391 | timestamp = ""; | |
| 1392 | if (*line == '[') { | |
| 1393 | timestamp = line; | |
| 1394 | while (*timestamp && *timestamp != ']') | |
| 1395 | timestamp++; | |
| 1396 | if (*timestamp == ']') { | |
| 1397 | *timestamp = '\0'; | |
| 1398 | line++; | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1399 | /* TODO: Parse the timestamp and convert it to Gaim's format. */ |
| 11459 | 1400 | g_string_append_printf(formatted, |
| 1401 | "<font size=\"2\">(%s)</font> ", line); | |
| 1402 | line = timestamp; | |
| 1403 | if (line[1] && line[2]) | |
| 1404 | line += 2; | |
| 1405 | } | |
| 1406 | ||
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1407 | if (gaim_str_has_prefix(line, "*** ")) { |
| 11459 | 1408 | line += (sizeof("*** ") - 1); |
| 1409 | g_string_append(formatted, "<b>"); | |
| 1410 | footer = "</b>"; | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1411 | if (gaim_str_has_prefix(line, "NOTE: This user is offline.")) { |
| 11459 | 1412 | line = _("User is offline."); |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1413 | } else if (gaim_str_has_prefix(line, |
| 11459 | 1414 | "NOTE: Your status is currently set to ")) { |
| 1415 | ||
| 1416 | line += (sizeof("NOTE: ") - 1); | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1417 | } else if (gaim_str_has_prefix(line, "Auto-response sent to ")) { |
| 11459 | 1418 | g_string_append(formatted, _("Auto-response sent:")); |
| 1419 | while (*line && *line != ':') | |
| 1420 | line++; | |
| 1421 | if (*line) | |
| 1422 | line++; | |
| 1423 | g_string_append(formatted, "</b>"); | |
| 1424 | footer = NULL; | |
| 1425 | } else if (strstr(line, " signed off ")) { | |
|
13492
70e810de341a
[gaim-migrate @ 15867]
Richard Laager <rlaager@pidgin.im>
parents:
13379
diff
changeset
|
1426 | if (buddy != NULL && buddy->alias) |
| 11459 | 1427 | g_string_append_printf(formatted, |
|
13364
b33c3d9aa7c9
[gaim-migrate @ 15736]
Richard Laager <rlaager@pidgin.im>
parents:
13158
diff
changeset
|
1428 | _("%s has signed off."), buddy->alias); |
| 11459 | 1429 | else |
| 1430 | g_string_append_printf(formatted, | |
|
13364
b33c3d9aa7c9
[gaim-migrate @ 15736]
Richard Laager <rlaager@pidgin.im>
parents:
13158
diff
changeset
|
1431 | _("%s has signed off."), log->name); |
| 11459 | 1432 | line = ""; |
| 1433 | } else if (strstr(line, " signed on ")) { | |
|
13492
70e810de341a
[gaim-migrate @ 15867]
Richard Laager <rlaager@pidgin.im>
parents:
13379
diff
changeset
|
1434 | if (buddy != NULL && buddy->alias) |
| 11459 | 1435 | g_string_append(formatted, buddy->alias); |
| 1436 | else | |
| 1437 | g_string_append(formatted, log->name); | |
| 1438 | line = " logged in."; | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1439 | } else if (gaim_str_has_prefix(line, |
| 11459 | 1440 | "One or more messages may have been undeliverable.")) { |
| 1441 | ||
| 1442 | g_string_append(formatted, | |
| 1443 | "<span style=\"color: #ff0000;\">"); | |
| 1444 | g_string_append(formatted, | |
| 1445 | _("One or more messages may have been " | |
| 1446 | "undeliverable.")); | |
| 1447 | line = ""; | |
| 1448 | footer = "</span></b>"; | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1449 | } else if (gaim_str_has_prefix(line, |
| 11459 | 1450 | "You have been disconnected.")) { |
| 1451 | ||
| 1452 | g_string_append(formatted, | |
| 1453 | "<span style=\"color: #ff0000;\">"); | |
| 1454 | g_string_append(formatted, | |
| 1455 | _("You were disconnected from the server.")); | |
| 1456 | line = ""; | |
| 1457 | footer = "</span></b>"; | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1458 | } else if (gaim_str_has_prefix(line, |
| 11459 | 1459 | "You are currently disconnected.")) { |
| 1460 | ||
| 1461 | g_string_append(formatted, | |
| 1462 | "<span style=\"color: #ff0000;\">"); | |
| 1463 | line = _("You are currently disconnected. Messages " | |
| 1464 | "will not be received unless you are " | |
| 1465 | "logged in."); | |
| 1466 | footer = "</span></b>"; | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1467 | } else if (gaim_str_has_prefix(line, |
| 11459 | 1468 | "Your previous message has not been sent.")) { |
| 1469 | ||
| 1470 | g_string_append(formatted, | |
| 1471 | "<span style=\"color: #ff0000;\">"); | |
|
14142
97cb27b1093f
[gaim-migrate @ 16701]
Daniel Atallah <datallah@pidgin.im>
parents:
14139
diff
changeset
|
1472 | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1473 | if (gaim_str_has_prefix(line, |
| 11459 | 1474 | "Your previous message has not been sent. " |
| 1475 | "Reason: Maximum length exceeded.")) { | |
| 1476 | ||
| 1477 | g_string_append(formatted, | |
| 1478 | _("Message could not be sent because " | |
| 1479 | "the maximum length was exceeded.")); | |
| 1480 | line = ""; | |
| 1481 | } else { | |
| 1482 | g_string_append(formatted, | |
| 1483 | _("Message could not be sent.")); | |
| 1484 | line += (sizeof( | |
| 1485 | "Your previous message " | |
| 1486 | "has not been sent. ") - 1); | |
| 1487 | } | |
| 1488 | ||
| 1489 | footer = "</span></b>"; | |
| 1490 | } | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1491 | } else if (gaim_str_has_prefix(line, data->their_nickname)) { |
|
13492
70e810de341a
[gaim-migrate @ 15867]
Richard Laager <rlaager@pidgin.im>
parents:
13379
diff
changeset
|
1492 | if (buddy != NULL && buddy->alias) { |
| 11459 | 1493 | line += strlen(data->their_nickname) + 2; |
| 1494 | g_string_append_printf(formatted, | |
| 1495 | "<span style=\"color: #A82F2F;\">" | |
| 1496 | "<b>%s</b></span>: ", buddy->alias); | |
| 1497 | } | |
| 1498 | } else { | |
| 1499 | char *line2 = line; | |
| 1500 | while (*line2 && *line2 != ':') | |
| 1501 | line2++; | |
| 1502 | if (*line2 == ':') { | |
| 1503 | line2++; | |
| 1504 | line = line2; | |
| 1505 | g_string_append_printf(formatted, | |
| 1506 | "<span style=\"color: #16569E;\">" | |
| 1507 | "<b>%s</b></span>:", log->account->alias); | |
| 1508 | } | |
| 1509 | } | |
| 1510 | } | |
| 1511 | ||
| 1512 | g_string_append(formatted, line); | |
| 1513 | ||
| 1514 | if (footer) | |
| 1515 | g_string_append(formatted, footer); | |
| 1516 | ||
| 1517 | g_string_append_c(formatted, '\n'); | |
| 1518 | ||
| 1519 | if (link_temp_line) | |
| 1520 | g_free(link_temp_line); | |
| 1521 | ||
| 1522 | c++; | |
| 1523 | line = c; | |
| 1524 | } else | |
| 1525 | c++; | |
| 1526 | } | |
| 1527 | ||
| 1528 | g_free(read); | |
| 1529 | read = formatted->str; | |
| 1530 | g_string_free(formatted, FALSE); | |
| 1531 | ||
| 1532 | return read; | |
| 1533 | } | |
| 1534 | ||
| 1535 | static int trillian_logger_size (GaimLog *log) | |
| 1536 | { | |
| 1537 | struct trillian_logger_data *data; | |
| 1538 | char *text; | |
| 1539 | size_t size; | |
| 1540 | ||
| 1541 | g_return_val_if_fail(log != NULL, 0); | |
| 1542 | ||
| 1543 | data = log->logger_data; | |
| 1544 | ||
| 1545 | if (gaim_prefs_get_bool("/plugins/core/log_reader/fast_sizes")) { | |
| 1546 | return data ? data->length : 0; | |
| 1547 | } | |
| 1548 | ||
| 1549 | text = trillian_logger_read(log, NULL); | |
| 1550 | size = strlen(text); | |
| 1551 | g_free(text); | |
| 1552 | ||
| 1553 | return size; | |
| 1554 | } | |
| 1555 | ||
| 1556 | static void trillian_logger_finalize(GaimLog *log) | |
| 1557 | { | |
| 1558 | struct trillian_logger_data *data; | |
| 1559 | ||
| 1560 | g_return_if_fail(log != NULL); | |
| 1561 | ||
| 1562 | data = log->logger_data; | |
| 1563 | ||
| 1564 | g_free(data->path); | |
| 1565 | g_free(data->their_nickname); | |
| 1566 | ||
| 1567 | } | |
| 1568 | ||
| 1569 | ||
| 1570 | /***************************************************************************** | |
| 1571 | * Plugin Code * | |
| 1572 | *****************************************************************************/ | |
| 1573 | ||
| 1574 | static void | |
| 1575 | init_plugin(GaimPlugin *plugin) | |
| 1576 | { | |
| 1577 | char *path; | |
| 1578 | #ifdef _WIN32 | |
| 1579 | char *folder; | |
|
14334
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1580 | gboolean found = FALSE; |
| 11459 | 1581 | #endif |
| 1582 | ||
| 1583 | g_return_if_fail(plugin != NULL); | |
| 1584 | ||
| 1585 | gaim_prefs_add_none("/plugins/core/log_reader"); | |
| 1586 | ||
| 1587 | ||
| 1588 | /* Add general preferences. */ | |
| 1589 | ||
| 1590 | gaim_prefs_add_bool("/plugins/core/log_reader/fast_sizes", FALSE); | |
| 1591 | gaim_prefs_add_bool("/plugins/core/log_reader/use_name_heuristics", TRUE); | |
| 1592 | ||
| 1593 | ||
| 1594 | /* Add Adium log directory preference. */ | |
| 1595 | gaim_prefs_add_none("/plugins/core/log_reader/adium"); | |
| 1596 | ||
| 1597 | /* Calculate default Adium log directory. */ | |
| 1598 | #ifdef _WIN32 | |
| 1599 | path = ""; | |
| 1600 | #else | |
| 1601 | path = g_build_filename(gaim_home_dir(), "Library", "Application Support", | |
| 1602 | "Adium 2.0", "Users", "Default", "Logs", NULL); | |
| 1603 | #endif | |
| 1604 | ||
| 1605 | gaim_prefs_add_string("/plugins/core/log_reader/adium/log_directory", path); | |
| 1606 | ||
| 1607 | #ifndef _WIN32 | |
| 1608 | g_free(path); | |
| 1609 | #endif | |
| 1610 | ||
| 1611 | ||
| 1612 | /* Add Fire log directory preference. */ | |
| 1613 | gaim_prefs_add_none("/plugins/core/log_reader/fire"); | |
| 1614 | ||
| 1615 | /* Calculate default Fire log directory. */ | |
| 1616 | #ifdef _WIN32 | |
| 1617 | path = ""; | |
| 1618 | #else | |
| 1619 | path = g_build_filename(gaim_home_dir(), "Library", "Application Support", | |
| 1620 | "Fire", "Sessions", NULL); | |
| 1621 | #endif | |
| 1622 | ||
| 1623 | gaim_prefs_add_string("/plugins/core/log_reader/fire/log_directory", path); | |
| 1624 | ||
| 1625 | #ifndef _WIN32 | |
| 1626 | g_free(path); | |
| 1627 | #endif | |
| 1628 | ||
| 1629 | ||
| 1630 | /* Add Messenger Plus! log directory preference. */ | |
| 1631 | gaim_prefs_add_none("/plugins/core/log_reader/messenger_plus"); | |
| 1632 | ||
| 1633 | /* Calculate default Messenger Plus! log directory. */ | |
| 1634 | #ifdef _WIN32 | |
| 1635 | folder = wgaim_get_special_folder(CSIDL_PERSONAL); | |
| 1636 | if (folder) { | |
| 1637 | #endif | |
| 1638 | path = g_build_filename( | |
| 1639 | #ifdef _WIN32 | |
| 1640 | folder, | |
| 1641 | #else | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1642 | GAIM_LOG_READER_WINDOWS_MOUNT_POINT, "Documents and Settings", |
| 11459 | 1643 | g_get_user_name(), "My Documents", |
| 1644 | #endif | |
| 1645 | "My Chat Logs", NULL); | |
| 1646 | #ifdef _WIN32 | |
| 1647 | g_free(folder); | |
| 1648 | } else /* !folder */ | |
| 1649 | path = g_strdup(""); | |
| 1650 | #endif | |
| 1651 | ||
| 1652 | gaim_prefs_add_string("/plugins/core/log_reader/messenger_plus/log_directory", path); | |
| 1653 | g_free(path); | |
| 1654 | ||
| 1655 | ||
| 1656 | /* Add MSN Messenger log directory preference. */ | |
| 1657 | gaim_prefs_add_none("/plugins/core/log_reader/msn"); | |
| 1658 | ||
| 1659 | /* Calculate default MSN message history directory. */ | |
| 1660 | #ifdef _WIN32 | |
| 1661 | folder = wgaim_get_special_folder(CSIDL_PERSONAL); | |
| 1662 | if (folder) { | |
| 1663 | #endif | |
| 1664 | path = g_build_filename( | |
| 1665 | #ifdef _WIN32 | |
| 1666 | folder, | |
| 1667 | #else | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1668 | GAIM_LOG_READER_WINDOWS_MOUNT_POINT, "Documents and Settings", |
| 11459 | 1669 | g_get_user_name(), "My Documents", |
| 1670 | #endif | |
| 1671 | "My Received Files", NULL); | |
| 1672 | #ifdef _WIN32 | |
| 1673 | g_free(folder); | |
| 1674 | } else /* !folder */ | |
| 1675 | path = g_strdup(""); | |
| 1676 | #endif | |
| 1677 | ||
| 1678 | gaim_prefs_add_string("/plugins/core/log_reader/msn/log_directory", path); | |
| 1679 | g_free(path); | |
| 1680 | ||
| 1681 | ||
| 1682 | /* Add Trillian log directory preference. */ | |
| 1683 | gaim_prefs_add_none("/plugins/core/log_reader/trillian"); | |
| 1684 | ||
| 1685 | #ifdef _WIN32 | |
| 1686 | /* XXX: While a major hack, this is the most reliable way I could | |
| 1687 | * think of to determine the Trillian installation directory. | |
| 1688 | */ | |
| 1689 | ||
| 1690 | path = NULL; | |
|
14334
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1691 | if ((folder = wgaim_read_reg_string(HKEY_CLASSES_ROOT, "Trillian.SkinZip\\shell\\Add\\command\\", NULL))) { |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1692 | char *value = folder; |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1693 | char *temp; |
| 11459 | 1694 | |
|
14334
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1695 | /* Break apart buffer. */ |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1696 | if (*value == '"') { |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1697 | value++; |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1698 | temp = value; |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1699 | while (*temp && *temp != '"') |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1700 | temp++; |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1701 | } else { |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1702 | temp = value; |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1703 | while (*temp && *temp != ' ') |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1704 | temp++; |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1705 | } |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1706 | *temp = '\0'; |
| 11459 | 1707 | |
|
14334
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1708 | /* Set path. */ |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1709 | if (gaim_str_has_suffix(value, "trillian.exe")) { |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1710 | value[strlen(value) - (sizeof("trillian.exe") - 1)] = '\0'; |
|
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1711 | path = g_build_filename(value, "users", "default", "talk.ini", NULL); |
| 11459 | 1712 | } |
|
14334
aec64dbd9564
[gaim-migrate @ 16957]
Daniel Atallah <datallah@pidgin.im>
parents:
14297
diff
changeset
|
1713 | g_free(folder); |
| 11459 | 1714 | } |
| 1715 | ||
| 1716 | if (!path) { | |
| 1717 | char *folder = wgaim_get_special_folder(CSIDL_PROGRAM_FILES); | |
|
14139
22ee84e0002b
[gaim-migrate @ 16698]
Daniel Atallah <datallah@pidgin.im>
parents:
14097
diff
changeset
|
1718 | if (folder) { |
| 11459 | 1719 | path = g_build_filename(folder, "Trillian", |
| 1720 | "users", "default", "talk.ini", NULL); | |
| 1721 | g_free(folder); | |
| 1722 | } | |
| 1723 | } | |
| 1724 | ||
| 1725 | if (path) { | |
| 1726 | /* Read talk.ini file to find the log directory. */ | |
| 1727 | GError *error = NULL; | |
| 1728 | ||
|
14139
22ee84e0002b
[gaim-migrate @ 16698]
Daniel Atallah <datallah@pidgin.im>
parents:
14097
diff
changeset
|
1729 | #if 0 && GLIB_CHECK_VERSION(2,6,0) /* FIXME: Not tested yet. */ |
| 11459 | 1730 | GKeyFile *key_file; |
| 1731 | ||
| 1732 | gaim_debug(GAIM_DEBUG_INFO, "Trillian talk.ini read", | |
| 1733 | "Reading %s\n", path); | |
| 1734 | if (!g_key_file_load_from_file(key_file, path, G_KEY_FILE_NONE, GError &error)) { | |
| 1735 | gaim_debug(GAIM_DEBUG_ERROR, "Trillian talk.ini read", | |
| 1736 | "Error reading talk.ini\n"); | |
| 1737 | if (error) | |
| 1738 | g_error_free(error); | |
| 1739 | } else { | |
| 1740 | char *logdir = g_key_file_get_string(key_file, "Logging", "Directory", &error); | |
| 1741 | if (error) { | |
| 1742 | gaim_debug(GAIM_DEBUG_ERROR, "Trillian talk.ini read", | |
| 1743 | "Error reading Directory value from Logging section\n"); | |
| 1744 | g_error_free(error); | |
| 1745 | } | |
| 1746 | ||
| 1747 | if (logdir) { | |
| 1748 | g_strchomp(logdir); | |
| 1749 | gaim_prefs_add_string( | |
| 1750 | "/plugins/core/log_reader/trillian/log_directory", logdir); | |
| 1751 | found = TRUE; | |
| 1752 | } | |
| 1753 | ||
| 1754 | g_key_file_free(key_file); | |
| 1755 | } | |
|
14139
22ee84e0002b
[gaim-migrate @ 16698]
Daniel Atallah <datallah@pidgin.im>
parents:
14097
diff
changeset
|
1756 | #else /* !GLIB_CHECK_VERSION(2,6,0) */ |
| 11459 | 1757 | gsize length; |
|
14139
22ee84e0002b
[gaim-migrate @ 16698]
Daniel Atallah <datallah@pidgin.im>
parents:
14097
diff
changeset
|
1758 | gchar *contents = NULL; |
| 11459 | 1759 | |
| 1760 | gaim_debug(GAIM_DEBUG_INFO, "Trillian talk.ini read", | |
| 1761 | "Reading %s\n", path); | |
| 1762 | if (!g_file_get_contents(path, &contents, &length, &error)) { | |
| 1763 | gaim_debug(GAIM_DEBUG_ERROR, "Trillian talk.ini read", | |
| 1764 | "Error reading talk.ini\n"); | |
| 1765 | if (error) | |
| 1766 | g_error_free(error); | |
| 1767 | } else { | |
| 1768 | char *line = contents; | |
| 1769 | while (*contents) { | |
| 1770 | if (*contents == '\n') { | |
| 1771 | *contents = '\0'; | |
| 1772 | ||
| 1773 | /* XXX: This assumes the first Directory key is under [Logging]. */ | |
|
13498
6a03aa3b5c1a
[gaim-migrate @ 15873]
Richard Laager <rlaager@pidgin.im>
parents:
13494
diff
changeset
|
1774 | if (gaim_str_has_prefix(line, "Directory=")) { |
| 11459 | 1775 | line += (sizeof("Directory=") - 1); |
| 1776 | g_strchomp(line); | |
| 1777 | gaim_prefs_add_string( | |
| 1778 | "/plugins/core/log_reader/trillian/log_directory", | |
| 1779 | line); | |
| 1780 | found = TRUE; | |
| 1781 | } | |
| 1782 | ||
| 1783 | contents++; | |
| 1784 | line = contents; | |
| 1785 | } else | |
| 1786 | contents++; | |
| 1787 | } | |
| 1788 | g_free(path); | |
| 1789 | g_free(contents); | |
| 1790 | } | |
| 1791 | #endif /* !GTK_CHECK_VERSION(2,6,0) */ | |
| 1792 | } /* path */ | |
| 1793 | ||
| 1794 | if (!found) { | |
| 1795 | #endif /* defined(_WIN32) */ | |
| 1796 | ||
| 1797 | /* Calculate default Trillian log directory. */ | |
| 1798 | #ifdef _WIN32 | |
| 1799 | folder = wgaim_get_special_folder(CSIDL_PROGRAM_FILES); | |
| 1800 | if (folder) { | |
| 1801 | #endif | |
| 1802 | path = g_build_filename( | |
| 1803 | #ifdef _WIN32 | |
| 1804 | folder, | |
| 1805 | #else | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1806 | GAIM_LOG_READER_WINDOWS_MOUNT_POINT, "Program Files", |
| 11459 | 1807 | #endif |
| 1808 | "Trillian", "users", "default", "logs", NULL); | |
| 1809 | #ifdef _WIN32 | |
| 1810 | g_free(folder); | |
| 1811 | } else /* !folder */ | |
| 1812 | path = g_strdup(""); | |
| 1813 | #endif | |
| 1814 | ||
| 1815 | gaim_prefs_add_string("/plugins/core/log_reader/trillian/log_directory", path); | |
| 1816 | g_free(path); | |
| 1817 | ||
| 1818 | #ifdef _WIN32 | |
| 1819 | } /* !found */ | |
| 1820 | #endif | |
| 1821 | } | |
| 1822 | ||
| 1823 | static gboolean | |
| 1824 | plugin_load(GaimPlugin *plugin) | |
| 1825 | { | |
| 1826 | g_return_val_if_fail(plugin != NULL, FALSE); | |
| 1827 | ||
|
13702
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1828 | /* The names of IM clients are marked for translation at the request of |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1829 | translators who wanted to transliterate them. Many translators |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1830 | choose to leave them alone. Choose what's best for your language. */ |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1831 | adium_logger = gaim_log_logger_new("adium", _("Adium"), 6, |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1832 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1833 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1834 | adium_logger_finalize, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1835 | adium_logger_list, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1836 | adium_logger_read, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1837 | adium_logger_size); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1838 | gaim_log_logger_add(adium_logger); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1839 | |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1840 | #if 0 |
|
13702
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1841 | /* The names of IM clients are marked for translation at the request of |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1842 | translators who wanted to transliterate them. Many translators |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1843 | choose to leave them alone. Choose what's best for your language. */ |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1844 | fire_logger = gaim_log_logger_new("fire", _("Fire"), 6, |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1845 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1846 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1847 | fire_logger_finalize, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1848 | fire_logger_list, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1849 | fire_logger_read, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1850 | fire_logger_size); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1851 | gaim_log_logger_add(fire_logger); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1852 | |
|
13702
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1853 | /* The names of IM clients are marked for translation at the request of |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1854 | translators who wanted to transliterate them. Many translators |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1855 | choose to leave them alone. Choose what's best for your language. */ |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1856 | messenger_plus_logger = gaim_log_logger_new("messenger_plus", _("Messenger Plus!"), 6, |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1857 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1858 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1859 | messenger_plus_logger_finalize, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1860 | messenger_plus_logger_list, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1861 | messenger_plus_logger_read, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1862 | messenger_plus_logger_size); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1863 | gaim_log_logger_add(messenger_plus_logger); |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1864 | #endif |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1865 | |
|
13702
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1866 | /* The names of IM clients are marked for translation at the request of |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1867 | translators who wanted to transliterate them. Many translators |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1868 | choose to leave them alone. Choose what's best for your language. */ |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1869 | msn_logger = gaim_log_logger_new("msn", _("MSN Messenger"), 6, |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1870 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1871 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1872 | msn_logger_finalize, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1873 | msn_logger_list, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1874 | msn_logger_read, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1875 | msn_logger_size); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1876 | gaim_log_logger_add(msn_logger); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1877 | |
|
13702
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1878 | /* The names of IM clients are marked for translation at the request of |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1879 | translators who wanted to transliterate them. Many translators |
|
35310965f38a
[gaim-migrate @ 16103]
Richard Laager <rlaager@pidgin.im>
parents:
13669
diff
changeset
|
1880 | choose to leave them alone. Choose what's best for your language. */ |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1881 | trillian_logger = gaim_log_logger_new("trillian", _("Trillian"), 6, |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1882 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1883 | NULL, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1884 | trillian_logger_finalize, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1885 | trillian_logger_list, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1886 | trillian_logger_read, |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1887 | trillian_logger_size); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1888 | gaim_log_logger_add(trillian_logger); |
| 11459 | 1889 | |
| 1890 | return TRUE; | |
| 1891 | } | |
| 1892 | ||
| 1893 | static gboolean | |
| 1894 | plugin_unload(GaimPlugin *plugin) | |
| 1895 | { | |
| 1896 | g_return_val_if_fail(plugin != NULL, FALSE); | |
| 1897 | ||
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1898 | gaim_log_logger_remove(adium_logger); |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1899 | #if 0 |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1900 | gaim_log_logger_remove(fire_logger); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1901 | gaim_log_logger_remove(messenger_plus_logger); |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1902 | #endif |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1903 | gaim_log_logger_remove(msn_logger); |
|
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1904 | gaim_log_logger_remove(trillian_logger); |
| 11459 | 1905 | |
| 1906 | return TRUE; | |
| 1907 | } | |
| 1908 | ||
| 1909 | static GaimPluginPrefFrame * | |
| 1910 | get_plugin_pref_frame(GaimPlugin *plugin) | |
| 1911 | { | |
| 1912 | GaimPluginPrefFrame *frame; | |
| 1913 | GaimPluginPref *ppref; | |
| 1914 | ||
| 1915 | g_return_val_if_fail(plugin != NULL, FALSE); | |
| 1916 | ||
| 1917 | frame = gaim_plugin_pref_frame_new(); | |
| 1918 | ||
| 1919 | ||
| 1920 | /* Add general preferences. */ | |
| 1921 | ||
| 1922 | ppref = gaim_plugin_pref_new_with_label(_("General Log Reading Configuration")); | |
| 1923 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 1924 | ||
| 1925 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 1926 | "/plugins/core/log_reader/fast_sizes", _("Fast size calculations")); | |
| 1927 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 1928 | ||
| 1929 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
| 1930 | "/plugins/core/log_reader/use_name_heuristics", _("Use name heuristics")); | |
| 1931 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 1932 | ||
| 1933 | ||
| 1934 | /* Add Log Directory preferences. */ | |
| 1935 | ||
| 1936 | ppref = gaim_plugin_pref_new_with_label(_("Log Directory")); | |
| 1937 | gaim_plugin_pref_frame_add(frame, ppref); | |
| 1938 | ||
| 1939 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1940 | "/plugins/core/log_reader/adium/log_directory", _("Adium")); |
| 11459 | 1941 | gaim_plugin_pref_frame_add(frame, ppref); |
| 1942 | ||
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1943 | #if 0 |
| 11459 | 1944 | ppref = gaim_plugin_pref_new_with_name_and_label( |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1945 | "/plugins/core/log_reader/fire/log_directory", _("Fire")); |
| 11459 | 1946 | gaim_plugin_pref_frame_add(frame, ppref); |
| 1947 | ||
| 1948 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1949 | "/plugins/core/log_reader/messenger_plus/log_directory", _("Messenger Plus!")); |
| 11459 | 1950 | gaim_plugin_pref_frame_add(frame, ppref); |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1951 | #endif |
| 11459 | 1952 | |
| 1953 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1954 | "/plugins/core/log_reader/msn/log_directory", _("MSN Messenger")); |
| 11459 | 1955 | gaim_plugin_pref_frame_add(frame, ppref); |
| 1956 | ||
| 1957 | ppref = gaim_plugin_pref_new_with_name_and_label( | |
|
13377
047baece8bf2
[gaim-migrate @ 15749]
Richard Laager <rlaager@pidgin.im>
parents:
13364
diff
changeset
|
1958 | "/plugins/core/log_reader/trillian/log_directory", _("Trillian")); |
| 11459 | 1959 | gaim_plugin_pref_frame_add(frame, ppref); |
| 1960 | ||
| 1961 | return frame; | |
| 1962 | } | |
| 1963 | ||
| 1964 | static GaimPluginUiInfo prefs_info = { | |
|
12727
05ed142fbbe6
[gaim-migrate @ 15071]
Richard Laager <rlaager@pidgin.im>
parents:
11702
diff
changeset
|
1965 | get_plugin_pref_frame, |
|
05ed142fbbe6
[gaim-migrate @ 15071]
Richard Laager <rlaager@pidgin.im>
parents:
11702
diff
changeset
|
1966 | 0, /* page_num (reserved) */ |
|
05ed142fbbe6
[gaim-migrate @ 15071]
Richard Laager <rlaager@pidgin.im>
parents:
11702
diff
changeset
|
1967 | NULL /* frame (reserved) */ |
| 11459 | 1968 | }; |
| 1969 | ||
| 1970 | static GaimPluginInfo info = | |
| 1971 | { | |
| 1972 | GAIM_PLUGIN_MAGIC, | |
| 1973 | GAIM_MAJOR_VERSION, | |
| 1974 | GAIM_MINOR_VERSION, | |
| 1975 | GAIM_PLUGIN_STANDARD, /**< type */ | |
| 1976 | NULL, /**< ui_requirement */ | |
| 1977 | 0, /**< flags */ | |
| 1978 | NULL, /**< dependencies */ | |
| 1979 | GAIM_PRIORITY_DEFAULT, /**< priority */ | |
| 1980 | "core-log_reader", /**< id */ | |
| 1981 | N_("Log Reader"), /**< name */ | |
| 1982 | VERSION, /**< version */ | |
| 1983 | ||
| 1984 | /** summary */ | |
| 1985 | N_("Includes other IM clients' logs in the " | |
| 1986 | "log viewer."), | |
| 1987 | ||
| 1988 | /** description */ | |
| 1989 | N_("When viewing logs, this plugin will include " | |
| 1990 | "logs from other IM clients. Currently, this " | |
|
14297
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1991 | "includes Adium, MSN Messenger, and Trillian.\n\n" |
|
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1992 | "WARNING: This plugin is still alpha code and " |
|
c1788b3112fd
[gaim-migrate @ 16917]
Richard Laager <rlaager@pidgin.im>
parents:
14253
diff
changeset
|
1993 | "may crash frequently. Use it at your own risk!"), |
| 11459 | 1994 | |
|
11503
9f15d4c089b9
[gaim-migrate @ 13748]
Richard Laager <rlaager@pidgin.im>
parents:
11459
diff
changeset
|
1995 | "Richard Laager <rlaager@users.sf.net>", /**< author */ |
| 11459 | 1996 | GAIM_WEBSITE, /**< homepage */ |
| 1997 | plugin_load, /**< load */ | |
| 1998 | plugin_unload, /**< unload */ | |
| 1999 | NULL, /**< destroy */ | |
| 2000 | NULL, /**< ui_info */ | |
| 2001 | NULL, /**< extra_info */ | |
| 2002 | &prefs_info, /**< prefs_info */ | |
| 2003 | NULL /**< actions */ | |
| 2004 | }; | |
| 2005 | ||
| 2006 | GAIM_INIT_PLUGIN(log_reader, init_plugin, info) |