[evolution-data-server] Bug 611775 - IMAPX : support for folder rename



commit d5e6beaa8112273ff1f6ed5a844e701dad51519f
Author: Chenthill Palanisamy <pchenthill novell com>
Date:   Wed Mar 24 16:07:17 2010 +0530

    Bug 611775 - IMAPX : support for folder rename

 camel/providers/imapx/camel-imapx-server.c |   62 +++++++++++++++++++++
 camel/providers/imapx/camel-imapx-server.h |    1 +
 camel/providers/imapx/camel-imapx-store.c  |   81 +++++++++++++++++++++++++++-
 3 files changed, 143 insertions(+), 1 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 22d5ab1..ddb75ec 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -185,6 +185,7 @@ enum {
 	IMAPX_JOB_MANAGE_SUBSCRIPTION = 1<<10,
 	IMAPX_JOB_CREATE_FOLDER = 1<<11,
 	IMAPX_JOB_DELETE_FOLDER = 1<<12,
+	IMAPX_JOB_RENAME_FOLDER = 1<<13,
 };
 
 /* Operations on the store (folder_tree) will have highest priority as we know for sure they are sync
@@ -192,6 +193,7 @@ enum {
 enum {
 	IMAPX_PRIORITY_CREATE_FOLDER = 200,
 	IMAPX_PRIORITY_DELETE_FOLDER = 200,
+	IMAPX_PRIORITY_RENAME_FOLDER = 200,
 	IMAPX_PRIORITY_MANAGE_SUBSCRIPTION = 200,
 	IMAPX_PRIORITY_SYNC_CHANGES = 150,
 	IMAPX_PRIORITY_EXPUNGE = 150,
@@ -283,6 +285,11 @@ struct _CamelIMAPXJob {
 			gboolean subscribe;
 		} manage_subscriptions;
 
+		struct {
+			const gchar *ofolder_name;
+			const gchar *nfolder_name;
+		} rename_folder;
+		
 		const gchar *folder_name;
 	} u;
 };
@@ -3359,6 +3366,41 @@ imapx_job_delete_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
 
 /* ********************************************************************** */
 
+	static void
+imapx_command_rename_folder_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+{
+	if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
+		if (!camel_exception_is_set (ic->ex))
+			camel_exception_setv(ic->job->ex, 1, "Error renaming to folder : %s", ic->status->text);
+		else
+			camel_exception_xfer (ic->job->ex, ic->ex);
+	}
+
+	imapx_job_done (is, ic->job);
+	camel_imapx_command_free (ic);
+}
+
+static void
+imapx_job_rename_folder_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+{
+	CamelIMAPXCommand *ic;
+	gchar *en_ofname = NULL, *en_nfname = NULL;
+
+	en_ofname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.ofolder_name);
+	en_nfname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.rename_folder.nfolder_name);
+	
+	ic = camel_imapx_command_new ("RENAME", "INBOX", "RENAME %s %s", en_ofname, en_nfname);
+	ic->pri = job->pri;
+	ic->job = job;
+	ic->complete = imapx_command_rename_folder_done;
+	imapx_command_queue(is, ic);
+
+	g_free (en_ofname);
+	g_free (en_nfname);
+}
+
+/* ********************************************************************** */
+
 static void
 imapx_command_noop_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 {
@@ -4508,3 +4550,23 @@ camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name
 
 	g_free (job);
 }
+
+void
+camel_imapx_server_rename_folder (CamelIMAPXServer *is, const gchar *old_name, const gchar *new_name, CamelException *ex)
+{
+	CamelIMAPXJob *job;
+	
+	job = g_malloc0(sizeof(*job));
+	job->type = IMAPX_JOB_RENAME_FOLDER;
+	job->start = imapx_job_rename_folder_start;
+	job->pri = IMAPX_PRIORITY_RENAME_FOLDER;
+	job->ex = ex;
+	job->u.rename_folder.ofolder_name = old_name;
+	job->u.rename_folder.nfolder_name = new_name;
+
+	if (imapx_register_job (is, job))
+		imapx_run_job (is, job);
+
+	g_free (job);
+
+}
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index 8573d66..037d653 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -132,5 +132,6 @@ void camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder,
 void camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folder_name, gboolean subscribe, CamelException *ex);
 void camel_imapx_server_create_folder (CamelIMAPXServer *is, const gchar *folder_name, CamelException *ex);
 void camel_imapx_server_delete_folder (CamelIMAPXServer *is, const gchar *folder_name, CamelException *ex);
