9 commits - pykolab/cli pykolab/imap pykolab/imap_utf7.py wallace/module_resources.py

Jeroen van Meeuwen vanmeeuwen at kolabsys.com
Fri Jul 5 21:25:27 CEST 2013


 pykolab/cli/cmd_create_mailbox.py        |    4 -
 pykolab/cli/cmd_delete_mailbox.py        |    4 +
 pykolab/cli/cmd_list_mailbox_acls.py     |    2 
 pykolab/cli/cmd_list_mailbox_metadata.py |    2 
 pykolab/cli/cmd_list_mailboxes.py        |    3 -
 pykolab/cli/cmd_list_quota.py            |   12 +++-
 pykolab/cli/cmd_set_mailbox_acl.py       |    2 
 pykolab/cli/cmd_undelete_mailbox.py      |    2 
 pykolab/imap/__init__.py                 |   46 +++++++++++----
 pykolab/imap_utf7.py                     |   91 +++++++++++++++++++++++++++++++
 wallace/module_resources.py              |    2 
 11 files changed, 146 insertions(+), 24 deletions(-)

New commits:
commit b6e86aca4378144c38424f2f796913fd4ac2172c
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 20:22:33 2013 +0100

    Fix the utf7 backend versus preferred utf8 display

diff --git a/pykolab/cli/cmd_delete_mailbox.py b/pykolab/cli/cmd_delete_mailbox.py
index 68e1735..61bc278 100644
--- a/pykolab/cli/cmd_delete_mailbox.py
+++ b/pykolab/cli/cmd_delete_mailbox.py
@@ -53,5 +53,5 @@ def execute(*args, **kw):
     delete_folders = imap.list_folders(delete_folder)
 
     for delete_folder in delete_folders:
-        imap.delete_mailfolder(imap.folder_utf8(delete_folder))
+        imap.delete_mailfolder(delete_folder)
 
diff --git a/pykolab/cli/cmd_list_mailbox_acls.py b/pykolab/cli/cmd_list_mailbox_acls.py
index ae04a04..f69c09d 100644
--- a/pykolab/cli/cmd_list_mailbox_acls.py
+++ b/pykolab/cli/cmd_list_mailbox_acls.py
@@ -55,7 +55,7 @@ def execute(*args, **kw):
 
     else:
         acls = []
-        folders = imap.lm(folder)
+        folders = imap.list_folders(folder)
         for folder in folders:
             print "Folder", folder
             acls = imap.list_acls(folder)
diff --git a/pykolab/cli/cmd_list_mailbox_metadata.py b/pykolab/cli/cmd_list_mailbox_metadata.py
index d54346d..a07420d 100644
--- a/pykolab/cli/cmd_list_mailbox_metadata.py
+++ b/pykolab/cli/cmd_list_mailbox_metadata.py
@@ -81,7 +81,7 @@ def execute(*args, **kw):
 
     else:
         metadata = []
-        folders = imap.lm(folder)
+        folders = imap.list_folders(folder)
         for folder in folders:
             print "Folder", folder
 
diff --git a/pykolab/cli/cmd_list_quota.py b/pykolab/cli/cmd_list_quota.py
index 0bb4789..4d3221f 100644
--- a/pykolab/cli/cmd_list_quota.py
+++ b/pykolab/cli/cmd_list_quota.py
@@ -50,7 +50,7 @@ def execute(*args, **kw):
 
     folders = []
 
-    quota_folders = imap.lm(quota_folder)
+    quota_folders = imap.list_folders(quota_folder)
     for quota_folder in quota_folders:
         try:
             (used, quota) = imap.get_quota(quota_folder)
@@ -63,7 +63,10 @@ def execute(*args, **kw):
                     percentage = round(((float)(used)/(float)(quota)) * 100.0, 1)
                     print "%d (Used: %d, Percentage: %d)" % (quota, used, percentage)
             else:
