aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2012-07-09 19:34:31 +0800
committerMatthew Barnes <mbarnes@redhat.com>2012-07-09 20:44:22 +0800
commitc44c65e85fe6413b69d26ae600be6bfb4952367c (patch)
treeb252e29cd601a97f83504790c1502caa4ce39647
parent07857224789b165e69bb170d364c9c13366fa952 (diff)
downloadgsoc2013-evolution-c44c65e85fe6413b69d26ae600be6bfb4952367c.tar.gz
gsoc2013-evolution-c44c65e85fe6413b69d26ae600be6bfb4952367c.tar.zst
gsoc2013-evolution-c44c65e85fe6413b69d26ae600be6bfb4952367c.zip
Add e_mail_folder_expunge().
To replace mail_expunge_folder().
-rw-r--r--libemail-engine/e-mail-folder-utils.c285
-rw-r--r--libemail-engine/e-mail-folder-utils.h12
2 files changed, 297 insertions, 0 deletions
diff --git a/libemail-engine/e-mail-folder-utils.c b/libemail-engine/e-mail-folder-utils.c
index 5e05b64844..e22e2d7360 100644
--- a/libemail-engine/e-mail-folder-utils.c
+++ b/libemail-engine/e-mail-folder-utils.c
@@ -24,6 +24,9 @@
#include <glib/gi18n-lib.h>
+#include <libedataserver/libedataserver.h>
+
+#include <libemail-engine/e-mail-session.h>
#include <libemail-engine/mail-tools.h>
/* X-Mailer header value */
@@ -186,6 +189,288 @@ e_mail_folder_append_message_finish (CamelFolder *folder,
}
static void
+mail_folder_expunge_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ GError *error = NULL;
+
+ e_mail_folder_expunge_sync (
+ CAMEL_FOLDER (object), cancellable, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
+}
+
+static gboolean
+mail_folder_expunge_pop3_stores (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GHashTable *expunging_uids;
+ CamelStore *parent_store;
+ CamelService *service;
+ CamelSession *session;
+ ESourceRegistry *registry;
+ GPtrArray *uids;
+ GList *list, *link;
+ const gchar *extension_name;
+ gboolean success = TRUE;
+ guint ii;
+
+ parent_store = camel_folder_get_parent_store (folder);
+
+ service = CAMEL_SERVICE (parent_store);
+ session = camel_service_get_session (service);
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
+ uids = camel_folder_get_uids (folder);
+
+ if (uids == NULL)
+ return TRUE;
+
+ expunging_uids = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ CamelMessageInfo *info;
+ CamelMessageFlags flags = 0;
+ CamelMimeMessage *message;
+ const gchar *pop3_uid;
+ const gchar *source_uid;
+
+ info = camel_folder_get_message_info (
+ folder, uids->pdata[ii]);
+
+ if (info != NULL) {
+ flags = camel_message_info_flags (info);
+ camel_folder_free_message_info (folder, info);
+ }
+
+ /* Only interested in deleted messages. */
+ if ((flags & CAMEL_MESSAGE_DELETED) == 0)
+ continue;
+
+ /* because the UID in the local store doesn't
+ * match with the UID in the pop3 store */
+ message = camel_folder_get_message_sync (
+ folder, uids->pdata[ii], cancellable, NULL);
+
+ if (message == NULL)
+ continue;
+
+ pop3_uid = camel_medium_get_header (
+ CAMEL_MEDIUM (message), "X-Evolution-POP3-UID");
+ source_uid = camel_mime_message_get_source (message);
+
+ if (pop3_uid != NULL)
+ g_hash_table_insert (
+ expunging_uids,
+ g_strstrip (g_strdup (pop3_uid)),
+ g_strstrip (g_strdup (source_uid)));
+
+ g_object_unref (message);
+ }
+
+ camel_folder_free_uids (folder, uids);
+ uids = NULL;
+
+ if (g_hash_table_size (expunging_uids) == 0) {
+ g_hash_table_destroy (expunging_uids);
+ return TRUE;
+ }
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceBackend *extension;
+ CamelFolder *folder;
+ CamelService *service;
+ CamelSettings *settings;
+ const gchar *backend_name;
+ const gchar *service_uid;
+ const gchar *source_uid;
+ gboolean any_found = FALSE;
+ gboolean delete_expunged = FALSE;
+ gboolean keep_on_server = FALSE;
+ gboolean enabled;
+
+ source_uid = e_source_get_uid (source);
+ enabled = e_source_get_enabled (source);
+
+ extension = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (extension);
+
+ if (!enabled || g_strcmp0 (backend_name, "pop") != 0)
+ continue;
+
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), source_uid);
+
+ service_uid = camel_service_get_uid (service);
+ settings = camel_service_get_settings (service);
+
+ g_object_get (
+ settings,
+ "delete-expunged", &delete_expunged,
+ "keep-on-server", &keep_on_server,
+ NULL);
+
+ if (!keep_on_server || !delete_expunged)
+ continue;
+
+ folder = camel_store_get_inbox_folder_sync (
+ CAMEL_STORE (service), cancellable, error);
+
+ /* Abort the loop on error. */
+ if (folder == NULL) {
+ success = FALSE;
+ break;
+ }
+
+ uids = camel_folder_get_uids (folder);
+
+ if (uids == NULL) {
+ g_object_unref (folder);
+ continue;
+ }
+
+ for (ii = 0; ii < uids->len; ii++) {
+ const gchar *source_uid;
+
+ source_uid = g_hash_table_lookup (
+ expunging_uids, uids->pdata[ii]);
+ if (g_strcmp0 (source_uid, service_uid) == 0) {
+ any_found = TRUE;
+ camel_folder_delete_message (
+ folder, uids->pdata[ii]);
+ }
+ }
+
+ camel_folder_free_uids (folder, uids);
+
+ if (any_found)
+ success = camel_folder_synchronize_sync (
+ folder, TRUE, cancellable, error);
+
+ g_object_unref (folder);
+
+ /* Abort the loop on error. */
+ if (!success)
+ break;
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ g_hash_table_destroy (expunging_uids);
+
+ return success;
+}
+
+gboolean
+e_mail_folder_expunge_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolder *local_inbox;
+ CamelStore *parent_store;
+ CamelService *service;
+ CamelSession *session;
+ gboolean is_local_inbox;
+ gboolean is_local_trash;
+ gboolean store_is_local;
+ gboolean success = TRUE;
+ const gchar *uid;
+
+ g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
+
+ parent_store = camel_folder_get_parent_store (folder);
+
+ service = CAMEL_SERVICE (parent_store);
+ session = camel_service_get_session (service);
+
+ uid = camel_service_get_uid (service);
+ store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
+
+ local_inbox = e_mail_session_get_local_folder (
+ E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_INBOX);
+ is_local_inbox = (folder == local_inbox);
+
+ if (store_is_local && !is_local_inbox) {
+ CamelFolder *local_trash;
+
+ local_trash = camel_store_get_trash_folder_sync (
+ parent_store, cancellable, error);
+
+ if (local_trash != NULL) {
+ is_local_trash = (folder == local_trash);
+ g_object_unref (local_trash);
+ } else {
+ return FALSE;
+ }
+ }
+
+ /* Expunge all POP3 accounts when expunging
+ * the local Inbox or Trash folder. */
+ if (is_local_inbox || is_local_trash)
+ success = mail_folder_expunge_pop3_stores (
+ folder, cancellable, error);
+
+ if (success)
+ success = camel_folder_expunge_sync (
+ folder, cancellable, error);
+
+ return success;
+}
+
+void
+e_mail_folder_expunge (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (folder), callback,
+ user_data, e_mail_folder_expunge);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_run_in_thread (
+ simple, mail_folder_expunge_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+gboolean
+e_mail_folder_expunge_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_expunge), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static void
mail_folder_build_attachment_thread (GSimpleAsyncResult *simple,
GObject *object,
GCancellable *cancellable)
diff --git a/libemail-engine/e-mail-folder-utils.h b/libemail-engine/e-mail-folder-utils.h
index 9e8dd0f050..5217f2d608 100644
--- a/libemail-engine/e-mail-folder-utils.h
+++ b/libemail-engine/e-mail-folder-utils.h
@@ -45,6 +45,18 @@ gboolean e_mail_folder_append_message_finish
gchar **appended_uid,
GError **error);
+gboolean e_mail_folder_expunge_sync (CamelFolder *folder,
+ GCancellable *cancellable,
+ GError **error);
+void e_mail_folder_expunge (CamelFolder *folder,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_mail_folder_expunge_finish (CamelFolder *folder,
+ GAsyncResult *result,
+ GError **error);
+
CamelMimePart * e_mail_folder_build_attachment_sync
(CamelFolder *folder,
GPtrArray *message_uids,