diff options
author | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2010-02-04 17:31:50 +0000 |
---|---|---|
committer | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2010-02-04 17:31:50 +0000 |
commit | 7cd4c1beaaff23982315feb17fbbc024e8b61377 (patch) | |
tree | dea24079fa14d8b51a9fa329e5e6206464e485ca | |
parent | bb2bb1bc6fced6e62e3481b904cf760664254295 (diff) | |
parent | 164d3acd8e76757d56a6e8e65f18edce0eb56a47 (diff) | |
download | telepathy-logger-7cd4c1beaaff23982315feb17fbbc024e8b61377.tar.gz |
Merge branch 'multi-logstore'
-rw-r--r-- | telepathy-logger/Makefile.am | 3 | ||||
-rw-r--r-- | telepathy-logger/channel-text.c | 16 | ||||
-rw-r--r-- | telepathy-logger/channel.c | 5 | ||||
-rw-r--r-- | telepathy-logger/datetime.c | 10 | ||||
-rw-r--r-- | telepathy-logger/log-entry.c | 2 | ||||
-rw-r--r-- | telepathy-logger/log-manager-priv.h | 1 | ||||
-rw-r--r-- | telepathy-logger/log-manager.c | 132 | ||||
-rw-r--r-- | telepathy-logger/log-manager.h | 11 | ||||
-rw-r--r-- | telepathy-logger/log-store-empathy.c | 478 | ||||
-rw-r--r-- | telepathy-logger/log-store-factory.c | 98 | ||||
-rw-r--r-- | telepathy-logger/log-store-factory.h | 42 | ||||
-rw-r--r-- | telepathy-logger/log-store.c | 129 | ||||
-rw-r--r-- | telepathy-logger/log-store.h | 129 | ||||
-rw-r--r-- | telepathy-logger/observer.c | 21 | ||||
-rw-r--r-- | tests/Makefile.am | 14 | ||||
-rw-r--r-- | tests/constants.h | 2 | ||||
-rw-r--r-- | tests/test-searches.c | 57 |
17 files changed, 773 insertions, 377 deletions
diff --git a/telepathy-logger/Makefile.am b/telepathy-logger/Makefile.am index 14cc182..73629f4 100644 --- a/telepathy-logger/Makefile.am +++ b/telepathy-logger/Makefile.am @@ -20,6 +20,8 @@ LIBTPL_HEADERS = \ log-entry.h \ log-entry-text.h \ log-manager.h \ + log-store.h \ + log-store-empathy.h \ datetime.h @@ -35,6 +37,7 @@ libtelepathy_logger_la_SOURCES = \ log-manager.c \ log-store.c \ log-store-empathy.c \ + log-store-factory.c \ observer.c \ util.c diff --git a/telepathy-logger/channel-text.c b/telepathy-logger/channel-text.c index 4f5baea..f3ab6dd 100644 --- a/telepathy-logger/channel-text.c +++ b/telepathy-logger/channel-text.c @@ -91,7 +91,7 @@ static void keepon (TplLogEntryText *log); * members */ -// used by _get_my_contact and _get_remote_contact +/* used by _get_my_contact and _get_remote_contact */ static void _tpl_channel_text_get_contact_cb (TpConnection *connection, guint n_contacts, @@ -183,7 +183,6 @@ pendingproc_get_my_contact (TplActionChain *ctx) TpHandle my_handle = tp_connection_get_self_handle ( tp_channel_borrow_connection (TP_CHANNEL (tpl_chan))); - g_debug ("get my contact"); GET_PRIV (tpl_text)->selector = TP_CONTACT_MYSELF; tp_connection_get_contacts_by_handle (tp_channel_borrow_connection ( TP_CHANNEL (tpl_chan)), 1, &my_handle, TP_CONTACT_FEATURES_LEN, @@ -310,7 +309,6 @@ tpl_channel_text_new (TpConnection *conn, /* Do what tpl_channel_new does + set TplChannelText specific properties */ -g_debug ("TPL CHAN TEXT NEW!"); g_return_val_if_fail (TP_IS_CONNECTION (conn), NULL); g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL); g_return_val_if_fail (!TPL_STR_EMPTY (object_path), NULL); @@ -461,7 +459,6 @@ pendingproc_prepare_tpl_channel (TplActionChain *ctx) { TplChannel *tpl_chan = TPL_CHANNEL (tpl_actionchain_get_object (ctx)); - g_debug ("prepare tpl"); TPL_CHANNEL_GET_CLASS (tpl_chan)->call_when_ready_protected (tpl_chan, got_tpl_chan_ready_cb, ctx); } @@ -473,9 +470,8 @@ got_tpl_chan_ready_cb (GObject *obj, gpointer user_data) { TplActionChain *ctx = user_data; - g_debug ("PREPARE"); - if (tpl_actionchain_finish (result) == TRUE) + if (tpl_actionchain_finish (result)) tpl_actionchain_continue (ctx); return; } @@ -533,8 +529,6 @@ pendingproc_connect_signals (TplActionChain *ctx) GError *error = NULL; TpChannel *channel = NULL; - g_debug ("CONNECT"); - channel = TP_CHANNEL (TPL_CHANNEL (tpl_text)); tp_cli_channel_type_text_connect_to_received (channel, @@ -625,7 +619,7 @@ _channel_on_lost_message_cb (TpChannel *proxy, GObject *weak_object) { g_debug ("lost message signal catched. nothing logged"); - // TODO log that the system lost a message + /* TODO log that the system lost a message */ } static void @@ -639,7 +633,7 @@ _channel_on_send_error_cb (TpChannel *proxy, { g_error ("unlogged event: " "TP was unable to send the message: %s", arg_Text); - // TODO log that the system was unable to send the message + /* TODO log that the system was unable to send the message */ } @@ -668,7 +662,7 @@ _channel_on_sent_signal_cb (TpChannel *proxy, tpl_contact_sender = tpl_contact_from_tp_contact (me); tpl_contact_set_contact_type (tpl_contact_sender, TPL_CONTACT_USER); - if (tpl_channel_text_is_chatroom (tpl_text) == FALSE) + if (!tpl_channel_text_is_chatroom (tpl_text)) { remote = tpl_channel_text_get_remote_contact (tpl_text); if (remote == NULL) diff --git a/telepathy-logger/channel.c b/telepathy-logger/channel.c index 45a6cd7..f2688c1 100644 --- a/telepathy-logger/channel.c +++ b/telepathy-logger/channel.c @@ -194,7 +194,6 @@ call_when_ready_protected (TplChannel *self, { TplActionChain *actions; - g_debug ("tp_connection_call_when_ready"); actions = tpl_actionchain_new (G_OBJECT(self), cb, user_data); tpl_actionchain_append (actions, pendingproc_get_ready_tp_connection); tpl_actionchain_append (actions, pendingproc_get_ready_tp_channel); @@ -210,7 +209,6 @@ pendingproc_get_ready_tp_connection (TplActionChain *ctx) TpConnection *tp_conn = tp_channel_borrow_connection (TP_CHANNEL ( tpl_chan)); - g_debug ("Preparing TpConnection"); tp_connection_call_when_ready (tp_conn, got_ready_tp_connection_cb, ctx); } @@ -233,7 +231,6 @@ got_ready_tp_connection_cb (TpConnection *connection, g_object_unref (tpl_chan); return; } - g_debug ("2"); tpl_actionchain_continue (ctx); } @@ -243,8 +240,6 @@ pendingproc_get_ready_tp_channel (TplActionChain *ctx) { TplChannel *tpl_chan = tpl_actionchain_get_object (ctx); - g_debug ("Preparing TpChannel"); - /* user_data is a TplChannel instance */ tp_channel_call_when_ready (TP_CHANNEL (tpl_chan), got_ready_tp_channel_cb, ctx); diff --git a/telepathy-logger/datetime.c b/telepathy-logger/datetime.c index 41f32b3..4cda4a6 100644 --- a/telepathy-logger/datetime.c +++ b/telepathy-logger/datetime.c @@ -50,14 +50,10 @@ tpl_time_get_local_time (struct tm * tm) t = mktime (tm); - if (tz) - { - g_setenv ("TZ", tz, TRUE); - } + if (tz != NULL) + g_setenv ("TZ", tz, TRUE); else - { - g_unsetenv ("TZ"); - } + g_unsetenv ("TZ"); tzset (); diff --git a/telepathy-logger/log-entry.c b/telepathy-logger/log-entry.c index f1ec9fd..6b0eedb 100644 --- a/telepathy-logger/log-entry.c +++ b/telepathy-logger/log-entry.c @@ -175,7 +175,7 @@ set_prop (GObject *object, static void -tpl_log_entry_class_init (TplLogEntryClass * klass) +tpl_log_entry_class_init (TplLogEntryClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GParamSpec *param_spec; diff --git a/telepathy-logger/log-manager-priv.h b/telepathy-logger/log-manager-priv.h index bdc0fbb..0822e6c 100644 --- a/telepathy-logger/log-manager-priv.h +++ b/telepathy-logger/log-manager-priv.h @@ -25,6 +25,7 @@ #define __TPL_LOG_MANAGER_PRIV_H__ #include <telepathy-logger/log-manager.h> +#include <telepathy-logger/log-store-factory.h> gboolean tpl_log_manager_add_message (TplLogManager *manager, TplLogEntry *message, GError **error); diff --git a/telepathy-logger/log-manager.c b/telepathy-logger/log-manager.c index 8eab6e4..6c2087c 100644 --- a/telepathy-logger/log-manager.c +++ b/telepathy-logger/log-manager.c @@ -40,9 +40,6 @@ #include <telepathy-logger/datetime.h> #include <telepathy-logger/util.h> -//#define DEBUG_FLAG EMPATHY_DEBUG_OTHER -//#include <empathy-debug.h> - #define DEBUG g_debug #define GET_PRIV(obj) TPL_GET_PRIV (obj, TplLogManager) @@ -104,11 +101,10 @@ log_manager_constructor (GType type, guint n_props, { GObject *retval; TplLogManagerPriv *priv; + TplLogStoreEmpathy *tplogger; if (manager_singleton) - { - retval = g_object_ref (manager_singleton); - } + retval = g_object_ref (manager_singleton); else { retval = G_OBJECT_CLASS (tpl_log_manager_parent_class)->constructor @@ -119,9 +115,22 @@ log_manager_constructor (GType type, guint n_props, priv = GET_PRIV (manager_singleton); - priv->stores = g_list_append (priv->stores, - g_object_new (TPL_TYPE_LOG_STORE_EMPATHY, - NULL)); + /* TODO currently I instantiate two LogStore, one read-only, and the + * default one, TpLogger, which will be used by add_message to store + * (write_access) new entries. + * NEXT step: use a LogStore map here, and instantiate LogStores + * using it. LogStore map should map names into (TPL_TYPE_LOG_STORE_FOO, + * is_writable, is_readable) to be passed to g_object_new cycling over + * its keys */ + tplogger = g_object_new (TPL_TYPE_LOG_STORE_EMPATHY, "name", "TpLogger", + "writable", FALSE, "readable", TRUE, NULL); + if (tplogger == NULL) + { + g_debug ("Error during TplLogStoreEmpathy (name=TpLogger) initialisation."); + return NULL; + } + + priv->stores = g_list_append (priv->stores, tplogger); } return retval; @@ -167,8 +176,12 @@ tpl_log_manager_dup_singleton (void) return g_object_new (TPL_TYPE_LOG_MANAGER, NULL); } -/* - * @message: a TplLogEntry subclass +/** + * tpl_log_manager_add_message + * @manager: the log manager + * @message: a TplLogEntry subclass's instance + * + * Returns: %TRUE if the message has been added successfully, %FALSE else. */ gboolean tpl_log_manager_add_message (TplLogManager *manager, @@ -180,8 +193,10 @@ tpl_log_manager_add_message (TplLogManager *manager, gboolean out = FALSE; gboolean found = FALSE; - /* TODO: When multiple log stores appear with add_message implementations - * make this customisable. */ + /* TODO: currently it look for a fixed string (add_store) to know there to + * send messages. + * NEXT step: it will cycle priv->stores and check which has is_writable flag on, and send the log + * to every entry with it TRUE. Multiple writers are possible here */ const gchar *add_store = "TpLogger"; g_return_val_if_fail (TPL_IS_LOG_MANAGER (manager), FALSE); @@ -189,6 +204,9 @@ tpl_log_manager_add_message (TplLogManager *manager, priv = GET_PRIV (manager); + /* TODO find a way to select just one LogStore, ie just the default one, or + * just "zeitgeist" in case an application is only interested in a specific + * store */ for (l = priv->stores; l; l = g_list_next (l)) { if (!tp_strdiff @@ -208,6 +226,20 @@ tpl_log_manager_add_message (TplLogManager *manager, } +void +tpl_log_manager_register_logstore (TplLogManager *self, + TplLogStore *logstore) +{ + TplLogManagerPriv *priv = GET_PRIV (self); + + g_return_if_fail (TPL_IS_LOG_MANAGER (self)); + g_return_if_fail (TPL_IS_LOG_STORE (logstore)); + g_return_if_fail (priv->stores != NULL); + + priv->stores = g_list_append (priv->stores, logstore); +} + + gboolean tpl_log_manager_exists (TplLogManager *manager, TpAccount *account, @@ -290,11 +322,8 @@ tpl_log_manager_get_messages_for_date (TplLogManager *manager, { TplLogStore *store = TPL_LOG_STORE (l->data); - out = - g_list_concat (out, - tpl_log_store_get_messages_for_date (store, account, - chat_id, chatroom, - date)); + out = g_list_concat (out, tpl_log_store_get_messages_for_date (store, + account, chat_id, chatroom, date)); } return out; @@ -346,8 +375,7 @@ tpl_log_manager_get_filtered_messages (TplLogManager *manager, GList *new; new = tpl_log_store_get_filtered_messages (store, account, chat_id, - chatroom, num_messages, - filter, user_data); + chatroom, num_messages, filter, user_data); while (new) { if (i < num_messages) @@ -383,6 +411,34 @@ tpl_log_manager_get_filtered_messages (TplLogManager *manager, } +gint +tpl_log_manager_search_hit_compare (TplLogSearchHit *a, + TplLogSearchHit *b) +{ + gint ret; + + if (g_strcmp0 (a->chat_id, b->chat_id) == 0) + /* if chat_ids differ, just return their sorting return value */ + ret = 0; + else + /* if they are the same, check if the entries are actually equal or not + have the same chat_id but one is a chatroom and the other not */ + ret = a->is_chatroom && b->is_chatroom ? 0 : 1; + return ret; +} + +/** + * tpl_log_manager_get_chats + * @manager: the log manager + * @account: a TpAccount the query will return data related to + * + * It queries the readable TplLogStores in @manager for all the buddies the + * log store has at least a conversation stored originated using @account. + * + * Returns: a list of pointer to TplLogSearchHit, having chat_id and + * is_chatroom fields filled. the result needs to be freed after use using + * #tpl_log_manager_search_hit_free + */ GList * tpl_log_manager_get_chats (TplLogManager *manager, TpAccount *account) @@ -398,8 +454,19 @@ tpl_log_manager_get_chats (TplLogManager *manager, for (l = priv->stores; l; l = g_list_next (l)) { TplLogStore *store = TPL_LOG_STORE (l->data); - - out = g_list_concat (out, tpl_log_store_get_chats (store, account)); + GList *in; + + /* merge the lists avoiding duplicates */ + for (in = tpl_log_store_get_chats (store, account); in != NULL; + in = g_list_next (in)) + if (g_list_find_custom (out, in->data, + (GCompareFunc) tpl_log_manager_search_hit_compare) == NULL) + /* add data if not already present */ + out = g_list_prepend (out, in->data); + else + /* free in->data if already present in out */ + tpl_log_manager_search_hit_free (in->data); + g_list_free (in); } return out; @@ -514,9 +581,9 @@ static void tpl_log_manager_chat_info_free (TplLogManagerChatInfo *data) { tpl_object_unref_if_not_null (data->account); - if (data->chat_id) + if (data->chat_id != NULL) g_free (data->chat_id); - if (data->date) + if (data->date != NULL) g_free (data->date); g_free (data); } @@ -797,12 +864,8 @@ _get_filtered_messages_thread (GSimpleAsyncResult *simple, chat_info = async_data->request; lst = tpl_log_manager_get_filtered_messages (async_data->manager, - chat_info->account, - chat_info->chat_id, - chat_info->is_chatroom, - chat_info->num_messages, - chat_info->filter, - chat_info->user_data); + chat_info->account, chat_info->chat_id, chat_info->is_chatroom, + chat_info->num_messages, chat_info->filter, chat_info->user_data); g_simple_async_result_set_op_res_gpointer (simple, lst, NULL); } @@ -860,8 +923,7 @@ tpl_log_manager_get_filtered_messages_async (TplLogManager *manager, async_data->user_data = user_data; _tpl_log_manager_call_async_operation (manager, - _get_filtered_messages_thread, - async_data, callback); + _get_filtered_messages_thread, async_data, callback); } /* End of get_filtered_messages async implementation */ @@ -914,8 +976,7 @@ tpl_log_manager_get_chats_async (TplLogManager *manager, async_data->cb = callback; async_data->user_data = user_data; - _tpl_log_manager_call_async_operation (manager, - _get_chats_thread, + _tpl_log_manager_call_async_operation (manager, _get_chats_thread, async_data, callback); } @@ -976,8 +1037,7 @@ tpl_log_manager_search_in_identifier_chats_new_async (TplLogManager *manager, async_data->user_data = user_data; _tpl_log_manager_call_async_operation (manager, - _search_in_identifier_chats_new_thread, - async_data, callback); + _search_in_identifier_chats_new_thread, async_data, callback); } /* End of tpl_log_manager_search_in_identifier_chats_new async implementation */ diff --git a/telepathy-logger/log-manager.h b/telepathy-logger/log-manager.h index bc083b2..bd375ad 100644 --- a/telepathy-logger/log-manager.h +++ b/telepathy-logger/log-manager.h @@ -29,6 +29,7 @@ #include <telepathy-glib/account.h> #include <telepathy-logger/log-entry.h> +#include <telepathy-logger/log-store.h> G_BEGIN_DECLS #define TPL_TYPE_LOG_MANAGER (tpl_log_manager_get_type ()) @@ -71,13 +72,8 @@ typedef struct } TplLogSearchHit; -typedef gboolean (*TplLogMessageFilter) (TplLogEntry *message, - gpointer user_data); - - GType tpl_log_manager_get_type (void); - gpointer tpl_log_manager_async_operation_finish (GAsyncResult *result, GError **error); @@ -133,6 +129,11 @@ void tpl_log_manager_search_free (GList *hits); gchar *tpl_log_manager_get_date_readable (const gchar *date); void tpl_log_manager_search_hit_free (TplLogSearchHit *hit); +gint tpl_log_manager_search_hit_compare (TplLogSearchHit *a, + TplLogSearchHit *b); + +void tpl_log_manager_register_logstore (TplLogManager *self, + TplLogStore *logstore); G_END_DECLS #endif /* __TPL_LOG_MANAGER_H__ */ diff --git a/telepathy-logger/log-store-empathy.c b/telepathy-logger/log-store-empathy.c index 6576c5d..9136405 100644 --- a/telepathy-logger/log-store-empathy.c +++ b/telepathy-logger/log-store-empathy.c @@ -20,6 +20,7 @@ * * Authors: Xavier Claessens <xclaesse@gmail.com> * Jonny Lamb <jonny.lamb@collabora.co.uk> + * Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> */ #include "log-store-empathy.h" @@ -64,29 +65,44 @@ typedef struct { gchar *basedir; - gchar *name; + gchar *type_name; + gchar *instance_name; TpAccountManager *account_manager; } TplLogStoreEmpathyPriv; +enum { + PROP_0, + PROP_INSTANCE_NAME, + PROP_READABLE, + PROP_WRITABLE +}; + static void log_store_iface_init (gpointer g_iface, gpointer iface_data); +static void get_prop (GObject *object, guint param_id, GValue *value, + GParamSpec *pspec); +static void set_prop (GObject *object, guint param_id, const GValue *value, + GParamSpec *pspec); +static const gchar *log_store_empathy_get_instance_name (TplLogStore *self); +static void log_store_empathy_set_instance_name (TplLogStore *self, const gchar *data); +static GObject *log_store_empathy_constructor (GType type, guint n_props, + GObjectConstructParam *props); G_DEFINE_TYPE_WITH_CODE (TplLogStoreEmpathy, tpl_log_store_empathy, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (TPL_TYPE_LOG_STORE, - log_store_iface_init)); + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TPL_TYPE_LOG_STORE, log_store_iface_init)) static void -log_store_empathy_dispose (GObject * object) +log_store_empathy_dispose (GObject *object) { TplLogStoreEmpathy *self = TPL_LOG_STORE_EMPATHY (object); TplLogStoreEmpathyPriv *priv = GET_PRIV (self); - // FIXME See TP-bug #25569, when dispose a non prepared TP_AM, it - // might segfault. - // To avoid it, a *klduge*, a reference in the TplObserver to - // the TplLogManager is kept, so that until TplObserver is instanced, - // there will always be a TpLogManager reference and it won't be - // diposed, not executing the follwoing unref (which caused the bug) + /* FIXME See TP-bug #25569, when dispose a non prepared TP_AM, it + might segfault. + To avoid it, a *klduge*, a reference in the TplObserver to + the TplLogManager is kept, so that until TplObserver is instanced, + there will always be a TpLogManager reference and it won't be + diposed */ if (priv->account_manager != NULL) { g_object_unref (priv->account_manager); @@ -96,46 +112,159 @@ log_store_empathy_dispose (GObject * object) static void -log_store_empathy_finalize (GObject * object) +log_store_empathy_finalize (GObject *object) { TplLogStoreEmpathy *self = TPL_LOG_STORE_EMPATHY (object); TplLogStoreEmpathyPriv *priv = GET_PRIV (self); - g_free (priv->basedir); - g_free (priv->name); + if (priv->basedir != NULL) + { + g_free (priv->basedir); + priv->basedir = NULL; + } + if (priv->instance_name != NULL) + { + g_free (priv->instance_name); + priv->instance_name = NULL; + } +} + + +static void +get_prop (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + TplLogStoreEmpathyPriv *priv = GET_PRIV (object); + + switch (param_id) + { + case PROP_INSTANCE_NAME: + g_value_set_string (value, priv->instance_name); + break; + case PROP_READABLE: + /* ignore */ + break; + case PROP_WRITABLE: + /* ignore */ + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + }; +} + + +static void +set_prop (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + TplLogStore *self = TPL_LOG_STORE (object); + TplLogStoreEmpathyPriv *priv = GET_PRIV (object); + + switch (param_id) + { + case PROP_INSTANCE_NAME: + g_assert (priv->instance_name == NULL); + log_store_empathy_set_instance_name (self, g_value_get_string (value)); + break; + case PROP_READABLE: + /* ignore */ + break; + case PROP_WRITABLE: + /* ignore */ + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + }; } + static void -tpl_log_store_empathy_class_init (TplLogStoreEmpathyClass * klass) +tpl_log_store_empathy_class_init (TplLogStoreEmpathyClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *param_spec; object_class->finalize = log_store_empathy_finalize; object_class->dispose = log_store_empathy_dispose; + object_class->get_property = get_prop; + object_class->set_property = set_prop; + object_class->constructor = log_store_empathy_constructor; + + param_spec = g_param_spec_string ("name", + "Name", + "The TplLogStore implementation's name", + NULL, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INSTANCE_NAME, param_spec); + + param_spec = g_param_spec_boolean ("readable", + "Readable", + "Defines wether the LogStore is readable or not, allowing searching " + "into this instance", + TRUE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_READABLE, param_spec); + + param_spec = g_param_spec_boolean ("writable", + "Writable", + "Defines wether the LogStore is writable or not, allowing message " + "to be stored into this instance", + FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_WRITABLE, param_spec); g_type_class_add_private (object_class, sizeof (TplLogStoreEmpathyPriv)); } + static void -tpl_log_store_empathy_init (TplLogStoreEmpathy * self) +tpl_log_store_empathy_init (TplLogStoreEmpathy *self) { TplLogStoreEmpathyPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - TPL_TYPE_LOG_STORE_EMPATHY, - TplLogStoreEmpathyPriv); + TPL_TYPE_LOG_STORE_EMPATHY, TplLogStoreEmpathyPriv); self->priv = priv; +} - priv->basedir = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (), - "TpLogger", "logs", NULL); - // TODO update to a more meaningful name when more than one LogStore - // implementation will exist, like TpXMLLogger and TPSQLiteLogger - priv->name = g_strdup ("TpLogger"); +static GObject * +log_store_empathy_constructor (GType type, + guint n_props, + GObjectConstructParam *props) +{ + GObject *retval; + TplLogStoreEmpathy *self; + TplLogStoreEmpathyPriv *priv; + + retval = G_OBJECT_CLASS (tpl_log_store_empathy_parent_class)->constructor( + type, n_props, props); + self = TPL_LOG_STORE_EMPATHY (retval); + + /* set a default value if no property has been set at g_object_new time */ + if (log_store_empathy_get_instance_name (TPL_LOG_STORE (self)) == NULL) + log_store_empathy_set_instance_name (TPL_LOG_STORE (self), "TpLogger"); + + priv = GET_PRIV (self); + priv->basedir = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (), + log_store_empathy_get_instance_name (TPL_LOG_STORE (self)), "logs", NULL); priv->account_manager = tp_account_manager_dup (); + + g_debug ("LogStoreName: %s", log_store_empathy_get_instance_name (TPL_LOG_STORE + (self))); + g_debug ("LogStore Dir: %s", priv->basedir); + + return retval; } + static gchar * -log_store_account_to_dirname (TpAccount * account) +log_store_account_to_dirname (TpAccount *account) { const gchar *name; @@ -148,11 +277,14 @@ log_store_account_to_dirname (TpAccount * account) return g_strdelimit (g_strdup (name), "/", '_'); } - +/* chat_id can be NULL, but if present have to be a non zero-lenght string. + * If NULL, the returned dir will be composed until the account part. + * If non-NULL, the returned dir will be composed until the chat_id part */ static gchar * -log_store_empathy_get_dir (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, gboolean chatroom) +log_store_empathy_get_dir (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom) { gchar *basedir; gchar *escaped; @@ -160,8 +292,8 @@ log_store_empathy_get_dir (TplLogStore * self, g_return_val_if_fail (TPL_IS_LOG_STORE (self), NULL); g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL); - // chat_id may be NULL, in order to obtain the account part of the - // path. + /* chat_id may be NULL, but not empthy string if not-NULL */ + g_return_val_if_fail ((chat_id == NULL) || (*chat_id != '\0'), NULL); priv = GET_PRIV (self); @@ -169,16 +301,17 @@ log_store_empathy_get_dir (TplLogStore * self, if (chatroom) basedir = g_build_path (G_DIR_SEPARATOR_S, priv->basedir, escaped, - LOG_DIR_CHATROOMS, chat_id, NULL); + LOG_DIR_CHATROOMS, chat_id, NULL); else basedir = g_build_path (G_DIR_SEPARATOR_S, priv->basedir, - escaped, chat_id, NULL); + escaped, chat_id, NULL); g_free (escaped); return basedir; } + static gchar * log_store_empathy_get_timestamp_filename (void) { @@ -195,6 +328,7 @@ log_store_empathy_get_timestamp_filename (void) return filename; } + static gchar * log_store_empathy_get_timestamp_from_message (TplLogEntry * message) { @@ -202,14 +336,16 @@ log_store_empathy_get_timestamp_from_message (TplLogEntry * message) t = tpl_log_entry_get_timestamp (message); - /* We keep the timestamps in the messages as UTC. */ + /* We keep the timestamps in the messages as UTC */ return tpl_time_to_string_utc (t, LOG_TIME_FORMAT_FULL); } + static gchar * -log_store_empathy_get_filename (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, gboolean chatroom) +log_store_empathy_get_filename (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom) { gchar *basedir; gchar *timestamp; @@ -225,12 +361,14 @@ log_store_empathy_get_filename (TplLogStore * self, return filename; } + static gboolean -_log_store_empathy_write_to_store (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, +_log_store_empathy_write_to_store (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, gboolean chatroom, - const gchar * entry, GError ** error) + const gchar *entry, + GError **error) { FILE *file; gchar *filename; @@ -250,7 +388,7 @@ _log_store_empathy_write_to_store (TplLogStore * self, { file = g_fopen (filename, "w+"); if (file != NULL) - g_fprintf (file, LOG_HEADER); + g_fprintf (file, LOG_HEADER); g_chmod (filename, LOG_FILE_CREATE_MODE); } @@ -258,7 +396,7 @@ _log_store_empathy_write_to_store (TplLogStore * self, { file = g_fopen (filename, "r+"); if (file != NULL) - fseek (file, -strlen (LOG_FOOTER), SEEK_END); + fseek (file, -strlen (LOG_FOOTER), SEEK_END); } g_fprintf (file, "%s", entry); @@ -268,6 +406,7 @@ _log_store_empathy_write_to_store (TplLogStore * self, return TRUE; } + static gboolean add_message_text_chat (TplLogStore *self, TplLogEntryText *message, @@ -347,7 +486,8 @@ add_message_text_chat (TplLogStore *self, static gboolean add_message_text (TplLogStore *self, - TplLogEntryText *message, GError **error) + TplLogEntryText *message, + GError **error) { TplLogEntryTextSignalType signal_type; const gchar *chat_id; @@ -386,7 +526,8 @@ add_message_text (TplLogStore *self, /* First of two phases selection: understand the type LogEntry */ static gboolean log_store_empathy_add_message (TplLogStore *self, - gpointer message, GError **error) + gpointer message, + GError **error) { g_return_val_if_fail (TPL_IS_LOG_ENTRY (message), FALSE); @@ -406,9 +547,10 @@ log_store_empathy_add_message (TplLogStore *self, static gboolean -log_store_empathy_exists (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, gboolean chatroom) +log_store_empathy_exists (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom) { gchar *dir; gboolean exists; @@ -424,10 +566,12 @@ log_store_empathy_exists (TplLogStore * self, return exists; } + static GList * -log_store_empathy_get_dates (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, gboolean chatroom) +log_store_empathy_get_dates (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom) { GList *dates = NULL; gchar *date; @@ -476,12 +620,13 @@ log_store_empathy_get_dates (TplLogStore * self, return dates; } + static gchar * -log_store_empathy_get_filename_for_date (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom, - const gchar * date) +log_store_empathy_get_filename_for_date (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom, + const gchar *date) { gchar *basedir; gchar *timestamp; @@ -503,8 +648,10 @@ log_store_empathy_get_filename_for_date (TplLogStore * self, return filename; } + static TplLogSearchHit * -log_store_empathy_search_hit_new (TplLogStore * self, const gchar * filename) +log_store_empathy_search_hit_new (TplLogStore *self, + const gchar *filename) { TplLogStoreEmpathyPriv *priv = GET_PRIV (self); TplLogSearchHit *hit; @@ -561,10 +708,11 @@ log_store_empathy_search_hit_new (TplLogStore * self, const gchar * filename) return hit; } + static GList * -log_store_empathy_get_messages_for_file (TplLogStore * self, - TpAccount * account, - const gchar * filename) +log_store_empathy_get_messages_for_file (TplLogStore *self, + TpAccount *account, + const gchar *filename) { GList *messages = NULL; xmlParserCtxtPtr ctxt; @@ -666,8 +814,9 @@ log_store_empathy_get_messages_for_file (TplLogStore * self, tpl_log_entry_set_timestamp (TPL_LOG_ENTRY (message), t); tpl_log_entry_text_set_message (message, body); tpl_log_entry_text_set_message_type (message, msg_type); - //TODO uderstand if useful - //tpl_log_entry_text_set_is_backlog (message, TRUE); + /* TODO uderstand if useful + tpl_log_entry_text_set_is_backlog (message, TRUE); + */ messages = g_list_append (messages, message); @@ -690,8 +839,12 @@ log_store_empathy_get_messages_for_file (TplLogStore * self, return messages; } + +/* If dir is NULL, basedir will be used instead. + * Used to make possible the full search vs. specific subtrees search */ static GList * -log_store_empathy_get_all_files (TplLogStore * self, const gchar * dir) +log_store_empathy_get_all_files (TplLogStore *self, + const gchar *dir) { GDir *gdir; GList *files = NULL; @@ -702,9 +855,9 @@ log_store_empathy_get_all_files (TplLogStore * self, const gchar * dir) priv = GET_PRIV (self); g_return_val_if_fail (TPL_IS_LOG_STORE (self), NULL); - // dir can be NULL, and basedir will be searched instead + /* dir can be NULL, do not check :-) */ - basedir = dir ? dir : priv->basedir; + basedir = (dir != NULL) ? dir : priv->basedir; gdir = g_dir_open (basedir, 0, NULL); if (!gdir) @@ -716,18 +869,18 @@ log_store_empathy_get_all_files (TplLogStore * self, const gchar * dir) filename = g_build_filename (basedir, name, NULL); if (g_str_has_suffix (filename, LOG_FILENAME_SUFFIX)) - { - files = g_list_prepend (files, filename); - continue; - } + { + files = g_list_prepend (files, filename); + continue; + } if (g_file_test (filename, G_FILE_TEST_IS_DIR)) - { - /* Recursively get all log files */ - files = g_list_concat (files, - log_store_empathy_get_all_files (self, - filename)); - } + { + /* Recursively get all log files */ + files = g_list_concat (files, + log_store_empathy_get_all_files (self, + filename)); + } g_free (filename); } @@ -739,8 +892,9 @@ log_store_empathy_get_all_files (TplLogStore * self, const gchar * dir) static GList * -_log_store_empathy_search_in_files (TplLogStore * self, - const gchar * text, GList * files) +_log_store_empathy_search_in_files (TplLogStore *self, + const gchar *text, + GList *files) { GList *l; GList *hits = NULL; @@ -763,7 +917,7 @@ _log_store_empathy_search_in_files (TplLogStore * self, file = g_mapped_file_new (filename, FALSE, NULL); if (!file) - continue; + continue; length = g_mapped_file_get_length (file); contents = g_mapped_file_get_contents (file); @@ -772,18 +926,17 @@ _log_store_empathy_search_in_files (TplLogStore * self, g_mapped_file_unref (file); if (strstr (contents_casefold, text_casefold)) - { - TplLogSearchHit *hit; - - hit = log_store_empathy_search_hit_new (self, filename); - - if (hit) - { - hits = g_list_prepend (hits, hit); - DEBUG ("Found text:'%s' in file:'%s' on date:'%s'", - text, hit->filename, hit->date); - } - } + { + TplLogSearchHit *hit; + + hit = log_store_empathy_search_hit_new (self, filename); + if (hit != NULL) + { + hits = g_list_prepend (hits, hit); + DEBUG ("Found text:'%s' in file:'%s' on date:'%s'", text, + hit->filename, hit->date); + } + } g_free (contents_casefold); g_free (filename); @@ -797,10 +950,10 @@ _log_store_empathy_search_in_files (TplLogStore * self, static GList * -log_store_empathy_search_in_identifier_chats_new (TplLogStore * self, - TpAccount * account, - gchar const *identifier, - const gchar * text) +log_store_empathy_search_in_identifier_chats_new (TplLogStore *self, + TpAccount *account, + gchar const *identifier, + const gchar *text) { GList *files; gchar *dir, *account_dir; @@ -812,9 +965,8 @@ log_store_empathy_search_in_identifier_chats_new (TplLogStore * self, g_return_val_if_fail (!TPL_STR_EMPTY (text), NULL); account_dir = log_store_account_to_dirname (account); - dir = - g_build_path (G_DIR_SEPARATOR_S, priv->basedir, account_dir, - G_DIR_SEPARATOR_S, identifier, NULL); + dir = g_build_path (G_DIR_SEPARATOR_S, priv->basedir, account_dir, + G_DIR_SEPARATOR_S, identifier, NULL); files = log_store_empathy_get_all_files (self, dir); DEBUG ("Found %d log files in total", g_list_length (files)); @@ -825,7 +977,8 @@ log_store_empathy_search_in_identifier_chats_new (TplLogStore * self, static GList * -log_store_empathy_search_new (TplLogStore * self, const gchar * text) +log_store_empathy_search_new (TplLogStore *self, + const gchar *text) { GList *files; @@ -838,25 +991,11 @@ log_store_empathy_search_new (TplLogStore * self, const gchar * text) return _log_store_empathy_search_in_files (self, text, files); } -/* -static gboolean -log_store_empathy_is_logfile (gchar const *filename) { - gchar **path; - guint len; - g_return_val_if_fail(!TPL_STR_EMPTY(filename), FALSE); - - - path = g_strsplit (filename, G_DIR_SEPARATOR_S, -1); - len = g_strv_length (path); - - return g_regex_match_simple ( - TPL_LOG_STORE_EMPATHY_LOGFILE_REGEX, path[len-1], 0, 0); -} -*/ - +/* Returns: (GList*) of (TplLogSearchHit*) */ static GList * -log_store_empathy_get_chats_for_dir (TplLogStore * self, - const gchar * dir, gboolean is_chatroom) +log_store_empathy_get_chats_for_dir (TplLogStore *self, + const gchar *dir, + gboolean is_chatroom) { GDir *gdir; GList *hits = NULL; @@ -876,16 +1015,13 @@ log_store_empathy_get_chats_for_dir (TplLogStore * self, TplLogSearchHit *hit; if (!is_chatroom && strcmp (name, LOG_DIR_CHATROOMS) == 0) - { - gchar *filename = g_build_filename (dir, name, NULL); - hits = - g_list_concat (hits, - log_store_empathy_get_chats_for_dir (self, - filename, - TRUE)); - g_free (filename); - continue; - } + { + gchar *filename = g_build_filename (dir, name, NULL); + hits = g_list_concat (hits, + log_store_empathy_get_chats_for_dir (self, filename, TRUE)); + g_free (filename); + continue; + } hit = g_slice_new0 (TplLogSearchHit); hit->chat_id = g_strdup (name); hit->is_chatroom = is_chatroom; @@ -900,11 +1036,11 @@ log_store_empathy_get_chats_for_dir (TplLogStore * self, static GList * -log_store_empathy_get_messages_for_date (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom, - const gchar * date) +log_store_empathy_get_messages_for_date (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom, + const gchar *date) { gchar *filename; GList *messages; @@ -913,18 +1049,18 @@ log_store_empathy_get_messages_for_date (TplLogStore * self, g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL); g_return_val_if_fail (!TPL_STR_EMPTY (chat_id), NULL); - filename = log_store_empathy_get_filename_for_date (self, account, - chat_id, chatroom, - date); - messages = - log_store_empathy_get_messages_for_file (self, account, filename); + filename = log_store_empathy_get_filename_for_date (self, account, chat_id, + chatroom, date); + messages = log_store_empathy_get_messages_for_file (self, account, + filename); g_free (filename); return messages; } static GList * -log_store_empathy_get_chats (TplLogStore * self, TpAccount * account) +log_store_empathy_get_chats (TplLogStore *self, + TpAccount *account) { gchar *dir; GList *hits; @@ -933,9 +1069,7 @@ log_store_empathy_get_chats (TplLogStore * self, TpAccount * account) priv = GET_PRIV (self); dir = log_store_empathy_get_dir (self, account, NULL, FALSE); - hits = log_store_empathy_get_chats_for_dir (self, dir, FALSE); - g_free (dir); for (guint i = 0; i < g_list_length (hits); ++i) @@ -948,22 +1082,39 @@ log_store_empathy_get_chats (TplLogStore * self, TpAccount * account) return hits; } + static const gchar * -log_store_empathy_get_name (TplLogStore * self) +log_store_empathy_get_instance_name (TplLogStore *self) { TplLogStoreEmpathyPriv *priv = GET_PRIV (self); - return priv->name; + g_return_val_if_fail (TPL_IS_LOG_STORE_EMPATHY (self), NULL); + + return priv->instance_name; } + +static void +log_store_empathy_set_instance_name (TplLogStore *self, + const gchar *data) +{ + TplLogStoreEmpathyPriv *priv = GET_PRIV (self); + + g_return_if_fail (TPL_IS_LOG_STORE_EMPATHY (self)); + g_return_if_fail (priv->instance_name == NULL); + + priv->instance_name = g_strdup (data); +} + + static GList * -log_store_empathy_get_filtered_messages (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom, - guint num_messages, - TplLogMessageFilter filter, - gpointer user_data) +log_store_empathy_get_filtered_messages (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom, + guint num_messages, + TplLogMessageFilter filter, + gpointer user_data) { GList *dates, *l, *messages = NULL; guint i = 0; @@ -978,25 +1129,21 @@ log_store_empathy_get_filtered_messages (TplLogStore * self, /* FIXME: We should really restrict the message parsing to get only * the newest num_messages. */ new_messages = log_store_empathy_get_messages_for_date (self, account, - chat_id, - chatroom, - l->data); + chat_id, chatroom, l->data); n = new_messages; while (n != NULL) - { - next = g_list_next (n); - if (!filter (n->data, user_data)) - { - g_object_unref (n->data); - new_messages = g_list_delete_link (new_messages, n); - } - else - { - i++; - } - n = next; - } + { + next = g_list_next (n); + if (!filter (n->data, user_data)) + { + g_object_unref (n->data); + new_messages = g_list_delete_link (new_messages, n); + } + else + i++; + n = next; + } messages = g_list_concat (messages, new_messages); } @@ -1007,11 +1154,12 @@ log_store_empathy_get_filtered_messages (TplLogStore * self, } static void -log_store_iface_init (gpointer g_iface, gpointer iface_data) +log_store_iface_init (gpointer g_iface, + gpointer iface_data) { TplLogStoreInterface *iface = (TplLogStoreInterface *) g_iface; - iface->get_name = log_store_empathy_get_name; + iface->get_name = log_store_empathy_get_instance_name; iface->exists = log_store_empathy_exists; iface->add_message = log_store_empathy_add_message; iface->get_dates = log_store_empathy_get_dates; diff --git a/telepathy-logger/log-store-factory.c b/telepathy-logger/log-store-factory.c new file mode 100644 index 0000000..8b54c4b --- /dev/null +++ b/telepathy-logger/log-store-factory.c @@ -0,0 +1,98 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include "log-store-factory.h" + +#include <telepathy-logger/util.h> +#include <telepathy-logger/log-store-empathy.h> + +static GHashTable *logstores_table = NULL; + +void +tpl_log_store_factory_init (void) +{ + g_return_if_fail (logstores_table == NULL); + + logstores_table = g_hash_table_new_full (g_str_hash, + (GEqualFunc) tpl_strequal, g_free, NULL); +} + + +void +tpl_log_store_factory_add (const gchar *logstore_type, + TplLogStoreConstructor constructor) +{ + gchar *key; + + g_return_if_fail (!TPL_STR_EMPTY (logstore_type)); + g_return_if_fail (constructor != NULL); + g_return_if_fail (logstores_table != NULL); + + key = g_strdup (logstore_type); + + if (g_hash_table_lookup (logstores_table, logstore_type) != NULL) + { + g_warning ("Type %s already mapped. replacing constructor.", + logstore_type); + g_hash_table_replace (logstores_table, key, constructor); + } + else + g_hash_table_insert (logstores_table, key, constructor); +} + + +TplLogStoreConstructor +tpl_log_store_factory_lookup (const gchar *logstore_type) +{ + g_return_val_if_fail (!TPL_STR_EMPTY (logstore_type), NULL); + g_return_val_if_fail (logstores_table != NULL, NULL); + + return g_hash_table_lookup (logstores_table, logstore_type); +} + +void +tpl_log_store_factory_deinit (void) +{ + g_return_if_fail (logstores_table != NULL); + + g_hash_table_unref (logstores_table); + logstores_table = NULL; +} + +TplLogStore * +tpl_log_store_factory_build (const gchar *logstore_type, + const gchar *name, + gboolean write_access, + gboolean read_access) +{ + TplLogStoreConstructor constructor; + + g_return_val_if_fail (logstores_table != NULL, NULL); + + constructor = tpl_log_store_factory_lookup (logstore_type); + if (constructor == NULL) + { + g_debug ("%s: log store type not handled by this logger", logstore_type); + return NULL; + } + + return constructor (name, write_access, read_access); +} diff --git a/telepathy-logger/log-store-factory.h b/telepathy-logger/log-store-factory.h new file mode 100644 index 0000000..5cbf750 --- /dev/null +++ b/telepathy-logger/log-store-factory.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#ifndef __TPL_LOG_STORE_FACTORY_H__ +#define __TPL_LOG_STORE_FACTORY_H__ + +#include <glib-object.h> + +#include <telepathy-logger/log-store.h> + +typedef TplLogStore* (*TplLogStoreConstructor) (const gchar *name, + gboolean write_access, gboolean read_access); +typedef TplLogStore* (*TplLogStoreFactory) (const gchar *logstore_type, + const gchar *name, gboolean write_access, gboolean read_access); + +void tpl_log_store_factory_init (void); +void tpl_log_store_factory_deinit (void); +void tpl_log_store_factory_add (const gchar *logstore_type, + TplLogStoreConstructor constructor); +TplLogStoreConstructor tpl_log_store_factory_lookup (const gchar *logstore_type); +TplLogStore *tpl_log_store_factory_build (const gchar *logstore_type, + const gchar *name, gboolean write_access, gboolean read_access); + +#endif /* __TPL_LOG_STORE_FACTORY_H__ */ diff --git a/telepathy-logger/log-store.c b/telepathy-logger/log-store.c index a98f5db..872d661 100644 --- a/telepathy-logger/log-store.c +++ b/telepathy-logger/log-store.c @@ -17,7 +17,8 @@ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA * - * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> + * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>, + * Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> */ #include "log-store.h" @@ -29,22 +30,23 @@ tpl_log_store_get_type (void) if (type == 0) { static const GTypeInfo info = { - sizeof (TplLogStoreInterface), - NULL, /* base_init */ - NULL, /* base_finalize */ - NULL, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL /* instance_init */ + sizeof (TplLogStoreInterface), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL /* instance_init */ }; type = g_type_register_static (G_TYPE_INTERFACE, "TplLogStore", - &info, 0); + &info, 0); } return type; } + const gchar * tpl_log_store_get_name (TplLogStore * self) { @@ -54,23 +56,25 @@ tpl_log_store_get_name (TplLogStore * self) return TPL_LOG_STORE_GET_INTERFACE (self)->get_name (self); } + gboolean -tpl_log_store_exists (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, gboolean chatroom) +tpl_log_store_exists (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->exists) return FALSE; return TPL_LOG_STORE_GET_INTERFACE (self)->exists (self, account, chat_id, - chatroom); + chatroom); } - gboolean -tpl_log_store_add_message (TplLogStore * self, - gpointer message, GError ** error) +tpl_log_store_add_message (TplLogStore *self, + gpointer message, + GError **error) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->add_message) { @@ -79,52 +83,56 @@ tpl_log_store_add_message (TplLogStore * self, } return TPL_LOG_STORE_GET_INTERFACE (self)->add_message (self, message, - error); + error); } + GList * -tpl_log_store_get_dates (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, gboolean chatroom) +tpl_log_store_get_dates (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->get_dates) return NULL; return TPL_LOG_STORE_GET_INTERFACE (self)->get_dates (self, account, - chat_id, chatroom); + chat_id, chatroom); } + GList * -tpl_log_store_get_messages_for_date (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom, const gchar * date) +tpl_log_store_get_messages_for_date (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom, + const gchar *date) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->get_messages_for_date) return NULL; return TPL_LOG_STORE_GET_INTERFACE (self)->get_messages_for_date (self, - account, - chat_id, - chatroom, - date); + account, chat_id, chatroom, date); } + GList * -tpl_log_store_get_last_messages (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, gboolean chatroom) +tpl_log_store_get_last_messages (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->get_last_messages) return NULL; return TPL_LOG_STORE_GET_INTERFACE (self)->get_last_messages (self, account, - chat_id, - chatroom); + chat_id, chatroom); } + GList * -tpl_log_store_get_chats (TplLogStore * self, TpAccount * account) +tpl_log_store_get_chats (TplLogStore *self, + TpAccount *account) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->get_chats) return NULL; @@ -135,24 +143,21 @@ tpl_log_store_get_chats (TplLogStore * self, TpAccount * account) GList * -tpl_log_store_search_in_identifier_chats_new (TplLogStore * self, - TpAccount * account, - gchar const *identifier, - const gchar * text) +tpl_log_store_search_in_identifier_chats_new (TplLogStore *self, + TpAccount *account, + gchar const *identifier, + const gchar *text) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->search_new) return NULL; - return - TPL_LOG_STORE_GET_INTERFACE (self)->search_in_identifier_chats_new (self, - account, - identifier, - text); + return TPL_LOG_STORE_GET_INTERFACE (self)->search_in_identifier_chats_new (self, + account, identifier, text); } GList * -tpl_log_store_search_new (TplLogStore * self, const gchar * text) +tpl_log_store_search_new (TplLogStore *self, const gchar *text) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->search_new) return NULL; @@ -160,10 +165,12 @@ tpl_log_store_search_new (TplLogStore * self, const gchar * text) return TPL_LOG_STORE_GET_INTERFACE (self)->search_new (self, text); } + void -tpl_log_store_ack_message (TplLogStore * self, - const gchar * chat_id, - gboolean chatroom, TplLogEntry * message) +tpl_log_store_ack_message (TplLogStore *self, + const gchar *chat_id, + gboolean chatroom, + TplLogEntry *message) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->ack_message) return; @@ -172,23 +179,19 @@ tpl_log_store_ack_message (TplLogStore * self, message); } + GList * -tpl_log_store_get_filtered_messages (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom, - guint num_messages, - TplLogMessageFilter filter, - gpointer user_data) +tpl_log_store_get_filtered_messages (TplLogStore *self, + TpAccount *account, + const gchar *chat_id, + gboolean chatroom, + guint num_messages, + TplLogMessageFilter filter, + gpointer user_data) { if (!TPL_LOG_STORE_GET_INTERFACE (self)->get_filtered_messages) return NULL; return TPL_LOG_STORE_GET_INTERFACE (self)->get_filtered_messages (self, - account, - chat_id, - chatroom, - num_messages, - filter, - user_data); + account, chat_id, chatroom, num_messages, filter, user_data); } diff --git a/telepathy-logger/log-store.h b/telepathy-logger/log-store.h index 83408b8..314a2a9 100644 --- a/telepathy-logger/log-store.h +++ b/telepathy-logger/log-store.h @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/*-*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2008 Collabora Ltd. * @@ -18,6 +18,7 @@ * Boston, MA 02110-1301 USA * * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> + * Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> */ #ifndef __TPL_LOG_STORE_H__ @@ -26,88 +27,74 @@ #include <glib-object.h> #include <telepathy-glib/account.h> -#include <telepathy-logger/log-manager.h> -#include <telepathy-logger/log-entry-text.h> +#include <telepathy-logger/log-entry.h> G_BEGIN_DECLS + #define TPL_TYPE_LOG_STORE (tpl_log_store_get_type ()) -#define TPL_LOG_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), TPL_TYPE_LOG_STORE, \ - TplLogStore)) -#define TPL_IS_LOG_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TPL_TYPE_LOG_STORE)) -#define TPL_LOG_STORE_GET_INTERFACE(inst) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((inst), TPL_TYPE_LOG_STORE, \ - TplLogStoreInterface)) -typedef struct _TplLogStore TplLogStore; /* dummy object */ +#define TPL_LOG_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + TPL_TYPE_LOG_STORE, TplLogStore)) +#define TPL_IS_LOG_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + TPL_TYPE_LOG_STORE)) +#define TPL_LOG_STORE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ( \ + (inst), TPL_TYPE_LOG_STORE, TplLogStoreInterface)) + +typedef struct _TplLogStore TplLogStore; /*dummy object */ typedef struct _TplLogStoreInterface TplLogStoreInterface; +typedef gboolean (*TplLogMessageFilter) (TplLogEntry *message, + gpointer user_data); + struct _TplLogStoreInterface { GTypeInterface parent; - const gchar *(*get_name) (TplLogStore * self); - gboolean (*exists) (TplLogStore * self, TpAccount * account, - const gchar * chat_id, gboolean chatroom); - gboolean (*add_message) (TplLogStore * self, gpointer message, - GError ** error); - GList *(*get_dates) (TplLogStore * self, TpAccount * account, - const gchar * chat_id, gboolean chatroom); - GList *(*get_messages_for_date) (TplLogStore * self, TpAccount * account, - const gchar * chat_id, gboolean chatroom, - const gchar * date); - GList *(*get_last_messages) (TplLogStore * self, TpAccount * account, - const gchar * chat_id, gboolean chatroom); - GList *(*get_chats) (TplLogStore * self, TpAccount * account); - GList *(*search_new) (TplLogStore * self, const gchar * text); - GList *(*search_in_identifier_chats_new) (TplLogStore * self, - TpAccount * account, - gchar const *identifier, - const gchar * text); - void (*ack_message) (TplLogStore * self, const gchar * chat_id, - gboolean chatroom, TplLogEntry * message); - GList *(*get_filtered_messages) (TplLogStore * self, TpAccount * account, - const gchar * chat_id, gboolean chatroom, - guint num_messages, - TplLogMessageFilter filter, - gpointer user_data); + const gchar * (*get_name) (TplLogStore *self); + gboolean (*exists) (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom); + gboolean (*add_message) (TplLogStore *self, gpointer message, + GError **error); + GList * (*get_dates) (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom); + GList * (*get_messages_for_date) (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom, const gchar *date); + GList * (*get_last_messages) (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom); + GList * (*get_chats) (TplLogStore *self, TpAccount *account); + GList * (*search_new) (TplLogStore *self, const gchar *text); + GList * (*search_in_identifier_chats_new) (TplLogStore *self, + TpAccount *account, gchar const *identifier, const gchar *text); + void (*ack_message) (TplLogStore *self, const gchar *chat_id, + gboolean chatroom, TplLogEntry *message); + GList * (*get_filtered_messages) (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom, guint num_messages, + TplLogMessageFilter filter, gpointer user_data); }; GType tpl_log_store_get_type (void); -const gchar *tpl_log_store_get_name (TplLogStore * self); -gboolean tpl_log_store_exists (TplLogStore * self, - TpAccount * account, const gchar * chat_id, - gboolean chatroom); -gboolean tpl_log_store_add_message (TplLogStore * self, gpointer message, - GError ** error); -GList *tpl_log_store_get_dates (TplLogStore * self, TpAccount * account, - const gchar * chat_id, gboolean chatroom); -GList *tpl_log_store_get_messages_for_date (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom, - const gchar * date); -GList *tpl_log_store_get_last_messages (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom); -GList *tpl_log_store_get_chats (TplLogStore * self, TpAccount * account); -GList *tpl_log_store_search_in_identifier_chats_new (TplLogStore * self, - TpAccount * account, - gchar const *identifier, - const gchar * text); -GList *tpl_log_store_search_new (TplLogStore * self, const gchar * text); -void tpl_log_store_ack_message (TplLogStore * self, - const gchar * chat_id, gboolean chatroom, - TplLogEntry * message); -GList *tpl_log_store_get_filtered_messages (TplLogStore * self, - TpAccount * account, - const gchar * chat_id, - gboolean chatroom, - guint num_messages, - TplLogMessageFilter filter, - gpointer user_data); +const gchar *tpl_log_store_get_name (TplLogStore *self); +gboolean tpl_log_store_exists (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom); +gboolean tpl_log_store_add_message (TplLogStore *self, gpointer message, + GError **error); +GList *tpl_log_store_get_dates (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom); +GList *tpl_log_store_get_messages_for_date (TplLogStore *self, + TpAccount *account, const gchar *chat_id, gboolean chatroom, + const gchar *date); +GList *tpl_log_store_get_last_messages (TplLogStore *self, TpAccount *account, + const gchar *chat_id, gboolean chatroom); +GList *tpl_log_store_get_chats (TplLogStore *self, TpAccount *account); +GList *tpl_log_store_search_in_identifier_chats_new (TplLogStore *self, + TpAccount *account, gchar const *identifier, const gchar *text); +GList *tpl_log_store_search_new (TplLogStore *self, const gchar *text); +void tpl_log_store_ack_message (TplLogStore *self, + const gchar *chat_id, gboolean chatroom, TplLogEntry *message); +GList *tpl_log_store_get_filtered_messages (TplLogStore *self, + TpAccount *account, const gchar *chat_id, gboolean chatroom, + guint num_messages, TplLogMessageFilter filter, gpointer user_data); G_END_DECLS -#endif /* __TPL_LOG_STORE_H__ */ + +#endif /*__TPL_LOG_STORE_H__ */ diff --git a/telepathy-logger/observer.c b/telepathy-logger/observer.c index 9b2a471..05d46d7 100644 --- a/telepathy-logger/observer.c +++ b/telepathy-logger/observer.c @@ -162,7 +162,8 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, if (tpl_conf_is_account_ignored(conf, account, &error)) { g_debug ("Logging is disabled for account %s. " - "Skipping channel logging.", account); + "Channel associated to this account. " + "Skipping this channel logging.", account); return; } @@ -198,8 +199,9 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, return; } - /* when all TplChannel will be ready, the counter will be 0 and - * tp_svc_client_observer_return_from_observe_channels can be called */ + /* Parallelize TplChannel preparations, when the last one will be ready, the + * counter will be 0 and tp_svc_client_observer_return_from_observe_channels + * can be called */ observing_ctx = g_slice_new0 (ObservingContext); observing_ctx->chan_n = channels->len; observing_ctx->dbus_ctx = dbus_context; @@ -220,7 +222,7 @@ tpl_observer_observe_channels (TpSvcClientObserver *self, tpl_chan = chan_factory (chan_type, tp_conn, path, map, tp_acc, &error); if (tpl_chan == NULL) { - g_debug ("%s", error->message); + g_debug ("Creating TplChannel: %s", error->message); g_clear_error (&error); g_error_free (error); error = NULL; @@ -245,7 +247,6 @@ got_tpl_channel_text_ready_cb (GObject *obj, DBusGMethodInvocation *dbus_ctx = observing_ctx->dbus_ctx; observing_ctx->chan_n -= 1; - g_debug ("CHAN LEN %d", observing_ctx->chan_n); if (observing_ctx->chan_n == 0) { tp_svc_client_observer_return_from_observe_channels (dbus_ctx); @@ -253,6 +254,7 @@ got_tpl_channel_text_ready_cb (GObject *obj, } } + static void get_prop (GObject *self, guint property_id, @@ -412,7 +414,7 @@ tpl_observer_init (TplObserver *self) self->priv = priv; priv->channel_map = g_hash_table_new_full (g_str_hash, - (GEqualFunc) tpl_strequal, g_free, g_object_unref); + (GEqualFunc) g_str_equal, g_free, g_object_unref); priv->logmanager = tpl_log_manager_dup_singleton (); } @@ -442,14 +444,14 @@ tpl_observer_register_dbus (TplObserver *self, /* just return TRUE if the Observer interface is actually already registered * to DBus */ - if (priv->dbus_registered == TRUE) + if (priv->dbus_registered) return TRUE; bus = tp_get_bus (); tp_bus = tp_dbus_daemon_new (bus); - if (FALSE == tp_dbus_daemon_request_name (tp_bus, - TPL_OBSERVER_WELL_KNOWN_BUS_NAME, TRUE, error)) + if (!tp_dbus_daemon_request_name (tp_bus, TPL_OBSERVER_WELL_KNOWN_BUS_NAME, + TRUE, error)) { g_assert (error == NULL || *error != NULL); return FALSE; @@ -465,6 +467,7 @@ tpl_observer_register_dbus (TplObserver *self, return TRUE; } + static void observer_iface_init (gpointer g_iface, gpointer iface_data) diff --git a/tests/Makefile.am b/tests/Makefile.am index 96ae708..48e34b7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,13 +2,18 @@ if WANT_TWISTED_TESTS CHECKTWISTED = twisted endif -#SUBDIRS = $(CHECKTWISTED) suppressions +SUBDIRS = $(CHECKTWISTED) suppressions noinst_PROGRAMS = \ test-tpl-channel \ test-tpl-conf \ test-tpl-log-entry \ - test-tpl-observer + test-tpl-observer \ + test-searches + +test_tpl_channel_SOURCES = \ + test-tpl-channel.c \ + tpl-channel-test.c LDADD = \ $(top_builddir)/telepathy-logger/libtelepathy-logger.la \ @@ -38,11 +43,12 @@ check-valgrind: $(TESTS) check_c_sources = \ $(dbus_test_sources) \ - tpl-channel-child.c \ + tpl-channel-test.c \ test-tpl-channel.c \ test-tpl-conf.c \ test-tpl-log-entry.c \ - test-tpl-observer.c + test-tpl-observer.c \ + test-searches.c include $(top_srcdir)/tools/check-coding-style.mk check-local: check-coding-style diff --git a/tests/constants.h b/tests/constants.h new file mode 100644 index 0000000..7507072 --- /dev/null +++ b/tests/constants.h @@ -0,0 +1,2 @@ +#define ACCOUNT_PATH "/org/freedesktop/Telepathy/Account/gabble/jabber/cosimo_2ealfarano_40collabora_2eco_2euk0" +#define ID "echo@test.collabora.co.uk" diff --git a/tests/test-searches.c b/tests/test-searches.c new file mode 100644 index 0000000..e6ca943 --- /dev/null +++ b/tests/test-searches.c @@ -0,0 +1,57 @@ +#include "constants.h" + +#include <telepathy-logger/log-manager.h> +#include <telepathy-logger/log-store.h> +#include <telepathy-logger/log-store-empathy.h> + +int +main (int argc, char *argv[]) +{ + GError *error = NULL; + TpDBusDaemon *dbus; + TpAccount *acc; + TplLogManager *manager; + TplLogStore *logstore; + GList *ret, *loc; + + g_type_init (); + + dbus = tp_dbus_daemon_dup (&error); + if (error != NULL) + { + g_debug ("%s", error->message); + } + acc = tp_account_new (dbus, ACCOUNT_PATH, NULL); + if (acc == NULL) + { + g_debug ("error during TpAccount creation"); + } + + /* get the LogManager and register a non-default LogManager */ + manager = tpl_log_manager_dup_singleton(); + logstore = g_object_new (TPL_TYPE_LOG_STORE_EMPATHY, + "name", "Empathy", NULL); + tpl_log_manager_register_logstore (manager, logstore); + + /* we are using the blocking API, the non-blocking one is a wrap around, so + * it's assured to work as long as the blocking API and the wapper work */ + + /* we do not want duplicates */ + ret = tpl_log_manager_get_dates (manager, acc, ID, FALSE); + ret = g_list_sort (ret, (GCompareFunc) g_strcmp0); + for (loc = ret; loc; loc = g_list_next (loc)) + if (loc->next) + g_assert (g_strcmp0 (loc->data, loc->next->data) != 0); + g_list_foreach (ret, (GFunc) g_free, NULL); + g_list_free (ret); + + /* we do not want duplicates */ + ret = tpl_log_manager_get_chats (manager, acc); + ret = g_list_sort (ret, (GCompareFunc) tpl_log_manager_search_hit_compare); + for (loc = ret; loc; loc = g_list_next (loc)) + if (loc->next) + g_assert (tpl_log_manager_search_hit_compare (loc->data, + loc->next->data) != 0); + g_list_foreach (ret, (GFunc) tpl_log_manager_search_hit_free, NULL); + g_list_free (ret); +} |