[evolution-data-server] Sync up the store summary and rename labels for backward, thunderbird



commit 0057115981a8d6ce407a0e2f4749eff77989dff8
Author: Chenthill Palanisamy <pchenthill novell com>
Date:   Mon Dec 7 14:27:37 2009 +0530

    Sync up the store summary and rename labels for backward, thunderbird
    compatibility - imapx

 camel/providers/imapx/camel-imapx-server.c |  105 +++++++++++++++++++++++++---
 camel/providers/imapx/camel-imapx-store.c  |    3 +-
 camel/providers/imapx/camel-imapx-stream.c |    1 -
 camel/providers/imapx/camel-imapx-utils.c  |   50 ++++++++++++-
 camel/providers/imapx/test-imapx.c         |    2 +-
 5 files changed, 143 insertions(+), 18 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 38f250d..baf5b63 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -937,6 +937,40 @@ imapx_expunged(CamelIMAPXServer *imap)
 	g_array_set_size(imap->expunged, 0); */
 }
 
+static void
+update_summary (CamelFolderSummary *summary, CamelMessageInfoBase *info)
+{
+	gint unread=0, deleted=0, junk=0;
+	guint32 flags = info->flags;
+
+	if (!(flags & CAMEL_MESSAGE_SEEN))
+		unread = 1;
+
+	if (flags & CAMEL_MESSAGE_DELETED)
+		deleted = 1;
+
+	if (flags & CAMEL_MESSAGE_JUNK)
+		junk = 1;
+
+	if (summary) {
+
+		if (unread)
+			summary->unread_count += unread;
+		if (deleted)
+			summary->deleted_count += deleted;
+		if (junk)
+			summary->junk_count += junk;
+		if (junk && !deleted)
+			summary->junk_not_deleted_count += junk;
+		summary->visible_count++;
+		if (junk ||  deleted)
+			summary->visible_count -= junk ? junk : deleted;
+
+		summary->saved_count++;
+		camel_folder_summary_touch(summary);
+	}
+}
+
 /* handle any untagged responses */
 static gint
 imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
@@ -1091,6 +1125,7 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
 					
 					if (!camel_folder_summary_check_uid (job->folder->summary, mi->uid)) {
 						camel_folder_summary_add(job->folder->summary, mi);
+						update_summary (job->folder->summary, (CamelMessageInfoBase *) mi);
 						camel_folder_change_info_add_uid (job->u.refresh_info.changes, mi->uid);
 					} 
 				}
@@ -1348,7 +1383,7 @@ imapx_step(CamelIMAPXServer *is, CamelException *ex)
 	else if (tok == '+')
 		imapx_continuation(is, ex);
 	else
-		camel_exception_setv (ex, 1, "unexpected server response: %s", token);
+		camel_exception_set (ex, 1, "unexpected server response:");
 }
 
 /* Used to run 1 command synchronously,
@@ -1364,7 +1399,7 @@ imapx_command_run(CamelIMAPXServer *is, CamelIMAPXCommand *ic, CamelException *e
 	QUEUE_UNLOCK(is);
 	do {
 		imapx_step(is, ex);
-	} while (ic->status == NULL);
+	} while (ic->status == NULL && !camel_exception_is_set (ex));
 
 	camel_dlist_remove((CamelDListNode *)ic);
 }
@@ -1561,6 +1596,11 @@ imapx_connect(CamelIMAPXServer *is, gint ssl_mode, gint try_starttls, CamelExcep
 	imapx_command_run(is, ic, ex);
 	camel_imapx_command_free(ic);
 
+	if (camel_exception_is_set (ex)) {
+		g_message ("Unable to connect %d %s \n", ex->id, ex->desc);
+		return;
+	}
+	
 	/* Fetch namespaces */
 	if (is->cinfo->capa & IMAP_CAPABILITY_NAMESPACE) {
 		ic = camel_imapx_command_new ("NAMESPACE", NULL, "NAMESPACE");
@@ -1871,13 +1911,33 @@ imapx_index_next (CamelFolderSummary *s, guint index)
 }
 
 static void
