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