]> git.0d.be Git - empathy.git/blob - libempathy/empathy-log-manager.c
Make get_dates check whether a date is already in the GList before adding it now...
[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 GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyLogManager)
40 typedef struct
41 {
42   GList *sources;
43 } EmpathyLogManagerPriv;
44
45 G_DEFINE_TYPE (EmpathyLogManager, empathy_log_manager, G_TYPE_OBJECT);
46
47 static EmpathyLogManager * manager_singleton = NULL;
48
49 static void
50 empathy_log_manager_init (EmpathyLogManager *manager)
51 {
52   EmpathyLogManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
53       EMPATHY_TYPE_LOG_MANAGER, EmpathyLogManagerPriv);
54   manager->priv = priv;
55 }
56
57 static void
58 log_manager_finalize (GObject *object)
59 {
60   EmpathyLogManagerPriv *priv;
61   GList *l;
62
63   priv = GET_PRIV (object);
64
65   for (l = priv->sources; l; l = l->next)
66     {
67       g_slice_free (EmpathyLogSource, l->data);
68     }
69
70   g_list_free (priv->sources);
71 }
72
73 static GObject *
74 log_manager_constructor (GType type,
75                          guint n_props,
76                          GObjectConstructParam *props)
77 {
78   GObject *retval;
79
80   if (manager_singleton)
81     {
82       retval = g_object_ref (manager_singleton);
83     }
84   else
85     {
86       retval = G_OBJECT_CLASS (empathy_log_manager_parent_class)->constructor
87           (type, n_props, props);
88
89       manager_singleton = EMPATHY_LOG_MANAGER (retval);
90       g_object_add_weak_pointer (retval, (gpointer *) &manager_singleton);
91
92       priv = GET_PRIV (manager_singleton);
93
94       manager_singleton = EMPATHY_LOG_MANAGER (retval);
95       g_object_add_weak_pointer (retval, (gpointer), &manager_singleton);
96
97       priv->sources = g_list_append (priv->sources,
98           empathy_log_source_empathy_get_source ());
99     }
100
101   return retval;
102 }
103
104 static void
105 empathy_log_manager_class_init (EmpathyLogManagerClass *klass)
106 {
107   GObjectClass *object_class = G_OBJECT_CLASS (klass);
108
109   object_class->finalize = log_manager_finalize;
110   object_class->constructor = log_manager_constructor;
111
112   g_type_class_add_private (object_class, sizeof (EmpathyLogManagerPriv));
113 }
114
115 EmpathyLogManager *
116 empathy_log_manager_dup_singleton (void)
117 {
118   return g_object_new (EMPATHY_TYPE_LOG_MANAGER, NULL);
119 }
120
121 void
122 empathy_log_manager_add_message (EmpathyLogManager *manager,
123                                  const gchar *chat_id,
124                                  gboolean chatroom,
125                                  EmpathyMessage *message)
126 {
127   EmpathyLogManagerPriv *priv;
128   GList *l;
129
130   g_return_if_fail (EMPATHY_IS_LOG_MANAGER (manager));
131   g_return_if_fail (chat_id != NULL);
132   g_return_if_fail (EMPATHY_IS_MESSAGE (message));
133
134   priv = GET_PRIV (manager);
135
136   for (l = priv->sources; l; l = l->next)
137     {
138       EmpathyLogSource *source = (EmpathyLogSource *) l->data;
139
140       if (!source->add_message)
141         continue;
142
143       source->add_message (manager, chat_id, chatroom, message);
144     }
145 }
146
147 gboolean
148 empathy_log_manager_exists (EmpathyLogManager *manager,
149                             McAccount *account,
150                             const gchar *chat_id,
151                             gboolean chatroom)
152 {
153   GList *l;
154   EmpathyLogManagerPriv *priv;
155
156   g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), FALSE);
157   g_return_val_if_fail (MC_IS_ACCOUNT (account), FALSE);
158   g_return_val_if_fail (chat_id != NULL, FALSE);
159
160   priv = GET_PRIV (manager);
161
162   for (l = priv->sources; l; l = l->next)
163     {
164       EmpathyLogSource *source = (EmpathyLogSource *) l->data;
165
166       if (!source->exists)
167         continue;
168
169       if (source->exists (manager, account, chat_id, chatroom))
170         return TRUE;
171     }
172
173   return FALSE;
174 }
175
176 static void
177 log_manager_get_dates_foreach (gpointer data,
178                                gpointer user_data)
179 {
180   /* g_list_first is needed in case an older date was last inserted */
181   GList *orig = g_list_first (user_data);
182
183   if (g_list_find_custom (orig, data, (GCompareFunc) strcmp))
184     orig = g_list_insert_sorted (orig, g_strdup (data), (GCompareFunc) strcmp);
185 }
186
187 GList *
188 empathy_log_manager_get_dates (EmpathyLogManager *manager,
189                                McAccount *account,
190                                const gchar *chat_id,
191                                gboolean chatroom)
192 {
193   GList *l, *out = NULL;
194   EmpathyLogManagerPriv *priv;
195
196   g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
197   g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
198   g_return_val_if_fail (chat_id != NULL, NULL);
199
200   priv = GET_PRIV (manager);
201
202   for (l = priv->sources; l; l = l->next)
203     {
204       EmpathyLogSource *source = (EmpathyLogSource *) l->data;
205
206       if (!source->get_dates)
207         continue;
208
209       if (!out)
210         out = source->get_dates (manager, account, chat_id, chatroom);
211       else
212         {
213           GList *new = source->get_dates (manager, account, chat_id, chatroom);
214           g_list_foreach (new, log_manager_get_dates_foreach, out);
215
216           g_list_foreach (new, (GFunc) g_free, NULL);
217           g_list_free (new);
218
219           /* Similar reason for using g_list_first here as before */
220           out = g_list_first (out);
221         }
222     }
223
224   return out;
225 }
226
227 GList *
228 empathy_log_manager_get_messages_for_date (EmpathyLogManager *manager,
229                                            McAccount *account,
230                                            const gchar *chat_id,
231                                            gboolean chatroom,
232                                            const gchar *date)
233 {
234   GList *l, *out = NULL;
235   EmpathyLogManagerPriv *priv;
236
237   g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
238   g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
239   g_return_val_if_fail (chat_id != NULL, NULL);
240
241   priv = GET_PRIV (manager);
242
243   for (l = priv->sources; l; l = l->next)
244     {
245       EmpathyLogSource *source = (EmpathyLogSource *) l->data;
246
247       if (!source->get_messages_for_date)
248         continue;
249
250       if (!out)
251         out = source->get_messages_for_date (manager, account, chat_id,
252             chatroom, date);
253       else
254         out = g_list_concat (out, source->get_messages_for_date (manager,
255               account, chat_id, chatroom, date));
256     }
257
258   return out;
259 }
260
261 GList *
262 empathy_log_manager_get_last_messages (EmpathyLogManager *manager,
263                                        McAccount *account,
264                                        const gchar *chat_id,
265                                        gboolean chatroom)
266 {
267   GList *messages = NULL;
268   GList *dates;
269   GList *l;
270
271   g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
272   g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
273   g_return_val_if_fail (chat_id != NULL, NULL);
274
275   dates = empathy_log_manager_get_dates (manager, account, chat_id, chatroom);
276
277   l = g_list_last (dates);
278   if (l)
279     messages = empathy_log_manager_get_messages_for_date (manager, account,
280         chat_id, chatroom, l->data);
281
282   g_list_foreach (dates, (GFunc) g_free, NULL);
283   g_list_free (dates);
284
285   return messages;
286 }
287
288 GList *
289 empathy_log_manager_get_chats (EmpathyLogManager *manager,
290                                McAccount *account)
291 {
292   GList *l, *out = NULL;
293   EmpathyLogManagerPriv *priv;
294
295   g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
296   g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
297
298   priv = GET_PRIV (manager);
299
300   for (l = priv->sources; l; l = l->next)
301     {
302       EmpathyLogSource *source = (EmpathyLogSource *) l->data;
303
304       if (!source->get_chats)
305         continue;
306
307       if (!out)
308         out = source->get_chats (manager, account);
309       else
310         out = g_list_concat (out, source->get_chats (manager, account));
311     }
312
313   return out;
314 }
315
316 GList *
317 empathy_log_manager_search_new (EmpathyLogManager *manager,
318                                 const gchar *text)
319 {
320   GList *l, *out = NULL;
321   EmpathyLogManagerPriv *priv;
322
323   g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
324   g_return_val_if_fail (!EMP_STR_EMPTY (text), NULL);
325
326   priv = GET_PRIV (manager);
327
328   for (l = priv->sources; l; l = l->next)
329     {
330       EmpathyLogSource *source = (EmpathyLogSource *) l->data;
331
332       if (!source->search_new)
333         continue;
334
335       if (!out)
336         out = source->search_new (manager, text);
337       else
338         out = g_list_concat (out, source->search_new (manager, text));
339     }
340
341   return out;
342 }
343
344 void
345 empathy_log_manager_search_hit_free (EmpathyLogSearchHit *hit)
346 {
347   if (hit->account)
348     g_object_unref (hit->account);
349
350   g_free (hit->date);
351   g_free (hit->filename);
352   g_free (hit->chat_id);
353
354   g_slice_free (EmpathyLogSearchHit, hit);
355 }
356
357 void
358 empathy_log_manager_search_free (GList *hits)
359 {
360   GList *l;
361
362   for (l = hits; l; l = l->next)
363     {
364       empathy_log_manager_search_hit_free (l->data);
365     }
366
367   g_list_free (hits);
368 }
369
370 /* Format is just date, 20061201. */
371 gchar *
372 empathy_log_manager_get_date_readable (const gchar *date)
373 {
374   time_t t;
375
376   t = empathy_time_parse (date);
377
378   return empathy_time_to_string_local (t, "%a %d %b %Y");
379 }