+update_store_summary (CamelFolder *folder, CamelException *ex)
+{
+	CamelStoreInfo *si;
+
+	si = camel_store_summary_path ((CamelStoreSummary *) ((CamelIMAPXStore *) folder->parent_store)->summary, folder->full_name);
+	if (si) {
+		guint32 unread, total;
+
+		camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &total, CAMEL_FOLDER_UNREAD, &unread, NULL);
+		if (si->unread != unread || si->total != total) {
+			si->unread = unread;
+			si->total = total;
+			
+			g_message ("Unread count is %d \n", unread);
+			camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) folder->parent_store)->summary);
+			camel_store_summary_save ((CamelStoreSummary *)((CamelIMAPXStore *) folder->parent_store)->summary);
+		}
+	}
+}
+
+static void
 imapx_job_refresh_info_step_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 {
 	CamelIMAPXJob *job = ic->job;
 	gint i = job->u.refresh_info.index;
 	GArray *infos = job->u.refresh_info.infos;
 
-	g_usleep (100000);
 	if (camel_folder_change_info_changed(job->u.refresh_info.changes))
 		camel_object_trigger_event(job->folder, "folder_changed", job->u.refresh_info.changes);
 	camel_folder_change_info_clear(job->u.refresh_info.changes);
@@ -1911,6 +1971,7 @@ imapx_job_refresh_info_step_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		}
 	}
 
+	update_store_summary (job->folder, job->ex);
 	camel_folder_summary_save_to_db (job->folder->summary, NULL);
 	for (i=0;i<infos->len;i++) {
 		struct _refresh_info *r = &g_array_index(infos, struct _refresh_info, i);
@@ -1945,6 +2006,7 @@ imapx_uid_cmp(gconstpointer ap, gconstpointer bp, gpointer data)
 	return strcmp(ae, be);
 }
 
+
 static void
 imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 {
@@ -1975,6 +2037,7 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		total = camel_folder_summary_count (s);
 		s_minfo = camel_folder_summary_index (s, 0);
 
+		camel_folder_freeze (job->folder);
 		for (i=0; i<infos->len; i++) {
 			struct _refresh_info *r = &g_array_index(infos, struct _refresh_info, i);
 
@@ -1992,8 +2055,9 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 			if (s_minfo && uid_cmp(s_minfo->uid, r->uid, s) == 0) {
 				info = (CamelIMAPXMessageInfo *)s_minfo;
 				if (info->server_flags !=  r->server_flags
-				    && camel_message_info_set_flags((CamelMessageInfo *)info, info->server_flags ^ r->server_flags, r->server_flags))
+				    && camel_message_info_set_flags((CamelMessageInfo *)info, info->server_flags ^ r->server_flags, r->server_flags)) 
 					camel_folder_change_info_change_uid (job->u.refresh_info.changes, camel_message_info_uid (s_minfo));
+				
 				g_free(r->uid);
 				r->uid = NULL;
 			} else 
@@ -2022,11 +2086,14 @@ imapx_job_refresh_info_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 		}
 
 		camel_db_delete_uids (is->store->cdb_w, s->folder->full_name, removed, NULL);
+		update_store_summary (job->folder, job->ex);
+		camel_folder_thaw (job->folder);
 
 		if (camel_folder_change_info_changed(job->u.refresh_info.changes))
 			camel_object_trigger_event(job->folder, "folder_changed", job->u.refresh_info.changes);
 		camel_folder_change_info_clear(job->u.refresh_info.changes);
 
+
 		/* If we have any new messages, download their headers, but only a few (100?) at a time */
 		if (fetch_new) {
 			imapx_uidset_init(&job->u.refresh_info.uidset, 500, 0);
@@ -2146,12 +2213,32 @@ imapx_job_sync_changes_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 				info->server_flags = ((CamelMessageInfoBase *)info)->flags & CAMEL_IMAPX_SERVER_FLAGS;
 				info->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
 				info->info.dirty = TRUE;
+			
+				camel_folder_summary_touch (job->folder->summary);
 
 				/* FIXME: move over user flags too */
 			}
 		}
 