-                print "No quota"
+                if used == None:
+                    print "%d (Used: %d, Percentage: %d)" % (quota, 0, 0)
+                else:
+                    print "No quota"
         except:
             try:
                 (quota_root, used, quota) = imap.get_quota_root(quota_folder)
@@ -76,7 +79,10 @@ def execute(*args, **kw):
                         percentage = round(((float)(used)/(float)(quota)) * 100.0, 1)
                         print "%d (Root: %s, Used: %d, Percentage: %d)" % (quota, quota_root, used, percentage)
                 else:
-                    print "No quota"
+                    if used == None and not quota_root == None:
+                        print "%d (Root: %s, Used: %d, Percentage: %d)" % (quota, quota_root, 0, 0)
+                    else:
+                        print "No quota"
             except:
                 print "Folder: %s" % (quota_folder)
                 print "No quota root"
diff --git a/pykolab/cli/cmd_set_mailbox_acl.py b/pykolab/cli/cmd_set_mailbox_acl.py
index 85e52b8..e86c62d 100644
--- a/pykolab/cli/cmd_set_mailbox_acl.py
+++ b/pykolab/cli/cmd_set_mailbox_acl.py
@@ -67,6 +67,6 @@ def execute(*args, **kw):
         print >> sys.stderr, _("No such folder %r") % (folder)
 
     else:
-        folders = imap.lm(folder)
+        folders = imap.list_folders(folder)
         for folder in folders:
             imap.set_acl(folder, identifier, acl)
diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index 8b7b899..b203db6 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -257,8 +257,14 @@ class IMAP(object):
         """
             Obtain all metadata entries on a folder
         """
+        metadata = {}
 
-        return self.imap.getannotation(folder, '*')
+        _metadata = self.imap.getannotation(self.folder_utf7(folder), '*')
+
+        for (k,v) in _metadata.items():
+            metadata[self.folder_utf8(k)] = v
+
+        return metadata
 
     def get_separator(self):
         if not hasattr(self, 'imap') or self.imap == None:
@@ -322,7 +328,7 @@ class IMAP(object):
         if short_rights.has_key(acl):
             acl = short_rights[acl]
 
-        self.imap.sam(folder, identifier, acl)
+        self.imap.sam(self.folder_utf7(folder), identifier, acl)
 
     def set_metadata(self, folder, metadata_path, metadata_value, shared=True):
         """
@@ -639,7 +645,7 @@ class IMAP(object):
             Check if the environment has a folder named folder.
         """
         folders = self.imap.lm(self.folder_utf7(folder))
-        log.debug(_("Looking for folder '%s', we found folders: %r") % (folder,folders), level=8)
+        log.debug(_("Looking for folder '%s', we found folders: %r") % (folder,[self.folder_utf8(x) for x in folders]), level=8)
         # Greater then one, this folder may have subfolders.
         if len(folders) > 0:
             return True
@@ -917,10 +923,10 @@ class IMAP(object):
         """
             List the ACL entries on a folder
         """
-        return self.imap.lam(folder)
+        return self.imap.lam(self.folder_utf7(folder))
 
     def list_folders(self, pattern):
-        return self.lm(self.folder_utf7(pattern))
+        return [self.folder_utf8(x) for x in self.lm(self.folder_utf7(pattern))]
 
     def list_user_folders(self, primary_domain=None, secondary_domains=[]):
         """


commit a8d64317834c4efc56d41b314d0a219e5de7ecfd
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 19:50:38 2013 +0100

    Make sure the pattern for deleting mailboxes is passed on right between various function calls

diff --git a/pykolab/cli/cmd_delete_mailbox.py b/pykolab/cli/cmd_delete_mailbox.py
index 99404ff..68e1735 100644
--- a/pykolab/cli/cmd_delete_mailbox.py
+++ b/pykolab/cli/cmd_delete_mailbox.py
@@ -49,7 +49,9 @@ def execute(*args, **kw):
     imap = IMAP()
 
     imap.connect()
-    delete_folders = imap.lm(delete_folder)
+
+    delete_folders = imap.list_folders(delete_folder)
+
     for delete_folder in delete_folders:
-        imap.delete_mailfolder(delete_folder)
+        imap.delete_mailfolder(imap.folder_utf8(delete_folder))
 
diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index 63245d6..8b7b899 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -249,6 +249,10 @@ class IMAP(object):
         from pykolab import imap_utf7
         return imap_utf7.encode(folder)
 
+    def folder_utf8(self, folder):
+        from pykolab import imap_utf7
+        return imap_utf7.decode(folder)
+
     def get_metadata(self, folder):
         """
             Obtain all metadata entries on a folder
