From 63c69e938a86c64fd73cda6777abe45a9a355dcc Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 17 May 2011 19:50:33 -0400 Subject: Remove mail_save_messages(). Use e_mail_folder_save_messages() instead. --- mail/e-mail-folder-utils.c | 242 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) (limited to 'mail/e-mail-folder-utils.c') diff --git a/mail/e-mail-folder-utils.c b/mail/e-mail-folder-utils.c index 10546c15d5..f244260bf5 100644 --- a/mail/e-mail-folder-utils.c +++ b/mail/e-mail-folder-utils.c @@ -34,6 +34,7 @@ struct _AsyncContext { CamelMimePart *part; GHashTable *hash_table; GPtrArray *ptr_array; + GFile *destination; gchar *fwd_subject; gchar *message_uid; }; @@ -56,6 +57,9 @@ async_context_free (AsyncContext *context) if (context->ptr_array != NULL) g_ptr_array_unref (context->ptr_array); + if (context->destination != NULL) + g_object_unref (context->destination); + g_free (context->fwd_subject); g_free (context->message_uid); @@ -884,6 +888,244 @@ e_mail_folder_remove_attachments_finish (CamelFolder *folder, return !g_simple_async_result_propagate_error (simple, error); } +static void +mail_folder_save_messages_thread (GSimpleAsyncResult *simple, + GObject *object, + GCancellable *cancellable) +{ + AsyncContext *context; + GError *error = NULL; + + context = g_simple_async_result_get_op_res_gpointer (simple); + + e_mail_folder_save_messages_sync ( + CAMEL_FOLDER (object), context->ptr_array, + context->destination, cancellable, &error); + + if (error != NULL) { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } +} + +/* Helper for e_mail_folder_save_messages_sync() */ +static void +mail_folder_save_prepare_part (CamelMimePart *mime_part) +{ + CamelDataWrapper *content; + + content = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); + + if (content == NULL) + return; + + if (CAMEL_IS_MULTIPART (content)) { + guint n_parts, ii; + + n_parts = camel_multipart_get_number ( + CAMEL_MULTIPART (content)); + for (ii = 0; ii < n_parts; ii++) { + mime_part = camel_multipart_get_part ( + CAMEL_MULTIPART (content), ii); + mail_folder_save_prepare_part (mime_part); + } + + } else if (CAMEL_IS_MIME_MESSAGE (content)) { + mail_folder_save_prepare_part (CAMEL_MIME_PART (content)); + + } else { + CamelContentType *type; + + /* Save textual parts as 8-bit, not encoded. */ + type = camel_data_wrapper_get_mime_type_field (content); + if (camel_content_type_is (type, "text", "*")) + camel_mime_part_set_encoding ( + mime_part, CAMEL_TRANSFER_ENCODING_8BIT); + } +} + +gboolean +e_mail_folder_save_messages_sync (CamelFolder *folder, + GPtrArray *message_uids, + GFile *destination, + GCancellable *cancellable, + GError **error) +{ + GFileOutputStream *file_output_stream; + GByteArray *byte_array; + CamelMimeFilter *filter; + CamelStream *base_stream; + CamelStream *stream; + gboolean success = TRUE; + guint ii; + + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE); + g_return_val_if_fail (message_uids != NULL, FALSE); + g_return_val_if_fail (G_IS_FILE (destination), FALSE); + + /* Need at least one message UID to save. */ + g_return_val_if_fail (message_uids->len > 0, FALSE); + + camel_operation_push_message ( + cancellable, ngettext ( + "Saving %d message", + "Saving %d messages", + message_uids->len), + message_uids->len); + + file_output_stream = g_file_replace ( + destination, NULL, FALSE, + G_FILE_CREATE_PRIVATE | + G_FILE_CREATE_REPLACE_DESTINATION, + cancellable, error); + + if (file_output_stream == NULL) { + camel_operation_pop_message (cancellable); + return FALSE; + } + + /* CamelStreamMem takes ownership of the GByteArray. */ + byte_array = g_byte_array_new (); + filter = camel_mime_filter_from_new (); + base_stream = camel_stream_mem_new_with_byte_array (byte_array); + stream = camel_stream_filter_new (base_stream); + camel_stream_filter_add (CAMEL_STREAM_FILTER (stream), filter); + g_object_unref (base_stream); + g_object_unref (filter); + + for (ii = 0; ii < message_uids->len; ii++) { + CamelMimeMessage *message; + const gchar *uid; + gchar *from_line; + gint percent; + gint retval; + + uid = g_ptr_array_index (message_uids, ii); + + message = camel_folder_get_message_sync ( + folder, uid, cancellable, error); + if (message == NULL) { + success = FALSE; + goto exit; + } + + mail_folder_save_prepare_part (CAMEL_MIME_PART (message)); + + from_line = camel_mime_message_build_mbox_from (message); + g_return_val_if_fail (from_line != NULL, FALSE); + + success = g_output_stream_write_all ( + G_OUTPUT_STREAM (file_output_stream), + from_line, strlen (from_line), NULL, + cancellable, error); + + g_free (from_line); + + if (!success) { + g_object_unref (message); + goto exit; + } + + retval = camel_data_wrapper_write_to_stream_sync ( + CAMEL_DATA_WRAPPER (message), + stream, cancellable, error); + + if (retval == -1) { + g_object_unref (message); + goto exit; + } + + g_byte_array_append (byte_array, (guint8 *) "\n", 1); + + success = g_output_stream_write_all ( + G_OUTPUT_STREAM (file_output_stream), + byte_array->data, byte_array->len, + NULL, cancellable, error); + + if (!success) { + g_object_unref (message); + goto exit; + } + + percent = ((ii + 1) * 100) / message_uids->len; + camel_operation_progress (cancellable, percent); + + /* Flush the buffer for the next message. + * For memory streams this never fails. */ + camel_stream_reset (stream, NULL); + + g_object_unref (message); + } + +exit: + g_object_unref (file_output_stream); + g_object_unref (stream); + + camel_operation_pop_message (cancellable); + + if (!success) { + /* Try deleting the destination file. */ + g_file_delete (destination, NULL, NULL); + } + + return success; +} + +void +e_mail_folder_save_messages (CamelFolder *folder, + GPtrArray *message_uids, + GFile *destination, + gint io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *context; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + g_return_if_fail (message_uids != NULL); + g_return_if_fail (G_IS_FILE (destination)); + + /* Need at least one message UID to save. */ + g_return_if_fail (message_uids->len > 0); + + context = g_slice_new0 (AsyncContext); + context->ptr_array = g_ptr_array_ref (message_uids); + context->destination = g_object_ref (destination); + + simple = g_simple_async_result_new ( + G_OBJECT (folder), callback, user_data, + e_mail_folder_save_messages); + + g_simple_async_result_set_op_res_gpointer ( + simple, context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, mail_folder_save_messages_thread, + io_priority, cancellable); + + g_object_unref (simple); +} + +gboolean +e_mail_folder_save_messages_finish (CamelFolder *folder, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail ( + g_simple_async_result_is_valid ( + result, G_OBJECT (folder), + e_mail_folder_save_messages), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + /* Assume success unless a GError is set. */ + return !g_simple_async_result_propagate_error (simple, error); +} + /** * e_mail_folder_uri_build: * @store: a #CamelStore -- cgit v1.2.3