[Evolution-hackers] RFC: Check for mail only in subscribed folders.



The IMAP RFCs define the meaning of 'subscribed' ambiguously -- they say
only that it's for 'active' mailboxes.

One possible interpretation of that is that it's for the mailboxes which
the user wants to _see_. However, it's very common with IMAP (as opposed
to NNTP) to display _all_ folders, not only the subscribed folders. 

In that case, there are few sane interpretations of what 'subscribed'
actually means. The only really useful one I can think of it that
'subscribed' folders should be the folders in which the user wants the
MUA to periodically check for new mail. That is; the folders are
'active' and receive mail delivery, rather than being archives of old
mail.

I have a large number of folders and always used to archive them
quarterly -- since switching to Evolution I've avoided archiving them,
because of Evolution's behaviour on checking for new mail. It checks
_all_ folders, and does so at startup before even displaying the INBOX
or responding to user requests to display certain mails. Archiving my
mail even once would instantly double the time taken for this, and it's
_already_ at the point where I often fire up pine and read my mail while
waiting for Evolution to start.

So I've implemented a 'check for new mail only in subscribed folders'
feature, so that I can start archiving my mail again without Evo
actually taking hours to start. 

The problem is that it's ugly as hell. The current IMAP code, when told
'show all folders', pretends to the Evo mailer that it is a store
incapable of handling subscriptions. The Evo mailer _always_ asks for
only subscribed folders on such a store, except in the subscription
dialog.

I don't feel _too_ guilty, since it was already ugly as hell... but does
anyone have better suggestions? I'd at least have liked to have a
drop-down box:

	Check for mail in:	[<All Folders>]
				[<Subscribed Folders>]
				[<INBOX only>]

Index: camel/providers/imap/camel-imap-provider.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/imap/camel-imap-provider.c,v
retrieving revision 1.26
diff -u -p -r1.26 camel-imap-provider.c
--- camel/providers/imap/camel-imap-provider.c	1 Dec 2003 02:10:49 -0000	1.26
+++ camel/providers/imap/camel-imap-provider.c	7 Jan 2004 15:15:13 -0000
@@ -54,6 +54,8 @@ CamelProviderConfEntry imap_conf_entries
 	{ CAMEL_PROVIDER_CONF_SECTION_START, "folders", NULL,
 	  N_("Folders") },
 	{ CAMEL_PROVIDER_CONF_CHECKBOX, "use_lsub", NULL,
+	  N_("Use list of subscribed folders"), "1" },
+	{ CAMEL_PROVIDER_CONF_CHECKBOX, "show_only_sub", "use_lsub",
 	  N_("Show only subscribed folders"), "1" },
 	{ CAMEL_PROVIDER_CONF_CHECKBOX, "override_namespace", NULL,
 	  N_("Override server-supplied folder namespace"), "0" },