@@ -898,16 +902,16 @@ class IMAP(object):
 
         log.info(_("Deleting folder %s") % (mailfolder_path))
 
-        self.imap.dm(mailfolder_path)
+        self.imap.dm(self.folder_utf7(mailfolder_path))
 
     def get_quota(self, mailfolder_path):
         try:
-            return self.lq(mailfolder_path)
+            return self.lq(self.folder_utf7(mailfolder_path))
         except:
             return
 
     def get_quota_root(self, mailfolder_path):
-        return self.lqr(mailfolder_path)
+        return self.lqr(self.folder_utf7(mailfolder_path))
 
     def list_acls(self, folder):
         """
@@ -915,6 +919,9 @@ class IMAP(object):
         """
         return self.imap.lam(folder)
 
+    def list_folders(self, pattern):
+        return self.lm(self.folder_utf7(pattern))
+
     def list_user_folders(self, primary_domain=None, secondary_domains=[]):
         """
             List the INBOX folders in the IMAP backend. Returns a list of unique


commit 4e63299089254bbe6be5fa6e58458475276825cb
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 18:06:16 2013 +0100

    Correct the resulting message in message_from_string not detecting the message is multipart

diff --git a/wallace/module_resources.py b/wallace/module_resources.py
index cd92e3c..b2924fa 100644
--- a/wallace/module_resources.py
+++ b/wallace/module_resources.py
@@ -127,7 +127,7 @@ def execute(*args, **kw):
 
     _message = json.load(open(filepath, 'r'))
     log.debug("Loaded message %r" % (_message), level=9)
-    message = message_from_string(_message['data'])
+    message = message_from_string(str(_message['data']))
     recipients = _message['to']
 
     any_itips = False


commit cebd042b87b5a85ea6f840b9c51c953dd0b9c282
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 19:26:32 2013 +0100

    Use imap.create_folder() for kolab cm

diff --git a/pykolab/cli/cmd_create_mailbox.py b/pykolab/cli/cmd_create_mailbox.py
index 453b41e..63ae0ad 100644
--- a/pykolab/cli/cmd_create_mailbox.py
+++ b/pykolab/cli/cmd_create_mailbox.py
@@ -63,9 +63,7 @@ def execute(*args, **kw):
     imap = IMAP()
     imap.connect()
 
-    admin_login = conf.get('cyrus-imap', 'admin_login')
-
-    imap.cm(mailbox)
+    imap.create_folder(mailbox)
 
     if not conf.metadata == None:
         imap.set_metadata(mailbox, conf.metadata.split('=')[0], conf.metadata.split('=')[1])


commit 76cefcae360ddfec1b08018c70df45490abfd693
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 19:38:56 2013 +0100

    If a string isn't unicode, attempt to make it so

diff --git a/pykolab/imap_utf7.py b/pykolab/imap_utf7.py
index 6a670b5..038623b 100644
--- a/pykolab/imap_utf7.py
+++ b/pykolab/imap_utf7.py
@@ -29,7 +29,10 @@ class FolderNameError(ValueError):
 
 def encode(s):
     if isinstance(s, str) and sum(n for n in (ord(c) for c in s) if n > 127):
-        raise FolderNameError("%r contains characters not valid in a str folder name. "
+        try:
+            s = unicode(s, "UTF-8")
+        except Exception, errmsg:
+            raise FolderNameError("%r contains characters not valid in a str folder name. "
                               "Convert to unicode first?" % s)
 
     r = []
@@ -49,6 +52,7 @@ def encode(s):
             _in.append(c)
     if _in:
         r.extend(['&', modified_base64(''.join(_in)), '-'])
+
     return ''.join(r)
 
 


commit a5735530bfa78ad9f926f578a4e17a6fc8dc3c28
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 19:38:34 2013 +0100

    Decode the mailbox names in kolab list-mailboxes

diff --git a/pykolab/cli/cmd_list_mailboxes.py b/pykolab/cli/cmd_list_mailboxes.py
index f765bac..4640bc5 100644
--- a/pykolab/cli/cmd_list_mailboxes.py
+++ b/pykolab/cli/cmd_list_mailboxes.py
@@ -21,6 +21,7 @@ import commands
 
 import pykolab
 
+from pykolab import imap_utf7
 from pykolab.imap import IMAP
 from pykolab.translate import _
 
@@ -76,4 +77,4 @@ def execute(*args, **kw):
         folders.extend(imap.lm(search))
 
     for folder in folders:
-        print folder
+        print imap_utf7.decode(folder)


commit d8ad999e066ff28a1645de314597c31b5378310b
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 18:07:48 2013 +0100

    Correct IMAP not being loaded / initialized

diff --git a/pykolab/cli/cmd_undelete_mailbox.py b/pykolab/cli/cmd_undelete_mailbox.py
index c21f7a4..46eec85 100644
--- a/pykolab/cli/cmd_undelete_mailbox.py
+++ b/pykolab/cli/cmd_undelete_mailbox.py
@@ -21,6 +21,7 @@ import commands
 
 import pykolab
 
+from pykolab.imap import IMAP
 from pykolab.translate import _
 
 log = pykolab.getLogger('pykolab.cli')
@@ -43,6 +44,7 @@ def execute(*args, **kw):
     if len(conf.cli_args) > 0:
         target_folder = conf.cli_args.pop(0)
 
+    imap = IMAP()
     imap.connect()
     imap.undelete_mailfolder(undelete_folder, target_folder)
 


commit 17c07881190307e14294e2887c055632297b3200
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 18:03:08 2013 +0100

    Correct conversion to utf7

diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index 8855909..63245d6 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -208,6 +208,8 @@ class IMAP(object):
                 log.warning(_("Called imap.disconnect() on a server that we had no connection to."))
 
     def create_folder(self, folder_path, server=None):
+        folder_path = self.folder_utf7(folder_path)
+
         if not server == None:
             if not self._imap.has_key(server):
                 self.connect(server=server)
@@ -245,7 +247,7 @@ class IMAP(object):
 
     def folder_utf7(self, folder):
         from pykolab import imap_utf7
-        return imap_utf7.encode(folder_path)
+        return imap_utf7.encode(folder)
 
     def get_metadata(self, folder):
         """


