From 95dec87e0292505c2d6d362f45f0bc1d745c48c7 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Mon, 2 Sep 2013 21:48:44 +0200 Subject: [PATCH] A hierarchy delimiter is not always the same. This code will behave better but it is far from perfect. see #435 --- modoboa/extensions/webmail/imaputils.py | 30 +++++++++++++++---- .../webmail/static/webmail/js/webmail.js | 21 ++++++------- .../webmail/templates/webmail/index.html | 3 +- modoboa/extensions/webmail/views.py | 1 + 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/modoboa/extensions/webmail/imaputils.py b/modoboa/extensions/webmail/imaputils.py index 189351705..e519e1a83 100644 --- a/modoboa/extensions/webmail/imaputils.py +++ b/modoboa/extensions/webmail/imaputils.py @@ -146,6 +146,7 @@ class IMAPconnector(object): unseen_pattern = re.compile(r'[^\(]+\(UNSEEN (\d+)\)') def __init__(self, user=None, password=None): + self.__hdelimiter = None self.criterions = [] self.address = parameters.get_admin("IMAP_SERVER") self.port = int(parameters.get_admin("IMAP_PORT")) @@ -220,6 +221,23 @@ class IMAPconnector(object): bodystruct[5], int(bodystruct[6])) return (None, None, 0) + @property + def hdelimiter(self): + """Return the default hierachy delimiter. + + This is a simple way to retrieve the default delimiter (see + http://www.imapwiki.org/ClientImplementation/MailboxList). + + :return: a string + """ + if self.__hdelimiter is None: + data = self._cmd("LIST", "", "") + m = self.list_response_pattern.match(data[0]) + if m is None: + raise WebmailError(_("Failed to retrieve hierarchy delimiter")) + self.__hdelimiter = m.group('delimiter') + return self.__hdelimiter + def refresh(self, user, password): """Check if current connection needs a refresh @@ -378,7 +396,7 @@ class IMAPconnector(object): newmboxes += [descr] if re.search("\%s" % delimiter, name): - parts = name.split(".") + parts = name.split(delimiter) if not descr.has_key("path"): descr["path"] = parts[0] descr["sub"] = [] @@ -392,7 +410,9 @@ class IMAPconnector(object): @capability('LIST-EXTENDED', '_listmboxes_simple') def _listmboxes(self, topmailbox, mailboxes, until_mailbox=None): - pattern = ("%s.%%" % topmailbox.encode("imap4-utf-7")) if len(topmailbox) else "%" + pattern = "%s%s%%" % (topmailbox.encode("imap4-utf-7"), self.hdelimiter) \ + if len(topmailbox) else "%" + print pattern resp = self._cmd("LIST", "", pattern, "RETURN", "(CHILDREN)") newmboxes = [] for mb in resp: @@ -452,7 +472,7 @@ class IMAPconnector(object): {"name" : parameters.get_user(user, "TRASH_FOLDER"), "class" : "icon-trash"}] if until_mailbox: - name, parent = separate_mailbox(until_mailbox) + name, parent = separate_mailbox(until_mailbox, self.hdelimiter) if parent: until_mailbox = parent self._listmboxes(topmailbox, md_mailboxes, until_mailbox) @@ -536,7 +556,7 @@ class IMAPconnector(object): def create_folder(self, name, parent=None): if parent is not None: - name = "%s.%s" % (parent, name) + name = "%s%s%s" % (parent, self.hdelimiter, name) typ, data = self.m.create(self._encode_mbox_name(name)) if typ == "NO": raise WebmailError(data[0]) @@ -659,7 +679,7 @@ def separate_mailbox(fullname, sep="."): If a separator is found in ``fullname``, this function returns the corresponding name and parent mailbox name. """ - if fullname.count("."): + if sep in fullname: parts = fullname.split(sep) name = parts[-1] parent = sep.join(parts[0:len(parts) - 1]) diff --git a/modoboa/extensions/webmail/static/webmail/js/webmail.js b/modoboa/extensions/webmail/static/webmail/js/webmail.js index 8d40667f7..8cea472b2 100644 --- a/modoboa/extensions/webmail/static/webmail/js/webmail.js +++ b/modoboa/extensions/webmail/static/webmail/js/webmail.js @@ -15,7 +15,8 @@ Webmail.prototype = { submboxes_url: "", delattachment_url: "", ro_mboxes: ["INBOX"], - trash: "" + trash: "", + hdelimiter: '.' }, initialize: function(options) { @@ -217,7 +218,7 @@ Webmail.prototype = { } var $link = $('a[href="' + mailbox + '"]'); - var parts = mailbox.split('.'); + var parts = mailbox.split(this.options.hdelimiter); var dname = " " + parts[parts.length - 1]; var $i = $link.children("i"); @@ -285,7 +286,7 @@ Webmail.prototype = { 'class': "block", href: mailbox }); - var parts = mailbox.split("."); + var parts = mailbox.split(this.options.hdelimiter); var linkcontent = " "; var displayname = linkcontent + parts[parts.length - 1]; @@ -401,18 +402,18 @@ Webmail.prototype = { * to access this mailbox are also loaded) */ load_and_select_mailbox: function(mailbox) { - if (mailbox.indexOf(".") == -1) { + if (mailbox.indexOf(this.options.hdelimiter) == -1) { this.select_mailbox(mailbox); return; } this.reset_mb_selection(); - var parts = mailbox.split("."); + var parts = mailbox.split(this.options.hdelimiter); var curmb = parts[0], lastmb = ""; for (var i = 1; i < parts.length; i++) { lastmb = curmb; - curmb += "." + parts[i]; + curmb += this.options.hdelimiter + parts[i]; var $link = $('a[href="' + curmb + '"]'); var $container = $('li[name="' + lastmb + '"]'); @@ -535,7 +536,7 @@ Webmail.prototype = { return; } $parent = $ul; - mailbox = $parent.attr("name") + "." + mailbox; + mailbox = $parent.attr("name") + this.hdelimiter + mailbox; } else { $parent = $("#mboxes_container").children("ul"); } @@ -548,8 +549,8 @@ Webmail.prototype = { * If needed, the mailbox will be moved to its new location. */ rename_mailbox: function(oldname, newname, oldparent, newparent) { - var oldpattern = (oldparent) ? oldparent + "." + oldname : oldname; - var newpattern = (newparent) ? newparent + "." + newparent : newname; + var oldpattern = (oldparent) ? oldparent + this.hdelimiter + oldname : oldname; + var newpattern = (newparent) ? newparent + this.hdelimiter + newparent : newname; var $link = $("#folders").find('a[href="' + oldpattern + '"]'); if (oldname != newname) { @@ -562,7 +563,7 @@ Webmail.prototype = { this.navobject.setparam("mbox", newname).update(false, true); } if (oldparent != newparent) { - var newlocation = (newparent) ? newparent + "." + newname : newname; + var newlocation = (newparent) ? newparent + this.hdelimiter + newname : newname; this.remove_mbox_from_tree($link.parent("li")); this.add_mailbox_to_tree(newparent, newname); if (this.navobject.getparam("action") == "listmailbox") { diff --git a/modoboa/extensions/webmail/templates/webmail/index.html b/modoboa/extensions/webmail/templates/webmail/index.html index b404f7efc..96c5b588f 100644 --- a/modoboa/extensions/webmail/templates/webmail/index.html +++ b/modoboa/extensions/webmail/templates/webmail/index.html @@ -20,7 +20,8 @@ $(document).ready(function() { deflocation: "{{ deflocation }}", defcallback: "{{ defcallback }}", ro_mboxes: {% tolist ro_mboxes %}, - trash: "{{ trash }}" + trash: "{{ trash }}", + hdelimiter: '{{ hdelimiter }}' }); }); diff --git a/modoboa/extensions/webmail/views.py b/modoboa/extensions/webmail/views.py index 8563bcc6b..968ee4436 100644 --- a/modoboa/extensions/webmail/views.py +++ b/modoboa/extensions/webmail/views.py @@ -504,6 +504,7 @@ def index(request): if not request.is_ajax(): request.session["lastaction"] = None imapc = get_imapconnector(request) + response["hdelimiter"] = imapc.hdelimiter response["mboxes"] = render_mboxes_list(request, imapc) imapc.getquota(curmbox) response["refreshrate"] = \