diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2013-05-25 09:28:22 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2013-05-25 10:29:39 +0800 |
commit | 7ed407b47667e850b1d0539855dcd9928de041b8 (patch) | |
tree | 8f21c2d6ecf2bed58a45cdc7f36d4c6258c8b5af | |
parent | b1e272a17e63322f87eb26dc4208804fc6fd55a7 (diff) | |
download | gsoc2013-evolution-7ed407b47667e850b1d0539855dcd9928de041b8.tar gsoc2013-evolution-7ed407b47667e850b1d0539855dcd9928de041b8.tar.gz gsoc2013-evolution-7ed407b47667e850b1d0539855dcd9928de041b8.tar.bz2 gsoc2013-evolution-7ed407b47667e850b1d0539855dcd9928de041b8.tar.lz gsoc2013-evolution-7ed407b47667e850b1d0539855dcd9928de041b8.tar.xz gsoc2013-evolution-7ed407b47667e850b1d0539855dcd9928de041b8.tar.zst gsoc2013-evolution-7ed407b47667e850b1d0539855dcd9928de041b8.zip |
Utilize the new EMailSession functions when sending.
(cherry picked from commit 92817706c525cf83f7b9867ea088b162b5348371)
Conflicts:
libemail-engine/e-mail-session-utils.c
-rw-r--r-- | libemail-engine/e-mail-session-utils.c | 241 | ||||
-rw-r--r-- | libemail-engine/mail-ops.c | 197 |
2 files changed, 152 insertions, 286 deletions
diff --git a/libemail-engine/e-mail-session-utils.c b/libemail-engine/e-mail-session-utils.c index 1ef18017dd..1e2d110767 100644 --- a/libemail-engine/e-mail-session-utils.c +++ b/libemail-engine/e-mail-session-utils.c @@ -48,6 +48,8 @@ struct _AsyncContext { CamelFilterDriver *driver; + CamelService *transport; + GCancellable *cancellable; gint io_priority; @@ -60,8 +62,6 @@ struct _AsyncContext { gchar *folder_uri; gchar *message_uid; - gchar *transport_uid; - gchar *sent_folder_uri; }; static void @@ -85,6 +85,9 @@ async_context_free (AsyncContext *context) if (context->driver != NULL) g_object_unref (context->driver); + if (context->transport != NULL) + g_object_unref (context->transport); + if (context->cancellable != NULL) { camel_operation_pop_message (context->cancellable); g_object_unref (context->cancellable); @@ -101,8 +104,6 @@ async_context_free (AsyncContext *context) g_free (context->folder_uri); g_free (context->message_uid); - g_free (context->transport_uid); - g_free (context->sent_folder_uri); g_slice_free (AsyncContext, context); } @@ -515,86 +516,84 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple, GCancellable *cancellable) { AsyncContext *context; + CamelProvider *provider; + CamelFolder *folder = NULL; CamelFolder *local_sent_folder; CamelServiceConnectionStatus status; GString *error_messages; gboolean copy_to_sent = TRUE; + gboolean did_connect = FALSE; guint ii; GError *error = NULL; context = g_simple_async_result_get_op_res_gpointer (simple); - /* Send the message to all recipients. */ - if (camel_address_length (context->recipients) > 0) { - CamelProvider *provider; - CamelService *service; - gboolean did_connect = FALSE; - - service = camel_session_ref_service ( - CAMEL_SESSION (session), context->transport_uid); - - if (service == NULL) { - g_simple_async_result_set_error ( - simple, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_URL_INVALID, - _("No mail service found with UID '%s'"), - context->transport_uid); - return; - } + if (camel_address_length (context->recipients) == 0) + goto skip_send; - if (!CAMEL_IS_TRANSPORT (service)) { - g_simple_async_result_set_error ( - simple, CAMEL_SERVICE_ERROR, - CAMEL_SERVICE_ERROR_URL_INVALID, - _("UID '%s' is not a mail transport"), - context->transport_uid); - g_object_unref (service); - return; - } + /* Send the message to all recipients. */ - status = camel_service_get_connection_status (service); - if (status != CAMEL_SERVICE_CONNECTED) { - did_connect = TRUE; + /* XXX Leave this untranslated in gnome-3-8. + * It was added during the string freeze, + * but should rarely ever be seen by users. */ + if (context->transport == NULL) { + g_simple_async_result_set_error ( + simple, CAMEL_SERVICE_ERROR, + CAMEL_SERVICE_ERROR_UNAVAILABLE, + "No mail transport service available"); + return; + } - camel_service_connect_sync ( - service, cancellable, &error); + provider = camel_service_get_provider (context->transport); + if ((provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0 && + !camel_session_get_online (CAMEL_SESSION (session))) { + /* silently ignore */ + return; + } - if (error != NULL) { - g_simple_async_result_take_error (simple, error); - g_object_unref (service); - return; - } - } + status = camel_service_get_connection_status (context->transport); + if (status != CAMEL_SERVICE_CONNECTED) { + did_connect = TRUE; - provider = camel_service_get_provider (service); + camel_service_connect_sync ( + context->transport, cancellable, &error); - if (provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER) - copy_to_sent = FALSE; + if (error != NULL) { + g_simple_async_result_take_error (simple, error); + return; + } + } - camel_transport_send_to_sync ( - CAMEL_TRANSPORT (service), - context->message, context->from, - context->recipients, cancellable, &error); + if (provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER) + copy_to_sent = FALSE; - if (did_connect) { - /* if the cancellable is cancelled, then the disconnect will not run, - * thus reset it to ensure the service will be properly disconnected */ - if (cancellable) - g_cancellable_reset (cancellable); + camel_transport_send_to_sync ( + CAMEL_TRANSPORT (context->transport), + context->message, context->from, + context->recipients, cancellable, &error); + if (did_connect) { + /* Disconnect regardless of error or cancellation, + * but be mindful of these conditions when calling + * camel_service_disconnect_sync(). */ + if (g_cancellable_is_cancelled (cancellable)) { camel_service_disconnect_sync ( - service, error == NULL, - cancellable, error ? NULL : &error); + context->transport, FALSE, NULL, NULL); + } else if (error != NULL) { + camel_service_disconnect_sync ( + context->transport, FALSE, cancellable, NULL); + } else { + camel_service_disconnect_sync ( + context->transport, TRUE, cancellable, &error); } - g_object_unref (service); - if (error != NULL) { g_simple_async_result_take_error (simple, error); return; } } +skip_send: /* Post the message to requested folders. */ for (ii = 0; ii < context->post_to_uris->len; ii++) { CamelFolder *folder; @@ -662,32 +661,19 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple, e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_SENT); - /* Try to extract a CamelFolder from the Sent folder URI. */ - if (context->sent_folder_uri != NULL) { - context->folder = e_mail_session_uri_to_folder_sync ( - session, context->sent_folder_uri, 0, - cancellable, &error); - if (error != NULL) { - g_warn_if_fail (context->folder == NULL); - if (error_messages->len > 0) - g_string_append (error_messages, "\n\n"); - g_string_append_printf ( - error_messages, - _("Failed to append to %s: %s\n" - "Appending to local 'Sent' folder instead."), - context->sent_folder_uri, error->message); - g_clear_error (&error); - } - } + folder = e_mail_session_get_fcc_for_message_sync ( + session, context->message, cancellable, &error); - /* Fall back to the local Sent folder. */ - if (context->folder == NULL) - context->folder = g_object_ref (local_sent_folder); + /* Sanity check. */ + g_return_if_fail ( + ((folder != NULL) && (error == NULL)) || + ((folder == NULL) && (error != NULL))); /* Append the message. */ - camel_folder_append_message_sync ( - context->folder, context->message, - context->info, NULL, cancellable, &error); + if (folder != NULL) + camel_folder_append_message_sync ( + folder, context->message, + context->info, NULL, cancellable, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) goto exit; @@ -695,12 +681,10 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple, if (error == NULL) goto cleanup; - /* If appending to a remote Sent folder failed, - * try appending to the local Sent folder. */ - if (context->folder != local_sent_folder) { + if (folder != NULL && folder != local_sent_folder) { const gchar *description; - description = camel_folder_get_description (context->folder); + description = camel_folder_get_description (folder); if (error_messages->len > 0) g_string_append (error_messages, "\n\n"); @@ -709,6 +693,12 @@ mail_session_send_to_thread (GSimpleAsyncResult *simple, _("Failed to append to %s: %s\n" "Appending to local 'Sent' folder instead."), description, error->message); + } + + /* If appending to a remote Sent folder failed, + * try appending to the local Sent folder. */ + if (folder != local_sent_folder) { + g_clear_error (&error); camel_folder_append_message_sync ( @@ -769,9 +759,11 @@ exit: } /* Synchronize the Sent folder. */ - if (context->folder != NULL) + if (folder != NULL) { camel_folder_synchronize_sync ( - context->folder, FALSE, cancellable, NULL); + folder, FALSE, cancellable, NULL); + g_object_unref (folder); + } g_string_free (error_messages, TRUE); } @@ -780,17 +772,16 @@ static guint32 get_message_size (CamelMimeMessage *message, GCancellable *cancellable) { - guint32 res = 0; CamelStream *null; - - g_return_val_if_fail (message != NULL, 0); + guint32 size; null = camel_stream_null_new (); - camel_data_wrapper_write_to_stream_sync (CAMEL_DATA_WRAPPER (message), null, cancellable, NULL); - res = CAMEL_STREAM_NULL (null)->written; + camel_data_wrapper_write_to_stream_sync ( + CAMEL_DATA_WRAPPER (message), null, cancellable, NULL); + size = CAMEL_STREAM_NULL (null)->written; g_object_unref (null); - return res; + return size; } void @@ -809,75 +800,28 @@ e_mail_session_send_to (EMailSession *session, CamelAddress *recipients; CamelMedium *medium; CamelMessageInfo *info; - ESourceRegistry *registry; - ESource *source = NULL; + CamelService *transport; GPtrArray *post_to_uris; struct _camel_header_raw *xev; struct _camel_header_raw *header; - const gchar *string; const gchar *resent_from; - gchar *transport_uid = NULL; - gchar *sent_folder_uri = NULL; - gboolean replies_to_origin_folder = FALSE; GError *error = NULL; g_return_if_fail (E_IS_MAIL_SESSION (session)); g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - registry = e_mail_session_get_registry (session); - medium = CAMEL_MEDIUM (message); camel_medium_set_header (medium, "X-Mailer", X_MAILER); + /* Do this before removing "X-Evolution" headers. */ + transport = e_mail_session_ref_transport_for_message ( + session, message); + xev = mail_tool_remove_xevolution_headers (message); /* Extract directives from X-Evolution headers. */ - string = camel_header_raw_find (&xev, "X-Evolution-Identity", NULL); - if (string != NULL) { - gchar *uid = g_strstrip (g_strdup (string)); - source = e_source_registry_ref_source (registry, uid); - g_free (uid); - } - - if (E_IS_SOURCE (source)) { - ESourceMailSubmission *extension; - const gchar *extension_name; - - extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION; - extension = e_source_get_extension (source, extension_name); - - string = e_source_mail_submission_get_sent_folder (extension); - sent_folder_uri = g_strdup (string); - - string = e_source_mail_submission_get_transport_uid (extension); - transport_uid = g_strdup (string); - - replies_to_origin_folder = e_source_mail_submission_get_replies_to_origin_folder (extension); - - g_object_unref (source); - } - - string = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL); - if (sent_folder_uri == NULL && string != NULL) - sent_folder_uri = g_strstrip (g_strdup (string)); - - string = camel_header_raw_find (&xev, "X-Evolution-Transport", NULL); - if (transport_uid == NULL && string != NULL) - transport_uid = g_strstrip (g_strdup (string)); - - if (replies_to_origin_folder) { - string = camel_header_raw_find (&xev, "X-Evolution-Source-Flags", NULL); - if (string != NULL && strstr (string, "FORWARDED") == NULL) { - string = camel_header_raw_find (&xev, "X-Evolution-Source-Folder", NULL); - if (string != NULL && camel_header_raw_find (&xev, "X-Evolution-Source-Message", NULL) != NULL) { - g_free (sent_folder_uri); - sent_folder_uri = g_strstrip (g_strdup (string)); - } - } - } - post_to_uris = g_ptr_array_new (); for (header = xev; header != NULL; header = header->next) { gchar *folder_uri; @@ -935,8 +879,10 @@ e_mail_session_send_to (EMailSession *session, /* Miscellaneous preparations. */ - info = camel_message_info_new_from_header (NULL, ((CamelMimePart *) message)->headers); - ((CamelMessageInfoBase *) info)->size = get_message_size (message, cancellable); + info = camel_message_info_new_from_header ( + NULL, CAMEL_MIME_PART (message)->headers); + ((CamelMessageInfoBase *) info)->size = + get_message_size (message, cancellable); camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0); /* The rest of the processing happens in a thread. */ @@ -949,8 +895,7 @@ e_mail_session_send_to (EMailSession *session, context->info = info; context->xev = xev; context->post_to_uris = post_to_uris; - context->transport_uid = transport_uid; - context->sent_folder_uri = sent_folder_uri; + context->transport = transport; if (G_IS_CANCELLABLE (cancellable)) context->cancellable = g_object_ref (cancellable); diff --git a/libemail-engine/mail-ops.c b/libemail-engine/mail-ops.c index 2084aa1e01..ec3e9bc992 100644 --- a/libemail-engine/mail-ops.c +++ b/libemail-engine/mail-ops.c @@ -560,49 +560,6 @@ static void report_status (struct _send_queue_msg *m, const gchar *desc, ...); -static gboolean -get_submission_details_from_identity (EMailSession *session, - const gchar *identity_uid, - gchar **out_transport_uid, - gchar **out_sent_folder_uri, - gboolean *out_replies_to_origin_folder) -{ - ESource *source; - ESourceRegistry *registry; - ESourceExtension *extension; - const gchar *extension_name; - - registry = e_mail_session_get_registry (session); - extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION; - source = e_source_registry_ref_source (registry, identity_uid); - - if (source == NULL) - return FALSE; - - if (!e_source_has_extension (source, extension_name)) { - g_object_unref (source); - return FALSE; - } - - extension = e_source_get_extension (source, extension_name); - - *out_sent_folder_uri = - e_source_mail_submission_dup_sent_folder ( - E_SOURCE_MAIL_SUBMISSION (extension)); - - *out_transport_uid = - e_source_mail_submission_dup_transport_uid ( - E_SOURCE_MAIL_SUBMISSION (extension)); - - *out_replies_to_origin_folder = - e_source_mail_submission_get_replies_to_origin_folder ( - E_SOURCE_MAIL_SUBMISSION (extension)); - - g_object_unref (source); - - return TRUE; -} - /* send 1 message to a specific transport */ static void mail_send_message (struct _send_queue_msg *m, @@ -618,10 +575,7 @@ mail_send_message (struct _send_queue_msg *m, CamelAddress *from, *recipients; CamelMessageInfo *info = NULL; CamelProvider *provider = NULL; - gchar *transport_uid = NULL; - gchar *sent_folder_uri = NULL; - const gchar *resent_from, *tmp; - gboolean replies_to_origin_folder = FALSE; + const gchar *resent_from; CamelFolder *folder = NULL; GString *err = NULL; struct _camel_header_raw *xev, *header; @@ -636,45 +590,15 @@ mail_send_message (struct _send_queue_msg *m, camel_medium_set_header (CAMEL_MEDIUM (message), "X-Mailer", x_mailer); - err = g_string_new (""); - xev = mail_tool_remove_xevolution_headers (message); - - tmp = camel_header_raw_find (&xev, "X-Evolution-Identity", NULL); - if (tmp != NULL) { - gchar *identity_uid; - - identity_uid = g_strstrip (g_strdup (tmp)); - get_submission_details_from_identity ( - m->session, identity_uid, - &transport_uid, &sent_folder_uri, - &replies_to_origin_folder); - g_free (identity_uid); - } - - tmp = camel_header_raw_find (&xev, "X-Evolution-Transport", NULL); - if (transport_uid == NULL && tmp != NULL) - transport_uid = g_strstrip (g_strdup (tmp)); - - tmp = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL); - if (sent_folder_uri == NULL && tmp != NULL) - sent_folder_uri = g_strstrip (g_strdup (tmp)); - - if (replies_to_origin_folder) { - tmp = camel_header_raw_find (&xev, "X-Evolution-Source-Flags", NULL); - if (tmp != NULL && strstr (tmp, "FORWARDED") == NULL) { - tmp = camel_header_raw_find (&xev, "X-Evolution-Source-Folder", NULL); - if (tmp != NULL && camel_header_raw_find (&xev, "X-Evolution-Source-Message", NULL) != NULL) { - g_free (sent_folder_uri); - sent_folder_uri = g_strstrip (g_strdup (tmp)); - } - } - } - - service = camel_session_ref_service ( - CAMEL_SESSION (m->session), transport_uid); + /* Do this before removing "X-Evolution" headers. */ + service = e_mail_session_ref_transport_for_message ( + m->session, message); if (service != NULL) provider = camel_service_get_provider (service); + err = g_string_new (""); + xev = mail_tool_remove_xevolution_headers (message); + if (CAMEL_IS_TRANSPORT (service)) { const gchar *tuid; @@ -685,8 +609,9 @@ mail_send_message (struct _send_queue_msg *m, /* Check for email sending */ from = (CamelAddress *) camel_internet_address_new (); - resent_from = camel_medium_get_header (CAMEL_MEDIUM (message), "Resent-From"); - if (resent_from) { + resent_from = camel_medium_get_header ( + CAMEL_MEDIUM (message), "Resent-From"); + if (resent_from != NULL) { camel_address_decode (from, resent_from); } else { iaddr = camel_mime_message_get_from (message); @@ -697,7 +622,10 @@ mail_send_message (struct _send_queue_msg *m, for (i = 0; i < 3; i++) { const gchar *type; - type = resent_from ? resent_recipients[i] : normal_recipients[i]; + if (resent_from != NULL) + type = resent_recipients[i]; + else + type = normal_recipients[i]; iaddr = camel_mime_message_get_recipients (message, type); camel_address_cat (recipients, CAMEL_ADDRESS (iaddr)); } @@ -729,7 +657,7 @@ mail_send_message (struct _send_queue_msg *m, /* FIXME Not passing a GCancellable or GError here. */ folder = e_mail_session_uri_to_folder_sync ( m->session, uri, 0, NULL, NULL); - if (folder) { + if (folder != NULL) { /* FIXME Not passing a GCancellable or GError here. */ camel_folder_append_message_sync ( folder, message, info, NULL, NULL, NULL); @@ -772,71 +700,65 @@ mail_send_message (struct _send_queue_msg *m, if (provider == NULL || !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER)) { + CamelFolder *local_sent_folder; GError *local_error = NULL; - if (sent_folder_uri) { - folder = e_mail_session_uri_to_folder_sync ( - m->session, sent_folder_uri, 0, - cancellable, &local_error); + local_sent_folder = e_mail_session_get_local_folder ( + m->session, E_MAIL_LOCAL_FOLDER_SENT); - if (local_error != NULL) { - g_string_append_printf ( - err, _("Failed to append to %s: %s\n" - "Appending to local 'Sent' folder instead."), - sent_folder_uri, - local_error->message); - g_clear_error (&local_error); - } - } - - if (!folder) { - folder = e_mail_session_get_local_folder ( - m->session, E_MAIL_LOCAL_FOLDER_SENT); - g_object_ref (folder); - } + folder = e_mail_session_get_fcc_for_message_sync ( + m->session, message, cancellable, &local_error); - if (!camel_folder_append_message_sync ( - folder, message, info, - NULL, cancellable, &local_error)) { + /* Sanity check. */ + g_return_if_fail ( + ((folder == NULL) && (local_error != NULL)) || + ((folder != NULL) && (local_error == NULL))); - CamelFolder *sent_folder; + if (local_error == NULL) + camel_folder_append_message_sync ( + folder, message, info, NULL, + cancellable, &local_error); - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - goto exit; + if (g_error_matches ( + local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + goto exit; - sent_folder = e_mail_session_get_local_folder ( - m->session, E_MAIL_LOCAL_FOLDER_SENT); + if (local_error != NULL && folder != local_sent_folder) { - if (folder != sent_folder) { + if (folder != NULL) { const gchar *description; - description = camel_folder_get_description (folder); - if (err->len) + description = + camel_folder_get_description (folder); + if (err->len > 0) g_string_append (err, "\n\n"); g_string_append_printf ( - err, _("Failed to append to %s: %s\n" + err, + _("Failed to append to %s: %s\n" "Appending to local 'Sent' folder instead."), - description, local_error->message); - g_object_ref (sent_folder); - g_object_unref (folder); - folder = sent_folder; + description, + local_error->message); - g_clear_error (&local_error); - camel_folder_append_message_sync ( - folder, message, info, - NULL, cancellable, &local_error); + g_object_unref (folder); } - if (local_error != NULL) { - if (g_error_matches ( - local_error, G_IO_ERROR, - G_IO_ERROR_CANCELLED)) - goto exit; + g_clear_error (&local_error); + folder = g_object_ref (local_sent_folder); + + camel_folder_append_message_sync ( + folder, message, info, NULL, + cancellable, &local_error); + + if (g_error_matches ( + local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + goto exit; - if (err->len) + if (local_error != NULL) { + if (err->len > 0) g_string_append (err, "\n\n"); g_string_append_printf ( - err, _("Failed to append to " + err, + _("Failed to append to " "local 'Sent' folder: %s"), local_error->message); } @@ -877,7 +799,7 @@ mail_send_message (struct _send_queue_msg *m, camel_folder_synchronize_sync (queue, FALSE, NULL, NULL); } - if (err->len) { + if (err->len > 0) { /* set the culmulative exception report */ g_set_error ( &local_error, CAMEL_ERROR, @@ -889,11 +811,12 @@ exit: g_propagate_error (error, local_error); /* FIXME Not passing a GCancellable or GError here. */ - if (folder) { + if (folder != NULL) { camel_folder_synchronize_sync (folder, FALSE, NULL, NULL); g_object_unref (folder); } - if (info) + + if (info != NULL) camel_message_info_free (info); if (service != NULL) @@ -901,8 +824,6 @@ exit: g_object_unref (recipients); g_object_unref (from); - g_free (sent_folder_uri); - g_free (transport_uid); camel_header_raw_clear (&xev); g_string_free (err, TRUE); g_object_unref (message); |