[evolution-data-server] Implement folder subscriptions - imapx



commit fefd0922d62038905afc744dba5c3a3e02ba3e51
Author: Chenthill Palanisamy <pchenthill novell com>
Date:   Tue Mar 9 23:48:05 2010 +0530

    Implement folder subscriptions - imapx

 camel/providers/imapx/camel-imapx-server.c |   82 ++++++++++++++++++++++++++
 camel/providers/imapx/camel-imapx-server.h |    2 +
 camel/providers/imapx/camel-imapx-store.c  |   86 +++++++++++++++++++++++++---
 3 files changed, 161 insertions(+), 9 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 8331c8d..cebccdd 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -182,9 +182,11 @@ enum {
 	IMAPX_JOB_NOOP = 1<<7,
 	IMAPX_JOB_IDLE = 1<<8,
 	IMAPX_JOB_LIST = 1<<9,
+	IMAPX_JOB_MANAGE_SUBSCRIPTION = 1<<10,
 };
 
 enum {
+	IMAPX_PRIORITY_MANAGE_SUBSCRIPTION = 200,
 	IMAPX_PRIORITY_GET_MESSAGE = 100,
 	IMAPX_PRIORITY_REFRESH_INFO = 0,
 	IMAPX_PRIORITY_NOOP = 0,
@@ -269,6 +271,11 @@ struct _CamelIMAPXJob {
 			guint32 flags;
 			GHashTable *folders;
 		} list;
+
+		struct {
+			const gchar *folder_name;
+			gboolean subscribe;
+		} manage_subscriptions;
 	} u;
 };
 
@@ -3123,8 +3130,64 @@ imapx_job_list_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
 	ic->complete = imapx_command_list_done;
 	imapx_command_queue(is, ic);
 }
