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