Index: camel/providers/imap/camel-imap-store.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/imap/camel-imap-store.c,v
retrieving revision 1.262
diff -u -p -r1.262 camel-imap-store.c
--- camel/providers/imap/camel-imap-store.c	10 Dec 2003 19:22:20 -0000	1.262
+++ camel/providers/imap/camel-imap-store.c	7 Jan 2004 15:15:14 -0000
@@ -311,6 +311,8 @@ construct (CamelService *service, CamelS
 	imap_store->parameters = 0;
 	if (camel_url_get_param (url, "use_lsub"))
 		store->flags |= CAMEL_STORE_SUBSCRIPTIONS;
+	if (camel_url_get_param (url, "show_only_sub"))
+		imap_store->parameters |= IMAP_PARAM_SHOW_ONLY_SUB;
 	if (camel_url_get_param (url, "namespace")) {
 		imap_store->parameters |= IMAP_PARAM_OVERRIDE_NAMESPACE;
 		g_free(imap_store->namespace);
@@ -2207,7 +2209,9 @@ get_subscribed_folders (CamelImapStore *
 		fi = parse_list_response_as_folder_info (imap_store, result);
 		if (!fi)
 			continue;
-		
+
+		fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
+
 		if (strncmp (top, fi->full_name, toplen) != 0) {
 			camel_folder_info_free (fi);
 			continue;
@@ -2268,12 +2272,37 @@ get_folders_online (CamelImapStore *imap
 		list = response->untagged->pdata[i];
 		fi = parse_list_response_as_folder_info (imap_store, list);
 		if (fi) {
+			if (lsub)
+				fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
 			g_ptr_array_add(folders, fi);
 			g_hash_table_insert(present, fi->full_name, fi);
 		}
 	}
 	camel_imap_response_free (imap_store, response);
 
+	/* If we're not asked for only subscribed folders, but subscriptions are available,
+	   issue LSUB _too_ and set CAMEL_FOLDER_SUBSCRIBED flag where appropriate */
+	if (!lsub && (CAMEL_STORE(imap_store)->flags & CAMEL_STORE_SUBSCRIPTIONS)) {
+		response = camel_imap_command (imap_store, NULL, ex,
+					       "%s \"\" %S", "LSUB", pattern);
+		if (!response)
+			goto out;
+
+		for (i = 0; i < response->untagged->len; i++) {
+			CamelFolderInfo *fi2;
+			list = response->untagged->pdata[i];
+			fi = parse_list_response_as_folder_info (imap_store, list);
+
+			/* Look up the original from the hash table and mark it subscribed. */
+			fi2 = g_hash_table_lookup(present, fi->full_name);
+			if (fi2)
+				fi2->flags |= CAMEL_FOLDER_SUBSCRIBED;
+
+			camel_folder_info_free(fi);
+		}
+		camel_imap_response_free (imap_store, response);
+	}
+
 	/* update our summary to match the server */
 	count = camel_store_summary_count((CamelStoreSummary *)imap_store->summary);
 	for (i=0;i<count;i++) {
@@ -2302,6 +2331,7 @@ get_folders_online (CamelImapStore *imap
 		}
 		camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
 	}
+out:
 	g_hash_table_destroy(present);
 }
 
@@ -2345,9 +2375,13 @@ get_folder_counts(CamelImapStore *imap_s
 		q = g_slist_remove_link(q, q);
 
 		while (fi) {
-			/* ignore noselect folders, and check only inbox if we only check inbox */
+			/* ignore noselect folders, and show other folders if one of the following is true:
+			    - We are set to check all folders.
+			    - The folder is the INBOX.
+			    - The folder is a subscribed folder, we're set to use subscriptions but not to show only subscribed folders */
 			if ((fi->flags & CAMEL_FOLDER_NOSELECT) == 0
 			    && ( (imap_store->parameters & IMAP_PARAM_CHECK_ALL)
+				 || ((CAMEL_STORE(imap_store)->flags & CAMEL_STORE_SUBSCRIPTIONS) && !(imap_store->parameters & IMAP_PARAM_SHOW_ONLY_SUB) && (fi->flags & CAMEL_FOLDER_SUBSCRIBED)) 
 				 || strcasecmp(fi->full_name, "inbox") == 0) ) {
 
 				CAMEL_SERVICE_LOCK (imap_store, connect_lock);
@@ -2468,7 +2502,8 @@ get_folders(CamelStore *store, const cha
 	folders = g_ptr_array_new();
 	
 	/* first get working list of names */
-	get_folders_online (imap_store, name[0]?name:"%", folders, flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, ex);
+	get_folders_online (imap_store, name[0]?name:"%", folders,
+			    (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) && (imap_store->parameters & IMAP_PARAM_SHOW_ONLY_SUB), ex);
 	if (camel_exception_is_set(ex))
 		goto fail;
 	for (i=0; i<folders->len && !haveinbox; i++) {
@@ -2478,7 +2513,7 @@ get_folders(CamelStore *store, const cha
 
 	if (!haveinbox && top == imap_store->namespace) {
 		get_folders_online (imap_store, "INBOX", folders,
-				    flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, ex);
+				    (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) && (imap_store->parameters & IMAP_PARAM_SHOW_ONLY_SUB), ex);
 		
 		if (camel_exception_is_set (ex))
 			goto fail;
@@ -2517,7 +2552,7 @@ get_folders(CamelStore *store, const cha
 
 				real = camel_imap_store_summary_full_from_path(imap_store->summary, fi->full_name);
 				n = imap_concat(imap_store, real?real:fi->full_name, "%");
-				get_folders_online(imap_store, n, folders, flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, ex);
+				get_folders_online(imap_store, n, folders, (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) && (imap_store->parameters & IMAP_PARAM_SHOW_ONLY_SUB), ex);
 				g_free(n);
 				g_free(real);
 
@@ -2566,7 +2601,7 @@ get_folder_info_online (CamelStore *stor
 	if (top == NULL)
 		top = "";
 
-	if ((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
+	if (((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) && (imap_store->parameters & IMAP_PARAM_SHOW_ONLY_SUB))
 	    && !(imap_store->capabilities & IMAP_CAPABILITY_useful_lsub)
 	    && (imap_store->parameters & IMAP_PARAM_CHECK_ALL))
 		folders = get_subscribed_folders(imap_store, top, ex);
Index: camel/providers/imap/camel-imap-store.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/imap/camel-imap-store.h,v
retrieving revision 1.57
diff -u -p -r1.57 camel-imap-store.h
--- camel/providers/imap/camel-imap-store.h	10 Dec 2003 19:22:20 -0000	1.57
+++ camel/providers/imap/camel-imap-store.h	7 Jan 2004 15:15:14 -0000
@@ -95,6 +95,7 @@ typedef enum {
 #define IMAP_PARAM_OVERRIDE_NAMESPACE		(1 << 0)
 #define IMAP_PARAM_CHECK_ALL			(1 << 1)
 #define IMAP_PARAM_FILTER_INBOX			(1 << 2)
+#define IMAP_PARAM_SHOW_ONLY_SUB		(1 << 3)
 
 struct _CamelImapStore {
 	CamelDiscoStore parent_object;	


-- 
dwmw2




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