aboutsummaryrefslogtreecommitdiffstats
path: root/mail/e-mail-folder-utils.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-05-18 07:50:33 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-05-18 21:25:59 +0800
commitf0a011f941bab3f6ac7228be4e1bec86a0de0d2a (patch)
treed5c64c9fc9922775171aa623223c0666bd833e64 /mail/e-mail-folder-utils.c
parentb3b917365ff2e813df0503e94267f2cb3bab4255 (diff)
downloadgsoc2013-evolution-f0a011f941bab3f6ac7228be4e1bec86a0de0d2a.tar
gsoc2013-evolution-f0a011f941bab3f6ac7228be4e1bec86a0de0d2a.tar.gz
gsoc2013-evolution-f0a011f941bab3f6ac7228be4e1bec86a0de0d2a.tar.bz2
gsoc2013-evolution-f0a011f941bab3f6ac7228be4e1bec86a0de0d2a.tar.lz
gsoc2013-evolution-f0a011f941bab3f6ac7228be4e1bec86a0de0d2a.tar.xz
gsoc2013-evolution-f0a011f941bab3f6ac7228be4e1bec86a0de0d2a.tar.zst
gsoc2013-evolution-f0a011f941bab3f6ac7228be4e1bec86a0de0d2a.zip
Remove mail_save_messages().
Use e_mail_folder_save_messages() instead.
Diffstat (limited to 'mail/e-mail-folder-utils.c')
-rw-r--r--mail/e-mail-folder-utils.c242
1 files changed, 242 insertions, 0 deletions
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