Implement folder subscriptions - imapx
authorChenthill Palanisamy <pchenthill@novell.com>
Tue, 9 Mar 2010 18:18:05 +0000 (23:48 +0530)
committerChenthill Palanisamy <pchenthill@novell.com>
Tue, 9 Mar 2010 18:18:41 +0000 (23:48 +0530)
camel/providers/imapx/camel-imapx-server.c
camel/providers/imapx/camel-imapx-server.h
camel/providers/imapx/camel-imapx-store.c

index 8331c8d..cebccdd 100644 (file)
@@ -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);
+}
index 57167d7..ae50e59 100644 (file)
@@ -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 */
index b2a001f..1a5ad5a 100644 (file)
@@ -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