]> git.0d.be Git - empathy.git/blob - libempathy/empathy-log-manager.c
Move avatar cache to ~/.cache and don't mix avatar from different contacts, tokens...
[empathy.git] / libempathy / empathy-log-manager.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2003-2007 Imendio AB
4  * Copyright (C) 2007-2008 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Xavier Claessens <xclaesse@gmail.com>
22  */
23
24 #include <config.h>
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <glib/gstdio.h>
30
31 #include "empathy-log-manager.h"
32 #include "empathy-contact.h"
33 #include "empathy-time.h"
34 #include "empathy-utils.h"
35
36 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
37 #include "empathy-debug.h"
38
39 #define LOG_DIR_CREATE_MODE       (S_IRUSR | S_IWUSR | S_IXUSR)
40 #define LOG_FILE_CREATE_MODE      (S_IRUSR | S_IWUSR)
41 #define LOG_DIR_CHATROOMS         "chatrooms"
42 #define LOG_FILENAME_SUFFIX       ".log"
43 #define LOG_TIME_FORMAT_FULL      "%Y%m%dT%H:%M:%S"
44 #define LOG_TIME_FORMAT           "%Y%m%d"
45 #define LOG_HEADER \
46     "<?xml version='1.0' encoding='utf-8'?>\n" \
47     "<?xml-stylesheet type=\"text/xsl\" href=\"empathy-log.xsl\"?>\n" \
48     "<log>\n"
49
50 #define LOG_FOOTER \
51     "</log>\n"
52
53 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyLogManager)
54 typedef struct {
55         gchar *basedir;
56 } EmpathyLogManagerPriv;
57
58 static void                 log_manager_finalize                   (GObject                *object);
59 static const gchar *        log_manager_get_basedir                (EmpathyLogManager      *manager);
60 static GList *              log_manager_get_all_files              (EmpathyLogManager      *manager,
61                                                                     const gchar            *dir);
62 static GList *              log_manager_get_chats                  (EmpathyLogManager      *manager,
63                                                                     const gchar            *dir,
64                                                                     gboolean                is_chatroom);
65 static gchar *              log_manager_get_dir                    (EmpathyLogManager      *manager,
66                                                                     McAccount              *account,
67                                                                     const gchar            *chat_id,
68                                                                     gboolean                chatroom);
69 static gchar *              log_manager_get_filename               (EmpathyLogManager      *manager,
70                                                                     McAccount              *account,
71                                                                     const gchar            *chat_id,
72                                                                     gboolean                chatroom);
73 static gchar *              log_manager_get_filename_for_date      (EmpathyLogManager      *manager,
74                                                                     McAccount              *account,
75                                                                     const gchar            *chat_id,
76                                                                     gboolean                chatroom,
77                                                                     const gchar            *date);
78 static gchar *              log_manager_get_timestamp_filename     (void);
79 static gchar *              log_manager_get_timestamp_from_message (EmpathyMessage          *message);
80 static EmpathyLogSearchHit *log_manager_search_hit_new             (EmpathyLogManager      *manager,
81                                                                     const gchar            *filename);
82 static void                 log_manager_search_hit_free            (EmpathyLogSearchHit    *hit);
83
84 G_DEFINE_TYPE (EmpathyLogManager, empathy_log_manager, G_TYPE_OBJECT);
85
86 static void
87 empathy_log_manager_class_init (EmpathyLogManagerClass *klass)
88 {
89         GObjectClass *object_class = G_OBJECT_CLASS (klass);
90
91         object_class->finalize = log_manager_finalize;
92
93         g_type_class_add_private (object_class, sizeof (EmpathyLogManagerPriv));
94 }
95
96 static void
97 empathy_log_manager_init (EmpathyLogManager *manager)
98 {
99         EmpathyLogManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
100                 EMPATHY_TYPE_LOG_MANAGER, EmpathyLogManagerPriv);
101
102         manager->priv = priv;
103 }
104
105 static void
106 log_manager_finalize (GObject *object)
107 {
108         EmpathyLogManagerPriv *priv;
109
110         priv = GET_PRIV (object);
111
112         g_free (priv->basedir);
113 }
114
115 EmpathyLogManager *
116 empathy_log_manager_new (void)
117 {
118         static EmpathyLogManager *manager = NULL;
119
120         if (!manager) {
121                 manager = g_object_new (EMPATHY_TYPE_LOG_MANAGER, NULL);
122                 g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager);
123         } else {
124                 g_object_ref (manager);
125         }
126
127         return manager;
128 }
129
130 void
131 empathy_log_manager_add_message (EmpathyLogManager *manager,
132                                  const gchar       *chat_id,
133                                  gboolean           chatroom,
134                                  EmpathyMessage     *message)
135 {
136         FILE          *file;
137         McAccount     *account;
138         EmpathyContact *sender;
139         const gchar   *body_str;
140         const gchar   *str;
141         EmpathyAvatar *avatar;
142         gchar         *avatar_token = NULL;
143         gchar         *filename;
144         gchar         *basedir;
145         gchar         *body;
146         gchar         *timestamp;
147         gchar         *contact_name;
148         gchar         *contact_id;
149         TpChannelTextMessageType msg_type;
150
151         g_return_if_fail (EMPATHY_IS_LOG_MANAGER (manager));
152         g_return_if_fail (chat_id != NULL);
153         g_return_if_fail (EMPATHY_IS_MESSAGE (message));
154
155         sender = empathy_message_get_sender (message);
156         account = empathy_contact_get_account (sender);
157         body_str = empathy_message_get_body (message);
158         msg_type = empathy_message_get_tptype (message);
159
160         if (G_STR_EMPTY (body_str)) {
161                 return;
162         }
163
164         filename = log_manager_get_filename (manager, account, chat_id, chatroom);
165         basedir = g_path_get_dirname (filename);
166         if (!g_file_test (basedir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
167                 DEBUG ("Creating directory:'%s'", basedir);
168
169                 g_mkdir_with_parents (basedir, LOG_DIR_CREATE_MODE);
170         }
171         g_free (basedir);
172
173         DEBUG ("Adding message: '%s' to file: '%s'", body_str, filename);
174
175         if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
176                 file = g_fopen (filename, "w+");
177                 if (file) {
178                         g_fprintf (file, LOG_HEADER);
179                 }
180                 g_chmod (filename, LOG_FILE_CREATE_MODE);
181         } else {
182                 file = g_fopen (filename, "r+");
183                 if (file) {
184                         fseek (file, - strlen (LOG_FOOTER), SEEK_END);
185                 }
186         }
187
188         body = g_markup_escape_text (body_str, -1);
189         timestamp = log_manager_get_timestamp_from_message (message);
190
191         str = empathy_contact_get_name (sender);
192         contact_name = g_markup_escape_text (str, -1);
193
194         str = empathy_contact_get_id (sender);
195         contact_id = g_markup_escape_text (str, -1);
196
197         avatar = empathy_contact_get_avatar (sender);
198         if (avatar) {
199                 avatar_token = g_markup_escape_text (avatar->token, -1);                
200         }
201
202         g_fprintf (file,
203                    "<message time='%s' id='%s' name='%s' token='%s' isuser='%s' type='%s'>%s</message>\n" LOG_FOOTER,
204                    timestamp,
205                    contact_id,
206                    contact_name,
207                    avatar_token ? avatar_token : "",
208                    empathy_contact_is_user (sender) ? "true" : "false",
209                    empathy_message_type_to_str (msg_type),
210                    body);
211
212         fclose (file);
213         g_free (filename);
214         g_free (contact_id);
215         g_free (contact_name);
216         g_free (timestamp);
217         g_free (body);
218         g_free (avatar_token);
219 }
220
221 gboolean
222 empathy_log_manager_exists (EmpathyLogManager *manager,
223                             McAccount         *account,
224                             const gchar       *chat_id,
225                             gboolean           chatroom)
226 {
227         gchar    *dir;
228         gboolean  exists;
229
230         dir = log_manager_get_dir (manager, account, chat_id, chatroom);
231         exists = g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR);
232         g_free (dir);
233
234         return exists;
235 }
236
237 GList *
238 empathy_log_manager_get_dates (EmpathyLogManager *manager,
239                                McAccount         *account,
240                                const gchar       *chat_id,
241                                gboolean           chatroom)
242 {
243         GList       *dates = NULL;
244         gchar       *date;
245         gchar       *directory;
246         GDir        *dir;
247         const gchar *filename;
248         const gchar *p;
249
250         g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
251         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
252         g_return_val_if_fail (chat_id != NULL, NULL);
253
254         directory = log_manager_get_dir (manager, account, chat_id, chatroom);
255         dir = g_dir_open (directory, 0, NULL);
256         if (!dir) {
257                 DEBUG ("Could not open directory:'%s'", directory);
258                 g_free (directory);
259                 return NULL;
260         }
261
262         DEBUG ("Collating a list of dates in:'%s'", directory);
263
264         while ((filename = g_dir_read_name (dir)) != NULL) {
265                 if (!g_str_has_suffix (filename, LOG_FILENAME_SUFFIX)) {
266                         continue;
267                 }
268
269                 p = strstr (filename, LOG_FILENAME_SUFFIX);
270                 date = g_strndup (filename, p - filename);
271                 if (!date) {
272                         continue;
273                 }
274
275                 if (!g_regex_match_simple ("\\d{8}", date, 0, 0)) {
276                         continue;
277                 }
278
279                 dates = g_list_insert_sorted (dates, date, (GCompareFunc) strcmp);
280         }
281
282         g_free (directory);
283         g_dir_close (dir);
284
285         DEBUG ("Parsed %d dates", g_list_length (dates));
286
287         return dates;
288 }
289
290 GList *
291 empathy_log_manager_get_messages_for_file (EmpathyLogManager *manager,
292                                            const gchar       *filename)
293 {
294         GList               *messages = NULL;
295         xmlParserCtxtPtr     ctxt;
296         xmlDocPtr            doc;
297         xmlNodePtr           log_node;
298         xmlNodePtr           node;
299         EmpathyLogSearchHit *hit;
300         McAccount           *account;
301
302         g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
303         g_return_val_if_fail (filename != NULL, NULL);
304
305         DEBUG ("Attempting to parse filename:'%s'...", filename);
306
307         if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
308                 DEBUG ("Filename:'%s' does not exist", filename);
309                 return NULL;
310         }
311
312         /* Get the account from the filename */
313         hit = log_manager_search_hit_new (manager, filename);
314         account = g_object_ref (hit->account);
315         log_manager_search_hit_free (hit);
316
317         /* Create parser. */
318         ctxt = xmlNewParserCtxt ();
319
320         /* Parse and validate the file. */
321         doc = xmlCtxtReadFile (ctxt, filename, NULL, 0);
322         if (!doc) {
323                 g_warning ("Failed to parse file:'%s'", filename);
324                 xmlFreeParserCtxt (ctxt);
325                 return NULL;
326         }
327
328         /* The root node, presets. */
329         log_node = xmlDocGetRootElement (doc);
330         if (!log_node) {
331                 xmlFreeDoc (doc);
332                 xmlFreeParserCtxt (ctxt);
333                 return NULL;
334         }
335
336         /* Now get the messages. */
337         for (node = log_node->children; node; node = node->next) {
338                 EmpathyMessage     *message;
339                 EmpathyContact     *sender;
340                 gchar              *time;
341                 time_t              t;
342                 gchar              *sender_id;
343                 gchar              *sender_name;
344                 gchar              *sender_avatar_token;
345                 gchar              *body;
346                 gchar              *is_user_str;
347                 gboolean            is_user = FALSE;
348                 gchar              *msg_type_str;
349                 TpChannelTextMessageType msg_type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
350
351                 if (strcmp (node->name, "message") != 0) {
352                         continue;
353                 }
354
355                 body = xmlNodeGetContent (node);
356                 time = xmlGetProp (node, "time");
357                 sender_id = xmlGetProp (node, "id");
358                 sender_name = xmlGetProp (node, "name");
359                 sender_avatar_token = xmlGetProp (node, "token");
360                 is_user_str = xmlGetProp (node, "isuser");
361                 msg_type_str = xmlGetProp (node, "type");
362
363                 if (is_user_str) {
364                         is_user = strcmp (is_user_str, "true") == 0;
365                 }
366                 if (msg_type_str) {
367                         msg_type = empathy_message_type_from_str (msg_type_str);
368                 }
369
370                 t = empathy_time_parse (time);
371
372                 sender = empathy_contact_new_full (account, sender_id, sender_name);
373                 empathy_contact_set_is_user (sender, is_user);
374                 if (!G_STR_EMPTY (sender_avatar_token)) {
375                         empathy_contact_load_avatar_cache (sender,
376                                                            sender_avatar_token);
377                 }
378
379                 message = empathy_message_new (body);
380                 empathy_message_set_sender (message, sender);
381                 empathy_message_set_timestamp (message, t);
382                 empathy_message_set_tptype (message, msg_type);
383
384                 messages = g_list_append (messages, message);
385
386                 g_object_unref (sender);
387                 xmlFree (time);
388                 xmlFree (sender_id);
389                 xmlFree (sender_name);
390                 xmlFree (body);
391                 xmlFree (is_user_str);
392                 xmlFree (msg_type_str);
393         }
394
395         DEBUG ("Parsed %d messages", g_list_length (messages));
396
397         xmlFreeDoc (doc);
398         xmlFreeParserCtxt (ctxt);
399
400         return messages;
401 }
402
403 GList *
404 empathy_log_manager_get_messages_for_date (EmpathyLogManager *manager,
405                                            McAccount         *account,
406                                            const gchar       *chat_id,
407                                            gboolean           chatroom,
408                                            const gchar       *date)
409 {
410         gchar *filename;
411         GList *messages;
412
413         g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
414         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
415         g_return_val_if_fail (chat_id != NULL, NULL);
416
417         filename = log_manager_get_filename_for_date (manager, account, chat_id, chatroom, date);
418         messages = empathy_log_manager_get_messages_for_file (manager, filename);
419         g_free (filename);
420
421         return messages;
422 }
423
424 GList *
425 empathy_log_manager_get_last_messages (EmpathyLogManager *manager,
426                                        McAccount         *account,
427                                        const gchar       *chat_id,
428                                        gboolean           chatroom)
429 {
430         GList *messages = NULL;
431         GList *dates;
432         GList *l;
433
434         g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
435         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
436         g_return_val_if_fail (chat_id != NULL, NULL);
437
438         dates = empathy_log_manager_get_dates (manager, account, chat_id, chatroom);
439
440         l = g_list_last (dates);
441         if (l) {
442                 messages = empathy_log_manager_get_messages_for_date (manager,
443                                                                       account,
444                                                                       chat_id,
445                                                                       chatroom,
446                                                                       l->data);
447         }
448
449         g_list_foreach (dates, (GFunc) g_free, NULL);
450         g_list_free (dates);
451
452         return messages;
453 }
454
455 GList *
456 empathy_log_manager_get_chats (EmpathyLogManager *manager,
457                                McAccount         *account)
458 {
459         const gchar *basedir;
460         gchar       *dir;
461
462         basedir = log_manager_get_basedir (manager);
463         dir = g_build_filename (basedir,
464                                 mc_account_get_unique_name (account),
465                                 NULL);
466
467         return log_manager_get_chats (manager, dir, FALSE);
468 }
469
470 GList *
471 empathy_log_manager_search_new (EmpathyLogManager *manager,
472                                 const gchar       *text)
473 {
474         GList *files, *l;
475         GList *hits = NULL;
476         gchar *text_casefold;
477
478         g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
479         g_return_val_if_fail (!G_STR_EMPTY (text), NULL);
480
481         text_casefold = g_utf8_casefold (text, -1);
482
483         files = log_manager_get_all_files (manager, NULL);
484         DEBUG ("Found %d log files in total", g_list_length (files));
485
486         for (l = files; l; l = l->next) {
487                 gchar       *filename;
488                 GMappedFile *file;
489                 gsize        length;
490                 gchar       *contents;
491                 gchar       *contents_casefold;
492
493                 filename = l->data;
494
495                 file = g_mapped_file_new (filename, FALSE, NULL);
496                 if (!file) {
497                         continue;
498                 }
499
500                 length = g_mapped_file_get_length (file);
501                 contents = g_mapped_file_get_contents (file);
502                 contents_casefold = g_utf8_casefold (contents, length);
503
504                 g_mapped_file_free (file);
505
506                 if (strstr (contents_casefold, text_casefold)) {
507                         EmpathyLogSearchHit *hit;
508
509                         hit = log_manager_search_hit_new (manager, filename);
510
511                         if (hit) {
512                                 hits = g_list_prepend (hits, hit);
513                                 DEBUG ("Found text:'%s' in file:'%s' on date:'%s'",
514                                         text, hit->filename, hit->date);
515                         }
516                 }
517
518                 g_free (contents_casefold);
519                 g_free (filename);
520         }
521         g_list_free (files);
522
523         g_free (text_casefold);
524
525         return hits;
526 }
527
528 void
529 empathy_log_manager_search_free (GList *hits)
530 {
531         GList *l;
532
533         for (l = hits; l; l = l->next) {
534                 log_manager_search_hit_free (l->data);
535         }
536         
537         g_list_free (hits);
538 }
539
540 /* Format is just date, 20061201. */
541 gchar *
542 empathy_log_manager_get_date_readable (const gchar *date)
543 {
544         time_t t;
545
546         t = empathy_time_parse (date);
547
548         return empathy_time_to_string_local (t, "%a %d %b %Y");
549 }
550
551 static const gchar *
552 log_manager_get_basedir (EmpathyLogManager *manager)
553 {
554         EmpathyLogManagerPriv *priv;    
555
556         priv = GET_PRIV (manager);
557
558         if (priv->basedir) {
559                 return priv->basedir;
560         }
561
562         priv->basedir = g_build_path (G_DIR_SEPARATOR_S,
563                                       g_get_home_dir (),
564                                       ".gnome2",
565                                       PACKAGE_NAME,
566                                       "logs",
567                                       NULL);
568
569         return priv->basedir;
570 }
571
572 static GList *
573 log_manager_get_all_files (EmpathyLogManager *manager,
574                            const gchar       *dir)
575 {
576         GDir        *gdir;
577         GList       *files = NULL;
578         const gchar *name;
579         
580         if (!dir) {
581                 dir = log_manager_get_basedir (manager);
582         }
583
584         gdir = g_dir_open (dir, 0, NULL);
585         if (!gdir) {
586                 return NULL;
587         }
588
589         while ((name = g_dir_read_name (gdir)) != NULL) {
590                 gchar *filename;
591
592                 filename = g_build_filename (dir, name, NULL);
593                 if (g_str_has_suffix (filename, LOG_FILENAME_SUFFIX)) {
594                         files = g_list_prepend (files, filename);
595                         continue;
596                 }
597
598                 if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
599                         /* Recursively get all log files */
600                         files = g_list_concat (files, log_manager_get_all_files (manager, filename));
601                 }
602                 g_free (filename);
603         }
604
605         g_dir_close (gdir);
606
607         return files;
608 }
609
610 static GList *
611 log_manager_get_chats (EmpathyLogManager *manager,
612                        const gchar       *dir,
613                        gboolean           is_chatroom)
614 {
615         GDir        *gdir;
616         GList       *hits = NULL;
617         const gchar *name;
618
619         gdir = g_dir_open (dir, 0, NULL);
620         if (!gdir) {
621                 return NULL;
622         }
623
624         while ((name = g_dir_read_name (gdir)) != NULL) {
625                 EmpathyLogSearchHit *hit;
626                 gchar *filename;
627
628                 filename = g_build_filename (dir, name, NULL);
629                 if (strcmp (name, LOG_DIR_CHATROOMS) == 0) {
630                         hits = g_list_concat (hits, log_manager_get_chats (manager, filename, TRUE));
631                         g_free (filename);
632                         continue;
633                 }
634
635                 hit = g_slice_new0 (EmpathyLogSearchHit);
636                 hit->chat_id = g_strdup (name);
637                 hit->is_chatroom = is_chatroom;
638
639                 hits = g_list_prepend (hits, hit);
640         }
641
642         g_dir_close (gdir);
643
644         return hits;
645 }
646
647 static gchar *
648 log_manager_get_dir (EmpathyLogManager *manager,
649                      McAccount         *account,
650                      const gchar       *chat_id,
651                      gboolean           chatroom)
652 {
653         const gchar *account_id;
654         gchar       *basedir;
655
656         account_id = mc_account_get_unique_name (account);
657
658         if (chatroom) {
659                 basedir = g_build_path (G_DIR_SEPARATOR_S,
660                                         log_manager_get_basedir (manager),
661                                         account_id,
662                                         LOG_DIR_CHATROOMS,
663                                         chat_id,
664                                         NULL);
665         } else {
666                 basedir = g_build_path (G_DIR_SEPARATOR_S,
667                                         log_manager_get_basedir (manager),
668                                         account_id,
669                                         chat_id,
670                                         NULL);
671         }
672
673         return basedir;
674 }
675
676 static gchar *
677 log_manager_get_filename (EmpathyLogManager *manager,
678                           McAccount         *account,
679                           const gchar       *chat_id,
680                           gboolean           chatroom)
681 {
682         gchar *basedir;
683         gchar *timestamp;
684         gchar *filename;
685
686         basedir = log_manager_get_dir (manager, account, chat_id, chatroom);
687         timestamp = log_manager_get_timestamp_filename ();
688         filename = g_build_filename (basedir, timestamp, NULL);
689
690         g_free (basedir);
691         g_free (timestamp);
692
693         return filename;
694 }
695
696 static gchar *
697 log_manager_get_filename_for_date (EmpathyLogManager *manager,
698                                    McAccount         *account,
699                                    const gchar       *chat_id,
700                                    gboolean           chatroom,
701                                    const gchar       *date)
702 {
703         gchar *basedir;
704         gchar *timestamp;
705         gchar *filename;
706
707         basedir = log_manager_get_dir (manager, account, chat_id, chatroom);
708         timestamp = g_strconcat (date, LOG_FILENAME_SUFFIX, NULL);
709         filename = g_build_filename (basedir, timestamp, NULL);
710
711         g_free (basedir);
712         g_free (timestamp);
713
714         return filename;
715 }
716
717 static gchar *
718 log_manager_get_timestamp_filename (void)
719 {
720         time_t      t;
721         gchar      *time_str;
722         gchar      *filename;
723
724         t = empathy_time_get_current ();
725         time_str = empathy_time_to_string_local (t, LOG_TIME_FORMAT);
726         filename = g_strconcat (time_str, LOG_FILENAME_SUFFIX, NULL);
727
728         g_free (time_str);
729
730         return filename;
731 }
732
733 static gchar *
734 log_manager_get_timestamp_from_message (EmpathyMessage *message)
735 {
736         time_t t;
737
738         t = empathy_message_get_timestamp (message);
739
740         /* We keep the timestamps in the messages as UTC. */
741         return empathy_time_to_string_utc (t, LOG_TIME_FORMAT_FULL);
742 }
743
744 static EmpathyLogSearchHit *
745 log_manager_search_hit_new (EmpathyLogManager *manager,
746                             const gchar       *filename)
747 {
748         EmpathyLogSearchHit  *hit;
749         const gchar          *account_name;
750         const gchar          *end;
751         gchar               **strv;
752         guint                 len;
753
754         if (!g_str_has_suffix (filename, LOG_FILENAME_SUFFIX)) {
755                 return NULL;
756         }
757
758         strv = g_strsplit (filename, G_DIR_SEPARATOR_S, -1);
759         len = g_strv_length (strv);
760
761         hit = g_slice_new0 (EmpathyLogSearchHit);
762
763         end = strstr (strv[len-1], LOG_FILENAME_SUFFIX);
764         hit->date = g_strndup (strv[len-1], end - strv[len-1]);
765         hit->chat_id = g_strdup (strv[len-2]);
766         hit->is_chatroom = (strcmp (strv[len-3], LOG_DIR_CHATROOMS) == 0);
767         if (hit->is_chatroom) {
768                 account_name = strv[len-4];
769         } else {
770                 account_name = strv[len-3];
771         }
772         hit->account = mc_account_lookup (account_name);
773         hit->filename = g_strdup (filename);
774
775         g_strfreev (strv);
776
777         return hit;
778 }
779
780 static void
781 log_manager_search_hit_free (EmpathyLogSearchHit *hit)
782 {
783         if (hit->account) {
784                 g_object_unref (hit->account);
785         }
786
787         g_free (hit->date);
788         g_free (hit->filename);
789         g_free (hit->chat_id);
790
791         g_slice_free (EmpathyLogSearchHit, hit);
792 }