-		camel_folder_summary_touch (job->folder->summary);
+		if (job->folder->summary && (job->folder->summary->flags & CAMEL_SUMMARY_DIRTY) != 0) {
+			CamelStoreInfo *si;
+
+			/* ... and store's summary when folder's summary is dirty */
+			si = camel_store_summary_path ((CamelStoreSummary *)((CamelIMAPXStore *) job->folder->parent_store)->summary, job->folder->full_name);
+			if (si) {
+				if (si->total != job->folder->summary->saved_count || si->unread != job->folder->summary->unread_count) {
+					si->total = job->folder->summary->saved_count;
+					si->unread = job->folder->summary->unread_count;
+					camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) job->folder->parent_store)->summary);
+				}
+
+				camel_store_summary_info_free ((CamelStoreSummary *)((CamelIMAPXStore *) job->folder->parent_store)->summary, si);
+			}
+		}
+
+		camel_folder_summary_save_to_db (job->folder->summary, job->ex);
+		camel_store_summary_save((CamelStoreSummary *)((CamelIMAPXStore *) job->folder->parent_store)->summary);
+
 		camel_dlist_remove((CamelDListNode *)job);
 		camel_msgport_reply((CamelMsg *)job);
 	}
@@ -2313,8 +2400,6 @@ imapx_server_loop(gpointer d)
 			PRPollDesc pollfds[2] = { };
 			gint res;
 
-			printf("\nGoing to sleep waiting for work to do\n\n");
-
 			pollfds[0].fd = camel_tcp_stream_ssl_sockfd((CamelTcpStreamSSL *)is->stream->source);
 			pollfds[0].in_flags = PR_POLL_READ;
 			pollfds[1].fd = camel_msgport_prfd(is->port);
@@ -2325,15 +2410,13 @@ imapx_server_loop(gpointer d)
 			if (res == -1)
 				sleep(1) /* ?? */ ;
 			else if ((pollfds[0].out_flags & PR_POLL_READ)) {
-				printf(" * woken * have data ready\n");
 				do {
 					/* This is quite shitty, it will often block on each
 					   part of the decode, causing significant
 					   processing delays. */
 					imapx_step(is, &ex);
-				} while (camel_imapx_stream_buffered(is->stream));
+				} while (camel_imapx_stream_buffered(is->stream) && !camel_exception_is_set (&ex));
 			} else if (pollfds[1].out_flags & PR_POLL_READ) {
-				printf(" * woken * have new job\n");
 				/* job is handled in main loop */
 			}
 		}
@@ -2356,7 +2439,7 @@ imapx_server_loop(gpointer d)
 			else if (fds[0].revents & POLLIN) {
 				do {
 					imapx_step(is, &ex);
-				} while (camel_imapx_stream_buffered(is->stream));
+				} while (camel_imapx_stream_buffered(is->stream) && !camel_exception_is_set (&ex));
 			}
 		}
 #endif
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index e9c478e..9797eef 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -819,8 +819,7 @@ imapx_get_folder_info(CamelStore *store, const gchar *top, guint32 flags, CamelE
 		return fi;
 	}
 
