[evolution-ews] Bug #654543 - Mark as junk doesn't work



commit 42cd667bdd00b958bdf507bcaca8b3052421efcb
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jun 6 17:15:54 2012 +0200

    Bug #654543 - Mark as junk doesn't work

 src/camel/camel-ews-folder.c |  134 ++++++++++++++++++++++++++++++++++++------
 src/camel/camel-ews-store.c  |   33 ++++++++--
 2 files changed, 142 insertions(+), 25 deletions(-)
---
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index 7d0e1fd..445b8f6 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -91,8 +91,8 @@ struct _CamelEwsFolderPrivate {
 
 extern gint camel_application_is_exiting;
 
-static gboolean
-ews_delete_messages (CamelFolder *folder, GSList *deleted_items, gboolean expunge, GCancellable *cancellable, GError **error);
+static gboolean ews_delete_messages (CamelFolder *folder, GSList *deleted_items, gboolean expunge, GCancellable *cancellable, GError **error);
+static gboolean ews_refresh_info_sync (CamelFolder *folder, GCancellable *cancellable, GError **error);
 
 #define d(x)
 
@@ -794,11 +794,12 @@ ews_sync_mi_flags (CamelFolder *folder,
 }
 
 static gboolean
-ews_folder_is_trash (CamelFolder *folder)
+ews_folder_is_of_type (CamelFolder *folder,
+		       guint32 folder_type)
 {
 	CamelStore *parent_store;
 	CamelEwsStore *ews_store;
-	gboolean is_deleted_items;
+	gboolean is_of_type;
 	gchar *folder_id;
 
 	g_return_val_if_fail (folder != NULL, FALSE);
@@ -808,12 +809,94 @@ ews_folder_is_trash (CamelFolder *folder)
 
 	g_return_val_if_fail (ews_store != NULL, FALSE);
 
+	folder_type = folder_type & CAMEL_FOLDER_TYPE_MASK;
 	folder_id = camel_ews_store_summary_get_folder_id_from_name (ews_store->summary, camel_folder_get_full_name (folder));
-	is_deleted_items = folder_id &&
-		(camel_ews_store_summary_get_folder_flags (ews_store->summary, folder_id, NULL) & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH;
+	is_of_type = folder_id &&
+		(camel_ews_store_summary_get_folder_flags (ews_store->summary, folder_id, NULL) & CAMEL_FOLDER_TYPE_MASK) == folder_type;
 	g_free (folder_id);
 
-	return is_deleted_items;
+	return is_of_type;
+}
+
+static gboolean
+ews_move_to_junk_folder (CamelFolder *folder,
+			 GSList *junk_uids,
+			 GCancellable *cancellable,
+			 GError **error)
+{
+	CamelEwsFolder *ews_folder;
+	CamelStore *parent_store;
+	CamelEwsStore *ews_store;
+	EEwsConnection *cnc;
+	gboolean status = TRUE;
+
+	if (ews_folder_is_of_type (folder, CAMEL_FOLDER_TYPE_JUNK)) {
+		/* cannot move to itself, but treat it as success */
+		g_slist_free_full (junk_uids, (GDestroyNotify) camel_pstring_free);
+		return TRUE;
+	}
+
+	ews_store = CAMEL_EWS_STORE (camel_folder_get_parent_store (folder));
+	cnc = camel_ews_store_get_connection (ews_store);
+
+	parent_store = camel_folder_get_parent_store (folder);
+	ews_folder = CAMEL_EWS_FOLDER (folder);
+	ews_store = CAMEL_EWS_STORE (parent_store);
+
+	cnc = camel_ews_store_get_connection (ews_store);
+
+	if (junk_uids) {
+		GSList *moved_items = NULL;
+		GError *local_error = NULL;
+		gchar *folder_id;
+
+		folder_id = camel_ews_store_summary_get_folder_id_from_folder_type (
+			ews_store->summary, CAMEL_FOLDER_TYPE_JUNK);
+
+		status = e_ews_connection_move_items_sync (cnc, EWS_PRIORITY_MEDIUM, folder_id, FALSE,
+			junk_uids, &moved_items, cancellable, &local_error);
+
+		if (!status && local_error && local_error->code == EWS_CONNECTION_ERROR_ITEMNOTFOUND) {
+			/* If move failed due to the item not found, ignore the error,
+			 * trigger folder info refresh and then go on to clear the
+			 * cache of the remove items anyway. */
+			g_clear_error (&local_error);
+			status = ews_refresh_info_sync (folder, cancellable, &local_error);
+		}
+
+		g_slist_free_full (moved_items, g_object_unref);
+		g_free (folder_id);
+
+		if (status) {
+			CamelFolderChangeInfo *changes;
+			GSList *iter;
+
+			changes = camel_folder_change_info_new ();
+
+			for (iter = junk_uids; iter; iter = g_slist_next (iter)) {
+				const gchar *uid = iter->data;
+
+				camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+				camel_folder_change_info_remove_uid (changes, uid);
+				camel_folder_summary_remove_uid (folder->summary, uid);
+				ews_data_cache_remove (ews_folder->cache, "cur", uid, NULL);
+
+				camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+			}
+
+			if (camel_folder_change_info_changed (changes))
+				camel_folder_changed (folder, changes);
+			camel_folder_change_info_free (changes);
+		}
+
+		if (local_error)
+			g_propagate_error (error, local_error);
+
+		g_slist_free_full (junk_uids, (GDestroyNotify) camel_pstring_free);
+	}
+
+	return status;
 }
 
 static gboolean
@@ -824,7 +907,7 @@ ews_synchronize_sync (CamelFolder *folder,
 {
 	CamelEwsStore *ews_store;
 	GPtrArray *uids;
-	GSList *mi_list = NULL, *deleted_uids = NULL;
+	GSList *mi_list = NULL, *deleted_uids = NULL, *junk_uids = NULL;
 	gint mi_list_len = 0;
 	gboolean success = TRUE;
 	gint i;
@@ -834,7 +917,8 @@ ews_synchronize_sync (CamelFolder *folder,
 	if (!camel_ews_store_connected (ews_store, error))
 		return FALSE;
 
-	if (camel_folder_summary_get_deleted_count (folder->summary) > 0) {
+	if (camel_folder_summary_get_deleted_count (folder->summary) > 0 ||
+	    camel_folder_summary_get_junk_count (folder->summary) > 0) {
 		camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
 		uids = camel_folder_summary_get_array (folder->summary);
 	} else {
@@ -846,12 +930,13 @@ ews_synchronize_sync (CamelFolder *folder,
 	}
 
 	for (i = 0; success && i < uids->len; i++) {
-		guint32 flags_changed;
+		guint32 flags_changed, flags_set;
 		CamelEwsMessageInfo *mi = (gpointer) camel_folder_summary_get (folder->summary, uids->pdata[i]);
 		if (!mi)
 			continue;
 
-		flags_changed = mi->server_flags ^ mi->info.flags;
+		flags_set = camel_message_info_flags (mi);
+		flags_changed = mi->server_flags ^ flags_set;
 
 		/* Exchange doesn't seem to have a sane representation
 		 * for most flags â not even replied/forwarded. */
@@ -859,12 +944,17 @@ ews_synchronize_sync (CamelFolder *folder,
 			mi_list = g_slist_append (mi_list, mi);
 			mi_list_len++;
 
-			if (flags_changed & CAMEL_MESSAGE_DELETED)
+			if (flags_set & CAMEL_MESSAGE_DELETED)
 				deleted_uids = g_slist_prepend (deleted_uids, (gpointer) camel_pstring_strdup (uids->pdata[i]));
-		} else if (flags_changed & CAMEL_MESSAGE_DELETED) {
+			else if (flags_set & CAMEL_MESSAGE_JUNK)
+				junk_uids = g_slist_prepend (junk_uids, (gpointer) camel_pstring_strdup (uids->pdata[i]));
+		} else if (flags_set & CAMEL_MESSAGE_DELETED) {
 			deleted_uids = g_slist_prepend (deleted_uids, (gpointer) camel_pstring_strdup (uids->pdata[i]));
 			camel_message_info_free (mi);
-		} else if (mi->info.dirty || (mi->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
+		} else if (flags_set & CAMEL_MESSAGE_JUNK) {
+			junk_uids = g_slist_prepend (junk_uids, (gpointer) camel_pstring_strdup (uids->pdata[i]));
+			camel_message_info_free (mi);
+		} else if (mi->info.dirty || (flags_set & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
 			/* OK, the change must have been the labels */
 			mi_list = g_slist_append (mi_list, mi);
 			mi_list_len++;
@@ -882,8 +972,15 @@ ews_synchronize_sync (CamelFolder *folder,
 	if (mi_list_len)
 		success = ews_sync_mi_flags (folder, mi_list, cancellable, error);
 
-	if (deleted_uids)
-		success = ews_delete_messages (folder, deleted_uids, ews_folder_is_trash (folder), cancellable, error);
+	if (deleted_uids && success)
+		success = ews_delete_messages (folder, deleted_uids, ews_folder_is_of_type (folder, CAMEL_FOLDER_TYPE_TRASH), cancellable, error);
+	else
+		g_slist_free_full (deleted_uids, (GDestroyNotify) camel_pstring_free);
+
+	if (junk_uids && success)
+		success = ews_move_to_junk_folder (folder, junk_uids, cancellable, error);
+	else
+		g_slist_free_full (junk_uids, (GDestroyNotify) camel_pstring_free);
 
 	camel_folder_summary_save_to_db (folder->summary, NULL);
 	camel_folder_summary_free_array (uids);
@@ -1364,6 +1461,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 			dst_id, !delete_originals,
 			ids, &ret_items,
 			cancellable, &rerror)) {
+
 		if (delete_originals) {
 			changes = camel_folder_change_info_new ();
 			for (i = 0; i < uids->len; i++) {
@@ -1385,7 +1483,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 
 	g_object_unref (cnc);
 	g_slist_free (ids);
-	g_slist_free (ret_items);
+	g_slist_free_full (ret_items, g_object_unref);
 
 	return !rerror;
 }
@@ -1477,7 +1575,7 @@ ews_expunge_sync (CamelFolder *folder,
 	if (!camel_ews_store_connected (ews_store, error))
 		return FALSE;
 
-	is_trash = ews_folder_is_trash (folder);
+	is_trash = ews_folder_is_of_type (folder, CAMEL_FOLDER_TYPE_TRASH);
 
 	camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
 	known_uids = camel_folder_summary_get_array (folder->summary);
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 859c854..ed4b3fe 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -170,6 +170,7 @@ ews_store_construct (CamelService *service,
 	/* Disable virtual trash and junk folders. Exchange has real
 	 * folders for that */
 	((CamelStore *) ews_store)->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK);
+	((CamelStore *) ews_store)->flags |= CAMEL_STORE_REAL_JUNK_FOLDER;
 
 	/*storage path*/
 	session_storage_path = g_strdup (camel_service_get_user_cache_dir (service));
@@ -1008,30 +1009,47 @@ camel_ews_store_get_connection (CamelEwsStore *ews_store)
 }
 
 static CamelFolder *
-ews_get_trash_folder_sync (CamelStore *store,
-                           GCancellable *cancellable,
-                           GError **error)
+ews_get_folder_by_type_sync (CamelStore *store,
+			     guint32 folder_type,
+			     GCancellable *cancellable,
+                             GError **error)
 {
 	CamelEwsStore *ews_store;
-	CamelFolder *trash = NULL;
+	CamelFolder *folder = NULL;
 	gchar *folder_id, *folder_name;
 
 	g_return_val_if_fail (CAMEL_IS_EWS_STORE (store), NULL);
 
 	ews_store = CAMEL_EWS_STORE (store);
-	folder_id = camel_ews_store_summary_get_folder_id_from_folder_type (ews_store->summary, CAMEL_FOLDER_TYPE_TRASH);
+	folder_id = camel_ews_store_summary_get_folder_id_from_folder_type (ews_store->summary, folder_type);
 
 	if (!folder_id)
 		return NULL;
 
 	folder_name = camel_ews_store_summary_get_folder_full_name (ews_store->summary, folder_id, NULL);
 
-	trash = ews_get_folder_sync (store, folder_name, 0, cancellable, error);
+	folder = ews_get_folder_sync (store, folder_name, 0, cancellable, error);
 
 	g_free (folder_name);
 	g_free (folder_id);
 
-	return trash;
+	return folder;
+}
+
+static CamelFolder *
+ews_get_trash_folder_sync (CamelStore *store,
+                           GCancellable *cancellable,
+                           GError **error)
+{
+	return ews_get_folder_by_type_sync (store, CAMEL_FOLDER_TYPE_TRASH, cancellable, error);
+}
+
+static CamelFolder *
+ews_get_junk_folder_sync (CamelStore *store,
+                          GCancellable *cancellable,
+                          GError **error)
+{
+	return ews_get_folder_by_type_sync (store, CAMEL_FOLDER_TYPE_JUNK, cancellable, error);
 }
 
 static gboolean
@@ -1134,6 +1152,7 @@ camel_ews_store_class_init (CamelEwsStoreClass *class)
 	store_class->free_folder_info = camel_store_free_folder_info_full;
 
 	store_class->get_trash_folder_sync = ews_get_trash_folder_sync;
+	store_class->get_junk_folder_sync = ews_get_junk_folder_sync;
 	store_class->can_refresh_folder = ews_can_refresh_folder;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]