commit 643a625bd75bcdc098b3c04ed7366207efb0dad0
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Fri Jul 5 17:09:53 2013 +0100

    Make sure folder names are utf-7 encoded

diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index fa71014..8855909 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -243,6 +243,10 @@ class IMAP(object):
         else:
             raise AttributeError, _("%r has no attribute %s") % (self,name)
 
+    def folder_utf7(self, folder):
+        from pykolab import imap_utf7
+        return imap_utf7.encode(folder_path)
+
     def get_metadata(self, folder):
         """
             Obtain all metadata entries on a folder
@@ -328,7 +332,7 @@ class IMAP(object):
             shared = False
             metadata_path = metadata_path.replace('/private/', '/')
 
-        self.imap._setannotation(folder, metadata_path, metadata_value, shared)
+        self.imap._setannotation(self.folder_utf7(folder), metadata_path, metadata_value, shared)
 
     def shared_folder_create(self, folder_path, server=None):
         """
@@ -478,9 +482,12 @@ class IMAP(object):
                 folder_name = "%s%s" % (personal, folder_name)
 
             try:
-                self.imap.cm(folder_name)
+                self.create_folder(folder_name)
             except:
                 log.warning(_("Mailbox already exists: %s") % (folder_name))
+                if conf.debuglevel > 8:
+                    import traceback
+                    traceback.print_exc()
                 continue
 
             if additional_folders[additional_folder].has_key("annotations"):
