From: Christian Kellner Date: Sat, 2 Jun 2007 22:44:21 +0000 (+0000) Subject: 2007-06-03 Christian Kellner X-Git-Tag: git_migration_finished~3439 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=f0e59e582ece5beef0ddd0e5660bb47051476762 2007-06-03 Christian Kellner * libmodest-dbus-client/libmodest-dbus-client.c: * libmodest-dbus-client/libmodest-dbus-client.h: Implement searching for mesages over raw dbus. (Client side) * src/dbus_api/Makefile.am: * src/dbus_api/modest-dbus-api.h: * src/dbus_api/modest-dbus-callbacks.c: * src/dbus_api/modest-dbus-callbacks.h: Search framework (Server side). Also implement on_idle_open_message(). * src/maemo/modest-platform.c: (modest_platform_init): Prepare for raw dbus/osso rpc interaction. * src/modest-search.h: Changed minsize from unspecific guint to guint32. * src/modest-search.c: (add_header): Added strange hack which magically made tnymail work. (modest_search_folder), (modest_search_account), (modest_search_all_accounts): Implement helper functions to search all accounts, specific account and folder. * tests/dbus_api/Makefile.am: * tests/dbus_api/test_open_message.c: Read url to open from commandline. * tests/dbus_api/test_search.c: Implement small test for dbus search stuff pmo-trunk-r2049 --- diff --git a/ChangeLog2 b/ChangeLog2 index ac55d97..7773326 100644 --- a/ChangeLog2 +++ b/ChangeLog2 @@ -1,3 +1,38 @@ +2007-06-03 Christian Kellner + + * libmodest-dbus-client/libmodest-dbus-client.c: + * libmodest-dbus-client/libmodest-dbus-client.h: + Implement searching for mesages over raw dbus. (Client side) + + * src/dbus_api/Makefile.am: + * src/dbus_api/modest-dbus-api.h: + * src/dbus_api/modest-dbus-callbacks.c: + * src/dbus_api/modest-dbus-callbacks.h: + Search framework (Server side). Also implement on_idle_open_message(). + + * src/maemo/modest-platform.c: (modest_platform_init): + Prepare for raw dbus/osso rpc interaction. + + * src/modest-search.h: + Changed minsize from unspecific guint to guint32. + + * src/modest-search.c: + (add_header): + Added strange hack which magically made tnymail work. + + (modest_search_folder), + (modest_search_account), + (modest_search_all_accounts): + Implement helper functions to search all accounts, specific account + and folder. + + * tests/dbus_api/Makefile.am: + * tests/dbus_api/test_open_message.c: + Read url to open from commandline. + + * tests/dbus_api/test_search.c: + Implement small test for dbus search stuff + 2007-06-02 Armin Burgmeier * src/maemo/modest-account-settings-dialog.c: Changed window title to diff --git a/libmodest-dbus-client/libmodest-dbus-client.c b/libmodest-dbus-client/libmodest-dbus-client.c index fefaaf2..709b3bb 100644 --- a/libmodest-dbus-client/libmodest-dbus-client.c +++ b/libmodest-dbus-client/libmodest-dbus-client.c @@ -30,6 +30,11 @@ #include "libmodest-dbus-client.h" #include /* For the API strings. */ +//#define DBUS_API_SUBJECT_TO_CHANGE 1 +#include +#include +#include + gboolean libmodest_dbus_client_send_mail (osso_context_t *osso_context, const gchar *to, const gchar *cc, const gchar *bcc, const gchar* subject, const gchar* body, GSList *attachments) @@ -165,3 +170,390 @@ libmodest_dbus_client_send_and_receive (osso_context_t *osso_context) return TRUE; } + +static void +modest_search_hit_free (ModestSearchHit *hit) +{ + g_free (hit->msgid); + + g_slice_free (ModestSearchHit, hit); +} + + +static char * +_dbus_iter_get_string_or_null (DBusMessageIter *iter) +{ + const char *string; + char *ret; + + dbus_message_iter_get_basic (iter, &string); + + ret = NULL; + if (string && strlen (string)) { + ret = g_strdup (string); + } + + return ret; +} + +static guint64 +_dbus_iter_get_uint64 (DBusMessageIter *iter) +{ + dbus_uint64_t ui64v; + guint64 ret; + + ui64v = 0; + dbus_message_iter_get_basic (iter, &ui64v); + + ret = (guint64) ui64v; + + return ret; +} + + +static gint64 +_dbus_iter_get_int64 (DBusMessageIter *iter) +{ + dbus_int64_t i64v; + gint64 ret; + + i64v = 0; + dbus_message_iter_get_basic (iter, &i64v); + + ret = (gint64) i64v; + + return ret; +} + +static gboolean +_dbus_iter_get_boolean (DBusMessageIter *iter) + +{ + dbus_bool_t val; + gboolean ret; + + val = FALSE; + dbus_message_iter_get_basic (iter, &val); + + ret = (gboolean) val; + + return ret; +} + + +static ModestSearchHit * +dbus_message_iter_get_search_hit (DBusMessageIter *parent) +{ + ModestSearchHit *hit; + DBusMessageIter child; + dbus_bool_t res; + int arg_type; + gboolean error; + + error = FALSE; + hit = g_slice_new0 (ModestSearchHit); + + arg_type = dbus_message_iter_get_arg_type (parent); + + if (arg_type != 'r') { + return NULL; + } + + g_debug ("Umarshalling hit (%d)", dbus_message_iter_get_arg_type (parent)); + + dbus_message_iter_recurse (parent, &child); + + /* msgid */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + hit->msgid = _dbus_iter_get_string_or_null (&child); + + res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* subject */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + hit->subject = _dbus_iter_get_string_or_null (&child); + + res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* folder */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + hit->folder = _dbus_iter_get_string_or_null (&child); + + res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* sender */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + hit->sender = _dbus_iter_get_string_or_null (&child); + + res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* msize */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_UINT64) { + error = TRUE; + goto out; + } + + hit->msize = _dbus_iter_get_uint64 (&child); + + res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* has_attachment */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_BOOLEAN) { + error = TRUE; + goto out; + } + + hit->has_attachment = _dbus_iter_get_boolean (&child); + + res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* is_unread */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_BOOLEAN) { + error = TRUE; + goto out; + } + + hit->is_unread = _dbus_iter_get_boolean (&child); + + res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* msize */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_INT64) { + error = TRUE; + goto out; + } + + hit->timestamp = _dbus_iter_get_int64 (&child); + + res = dbus_message_iter_next (&child); + if (res == TRUE) { + error = TRUE; + goto out; + } + +out: + if (error) { + g_warning ("Error during unmarshaling"); + modest_search_hit_free (hit); + hit = NULL; + } + + return hit; +} + + +gboolean +libmodest_dbus_client_search (osso_context_t *osso_ctx, + const gchar *query, + const gchar *folder, + time_t start_date, + time_t end_date, + guint32 min_size, + ModestDBusSearchFlags flags, + GList **hits) +{ + + DBusMessage *msg; + dbus_bool_t res; + DBusError err; + DBusConnection *con; + DBusMessageIter iter; + DBusMessageIter child; + DBusMessage *reply = NULL; + gint timeout; + int arg_type; + dbus_int64_t sd_v; + dbus_int64_t ed_v; + dbus_int32_t flags_v; + dbus_uint32_t size_v; + + + con = osso_get_dbus_connection (osso_ctx); + + if (con == NULL) { + g_warning ("Could not get dbus connection\n"); + return FALSE; + + } + + + msg = dbus_message_new_method_call (MODEST_DBUS_SERVICE, + MODEST_DBUS_OBJECT, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_SEARCH); + + if (msg == NULL) { + //ULOG_ERR_F("dbus_message_new_method_call failed"); + return OSSO_ERROR; + } + + sd_v = start_date; + ed_v = end_date; + flags_v = (dbus_int32_t) flags; + size_v = (dbus_uint32_t) min_size; + + res = dbus_message_append_args (msg, + DBUS_TYPE_STRING, &query, + DBUS_TYPE_STRING, &folder, + DBUS_TYPE_INT64, &sd_v, + DBUS_TYPE_INT64, &ed_v, + DBUS_TYPE_INT32, &flags_v, + DBUS_TYPE_UINT32, &size_v, + DBUS_TYPE_INVALID); + + dbus_message_set_auto_start (msg, TRUE); + + dbus_error_init (&err); + + timeout = 1000; //XXX + osso_rpc_get_timeout (osso_ctx, &timeout); + + reply = dbus_connection_send_with_reply_and_block (con, + msg, + timeout, + &err); + + dbus_message_unref (msg); + + + if (reply == NULL) { + //ULOG_ERR_F("dbus_connection_send_with_reply_and_block error: %s", err.message); + //XXX to GError?! + return FALSE; + } + + switch (dbus_message_get_type (reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + dbus_set_error_from_message (&err, reply); + //XXX to GError?! + dbus_error_free (&err); + dbus_message_unref (reply); + return FALSE; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + /* ok we are good to go + * lets drop outa here and handle that */ + break; + default: + //ULOG_WARN_F("got unknown message type as reply"); + //retval->type = DBUS_TYPE_STRING; + //retval->value.s = g_strdup("Invalid return value"); + //XXX to GError?! + dbus_message_unref (reply); + return FALSE; + } + + g_debug ("message return"); + + dbus_message_iter_init (reply, &iter); + arg_type = dbus_message_iter_get_arg_type (&iter); + + g_debug ("iter type: %d", arg_type); + dbus_message_iter_recurse (&iter, &child); + g_debug ("recursed"); + + do { + ModestSearchHit *hit; + + hit = dbus_message_iter_get_search_hit (&child); + + if (hit) { + *hits = g_list_prepend (*hits, hit); + } + + } while (dbus_message_iter_next (&child)); + + dbus_message_unref (reply); + + g_debug ("Done unmarshalling message"); +#if 0 + /* Tell TaskNavigator to show "launch banner" */ + msg = dbus_message_new_method_call (TASK_NAV_SERVICE, + APP_LAUNCH_BANNER_METHOD_PATH, + APP_LAUNCH_BANNER_METHOD_INTERFACE, + APP_LAUNCH_BANNER_METHOD); + + if (msg == NULL) { + g_warn ("dbus_message_new_method_call failed"); + } + + + + dbus_message_append_args (msg, + DBUS_TYPE_STRING, + &service, + DBUS_TYPE_INVALID); + + b = dbus_connection_send (conn, msg, NULL); + + if (b == NULL) { + ULOG_WARN_F("dbus_connection_send failed"); + } + + dbus_message_unref (msg); +#endif + + return TRUE; +} + diff --git a/libmodest-dbus-client/libmodest-dbus-client.h b/libmodest-dbus-client/libmodest-dbus-client.h index 7d3eaa1..2795f76 100644 --- a/libmodest-dbus-client/libmodest-dbus-client.h +++ b/libmodest-dbus-client/libmodest-dbus-client.h @@ -50,4 +50,39 @@ libmodest_dbus_client_open_message (osso_context_t *osso_context, gboolean libmodest_dbus_client_send_and_receive (osso_context_t *osso_context); + +typedef enum { + + MODEST_DBUS_SEARCH_SUBJECT = (1 << 0), + MODEST_DBUS_SEARCH_SENDER = (1 << 1), + MODEST_DBUS_SEARCH_RECIPIENT = (1 << 2), + MODEST_DBUS_SEARCH_SIZE = (1 << 3), + MODEST_DBUS_SEARCH_BODY = (1 << 6) + +} ModestDBusSearchFlags; + +typedef struct { + + gchar *msgid; + gchar *subject; + gchar *folder; + gchar *sender; + guint64 msize; + gboolean has_attachment; + gboolean is_unread; + gint64 timestamp; + +} ModestSearchHit; + +gboolean +libmodest_dbus_client_search (osso_context_t *osso_ctx, + const gchar *query, + const gchar *folder, + time_t start_date, + time_t end_date, + guint32 min_size, + ModestDBusSearchFlags flags, + GList **hits); + + #endif /* __LIBMODEST_DBUS_CLIENT_H__ */ diff --git a/src/dbus_api/Makefile.am b/src/dbus_api/Makefile.am index 288382c..9105bae 100644 --- a/src/dbus_api/Makefile.am +++ b/src/dbus_api/Makefile.am @@ -30,6 +30,7 @@ INCLUDES=\ $(MODEST_GSTUFF_CFLAGS) \ $(MODEST_LIBTINYMAIL_MAEMO_CFLAGS) \ + $(OGS_CFLAGS) \ -DMODEST_PLATFORM_ID=$(MODEST_PLATFORM_ID) \ -I ${top_srcdir}/src/widgets \ -I ${top_srcdir}/src \ @@ -49,5 +50,6 @@ libmodest_dbus_api_la_SOURCES= \ LDADD = \ $(MODEST_GSTUFF_LIBS) \ - $(MODEST_LIBTINYMAIL_MAEMO_LIBS) + $(MODEST_LIBTINYMAIL_MAEMO_LIBS) \ + $(OGS_LIBS) diff --git a/src/dbus_api/modest-dbus-api.h b/src/dbus_api/modest-dbus-api.h index ad88a25..1469d81 100644 --- a/src/dbus_api/modest-dbus-api.h +++ b/src/dbus_api/modest-dbus-api.h @@ -80,4 +80,9 @@ enum ModestDbusComposeMailArguments MODEST_DEBUS_COMPOSE_MAIL_ARGS_COUNT }; +#define MODEST_DBUS_METHOD_SEARCH "Search" + + + + #endif /* __MODEST_DBUS_API__ */ diff --git a/src/dbus_api/modest-dbus-callbacks.c b/src/dbus_api/modest-dbus-callbacks.c index 103c497..9ef5ed9 100644 --- a/src/dbus_api/modest-dbus-callbacks.c +++ b/src/dbus_api/modest-dbus-callbacks.c @@ -33,8 +33,10 @@ #include "modest-account-mgr-helpers.h" #include "modest-tny-account.h" #include "modest-ui-actions.h" +#include "modest-search.h" #include "widgets/modest-msg-edit-window.h" #include "modest-tny-msg.h" +#include #include #include #include @@ -503,14 +505,105 @@ static gint on_compose_mail(GArray * arguments, gpointer data, osso_rpc_t * retv } +static TnyMsg * +find_message_by_url (const char *uri, TnyAccount **ac_out) +{ + + ModestTnyAccountStore *astore; + TnyAccount *account; + TnyFolder *folder; + TnyMsg *msg; + + account = NULL; + msg = NULL; + folder = NULL; + + astore = modest_runtime_get_account_store (); + + if (astore == NULL) { + return NULL; + } + + g_debug ("Got AccountStore, lets go"); + + account = tny_account_store_find_account (TNY_ACCOUNT_STORE (astore), + uri); + + if (account == NULL) { + return NULL; + } + + g_debug ("Found account"); + + if ( ! TNY_IS_STORE_ACCOUNT (account)) { + goto out; + } + + g_debug ("Account is store account"); + + *ac_out = account; + + folder = tny_store_account_find_folder (TNY_STORE_ACCOUNT (account), + uri, + NULL); + + if (folder == NULL) { + goto out; + } + g_debug ("Found folder"); + + + msg = tny_folder_find_msg (folder, uri, NULL); + +out: + if (account && !msg) { + g_object_unref (account); + *ac_out = NULL; + } + + if (folder) { + g_object_unref (folder); + } + + return msg; +} + static gboolean -on_idle_open_message(gpointer user_data) +on_idle_open_message (gpointer user_data) { - gchar *uri = (gchar*)user_data; + ModestWindow *msg_view; + TnyMsg *msg; + TnyAccount *account; + TnyHeader *header; + const char *msg_uid; + const char *account_name; + char *uri; + + uri = (char *) user_data; + + g_debug ("Trying to find msg by url: %s", uri); + msg = find_message_by_url (uri, &account); + g_free (uri); + + if (msg == NULL) { + return FALSE; + } + g_debug ("Found message"); + + header = tny_msg_get_header (msg); + account_name = tny_account_get_name (account); + msg_uid = tny_header_get_uid (header); - g_message ("not implemented yet %s", __FUNCTION__); + msg_view = modest_msg_view_window_new (msg, + account_name, + msg_uid); + /* TODO: does that leak the msg_view ?! */ + + gtk_widget_show_all (GTK_WIDGET (msg_view)); + + g_object_unref (header); + g_object_unref (account); - g_free(uri); return FALSE; /* Do not call this callback again. */ } @@ -568,10 +661,10 @@ gint modest_dbus_req_handler(const gchar * interface, const gchar * method, GArray * arguments, gpointer data, osso_rpc_t * retval) { - /* + printf("debug: modest_dbus_req_handler()\n"); printf("debug: method received: %s\n", method); - */ + if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_SEND_MAIL) == 0) { return on_send_mail (arguments, data, retval); } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_MAIL_TO) == 0) { @@ -583,8 +676,246 @@ gint modest_dbus_req_handler(const gchar * interface, const gchar * method, } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_COMPOSE_MAIL) == 0) { return on_compose_mail (arguments, data, retval); } - else - return OSSO_ERROR; + else { + /* We need to return INVALID here so + * osso is returning DBUS_HANDLER_RESULT_NOT_YET_HANDLED + * so our modest_dbus_req_filter can kick in! + * */ + return OSSO_INVALID; + } +} + +#define SEARCH_HIT_DBUS_TYPE \ + DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_UINT64_AS_STRING \ + DBUS_TYPE_BOOLEAN_AS_STRING \ + DBUS_TYPE_BOOLEAN_AS_STRING \ + DBUS_TYPE_INT64_AS_STRING \ + DBUS_STRUCT_END_CHAR_AS_STRING + +static DBusMessage * +search_result_to_messsage (DBusMessage *reply, + GList *hits) +{ + DBusMessageIter iter; + DBusMessageIter array_iter; + GList *hit_iter; + + dbus_message_iter_init_append (reply, &iter); + dbus_message_iter_open_container (&iter, + DBUS_TYPE_ARRAY, + SEARCH_HIT_DBUS_TYPE, + &array_iter); + + for (hit_iter = hits; hit_iter; hit_iter = hit_iter->next) { + DBusMessageIter struct_iter; + TnyFolder *tf; + TnyHeader *header; + TnyHeaderFlags flags; + char *msg_url = ""; + const char *subject = ""; + const char *folder = ""; + const char *sender = ""; + guint64 size = 0; + gboolean has_attachemnt = FALSE; + gboolean is_unread = FALSE; + gint64 ts = 0; + char *furl; + const char *uid; + + g_debug ("Marshalling hit ...(%s)", + TNY_IS_HEADER (hit_iter->data) ? "yes" : "no"); + + header = TNY_HEADER (hit_iter->data); + tf = tny_header_get_folder (header); + furl = tny_folder_get_url_string (tf); + + uid = tny_header_get_uid (header); + msg_url = g_strdup_printf ("%s/%s", furl, uid); + + subject = tny_header_get_subject (header); + folder = furl; + sender = tny_header_get_from (header); + size = tny_header_get_message_size (header); + + flags = tny_header_get_flags (header); + has_attachemnt = flags & TNY_HEADER_FLAG_ATTACHMENTS; + is_unread = ! (flags & TNY_HEADER_FLAG_SEEN); + ts = tny_header_get_date_received (header); + + g_debug ("Adding hit: %s", msg_url); + + dbus_message_iter_open_container (&array_iter, + DBUS_TYPE_STRUCT, + NULL, + &struct_iter); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_STRING, + &msg_url); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_STRING, + &subject); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_STRING, + &folder); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_STRING, + &sender); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_UINT64, + &size); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_BOOLEAN, + &has_attachemnt); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_BOOLEAN, + &is_unread); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_INT64, + &ts); + + dbus_message_iter_close_container (&array_iter, + &struct_iter); + + + g_free (msg_url); + g_free (furl); + + /* Also unref the header, we don't need it anymore */ + g_object_unref (header); + } + + dbus_message_iter_close_container (&iter, &array_iter); + + return reply; +} + +DBusHandlerResult +modest_dbus_req_filter (DBusConnection *con, + DBusMessage *message, + void *user_data) +{ + gboolean handled = FALSE; + DBusError error; + + if (dbus_message_is_method_call (message, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_SEARCH)) { + ModestDBusSearchFlags dbus_flags; + ModestSearch search; + DBusMessage *reply = NULL; + dbus_bool_t res; + dbus_int64_t sd_v; + dbus_int64_t ed_v; + dbus_int32_t flags_v; + dbus_uint32_t serial; + dbus_uint32_t size_v; + char *folder; + char *query; + time_t start_date; + time_t end_date; + GList *hits; + + handled = TRUE; + + dbus_error_init (&error); + + sd_v = ed_v = 0; + flags_v = 0; + + res = dbus_message_get_args (message, + &error, + DBUS_TYPE_STRING, &query, + DBUS_TYPE_STRING, &folder, + DBUS_TYPE_INT64, &sd_v, + DBUS_TYPE_INT64, &ed_v, + DBUS_TYPE_INT32, &flags_v, + DBUS_TYPE_UINT32, &size_v, + DBUS_TYPE_INVALID); + + dbus_flags = (ModestDBusSearchFlags) flags_v; + start_date = (time_t) sd_v; + end_date = (time_t) ed_v; + + memset (&search, 0, sizeof (search)); + search.query = query; + search.before = start_date; + search.after = end_date; + search.flags = 0; + + if (dbus_flags & MODEST_DBUS_SEARCH_SUBJECT) { + search.flags |= MODEST_SEARCH_SUBJECT; + search.subject = query; + } + + if (dbus_flags & MODEST_DBUS_SEARCH_SENDER) { + search.flags |= MODEST_SEARCH_SENDER; + search.from = query; + } + + if (dbus_flags & MODEST_DBUS_SEARCH_RECIPIENT) { + search.flags |= MODEST_SEARCH_RECIPIENT; + search.recipient = query; + } + + if (dbus_flags & MODEST_DBUS_SEARCH_BODY) { + search.flags |= MODEST_SEARCH_BODY; + search.subject = query; + } + + if (sd_v > 0) { + search.flags |= MODEST_SEARCH_BEFORE; + search.before = start_date; + } + + if (ed_v > 0) { + search.flags |= MODEST_SEARCH_AFTER; + search.after = end_date; + } + + if (size_v > 0) { + search.flags |= MODEST_SEARCH_SIZE; + search.minsize = size_v; + } + +#ifdef MODEST_HAVE_OGS + search.flags |= MODEST_SEARCH_USE_OGS; +#endif + + hits = modest_search_all_accounts (&search); + + reply = dbus_message_new_method_return (message); + + search_result_to_messsage (reply, hits); + + if (reply == NULL) { + g_warning ("Could not create reply"); + } + + if (reply) { + dbus_connection_send (con, reply, &serial); + dbus_connection_flush (con); + dbus_message_unref (reply); + } + + } + + + return (handled ? + DBUS_HANDLER_RESULT_HANDLED : + DBUS_HANDLER_RESULT_NOT_YET_HANDLED); } void diff --git a/src/dbus_api/modest-dbus-callbacks.h b/src/dbus_api/modest-dbus-callbacks.h index 26344f8..5063767 100644 --- a/src/dbus_api/modest-dbus-callbacks.h +++ b/src/dbus_api/modest-dbus-callbacks.h @@ -41,4 +41,7 @@ gint modest_dbus_req_handler(const gchar * interface, const gchar * method, void modest_osso_cb_hw_state_handler(osso_hw_state_t *state, gpointer data); +DBusHandlerResult modest_dbus_req_filter (DBusConnection *con, + DBusMessage *message, + void *user_data); #endif /* __MODEST_DBUS_CALLBACKS_H__ */ diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index 11bc77a..54798d6 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -65,7 +65,8 @@ on_modest_conf_update_interval_changed (ModestConf* self, const gchar *key, gboolean modest_platform_init (void) { - osso_hw_state_t hw_state = { 0 }; + osso_hw_state_t hw_state = { 0 }; + DBusConnection *con; osso_context = osso_initialize(PACKAGE,PACKAGE_VERSION, FALSE, NULL); @@ -74,6 +75,21 @@ modest_platform_init (void) return FALSE; } + if ((con = osso_get_dbus_connection (osso_context)) == NULL) { + g_printerr ("Could not get dbus connection\n"); + return FALSE; + + } + + if (!dbus_connection_add_filter (con, + modest_dbus_req_filter, + NULL, + NULL)) { + + g_printerr ("Could not add dbus filter\n"); + return FALSE; + } + /* Register our D-Bus callbacks, via the osso API: */ osso_return_t result = osso_rpc_set_cb_f(osso_context, MODEST_DBUS_SERVICE, diff --git a/src/modest-search.c b/src/modest-search.c index 92d0452..d8cf19c 100644 --- a/src/modest-search.c +++ b/src/modest-search.c @@ -8,23 +8,29 @@ #include #include +#include #include #include #include #include "modest-text-utils.h" - +#include "modest-account-mgr.h" +#include "modest-tny-account-store.h" +#include "modest-tny-account.h" #include "modest-search.h" - +#include "modest-runtime.h" static GList* add_header (GList *list, TnyHeader *header, TnyFolder *folder) { - gchar *furl = tny_folder_get_url_string (folder); - const gchar *uid = tny_header_get_uid (header); - gchar *str = g_strdup_printf ("%s/%s", furl, uid); - g_free (furl); - return g_list_prepend (list, str); + TnyFolder *f; + + /* TODO: we need this call otherwise it will crash later + * when we try to do that call again without having the + * folder around, I guess that is a bug in TinyThingy */ + f = tny_header_get_folder (header); + + return g_list_prepend (list, g_object_ref (header)); } static gboolean @@ -199,6 +205,10 @@ search_string (const char *what, ogs_text_searcher_reset (search->text_searcher); } else { #endif + if (what == NULL || where == NULL) { + return FALSE; + } + found = !modest_text_utils_utf8_strcmp (what, where, TRUE); #ifdef MODEST_HAVE_OGS } @@ -207,6 +217,7 @@ search_string (const char *what, } + /** * modest_search: * @folder: a #TnyFolder instance @@ -216,7 +227,7 @@ search_string (const char *what, * It will return a doubly linked list with URIs that point to the message. **/ GList * -modest_search (TnyFolder *folder, ModestSearch *search) +modest_search_folder (TnyFolder *folder, ModestSearch *search) { GList *retval = NULL; TnyIterator *iter; @@ -249,7 +260,7 @@ modest_search (TnyFolder *folder, ModestSearch *search) TnyHeader *cur = (TnyHeader *) tny_iterator_get_current (iter); time_t t = tny_header_get_date_sent (cur); gboolean found = FALSE; - + if (search->flags & MODEST_SEARCH_BEFORE) if (!(t <= search->before)) goto go_next; @@ -259,7 +270,7 @@ modest_search (TnyFolder *folder, ModestSearch *search) goto go_next; if (search->flags & MODEST_SEARCH_SIZE) - if (tny_header_get_message_size (cur) < search->minsize) + if (tny_header_get_message_size (cur) < search->minsize) goto go_next; if (search->flags & MODEST_SEARCH_SUBJECT) { @@ -285,7 +296,7 @@ modest_search (TnyFolder *folder, ModestSearch *search) retval = add_header (retval, cur, folder); } } - + if (!found && search->flags & MODEST_SEARCH_BODY) { TnyHeaderFlags flags; GError *err = NULL; @@ -340,3 +351,99 @@ go_next: return retval; } +GList * +modest_search_account (TnyAccount *account, ModestSearch *search) +{ + TnyFolderStore *store; + TnyIterator *iter; + TnyList *folders; + GList *hits; + GError *error; + + error = NULL; + hits = NULL; + + store = TNY_FOLDER_STORE (account); + + folders = tny_simple_list_new (); + tny_folder_store_get_folders (store, folders, NULL, &error); + + if (error != NULL) { + g_object_unref (folders); + return NULL; + } + + iter = tny_list_create_iterator (folders); + while (!tny_iterator_is_done (iter)) { + TnyFolder *folder; + GList *res; + + folder = TNY_FOLDER (tny_iterator_get_current (iter)); + + res = modest_search_folder (folder, search); + + if (res != NULL) { + if (hits == NULL) { + hits = res; + } else { + hits = g_list_concat (hits, res); + } + } + + g_object_unref (folder); + tny_iterator_next (iter); + } + + g_object_unref (iter); + g_object_unref (folders); + + return hits; +} + +GList * +modest_search_all_accounts (ModestSearch *search) +{ + ModestAccountMgr *account_mgr; + ModestTnyAccountStore *astore; + GSList *accounts; + GSList *iter; + GList *hits; + + account_mgr = modest_runtime_get_account_mgr (); + + accounts = modest_account_mgr_account_names (account_mgr, FALSE); + astore = modest_runtime_get_account_store (); + hits = NULL; + + for (iter = accounts; iter; iter = iter->next) { + GList *res; + const char *ac_name; + TnyAccount *account = NULL; + + ac_name = (const char *) iter->data; + + account = modest_tny_account_store_get_tny_account_by_account (astore, + ac_name, + TNY_ACCOUNT_TYPE_STORE); + + if (account == NULL) { + g_warning ("Could not get account for %s", ac_name); + continue; + } + + res = modest_search_account (account, search); + + if (res != NULL) { + + if (hits == NULL) { + hits = res; + } else { + hits = g_list_concat (hits, res); + } + } + } + + return hits; +} + + diff --git a/src/modest-search.h b/src/modest-search.h index d4a1894..091a9dd 100644 --- a/src/modest-search.h +++ b/src/modest-search.h @@ -4,6 +4,8 @@ #include #include +#define _GNU_SOURCE + #ifdef HAVE_CONFIG_H #include #endif @@ -28,7 +30,7 @@ typedef enum { typedef struct { gchar *subject, *from, *recipient, *body; time_t before, after; - guint minsize; + guint32 minsize; ModestSearchFlags flags; #ifdef MODEST_HAVE_OGS const gchar *query; @@ -36,8 +38,9 @@ typedef struct { #endif } ModestSearch; -GList * modest_search (TnyFolder *folder, ModestSearch *search); - +GList * modest_search_folder (TnyFolder *folder, ModestSearch *search); +GList * modest_search_all_accounts (ModestSearch *search); +GList * modest_search_account (TnyAccount *account, ModestSearch *search); G_END_DECLS #endif diff --git a/tests/dbus_api/Makefile.am b/tests/dbus_api/Makefile.am index 37859b0..a4a53cd 100644 --- a/tests/dbus_api/Makefile.am +++ b/tests/dbus_api/Makefile.am @@ -16,7 +16,7 @@ objects=\ $(MODEST_LIBTINYMAIL_MAEMO_LIBS) \ ${top_srcdir}/libmodest-dbus-client/libmodest-dbus-client-1.0.la -noinst_PROGRAMS = test_send_mail test_mail_to test_open_message +noinst_PROGRAMS = test_send_mail test_mail_to test_open_message test_search test_send_mail_SOURCES = test_send_mail.c test_send_mail_LDADD = $(objects) @@ -27,4 +27,7 @@ test_mail_to_LDADD = $(objects) test_open_message_SOURCES = test_open_message.c test_open_message_LDADD = $(objects) +test_search_SOURCES = test_search.c +test_search_LDADD = $(objects) + diff --git a/tests/dbus_api/test_open_message.c b/tests/dbus_api/test_open_message.c index 5f1afe9..e518ddf 100644 --- a/tests/dbus_api/test_open_message.c +++ b/tests/dbus_api/test_open_message.c @@ -1,30 +1,39 @@ #include #include -int main(int argc, char *argv[]) +int +main (int argc, char *argv[]) { - /* Initialize maemo application */ - osso_context_t * osso_context = osso_initialize( - "test_hello", "0.0.1", TRUE, NULL); + osso_context_t *osso_context; + const char *url; + gboolean ret; + + osso_context = osso_initialize ("test_open_msg", + "0.0.1", + TRUE, + NULL); - /* Check that initialization was ok */ - if (osso_context == NULL) - { - printf("osso_initialize() failed.\n"); - return OSSO_ERROR; + if (osso_context == NULL) { + g_printerr ("osso_initialize() failed.\n"); + return -1; } - /* Call the function in libmodest-dbus-client: */ - /* TODO: The Message URI system is not yet implemented. */ - const gboolean ret = libmodest_dbus_client_open_message (osso_context, - "http://todo_some_message_uri"); + if (argc == 2) { + url = argv[1]; + } else { + url = "local://???FIXME???"; + } + + g_print ("Trying to open msg: %s\n", url); + ret = libmodest_dbus_client_open_message (osso_context, + url); + if (!ret) { - printf("libmodest_dbus_client_open_message() failed.\n"); - return OSSO_ERROR; + g_printerr ("libmodest_dbus_client_open_message() failed.\n"); } else { - printf("libmodest_dbus_client_open_message() succeeded.\n"); + g_print ("libmodest_dbus_client_open_message() succeeded.\n"); } - /* Exit */ - return 0; + return ret ? 0 : -1; + } diff --git a/tests/dbus_api/test_search.c b/tests/dbus_api/test_search.c new file mode 100644 index 0000000..414231b --- /dev/null +++ b/tests/dbus_api/test_search.c @@ -0,0 +1,48 @@ +#include +#include +#include + +int main (int argc, char *argv[]) +{ + osso_context_t *osso_context; + gboolean res; + ModestDBusSearchFlags flags; + GList *hits, *iter; + + osso_context = osso_initialize ("test_search", + "0.0.1", + TRUE, + NULL); + + + /* Check that initialization was ok */ + if (osso_context == NULL) { + g_printerr ("osso_initialize() failed.\n"); + return OSSO_ERROR; + } + + hits = NULL; + flags = MODEST_DBUS_SEARCH_SUBJECT | MODEST_DBUS_SEARCH_BODY; + + g_print ("Starting search ...\n"); + + res = libmodest_dbus_client_search (osso_context, + "no", + "", + 0, + 0, + 0, + flags, + &hits); + + g_print ("Search done. (success: %s)\n", res ? "yes" : "no"); + + for (iter = hits; iter; iter = iter->next) { + ModestSearchHit *hit = (ModestSearchHit *) iter->data; + + g_print ("Hit: id: %s\n", hit->msgid); + + } + + return res ? 0 : -1; +}