From: Chenthill Palanisamy Date: Tue, 9 Mar 2010 18:18:05 +0000 (+0530) Subject: Implement folder subscriptions - imapx X-Git-Tag: upstream/3.7.4~3282 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fefd0922d62038905afc744dba5c3a3e02ba3e51;p=platform%2Fupstream%2Fevolution-data-server.git Implement folder subscriptions - imapx --- 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