@@ -625,7 +632,7 @@ class IMAP(object):
         """
             Check if the environment has a folder named folder.
         """
-        folders = self.imap.lm(folder)
+        folders = self.imap.lm(self.folder_utf7(folder))
         log.debug(_("Looking for folder '%s', we found folders: %r") % (folder,folders), level=8)
         # Greater then one, this folder may have subfolders.
         if len(folders) > 0:
@@ -653,7 +660,7 @@ class IMAP(object):
                             "%s") % (rights,subject,folder), level=8)
 
                 self.set_acl(
-                        folder,
+                        self.folder_utf7(folder),
                         "%s" % (subject),
                         "%s" % (rights)
                     )
@@ -664,7 +671,7 @@ class IMAP(object):
                             "%s") % (rights,subject,folder), level=8)
 
                 self.set_acl(
-                        folder,
+                        self.folder_utf7(folder),
                         "%s" % (subject),
                         ""
                     )
diff --git a/pykolab/imap_utf7.py b/pykolab/imap_utf7.py
new file mode 100644
index 0000000..6a670b5
--- /dev/null
+++ b/pykolab/imap_utf7.py
@@ -0,0 +1,87 @@
+# The contents of this file has been derived code from the Twisted project
+# (http://twistedmatrix.com/). The original author is Jp Calderone.
+
+# Twisted project license follows:
+
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+# 
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+class FolderNameError(ValueError):
+    pass
+
+
+def encode(s):
+    if isinstance(s, str) and sum(n for n in (ord(c) for c in s) if n > 127):
+        raise FolderNameError("%r contains characters not valid in a str folder name. "
+                              "Convert to unicode first?" % s)
+
+    r = []
+    _in = []
+    for c in s:
+        if ord(c) in (range(0x20, 0x26) + range(0x27, 0x7f)):
+            if _in:
+                r.extend(['&', modified_base64(''.join(_in)), '-'])
+                del _in[:]
+            r.append(str(c))
+        elif c == '&':
+            if _in:
+                r.extend(['&', modified_base64(''.join(_in)), '-'])
+                del _in[:]
+            r.append('&-')
+        else:
+            _in.append(c)
+    if _in:
+        r.extend(['&', modified_base64(''.join(_in)), '-'])
+    return ''.join(r)
+
+
+def decode(s):
+    r = []
+    decode = []
+    for c in s:
+        if c == '&' and not decode:
+            decode.append('&')
+        elif c == '-' and decode:
+            if len(decode) == 1:
+                r.append('&')
+            else:
+                r.append(modified_unbase64(''.join(decode[1:])))
+            decode = []
+        elif decode:
+            decode.append(c)
+        else:
+            r.append(c)
+    if decode:
+        r.append(modified_unbase64(''.join(decode[1:])))
+    out = ''.join(r)
+
+    if not isinstance(out, unicode):
+        out = unicode(out, 'latin-1')
+    return out
+
+
+def modified_base64(s):
+    s_utf7 = s.encode('utf-7')
+    return s_utf7[1:-1].replace('/', ',')
+
+
+def modified_unbase64(s):
+    s_utf7 = '+' + s.replace(',', '/') + '-'
+    return s_utf7.decode('utf-7')





More information about the commits mailing list