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