-	camel_service_connect((CamelService *)store, ex);
-	if (camel_exception_is_set(ex))
+	if (!camel_service_connect((CamelService *)store, ex))
 		return NULL;
 
 	if (camel_store_summary_count ((CamelStoreSummary *) istore->summary) == 0) {
diff --git a/camel/providers/imapx/camel-imapx-stream.c b/camel/providers/imapx/camel-imapx-stream.c
index c4ca5f3..bcc9e80 100644
--- a/camel/providers/imapx/camel-imapx-stream.c
+++ b/camel/providers/imapx/camel-imapx-stream.c
@@ -614,7 +614,6 @@ camel_imapx_stream_token(CamelIMAPXStream *is, guchar **data, guint *len, CamelE
 
 	/* Had an i/o erorr */
 io_error:
-	printf("Got io error\n");
 	camel_exception_set (ex, 1, "io error");
 	return IMAP_TOK_ERROR;
 
diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c
index e66dede..088fbbe 100644
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@ -37,6 +37,7 @@ imap_tokenise (register const gchar *str, register guint len)
 }
 
 static void imapx_namespace_clear (CamelIMAPXStoreNamespace **ns);
+static const gchar * rename_label_flag (const gchar *flag, gint len, gboolean server_to_evo);
 
 /* flag table */
 static struct {
@@ -80,8 +81,12 @@ imap_parse_flags(CamelIMAPXStream *stream, guint32 *flagsp, CamelFlag **user_fla
 						flags |= flag_table[i].flag;
 						goto found;
 					}
-				if (user_flagsp)
-					camel_flag_set(user_flagsp, (gchar *)token, TRUE);
+				if (user_flagsp) {
+					const char *flag_name = rename_label_flag ((gchar *) token, strlen ((gchar *) token), TRUE);
+					
+					camel_flag_set(user_flagsp, flag_name, TRUE);
+					
+				}
 			found:
 				tok = tok; /* fixes stupid warning */
 			} else if (tok != ')') {
@@ -97,6 +102,42 @@ imap_parse_flags(CamelIMAPXStream *stream, guint32 *flagsp, CamelFlag **user_fla
 	*flagsp = flags;
 }
 
+
+/*
+ * rename_flag
+ * Converts label flag name on server to name used in Evolution or back.
+ * if the flags does not match returns the original one as it is.
+ * It will never return NULL, it will return empty string, instead.
+ *
+ * @param flag Flag to rename.
+ * @param len Length of the flag name.
+ * @param server_to_evo if TRUE, then converting server names to evo's names, if FALSE then opposite.
+ */
+static const gchar *
+rename_label_flag (const gchar *flag, gint len, gboolean server_to_evo)
+{
+	gint i;
+	const gchar *labels[] = {
+		"$Label1", "$Labelimportant",
+		"$Label2", "$Labelwork",
+		"$Label3", "$Labelpersonal",
+		"$Label4", "$Labeltodo",
+		"$Label5", "$Labellater",
+		NULL,      NULL };
+
+	/* It really can pass zero-length flags inside, in that case it was able
+	   to always add first label, which is definitely wrong. */
+	if (!len || !flag || !*flag)
+		return "";
+
+	for (i = 0 + (server_to_evo ? 0 : 1); labels[i]; i = i + 2) {
+		if (!g_ascii_strncasecmp (flag, labels[i], len))
+			return labels [i + (server_to_evo ? 1 : -1)];
+	}
+
+	return flag;
+}
+
 void
 imap_write_flags(CamelStream *stream, guint32 flags, CamelFlag *user_flags, CamelException *ex)
 /* throws IO exception */
@@ -125,7 +166,10 @@ imap_write_flags(CamelStream *stream, guint32 flags, CamelFlag *user_flags, Came
 	}
 
 	while (user_flags) {
-		if (camel_stream_write(stream, user_flags->name, strlen(user_flags->name)) == -1) {
+		const char *flag_name = rename_label_flag (user_flags->name, strlen (user_flags->name), FALSE);
+		
+		
+		if (camel_stream_write(stream, flag_name, strlen (flag_name)) == -1) {
 			camel_exception_setv (ex, 1, "io error: %s", strerror(errno));
 			return;
 		}
diff --git a/camel/providers/imapx/test-imapx.c b/camel/providers/imapx/test-imapx.c
index f65ff6e..2f139d7 100644
--- a/camel/providers/imapx/test-imapx.c
+++ b/camel/providers/imapx/test-imapx.c
@@ -21,7 +21,7 @@ main (gint argc, gchar *argv [])
 	uri = argv [1];
 	g_thread_init (NULL);
 	system ("rm -rf /tmp/test-camel-imapx");
-	camel_init ("/tmp/test-camel-imapx", 0);
+	camel_init ("/tmp/test-camel-imapx", TRUE);
 	camel_provider_init ();
 	ex = camel_exception_new ();
 



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