diff options
Diffstat (limited to 'mail/mail-ops.c')
-rw-r--r-- | mail/mail-ops.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 24826afd10..28cd77a613 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -2599,3 +2599,142 @@ mail_disconnect_store (CamelStore *store) return id; } + +/* ---------------------------------------------------------------------------------- */ + +struct _remove_attachments_msg { + MailMsg base; + + CamelFolder *folder; + GPtrArray *uids; +}; + +static gchar * +remove_attachments_desc (struct _remove_attachments_msg *m) +{ + return g_strdup_printf (_("Removing attachments")); +} + +static void +remove_attachments_exec (struct _remove_attachments_msg *m, + GCancellable *cancellable, + GError **error) +{ + CamelFolder *folder = m->folder; + GPtrArray *uids = m->uids; + gint ii, jj; + + camel_folder_freeze (folder); + for (ii = 0; ii < (uids ? uids->len : 0); ii++) { + gint pc = ((ii + 1) * 100) / uids->len; + CamelMimeMessage *message; + CamelDataWrapper *containee; + gchar *uid; + + uid = g_ptr_array_index (uids, ii); + + /* retrieve the message from the CamelFolder */ + message = camel_folder_get_message_sync (folder, uid, cancellable, NULL); + if (!message) { + camel_operation_progress (cancellable, pc); + continue; + } + + containee = camel_medium_get_content (CAMEL_MEDIUM (message)); + if (containee == NULL) { + camel_operation_progress (cancellable, pc); + continue; + } + + if (CAMEL_IS_MULTIPART (containee)) { + gboolean deleted = FALSE; + gint parts; + + parts = camel_multipart_get_number (CAMEL_MULTIPART (containee)); + for (jj = 0; jj < parts; jj++) { + CamelMimePart *mpart = camel_multipart_get_part (CAMEL_MULTIPART (containee), jj); + const gchar *disposition = camel_mime_part_get_disposition (mpart); + if (disposition && (!strcmp (disposition, "attachment") || !strcmp (disposition, "inline"))) { + gchar *desc; + const gchar *filename; + + filename = camel_mime_part_get_filename (mpart); + desc = g_strdup_printf (_("File \"%s\" has been removed."), filename ? filename : ""); + camel_mime_part_set_disposition (mpart, "inline"); + camel_mime_part_set_content (mpart, desc, strlen (desc), "text/plain"); + camel_mime_part_set_content_type (mpart, "text/plain"); + deleted = TRUE; + } + } + + if (deleted) { + /* copy the original message with the deleted attachment */ + CamelMessageInfo *info, *newinfo; + guint32 flags; + GError *local_error = NULL; + + info = camel_folder_get_message_info (folder, uid); + newinfo = camel_message_info_new_from_header (NULL, CAMEL_MIME_PART (message)->headers); + flags = camel_folder_get_message_flags (folder, uid); + + /* make a copy of the message */ + camel_message_info_set_flags (newinfo, flags, flags); + camel_folder_append_message_sync (folder, message, newinfo, NULL, cancellable, &local_error); + + if (!local_error) { + /* marked the original message deleted */ + camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED); + } + + camel_folder_free_message_info (folder, info); + camel_message_info_free (newinfo); + + if (local_error) { + g_propagate_error (error, local_error); + break; + } + } + } + + camel_operation_progress (cancellable, pc); + } + + if (!error || !*error) + camel_folder_synchronize_sync (folder, FALSE, cancellable, error); + camel_folder_thaw (folder); +} + +static void +remove_attachments_free (struct _remove_attachments_msg *m) +{ + g_object_unref (m->folder); + em_utils_uids_free (m->uids); +} + +static MailMsgInfo remove_attachments_info = { + sizeof (struct _remove_attachments_msg), + (MailMsgDescFunc) remove_attachments_desc, + (MailMsgExecFunc) remove_attachments_exec, + (MailMsgDoneFunc) NULL, + (MailMsgFreeFunc) remove_attachments_free +}; + +/* it takes ownership of 'uids' array */ +gint +mail_remove_attachments (CamelFolder *folder, GPtrArray *uids) +{ + struct _remove_attachments_msg *m; + gint id; + + g_return_val_if_fail (folder != NULL, -1); + g_return_val_if_fail (uids != NULL, -1); + + m = mail_msg_new (&remove_attachments_info); + m->folder = g_object_ref (folder); + m->uids = uids; + + id = m->base.seq; + mail_msg_unordered_push (m); + + return id; +} |