Re: [Evolution-hackers] Support for LIST-EXTENDED's SUBSCRIBED parameter
On Thu, 2007-12-20 at 21:46 +0100, Philip Van Hoof wrote: > This is some first piece of code to parse "the other" namespaces Forget that, imap_parse_namespace_response implements this already and looks like a fine starting point. -- Philip Van Hoof, freelance software developer home: me at pvanhoof dot be gnome: pvanhoof at gnome dot org http://pvanhoof.be/blog http://codeminded.be ___ Evolution-hackers mailing list Evolution-hackers@gnome.org http://mail.gnome.org/mailman/listinfo/evolution-hackers
Re: [Evolution-hackers] Support for LIST-EXTENDED's SUBSCRIBED parameter
Oh, and it's wrong. It seems that an IMAP server can send an multiple parameters after the directory separator for a namespace. So after the directory separator, the ptr should be read skipping each \"string\" until "))" is seen. And it seems that it's a skiplist, so a parameter can be a "SOMETHING" ("Some setting" "Some more"). hrm ... that's more work :) On Thu, 2007-12-20 at 21:46 +0100, Philip Van Hoof wrote: > This is some first piece of code to parse "the other" namespaces > > In: imap_connect_online > > > result = camel_imap_response_extract (store, response, > "NAMESPACE", ex); > if (!result) > goto done; > > #if 0 > /* new code... */ > namespaces = imap_parse_namespace_response (result); > imap_namespaces_destroy (namespaces); > /* end new code */ > #endif > > name = camel_strstrcase (result, "NAMESPACE (("); > if (name) { > gboolean first = TRUE; > gboolean cont = TRUE; > name += 10; > > while (cont) { > char *sep, *str = NULL; > > while (*name == ' ') > name++; > > if (*name == '(' && *(name+1) == '(') { > name += 2; > if (first) > store->namespace = > imap_parse_string ((const char **) &name, &len); > else > str = imap_parse_string ((const > char **) &name, &len); > > if (name && *name++ == ' ') { > sep = imap_parse_string ((const > char **) &name, &len); > if (sep) { > if (first) > store->dir_sep > = *sep; > g_free (sep); > } > if (*name != ')' || *(name+1) > != ')') { > cont = FALSE; > break; > } > /* The )) */ > name += 2; > } > } else if (!strncmp (name, "NIL", 3)) > name += 3; > > if (!name) > cont = FALSE; > > if (str) { > printf ("Other namespace:%s\n", str); > g_free (str); > } > first = FALSE; > } > } > g_free (result); > } > > On Thu, 2007-12-20 at 14:06 +0100, Philip Van Hoof wrote: > > I further changed Camel-lite in such a way that only the following > > protocol conversation takes place: > > > > if CAPABILITIES contains NAMESPACE > > -> NAMESPACE > > <- NAMESPACE (("namespace that matters" "dir_sep_char") ... ) > > # Camel ignores the other namespaces (this is bad!) > > item = "namespace that matters" + dir_sep_char + "*" or "%" > > else > > namespace = false > > item = "*" > > endif > > > > Note that usually "namespace that matters" is simply "INBOX". Note that > > Camel ignores all not-first namespaces (and that supporting all > > namespaces implies a format change of the CamelStoreSummary's caching). > > > > Then this is done to know the subscription state of INBOX (and counts as > > a roundtrip, I'm still figuring out how I can avoid this one as I think > > it's unnecessary): > > > > (now, this only happens if namespace != "") > > > > if capabilities contains LIST-EXTENDED > > -> LIST (SUBSCRIBED) "" INBOX > > <- LIST (\Subscribed) INBOX ... > > else > > -> LIST "" INBOX > > <- LIST INBOX ... > > -> LSUB "" INBOX > > <- LSUB INBOX ... > > endif > > > > This is getting the list of folders. Either item is "namespace.*' or > > it's "*". Note that requesting "*" is a very bad idea for very large > > folder lists (it's recursive, not all IMAP servers will like you for > > doing this, and it'll be a lot slower than requesting "%" in stead). > > > > In case you don't request a recursive list, Camel puts "%" in stead of > > "*", but note that most of Evolution's code requests a recursive one (so > > it'll at least once occur that a recursive is requested, and therefore > > it'll request it as "*" anyway, or
Re: [Evolution-hackers] Support for LIST-EXTENDED's SUBSCRIBED parameter
This is some first piece of code to parse "the other" namespaces In: imap_connect_online result = camel_imap_response_extract (store, response, "NAMESPACE", ex); if (!result) goto done; #if 0 /* new code... */ namespaces = imap_parse_namespace_response (result); imap_namespaces_destroy (namespaces); /* end new code */ #endif name = camel_strstrcase (result, "NAMESPACE (("); if (name) { gboolean first = TRUE; gboolean cont = TRUE; name += 10; while (cont) { char *sep, *str = NULL; while (*name == ' ') name++; if (*name == '(' && *(name+1) == '(') { name += 2; if (first) store->namespace = imap_parse_string ((const char **) &name, &len); else str = imap_parse_string ((const char **) &name, &len); if (name && *name++ == ' ') { sep = imap_parse_string ((const char **) &name, &len); if (sep) { if (first) store->dir_sep = *sep; g_free (sep); } if (*name != ')' || *(name+1) != ')') { cont = FALSE; break; } /* The )) */ name += 2; } } else if (!strncmp (name, "NIL", 3)) name += 3; if (!name) cont = FALSE; if (str) { printf ("Other namespace:%s\n", str); g_free (str); } first = FALSE; } } g_free (result); } On Thu, 2007-12-20 at 14:06 +0100, Philip Van Hoof wrote: > I further changed Camel-lite in such a way that only the following > protocol conversation takes place: > > if CAPABILITIES contains NAMESPACE > -> NAMESPACE > <- NAMESPACE (("namespace that matters" "dir_sep_char") ... ) > # Camel ignores the other namespaces (this is bad!) > item = "namespace that matters" + dir_sep_char + "*" or "%" > else > namespace = false > item = "*" > endif > > Note that usually "namespace that matters" is simply "INBOX". Note that > Camel ignores all not-first namespaces (and that supporting all > namespaces implies a format change of the CamelStoreSummary's caching). > > Then this is done to know the subscription state of INBOX (and counts as > a roundtrip, I'm still figuring out how I can avoid this one as I think > it's unnecessary): > > (now, this only happens if namespace != "") > > if capabilities contains LIST-EXTENDED > -> LIST (SUBSCRIBED) "" INBOX > <- LIST (\Subscribed) INBOX ... > else > -> LIST "" INBOX > <- LIST INBOX ... > -> LSUB "" INBOX > <- LSUB INBOX ... > endif > > This is getting the list of folders. Either item is "namespace.*' or > it's "*". Note that requesting "*" is a very bad idea for very large > folder lists (it's recursive, not all IMAP servers will like you for > doing this, and it'll be a lot slower than requesting "%" in stead). > > In case you don't request a recursive list, Camel puts "%" in stead of > "*", but note that most of Evolution's code requests a recursive one (so > it'll at least once occur that a recursive is requested, and therefore > it'll request it as "*" anyway, or at least that's what I saw happening > when analysing the traffic). > > Better would indeed be to request a new list each time you click-open a > tree node, and request "%" in stead. This might not be practical for the > UI developer, though. > > Here the LIST-EXTENDED changes kick into action. > > if capabilities contains LIST-EXTENDED > -> LIST (SUBSCRIBED) "" item > <- LIST (\NonExistent \Subscribed) ... > <- LIST (\Subscribed) ... > <- ... > else > -> LIST "" item > <- LIST ... > -> LSUB "" item > <- LSUB ... > endif > > N
Re: [Evolution-hackers] Support for LIST-EXTENDED's SUBSCRIBED parameter
I further changed Camel-lite in such a way that only the following protocol conversation takes place: if CAPABILITIES contains NAMESPACE -> NAMESPACE <- NAMESPACE (("namespace that matters" "dir_sep_char") ... ) # Camel ignores the other namespaces (this is bad!) item = "namespace that matters" + dir_sep_char + "*" or "%" else namespace = false item = "*" endif Note that usually "namespace that matters" is simply "INBOX". Note that Camel ignores all not-first namespaces (and that supporting all namespaces implies a format change of the CamelStoreSummary's caching). Then this is done to know the subscription state of INBOX (and counts as a roundtrip, I'm still figuring out how I can avoid this one as I think it's unnecessary): (now, this only happens if namespace != "") if capabilities contains LIST-EXTENDED -> LIST (SUBSCRIBED) "" INBOX <- LIST (\Subscribed) INBOX ... else -> LIST "" INBOX <- LIST INBOX ... -> LSUB "" INBOX <- LSUB INBOX ... endif This is getting the list of folders. Either item is "namespace.*' or it's "*". Note that requesting "*" is a very bad idea for very large folder lists (it's recursive, not all IMAP servers will like you for doing this, and it'll be a lot slower than requesting "%" in stead). In case you don't request a recursive list, Camel puts "%" in stead of "*", but note that most of Evolution's code requests a recursive one (so it'll at least once occur that a recursive is requested, and therefore it'll request it as "*" anyway, or at least that's what I saw happening when analysing the traffic). Better would indeed be to request a new list each time you click-open a tree node, and request "%" in stead. This might not be practical for the UI developer, though. Here the LIST-EXTENDED changes kick into action. if capabilities contains LIST-EXTENDED -> LIST (SUBSCRIBED) "" item <- LIST (\NonExistent \Subscribed) ... <- LIST (\Subscribed) ... <- ... else -> LIST "" item <- LIST ... -> LSUB "" item <- LSUB ... endif Now. What Evolution does (it doesn't support the LIST-EXTENDED case) is merge the LIST and LSUB together while marking items in LSUB as CAMEL_FOLDER_SUBSCRIBED. Marking them is fine, of course, but merging them together is utterly wrong. Courier is one of the IMAP server that don't do housekeeping of LSUB when you for example delete a folder yet don't unsubscribed it first. The net result is that with Evolution you get folder-nodes that don't exist at the server. For the user this means that when he clicks on that folder-node, that he gets an error about the folder not existing. Of course in Courier you can have subfolders of folders that don't exist. Oh the joys of IMAP :) (and the joys of server people disagreeing on the interpretation of the standard). As how I see it should the IMAP server give in its LIST response a \NonExistant and/or \NoSelect flag for such folders. But should not omit them in LIST. But merging LSUB and LIST together is even more wrong. At least in my opinion (you end up showing folders to the user that simply don't exist on the server). Note: A greyish tree node that presents a parent for child-folders when it ain't selectable ... would be a more correct UI presentation of such a \NoSelect parent folder (or, placeholder in the folder tree). Note. An example is the [GMail] folder of Google IMAP. Google's IMAP server is one of the first times that I saw \NoSelect being actively used by an IMAP server in a default-ish way. Evolution will soon get a lot of GMail IMAP users ... Sounds like something to correctly handle from now on. On Wed, 2007-12-19 at 21:32 +0100, Philip Van Hoof wrote: > The net result of this patch is less round trips when connecting with an > IMAP server that has support for LIST-EXTENDED. > > http://tinymail.org/trac/tinymail/changeset/3155 > > Note that Evolution merges LIST and LSUB together. This is wrong > behaviour. An item not in LIST yet in LSUB simply doesn't exist. > > -- Philip Van Hoof, freelance software developer home: me at pvanhoof dot be gnome: pvanhoof at gnome dot org http://pvanhoof.be/blog http://codeminded.be ___ Evolution-hackers mailing list Evolution-hackers@gnome.org http://mail.gnome.org/mailman/listinfo/evolution-hackers
[Evolution-hackers] Support for LIST-EXTENDED's SUBSCRIBED parameter
The net result of this patch is less round trips when connecting with an IMAP server that has support for LIST-EXTENDED. http://tinymail.org/trac/tinymail/changeset/3155 Note that Evolution merges LIST and LSUB together. This is wrong behaviour. An item not in LIST yet in LSUB simply doesn't exist. -- Philip Van Hoof, freelance software developer home: me at pvanhoof dot be gnome: pvanhoof at gnome dot org http://pvanhoof.be/blog http://codeminded.be ___ Evolution-hackers mailing list Evolution-hackers@gnome.org http://mail.gnome.org/mailman/listinfo/evolution-hackers