1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2003-2007 Imendio AB
4 * Copyright (C) 2007-2008 Collabora Ltd.
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.
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.
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.
21 * Authors: Xavier Claessens <xclaesse@gmail.com>
29 #include <glib/gstdio.h>
31 #include <telepathy-glib/util.h>
33 #include "empathy-log-manager.h"
34 #include "empathy-log-store-empathy.h"
35 #include "empathy-log-store.h"
36 #include "empathy-tp-chat.h"
37 #include "empathy-utils.h"
39 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
40 #include "empathy-debug.h"
42 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyLogManager)
46 } EmpathyLogManagerPriv;
48 G_DEFINE_TYPE (EmpathyLogManager, empathy_log_manager, G_TYPE_OBJECT);
50 static EmpathyLogManager * manager_singleton = NULL;
53 log_manager_finalize (GObject *object)
55 EmpathyLogManagerPriv *priv;
58 priv = GET_PRIV (object);
60 for (l = priv->stores; l; l = l->next)
62 EmpathyLogStore *store = (EmpathyLogStore *) l->data;
63 g_object_unref (store);
66 g_list_free (priv->stores);
70 log_manager_constructor (GType type,
72 GObjectConstructParam *props)
75 EmpathyLogManagerPriv *priv;
77 if (manager_singleton)
79 retval = g_object_ref (manager_singleton);
83 retval = G_OBJECT_CLASS (empathy_log_manager_parent_class)->constructor
84 (type, n_props, props);
86 manager_singleton = EMPATHY_LOG_MANAGER (retval);
87 g_object_add_weak_pointer (retval, (gpointer *) &manager_singleton);
89 priv = GET_PRIV (manager_singleton);
91 priv->stores = g_list_append (priv->stores,
92 g_object_new (EMPATHY_TYPE_LOG_STORE_EMPATHY, NULL));
99 empathy_log_manager_class_init (EmpathyLogManagerClass *klass)
101 GObjectClass *object_class = G_OBJECT_CLASS (klass);
103 object_class->constructor = log_manager_constructor;
104 object_class->finalize = log_manager_finalize;
106 g_type_class_add_private (object_class, sizeof (EmpathyLogManagerPriv));
110 empathy_log_manager_init (EmpathyLogManager *manager)
112 EmpathyLogManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
113 EMPATHY_TYPE_LOG_MANAGER, EmpathyLogManagerPriv);
115 manager->priv = priv;
119 empathy_log_manager_dup_singleton (void)
121 return g_object_new (EMPATHY_TYPE_LOG_MANAGER, NULL);
125 empathy_log_manager_add_message (EmpathyLogManager *manager,
126 const gchar *chat_id,
128 EmpathyMessage *message,
131 EmpathyLogManagerPriv *priv;
133 gboolean out = FALSE;
134 gboolean found = FALSE;
136 /* TODO: When multiple log stores appear with add_message implementations
137 * make this customisable. */
138 const gchar *add_store = "Empathy";
140 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), FALSE);
141 g_return_val_if_fail (chat_id != NULL, FALSE);
142 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
144 priv = GET_PRIV (manager);
146 for (l = priv->stores; l; l = l->next)
148 if (!tp_strdiff (empathy_log_store_get_name (
149 EMPATHY_LOG_STORE (l->data)), add_store))
151 out = empathy_log_store_add_message (EMPATHY_LOG_STORE (l->data),
152 chat_id, chatroom, message, error);
159 DEBUG ("Failed to find chosen log store to write to.");
165 empathy_log_manager_exists (EmpathyLogManager *manager,
167 const gchar *chat_id,
171 EmpathyLogManagerPriv *priv;
173 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), FALSE);
174 g_return_val_if_fail (MC_IS_ACCOUNT (account), FALSE);
175 g_return_val_if_fail (chat_id != NULL, FALSE);
177 priv = GET_PRIV (manager);
179 for (l = priv->stores; l; l = l->next)
181 if (empathy_log_store_exists (EMPATHY_LOG_STORE (l->data),
182 account, chat_id, chatroom))
190 log_manager_get_dates_foreach (gpointer data,
193 /* g_list_first is needed in case an older date was last inserted */
194 GList *orig = g_list_first (user_data);
196 if (g_list_find_custom (orig, data, (GCompareFunc) strcmp))
197 orig = g_list_insert_sorted (orig, g_strdup (data), (GCompareFunc) strcmp);
201 empathy_log_manager_get_dates (EmpathyLogManager *manager,
203 const gchar *chat_id,
206 GList *l, *out = NULL;
207 EmpathyLogManagerPriv *priv;
209 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
210 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
211 g_return_val_if_fail (chat_id != NULL, NULL);
213 priv = GET_PRIV (manager);
215 for (l = priv->stores; l; l = l->next)
217 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
220 out = empathy_log_store_get_dates (store, account, chat_id, chatroom);
223 GList *new = empathy_log_store_get_dates (store, account, chat_id,
225 g_list_foreach (new, log_manager_get_dates_foreach, out);
227 g_list_foreach (new, (GFunc) g_free, NULL);
230 /* Similar reason for using g_list_first here as before */
231 out = g_list_first (out);
239 empathy_log_manager_get_messages_for_date (EmpathyLogManager *manager,
241 const gchar *chat_id,
245 GList *l, *out = NULL;
246 EmpathyLogManagerPriv *priv;
248 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
249 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
250 g_return_val_if_fail (chat_id != NULL, NULL);
252 priv = GET_PRIV (manager);
254 for (l = priv->stores; l; l = l->next)
256 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
258 out = g_list_concat (out, empathy_log_store_get_messages_for_date (
259 store, account, chat_id, chatroom, date));
266 empathy_log_manager_get_last_messages (EmpathyLogManager *manager,
268 const gchar *chat_id,
271 GList *messages = NULL;
275 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
276 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
277 g_return_val_if_fail (chat_id != NULL, NULL);
279 dates = empathy_log_manager_get_dates (manager, account, chat_id, chatroom);
281 l = g_list_last (dates);
284 messages = empathy_log_manager_get_messages_for_date (manager, account,
285 chat_id, chatroom, l->data);
287 /* The latest date will always be today as messages are logged immediately. */
288 l = g_list_previous (l);
291 messages = g_list_concat (messages, empathy_log_manager_get_messages_for_date (
292 manager, account, chat_id, chatroom, l->data));
296 g_list_foreach (dates, (GFunc) g_free, NULL);
303 empathy_log_manager_get_chats (EmpathyLogManager *manager,
306 GList *l, *out = NULL;
307 EmpathyLogManagerPriv *priv;
309 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
310 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
312 priv = GET_PRIV (manager);
314 for (l = priv->stores; l; l = l->next)
316 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
318 out = g_list_concat (out,
319 empathy_log_store_get_chats (store, account));
326 empathy_log_manager_search_new (EmpathyLogManager *manager,
329 GList *l, *out = NULL;
330 EmpathyLogManagerPriv *priv;
332 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
333 g_return_val_if_fail (!EMP_STR_EMPTY (text), NULL);
335 priv = GET_PRIV (manager);
337 for (l = priv->stores; l; l = l->next)
339 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
341 out = g_list_concat (out,
342 empathy_log_store_search_new (store, text));
349 empathy_log_manager_search_hit_free (EmpathyLogSearchHit *hit)
352 g_object_unref (hit->account);
355 g_free (hit->filename);
356 g_free (hit->chat_id);
358 g_slice_free (EmpathyLogSearchHit, hit);
362 empathy_log_manager_search_free (GList *hits)
366 for (l = hits; l; l = l->next)
368 empathy_log_manager_search_hit_free (l->data);
374 /* Format is just date, 20061201. */
376 empathy_log_manager_get_date_readable (const gchar *date)
380 t = empathy_time_parse (date);
382 return empathy_time_to_string_local (t, "%a %d %b %Y");
386 log_manager_chat_received_message_cb (EmpathyTpChat *tp_chat,
387 EmpathyMessage *message,
388 EmpathyLogManager *log_manager)
390 GError *error = NULL;
391 TpHandleType handle_type;
394 channel = empathy_tp_chat_get_channel (tp_chat);
395 tp_channel_get_handle (channel, &handle_type);
397 if (!empathy_log_manager_add_message (log_manager,
398 tp_channel_get_identifier (channel),
399 handle_type == TP_HANDLE_TYPE_ROOM,
402 DEBUG ("Failed to write message: %s",
403 error ? error->message : "No error message");
406 g_error_free (error);
411 log_manager_dispatcher_observe_cb (EmpathyDispatcher *dispatcher,
412 EmpathyDispatchOperation *operation,
413 EmpathyLogManager *log_manager)
417 channel_type = empathy_dispatch_operation_get_channel_type_id (operation);
419 if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)
421 EmpathyTpChat *tp_chat;
423 tp_chat = EMPATHY_TP_CHAT (
424 empathy_dispatch_operation_get_channel_wrapper (operation));
426 g_signal_connect (tp_chat, "message-received",
427 G_CALLBACK (log_manager_chat_received_message_cb), log_manager);
433 empathy_log_manager_observe (EmpathyLogManager *log_manager,
434 EmpathyDispatcher *dispatcher)
436 g_signal_connect (dispatcher, "observe",
437 G_CALLBACK (log_manager_dispatcher_observe_cb), log_manager);