+/* ********************************************************************** */
+
+
+static gchar *
+imapx_encode_folder_name (CamelIMAPXStore *istore, const gchar *folder_name)
+{
+	gchar *fname, *encoded;
+
+	fname = camel_imapx_store_summary_full_from_path(istore->summary, folder_name);
+	if (fname) {
+		encoded = camel_utf8_utf7(fname);
+		g_free (fname);
+	} else
+		encoded = camel_utf8_utf7 (folder_name);
+	
+	return encoded;
+}
+
+static void
+imapx_command_subscription_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 subscribing 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_manage_subscription_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+{
+	CamelIMAPXCommand *ic;
+	const gchar *str = NULL;
+	gchar *encoded_fname = NULL;
+	
+	
+	if (job->u.manage_subscriptions.subscribe)
+		str = "SUBSCRIBE";
+	else
+		str = "UNSUBSCRIBE";
+
+	encoded_fname = imapx_encode_folder_name ((CamelIMAPXStore *) is->store, job->u.manage_subscriptions.folder_name);
+	ic = camel_imapx_command_new (str, NULL, "%s %s", str, encoded_fname);
+	
+	ic->pri = job->pri;
+	ic->job = job;
+	ic->complete = imapx_command_subscription_done;
+	imapx_command_queue(is, ic);
+
+	g_free (encoded_fname);
+}
+
+/* ********************************************************************** */
+static void
 imapx_command_noop_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 {
 	if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
@@ -4175,3 +4238,22 @@ camel_imapx_server_list(CamelIMAPXServer *is, const gchar *top, guint32 flags, C
 
 	return folders;
 }
+
+void
+camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folder_name, gboolean subscribe, CamelException *ex)
+{
+	CamelIMAPXJob *job;
+	
+	job = g_malloc0(sizeof(*job));
+	job->type = IMAPX_JOB_MANAGE_SUBSCRIPTION;
+	job->start = imapx_job_manage_subscription_start;
+	job->pri = IMAPX_PRIORITY_MANAGE_SUBSCRIPTION;
+	job->ex = ex;
+	job->u.manage_subscriptions.subscribe = subscribe;
+	job->u.manage_subscriptions.folder_name = folder_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 57167d7..ae50e59 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -125,4 +125,6 @@ void camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source,
 void camel_imapx_server_append_message(CamelIMAPXServer *is, CamelFolder *folder, struct _CamelMimeMessage *message, const struct _CamelMessageInfo *mi, CamelException *ex);
 void camel_imapx_server_sync_message (CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, CamelException *ex);
 
+void camel_imapx_server_manage_subscription (CamelIMAPXServer *is, const gchar *folder_name, gboolean subscribe, 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 b2a001f..1a5ad5a 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -449,10 +449,8 @@ imapx_match_pattern(CamelIMAPXStoreNamespace *ns, const gchar *pattern, const gc
 }
 
 static void
-imapx_folder_unsubscribe_from_cache (CamelIMAPXStore *istore,
-				     const gchar *folder_name, CamelException *ex)
+imapx_unmark_folder_subscribed (CamelIMAPXStore *istore, const gchar *folder_name, gboolean emit_signal, CamelException *ex)
 {
-	CamelFolderInfo *fi;
 	CamelStoreInfo *si;
 
 	si = camel_store_summary_path((CamelStoreSummary *)istore->summary, folder_name);
@@ -465,11 +463,79 @@ imapx_folder_unsubscribe_from_cache (CamelIMAPXStore *istore,
 		camel_store_summary_info_free((CamelStoreSummary *)istore->summary, si);
 	}
 
-	/* handle rename */
+	if (emit_signal) {
+		CamelFolderInfo *fi;
 
-	fi = imapx_build_folder_info(istore, folder_name);
-	camel_object_trigger_event (CAMEL_OBJECT (istore), "folder_unsubscribed", fi);
-	camel_folder_info_free (fi);
+		fi = imapx_build_folder_info(istore, folder_name);
+		camel_object_trigger_event (CAMEL_OBJECT (istore), "folder_unsubscribed", fi);
+		camel_folder_info_free (fi);
+	}
+}
+
+static void
+imapx_mark_folder_subscribed (CamelIMAPXStore *istore, const gchar *folder_name, gboolean emit_signal, CamelException *ex)
+{
+	CamelStoreInfo *si;
+
+	si = camel_store_summary_path((CamelStoreSummary *)istore->summary, folder_name);
+	if (si) {
+		if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0) {
+			si->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+			camel_store_summary_touch((CamelStoreSummary *)istore->summary);
+			camel_store_summary_save((CamelStoreSummary *)istore->summary);
+		}
+		camel_store_summary_info_free((CamelStoreSummary *)istore->summary, si);
+	}
+	
+	if (emit_signal) {
+		CamelFolderInfo *fi;
+
+		fi = imapx_build_folder_info(istore, folder_name);
+		camel_object_trigger_event (CAMEL_OBJECT (istore), "folder_subscribed", fi);
+		camel_folder_info_free (fi);
+	}
+}
+
+static void
+imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, CamelException *ex)
+{
+	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+
+	if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+		return;
+
+	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+		camel_imapx_server_manage_subscription (istore->server, folder_name, TRUE, ex);
+
+	if (!camel_exception_is_set (ex))
+		imapx_mark_folder_subscribed (istore, folder_name, emit_signal, ex);
+}
+
+static void
+imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean emit_signal, CamelException *ex)
+{
+	CamelIMAPXStore *istore = (CamelIMAPXStore *) store;
+
+	if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+		return;
+
+	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+		camel_imapx_server_manage_subscription (istore->server, folder_name, FALSE, ex);
+	
+	if (!camel_exception_is_set (ex))
+		imapx_unmark_folder_subscribed (istore, folder_name, emit_signal, ex);
+}
+
+static void
+imapx_store_subscribe_folder (CamelStore *store, const gchar *folder_name, CamelException *ex)
+{
+	imapx_subscribe_folder (store, folder_name, TRUE, ex);
+}
+
+static void
+imapx_store_unsubscribe_folder (CamelStore *store, const gchar *folder_name, CamelException *ex)
+{
+	imapx_unsubscribe_folder (store, folder_name, TRUE, ex);
 }
 
 static void
@@ -830,7 +896,7 @@ sync_folders (CamelIMAPXStore *istore, const gchar *pattern, CamelException *ex)
 					CamelException eex;
 
 					camel_exception_init (&eex);
-					imapx_folder_unsubscribe_from_cache (istore,dup_folder_name, &eex);
+					imapx_unmark_folder_subscribed (istore,dup_folder_name, TRUE, &eex);
 					imapx_delete_folder_from_cache (istore, dup_folder_name, &eex);
 					
 					g_free (dup_folder_name);
@@ -962,6 +1028,8 @@ camel_imapx_store_class_init(CamelIMAPXStoreClass *klass)
 	camel_store_class->create_folder = imapx_create_folder;
 	camel_store_class->rename_folder = imapx_rename_folder;
 	camel_store_class->delete_folder = imapx_delete_folder;
+	camel_store_class->subscribe_folder = imapx_store_subscribe_folder;
+	camel_store_class->unsubscribe_folder = imapx_store_unsubscribe_folder;
 	camel_store_class->get_folder_info = imapx_get_folder_info;
 	camel_store_class->folder_subscribed = imapx_folder_subscribed;
 	camel_store_class->free_folder_info = camel_store_free_folder_info_full;
@@ -975,7 +1043,7 @@ camel_imapx_store_init (gpointer object, gpointer klass)
 {
 	CamelStore *store = (CamelStore *) object;
 
-	store->flags |= CAMEL_STORE_ASYNC;
+	store->flags |= CAMEL_STORE_ASYNC | CAMEL_STORE_SUBSCRIPTIONS;
 }
 
 static void



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