+void camel_imapx_server_rename_folder (CamelIMAPXServer *is, const gchar *old_name, const gchar *new_name, CamelException *ex);
 
 #endif /* _CAMEL_IMAPX_SERVER_H */
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 68bfbb0..9d082cb 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -628,10 +628,89 @@ imapx_delete_folder (CamelStore *store, const gchar *folder_name, CamelException
 		imapx_delete_folder_from_cache (istore, folder_name, ex);
 }
 
+
+static void
+rename_folder_info (CamelIMAPXStore *istore, const gchar *old_name, const gchar *new_name, CamelException *ex)
+{
+	gint i, count;
+	CamelStoreInfo *si;
+	gint olen = strlen(old_name);
+	const gchar *path;
+	gchar *npath, *nfull;
+
+	count = camel_store_summary_count((CamelStoreSummary *)istore->summary);
+	for (i=0;i<count;i++) {
+		si = camel_store_summary_index((CamelStoreSummary *)istore->summary, i);
+		if (si == NULL)
+			continue;
+		path = camel_store_info_path(istore->summary, si);
+		if (strncmp(path, old_name, olen) == 0) {
+			if (strlen(path) > olen)
+				npath = g_strdup_printf("%s/%s", new_name, path+olen+1);
+			else
+				npath = g_strdup(new_name);
+			nfull = camel_imapx_store_summary_path_to_full(istore->summary, npath, istore->dir_sep);
+
+			/* workaround for broken server (courier uses '.') that doesn't rename
+			   subordinate folders as required by rfc 2060 */
+			if (istore->dir_sep == '.') {
+				camel_imapx_server_rename_folder (istore->server, path, nfull, ex);
+			}
+
+			camel_store_info_set_string((CamelStoreSummary *)istore->summary, si, CAMEL_STORE_INFO_PATH, npath);
+			camel_store_info_set_string((CamelStoreSummary *)istore->summary, si, CAMEL_IMAPX_STORE_INFO_FULL_NAME, nfull);
+
+			camel_store_summary_touch((CamelStoreSummary *)istore->summary);
+			g_free(nfull);
+			g_free(npath);
+		}
+		camel_store_summary_info_free((CamelStoreSummary *)istore->summary, si);
+	}
+}
+
 static void
 imapx_rename_folder (CamelStore *store, const gchar *old, const gchar *new, CamelException *ex)
 {
-	camel_exception_setv(ex, 1, "rename_folder::unimplemented");
+	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+	gchar *oldpath, *newpath, *storage_path;
+
+
+	if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+				     _("You must be working online to complete this operation"));
+		return;
+	}
+
+	if (istore->rec_options & IMAPX_SUBSCRIPTIONS)
+		imapx_unsubscribe_folder (store, old, FALSE, ex);
+
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
+		camel_imapx_server_rename_folder (istore->server, old, new, ex);
+
+	if (camel_exception_is_set (ex)) {
+		imapx_subscribe_folder (store, old, FALSE, ex);
+		return;
+	}
+
+	/* rename summary, and handle broken server */
+	rename_folder_info(istore, old, new, ex);
+
+	if (istore->rec_options & IMAPX_SUBSCRIPTIONS)
+		imapx_subscribe_folder (store, new, FALSE, ex);
+
+	storage_path = g_strdup_printf("%s/folders", istore->storage_path);
+	oldpath = imapx_path_to_physical (storage_path, old);
+	newpath = imapx_path_to_physical (storage_path, new);
+	g_free(storage_path);
+
+	/* So do we care if this didn't work?  Its just a cache? */
+	if (g_rename (oldpath, newpath) == -1) {
+		g_warning ("Could not rename message cache '%s' to '%s': %s: cache reset",
+			   oldpath, newpath, g_strerror (errno));
+	}
+
+	g_free (oldpath);
+	g_free (newpath);
 }
 
 static CamelFolderInfo *



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