X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=libmodest-dbus-client%2Flibmodest-dbus-client.c;h=35041ac8ca30ac2e07955331dbc48a646d48cac8;hp=29bbbefe9d6a077f4eada4e76b84931caa1e26b9;hb=93f1026bac7fc03ff2395ee29de1366bbb9d01a1;hpb=e0311995d932807bedf6557454d903b7bd73d2e1 diff --git a/libmodest-dbus-client/libmodest-dbus-client.c b/libmodest-dbus-client/libmodest-dbus-client.c index 29bbbef..35041ac 100644 --- a/libmodest-dbus-client/libmodest-dbus-client.c +++ b/libmodest-dbus-client/libmodest-dbus-client.c @@ -35,15 +35,37 @@ #include #include + + +/** Get a comma-separated list of attachement URI strings, + * from a list of strings. + */ +static gchar* get_attachments_string (GSList *attachments) +{ + if (!attachments) + return NULL; + + gchar *attachments_str = g_strdup(""); + + GSList *iter = attachments; + while (iter) + { + if (iter->data) { + gchar *tmp = g_strconcat(attachments_str, ",", (gchar *) (iter->data), NULL); + g_free(attachments_str); + attachments_str = tmp; + } + + iter = g_slist_next(iter); + } + + return attachments_str; +} + /** - * libmodest_dbus_client_send_mail: + * libmodest_dbus_client_mail_to: * @osso_context: a valid #osso_context_t object. - * @to: The Recipients (From: line) - * @cc: Recipients for carbon copies - * @bcc: Recipients for blind carbon copies - * @subject: Subject line - * @body: The actual body of the mail to send - * @attachments: Additional list of attachments + * @mailto_uri: A mailto URI. * * This function will try to do a remote procedure call (rpc) * into modest (or start it if necessary) and open a composer @@ -52,34 +74,6 @@ * Return value: Whether or not the rpc call to modest * was successfull **/ - -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) -{ - osso_rpc_t retval; - const osso_return_t ret = osso_rpc_run_with_defaults(osso_context, - MODEST_DBUS_NAME, - MODEST_DBUS_METHOD_SEND_MAIL, &retval, - DBUS_TYPE_STRING, to, - DBUS_TYPE_STRING, cc, - DBUS_TYPE_STRING, bcc, - DBUS_TYPE_STRING, subject, - DBUS_TYPE_STRING, body, - DBUS_TYPE_INVALID); - - if (ret != OSSO_OK) { - printf("debug: osso_rpc_run() failed.\n"); - return FALSE; - } else { - printf("debug: osso_rpc_run() succeeded.\n"); - } - - osso_rpc_free_val(&retval); - - return TRUE; -} - gboolean libmodest_dbus_client_mail_to (osso_context_t *osso_context, const gchar *mailto_uri) { @@ -91,10 +85,10 @@ libmodest_dbus_client_mail_to (osso_context_t *osso_context, const gchar *mailto DBUS_TYPE_INVALID); if (ret != OSSO_OK) { - printf("debug: osso_rpc_run() failed.\n"); + printf("debug: %s: osso_rpc_run() failed.\n", __FUNCTION__); return FALSE; } else { - printf("debug: osso_rpc_run() succeeded.\n"); + printf("debug: %s: osso_rpc_run() succeeded.\n", __FUNCTION__); } osso_rpc_free_val(&retval); @@ -102,28 +96,32 @@ libmodest_dbus_client_mail_to (osso_context_t *osso_context, const gchar *mailto return TRUE; } +/** + * libmodest_dbus_client_compose_mail: + * @osso_context: a valid #osso_context_t object. + * @to: The Recipients (From: line) + * @cc: Recipients for carbon copies + * @bcc: Recipients for blind carbon copies + * @subject: Subject line + * @body: The actual body of the mail to compose. + * @attachments: Additional list of attachments. A list of URI strings. + * + * This function will try to do a remote procedure call (rpc) + * into modest (or start it if necessary) and open a composer + * window with the supplied parameters prefilled. + * + * Return value: Whether or not the rpc call to modest + * was successfull + **/ gboolean libmodest_dbus_client_compose_mail (osso_context_t *osso_context, const gchar *to, const gchar *cc, const gchar *bcc, const gchar* subject, const gchar* body, GSList *attachments) { osso_rpc_t retval; - gchar *attachments_str = NULL; - gchar *tmp = NULL; - GSList *next = NULL; - - attachments_str = g_strdup( (gchar *) attachments->data ); - - for (next = g_slist_next(attachments); next != NULL; next = g_slist_next(next)) - { - tmp = g_strconcat(attachments_str, ",", (gchar *) (next->data), NULL); - g_free(attachments_str); - attachments_str = tmp; - if (attachments_str == NULL) { - return OSSO_ERROR; - } - } - const osso_return_t ret = osso_rpc_run_with_defaults(osso_context, + gchar *attachments_str = get_attachments_string(attachments); + + const osso_return_t ret = osso_rpc_run_with_defaults(osso_context, MODEST_DBUS_NAME, MODEST_DBUS_METHOD_COMPOSE_MAIL, &retval, DBUS_TYPE_STRING, to, @@ -133,21 +131,24 @@ libmodest_dbus_client_compose_mail (osso_context_t *osso_context, const gchar *t DBUS_TYPE_STRING, body, DBUS_TYPE_STRING, attachments_str, DBUS_TYPE_INVALID); - + + g_free (attachments_str); + if (ret != OSSO_OK) { - printf("debug: osso_rpc_run() failed.\n"); + printf("debug: %s: osso_rpc_run() failed.\n", __FUNCTION__); return FALSE; } else { - printf("debug: osso_rpc_run() succeeded.\n"); + printf("debug: %s: osso_rpc_run() succeeded.\n", __FUNCTION__); } - + osso_rpc_free_val(&retval); - + + return TRUE; } /** - * libmodest_dbus_client_dopen_message: + * libmodest_dbus_client_open_message: * @osso_context: a valid #osso_context_t object. * @msg_uri: A valid url to a mail * @@ -169,10 +170,10 @@ libmodest_dbus_client_open_message (osso_context_t *osso_context, const gchar *m DBUS_TYPE_INVALID); if (ret != OSSO_OK) { - printf("debug: osso_rpc_run() failed.\n"); + printf("debug: %s: osso_rpc_run() failed.\n", __FUNCTION__); return FALSE; } else { - printf("debug: osso_rpc_run() succeeded.\n"); + printf("debug: %s: osso_rpc_run() succeeded.\n", __FUNCTION__); } osso_rpc_free_val(&retval); @@ -190,10 +191,31 @@ libmodest_dbus_client_send_and_receive (osso_context_t *osso_context) DBUS_TYPE_INVALID); if (ret != OSSO_OK) { - printf("debug: osso_rpc_run() failed.\n"); + printf("debug: %s: osso_rpc_run() failed.\n", __FUNCTION__); + return FALSE; + } else { + printf("debug: %s: osso_rpc_run() succeeded.\n", __FUNCTION__); + } + + osso_rpc_free_val(&retval); + + return TRUE; +} + +gboolean +libmodest_dbus_client_open_default_inbox (osso_context_t *osso_context) +{ + osso_rpc_t retval; + const osso_return_t ret = osso_rpc_run_with_defaults(osso_context, + MODEST_DBUS_NAME, + MODEST_DBUS_METHOD_OPEN_DEFAULT_INBOX, &retval, + DBUS_TYPE_INVALID); + + if (ret != OSSO_OK) { + printf("debug: %s: osso_rpc_run() failed.\n", __FUNCTION__); return FALSE; } else { - printf("debug: osso_rpc_run() succeeded.\n"); + printf("debug: %s: osso_rpc_run() succeeded.\n", __FUNCTION__); } osso_rpc_free_val(&retval); @@ -201,6 +223,30 @@ libmodest_dbus_client_send_and_receive (osso_context_t *osso_context) return TRUE; } +gboolean +libmodest_dbus_client_open_account (osso_context_t *osso_context, + const gchar *account_id) +{ + osso_rpc_t retval; + const osso_return_t ret = + osso_rpc_run_with_defaults(osso_context, + MODEST_DBUS_NAME, + MODEST_DBUS_METHOD_OPEN_ACCOUNT, &retval, + DBUS_TYPE_STRING, account_id, + DBUS_TYPE_INVALID); + + if (ret != OSSO_OK) { + printf("debug: %s: osso_rpc_run() failed.\n", __FUNCTION__); + return FALSE; + } else { + printf("debug: %s: osso_rpc_run() succeeded.\n", __FUNCTION__); + } + + osso_rpc_free_val(&retval); + + return TRUE; +} + /** * libmodest_dbus_client_delete_message: * @osso_context: a valid #osso_context_t object. @@ -236,7 +282,7 @@ libmodest_dbus_client_delete_message (osso_context_t *osso_ctx, return ret == OSSO_OK; } -void +static void modest_search_hit_free (ModestSearchHit *hit) { g_free (hit->msgid); @@ -262,12 +308,11 @@ modest_search_hit_list_free (GList *hits) static char * _dbus_iter_get_string_or_null (DBusMessageIter *iter) { - const char *string; - char *ret; + const char *string = NULL; + char *ret = NULL; dbus_message_iter_get_basic (iter, &string); - ret = NULL; if (string && strlen (string)) { ret = g_strdup (string); } @@ -319,9 +364,10 @@ _dbus_iter_get_boolean (DBusMessageIter *iter) return ret; } - +/** Get the values from the complex type (SEARCH_HIT_DBUS_TYPE) + * in the D-Bus return message. */ static ModestSearchHit * -dbus_message_iter_get_search_hit (DBusMessageIter *parent) +modest_dbus_message_iter_get_search_hit (DBusMessageIter *parent) { ModestSearchHit *hit; DBusMessageIter child; @@ -452,7 +498,7 @@ dbus_message_iter_get_search_hit (DBusMessageIter *parent) goto out; } - /* msize */ + /* timestamp */ arg_type = dbus_message_iter_get_arg_type (&child); if (arg_type != DBUS_TYPE_INT64) { @@ -470,7 +516,7 @@ dbus_message_iter_get_search_hit (DBusMessageIter *parent) out: if (error) { - g_warning ("Error during unmarshaling"); + g_warning ("%s: Error during unmarshalling", __FUNCTION__); modest_search_hit_free (hit); hit = NULL; } @@ -489,7 +535,8 @@ out: * @flags: A list of flags where to search so the documentation * of %ModestDBusSearchFlags for details. * @hits: A pointer to a valid GList pointer that will contain the search - * hits (must be freed by the caller). + * hits (ModestSearchHit). The list and the items must be freed by the caller + * with modest_search_hit_list_free(). * * This method will search the folder specified by a valid url in @folder or all * known accounts (local and remote) if %NULL for matches of the search term(s) @@ -513,8 +560,8 @@ out: * Example to search every account for message containing "no": * * ModestDBusSearchFlags flags; - * osso_context_t *osso_ctx; - * GList *hit; + * osso_context_t *osso_context; + * GList *hits; * GList *iter; * gboolean res; * @@ -553,14 +600,13 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, { DBusMessage *msg; - dbus_bool_t res; - DBusError err; + dbus_bool_t res; DBusConnection *con; DBusMessageIter iter; DBusMessageIter child; - DBusMessage *reply = NULL; + DBusMessage *reply = NULL; gint timeout; - int arg_type; + int arg_type; dbus_int64_t sd_v; dbus_int64_t ed_v; dbus_int32_t flags_v; @@ -580,21 +626,21 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, msg = dbus_message_new_method_call (MODEST_DBUS_SERVICE, - MODEST_DBUS_OBJECT, - MODEST_DBUS_IFACE, - MODEST_DBUS_METHOD_SEARCH); + MODEST_DBUS_OBJECT, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_SEARCH); - if (msg == NULL) { - //ULOG_ERR_F("dbus_message_new_method_call failed"); + if (msg == NULL) { + //ULOG_ERR_F("dbus_message_new_method_call failed"); return OSSO_ERROR; - } + } if (folder == NULL) { folder = ""; } - sd_v = start_date; - ed_v = end_date; + sd_v = (dbus_int64_t) start_date; + ed_v = (dbus_int64_t) end_date; flags_v = (dbus_int32_t) flags; size_v = (dbus_uint32_t) min_size; @@ -609,24 +655,30 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, dbus_message_set_auto_start (msg, TRUE); - dbus_error_init (&err); - - timeout = 1000; //XXX - osso_rpc_get_timeout (osso_ctx, &timeout); + /* Use a long timeout (2 minutes) because the search currently + * gets folders and messages from the servers. */ + timeout = 120000; //milliseconds. + //osso_rpc_get_timeout (osso_ctx, &timeout); + /*printf("DEBUG: %s: Before dbus_connection_send_with_reply_and_block().\n", + __FUNCTION__); */ + /* TODO: Detect the timeout somehow. */ + DBusError err; + dbus_error_init (&err); reply = dbus_connection_send_with_reply_and_block (con, msg, timeout, &err); + /* printf("DEBUG: %s: dbus_connection_send_with_reply_and_block() finished.\n", + __FUNCTION__); */ 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; - } + if (!reply) { + g_warning("%s: dbus_connection_send_with_reply_and_block() error: %s", + __FUNCTION__, err.message); + return FALSE; + } switch (dbus_message_get_type (reply)) { @@ -650,7 +702,7 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, return FALSE; } - g_debug ("message return"); + g_debug ("%s: message return", __FUNCTION__); dbus_message_iter_init (reply, &iter); arg_type = dbus_message_iter_get_arg_type (&iter); @@ -661,7 +713,7 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, do { ModestSearchHit *hit; - hit = dbus_message_iter_get_search_hit (&child); + hit = modest_dbus_message_iter_get_search_hit (&child); if (hit) { *hits = g_list_prepend (*hits, hit); @@ -703,3 +755,228 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, return TRUE; } + +static void +modest_folder_result_free (ModestFolderResult *item) +{ + g_free (item->folder_name); + g_free (item->folder_uri); + g_slice_free (ModestFolderResult, item); +} + +void +modest_folder_result_list_free (GList *list) +{ + GList *iter; + + if (list == NULL) { + return; + } + + for (iter = list; iter; iter = iter->next) { + modest_folder_result_free ((ModestFolderResult *) iter->data); + } + + g_list_free (list); +} + + +/** Get the values from the complex type (GET_FOLDERS_RESULT_DBUS_TYPE) + * in the D-Bus return message. */ +static ModestFolderResult * +modest_dbus_message_iter_get_folder_item (DBusMessageIter *parent) +{ + gboolean error = FALSE; + ModestFolderResult *item = g_slice_new0 (ModestFolderResult); + + int arg_type = dbus_message_iter_get_arg_type (parent); + + if (arg_type != 'r') { + return NULL; + } + + DBusMessageIter child; + dbus_message_iter_recurse (parent, &child); + + /* folder name: */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + item->folder_name = _dbus_iter_get_string_or_null (&child); + + + dbus_bool_t res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* folder URI: */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + item->folder_uri = _dbus_iter_get_string_or_null (&child); + + +out: + if (error) { + g_warning ("%s: Error during unmarshalling", __FUNCTION__); + modest_folder_result_free (item); + item = NULL; + } + + return item; +} + +/** + * libmodest_dbus_client_get_folders: + * @osso_ctx: A valid #osso_context_t object. + * @folders: A pointer to a valid GList pointer that will contain the folder items + * (ModestFolderResult). The list and the items must be freed by the caller + * with modest_folder_result_list_free(). + * + * This method will obtain a list of folders in the default account. + * + * Upon success TRUE is returned and @folders will include the folders or the list + * might be empty if there are no folders. The returned + * list must be freed with modest_folder_result_list_free (). + * + * NOTE: A folder will only be retrieved if it was previously downloaded by + * modest. This function does also not attempt do to remote refreshes (i.e. IMAP). + * + * Return value: TRUE if the request succeded or FALSE for an error. + **/ +gboolean +libmodest_dbus_client_get_folders (osso_context_t *osso_ctx, + GList **folders) +{ + /* Initialize output argument: */ + if (folders) + *folders = NULL; + else + return FALSE; + + DBusConnection *con = osso_get_dbus_connection (osso_ctx); + + if (con == NULL) { + g_warning ("Could not get dbus connection\n"); + return FALSE; + + } + + DBusMessage *msg = dbus_message_new_method_call (MODEST_DBUS_SERVICE, + MODEST_DBUS_OBJECT, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_GET_FOLDERS); + + if (msg == NULL) { + //ULOG_ERR_F("dbus_message_new_method_call failed"); + return OSSO_ERROR; + } + + dbus_message_set_auto_start (msg, TRUE); + + /* Use a long timeout (2 minutes) because the search currently + * gets folders from the servers. */ + gint timeout = 120000; + //osso_rpc_get_timeout (osso_ctx, &timeout); + + DBusError err; + dbus_error_init (&err); + DBusMessage *reply = dbus_connection_send_with_reply_and_block (con, + msg, + timeout, + &err); + + dbus_message_unref (msg); + msg = NULL; + + if (reply == NULL) { + g_warning("%s: dbus_connection_send_with_reply_and_block() error:\n %s", + __FUNCTION__, err.message); + 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 ("%s: message return", __FUNCTION__); + + DBusMessageIter iter; + dbus_message_iter_init (reply, &iter); + /* int arg_type = dbus_message_iter_get_arg_type (&iter); */ + + DBusMessageIter child; + dbus_message_iter_recurse (&iter, &child); + + do { + ModestFolderResult *item = modest_dbus_message_iter_get_folder_item (&child); + + if (item) { + *folders = g_list_append (*folders, item); + } + + } while (dbus_message_iter_next (&child)); + + dbus_message_unref (reply); + + + /* TODO: This is from osso source, do we need it? */ +#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; +} + +