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 priv->stores = g_list_append (priv->stores,
116 g_object_new (EMPATHY_TYPE_LOG_STORE_EMPATHY, NULL));
118 manager->priv = priv;
122 empathy_log_manager_dup_singleton (void)
124 return g_object_new (EMPATHY_TYPE_LOG_MANAGER, NULL);
128 empathy_log_manager_add_message (EmpathyLogManager *manager,
129 const gchar *chat_id,
131 EmpathyMessage *message,
134 EmpathyLogManagerPriv *priv;
136 gboolean out = FALSE;
137 gboolean found = FALSE;
139 /* TODO: When multiple log stores appear with add_message implementations
140 * make this customisable. */
141 const gchar *add_store = "Empathy";
143 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), FALSE);
144 g_return_val_if_fail (chat_id != NULL, FALSE);
145 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
147 priv = GET_PRIV (manager);
149 for (l = priv->stores; l; l = l->next)
151 if (!tp_strdiff (empathy_log_store_get_name (
152 EMPATHY_LOG_STORE (l->data)), add_store))
154 out = empathy_log_store_add_message (EMPATHY_LOG_STORE (l->data),
155 chat_id, chatroom, message, error);
162 DEBUG ("Failed to find chosen log store to write to.");
168 empathy_log_manager_exists (EmpathyLogManager *manager,
170 const gchar *chat_id,
174 EmpathyLogManagerPriv *priv;
176 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), FALSE);
177 g_return_val_if_fail (MC_IS_ACCOUNT (account), FALSE);
178 g_return_val_if_fail (chat_id != NULL, FALSE);
180 priv = GET_PRIV (manager);
182 for (l = priv->stores; l; l = l->next)
184 if (empathy_log_store_exists (EMPATHY_LOG_STORE (l->data),
185 account, chat_id, chatroom))
193 log_manager_get_dates_foreach (gpointer data,
196 /* g_list_first is needed in case an older date was last inserted */
197 GList *orig = g_list_first (user_data);
199 if (g_list_find_custom (orig, data, (GCompareFunc) strcmp))
200 orig = g_list_insert_sorted (orig, g_strdup (data), (GCompareFunc) strcmp);
204 empathy_log_manager_get_dates (EmpathyLogManager *manager,
206 const gchar *chat_id,
209 GList *l, *out = NULL;
210 EmpathyLogManagerPriv *priv;
212 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
213 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
214 g_return_val_if_fail (chat_id != NULL, NULL);
216 priv = GET_PRIV (manager);
218 for (l = priv->stores; l; l = l->next)
220 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
223 out = empathy_log_store_get_dates (store, account, chat_id, chatroom);
226 GList *new = empathy_log_store_get_dates (store, account, chat_id,
228 g_list_foreach (new, log_manager_get_dates_foreach, out);
230 g_list_foreach (new, (GFunc) g_free, NULL);
233 /* Similar reason for using g_list_first here as before */
234 out = g_list_first (out);
242 empathy_log_manager_get_messages_for_date (EmpathyLogManager *manager,
244 const gchar *chat_id,
248 GList *l, *out = NULL;
249 EmpathyLogManagerPriv *priv;
251 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
252 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
253 g_return_val_if_fail (chat_id != NULL, NULL);
255 priv = GET_PRIV (manager);
257 for (l = priv->stores; l; l = l->next)
259 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
261 out = g_list_concat (out, empathy_log_store_get_messages_for_date (
262 store, account, chat_id, chatroom, date));
269 empathy_log_manager_get_last_messages (EmpathyLogManager *manager,
271 const gchar *chat_id,
274 GList *messages = NULL;
278 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
279 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
280 g_return_val_if_fail (chat_id != NULL, NULL);
282 dates = empathy_log_manager_get_dates (manager, account, chat_id, chatroom);
284 l = g_list_last (dates);
286 messages = empathy_log_manager_get_messages_for_date (manager, account,
287 chat_id, chatroom, l->data);
289 g_list_foreach (dates, (GFunc) g_free, NULL);
296 empathy_log_manager_get_chats (EmpathyLogManager *manager,
299 GList *l, *out = NULL;
300 EmpathyLogManagerPriv *priv;
302 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
303 g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
305 priv = GET_PRIV (manager);
307 for (l = priv->stores; l; l = l->next)
309 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
311 out = g_list_concat (out,
312 empathy_log_store_get_chats (store, account));
319 empathy_log_manager_search_new (EmpathyLogManager *manager,
322 GList *l, *out = NULL;
323 EmpathyLogManagerPriv *priv;
325 g_return_val_if_fail (EMPATHY_IS_LOG_MANAGER (manager), NULL);
326 g_return_val_if_fail (!EMP_STR_EMPTY (text), NULL);
328 priv = GET_PRIV (manager);
330 for (l = priv->stores; l; l = l->next)
332 EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
334 out = g_list_concat (out,
335 empathy_log_store_search_new (store, text));
342 empathy_log_manager_search_hit_free (EmpathyLogSearchHit *hit)
345 g_object_unref (hit->account);
348 g_free (hit->filename);
349 g_free (hit->chat_id);
351 g_slice_free (EmpathyLogSearchHit, hit);
355 empathy_log_manager_search_free (GList *hits)
359 for (l = hits; l; l = l->next)
361 empathy_log_manager_search_hit_free (l->data);
367 /* Format is just date, 20061201. */
369 empathy_log_manager_get_date_readable (const gchar *date)
373 t = empathy_time_parse (date);
375 return empathy_time_to_string_local (t, "%a %d %b %Y");
379 log_manager_chat_received_message_cb (EmpathyTpChat *tp_chat,
380 EmpathyMessage *message,
381 EmpathyLogManager *log_manager)
383 GError *error = NULL;
384 TpHandleType handle_type;
387 channel = empathy_tp_chat_get_channel (tp_chat);
388 tp_channel_get_handle (channel, &handle_type);
390 if (!empathy_log_manager_add_message (log_manager,
391 tp_channel_get_identifier (channel),
392 handle_type == TP_HANDLE_TYPE_ROOM,
395 DEBUG ("Failed to write message: %s",
396 error ? error->message : "No error message");
399 g_error_free (error);
404 log_manager_dispatcher_observe_cb (EmpathyDispatcher *dispatcher,
405 EmpathyDispatchOperation *operation,
406 EmpathyLogManager *log_manager)
410 channel_type = empathy_dispatch_operation_get_channel_type_id (operation);
412 if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)
414 EmpathyTpChat *tp_chat;
416 tp_chat = EMPATHY_TP_CHAT (
417 empathy_dispatch_operation_get_channel_wrapper (operation));
419 g_signal_connect (tp_chat, "message-received",
420 G_CALLBACK (log_manager_chat_received_message_cb), log_manager);
426 empathy_log_manager_observe (EmpathyLogManager *log_manager,
427 EmpathyDispatcher *dispatcher)
429 g_signal_connect (dispatcher, "observe",
430 G_CALLBACK (log_manager_dispatcher_observe_cb), log_manager);