summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2011-06-17 16:08:54 -0500
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2011-06-17 16:08:54 -0500
commitba0a4c06fec4cbcb2a763257592cd841f1ed20dd (patch)
tree4552cf85260ca7ca637539b7edda2927d553978e
parentb415ce79de1271eacbcb6dd5e65d15ded8662ada (diff)
downloadpykolab-ba0a4c06fec4cbcb2a763257592cd841f1ed20dd.tar.gz
Fix the undelete code
-rw-r--r--pykolab/imap/__init__.py79
-rw-r--r--pykolab/imap/cyrus.py39
2 files changed, 102 insertions, 16 deletions
diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index a3533f3..03a87ae 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -21,6 +21,7 @@
import logging
import re
import time
+import sys
from urlparse import urlparse
@@ -40,6 +41,9 @@ class IMAP(object):
# Place holder for the current IMAP connection
self.imap = None
+ self.users = []
+ self.inbox_folders = []
+
def connect(self, uri=None):
backend = conf.get('kolab', 'imap_backend')
@@ -118,6 +122,7 @@ class IMAP(object):
if not self.has_folder(inbox):
self.imap.rename(old_inbox,inbox)
+ self.inbox_folders.append(inbox)
else:
log.warning(_("Moving INBOX folder %s won't succeed as target folder %s already exists") %(old_inbox,inbox))
else:
@@ -135,17 +140,15 @@ class IMAP(object):
# See if the folder belongs to any of the users
_match_attr = conf.get('cyrus-sasl', 'result_attribute')
- #print domain
-
if not users:
users = auth.list_users(primary_domain)
for user in users:
if type(user) == dict:
if user.has_key(_match_attr):
- inbox_folders.append(user[_match_attr])
+ inbox_folders.append(user[_match_attr].lower())
elif type(user) == str:
- inbox_folders.append(user)
+ inbox_folders.append(user.lower())
for folder in inbox_folders:
additional_folders = None
@@ -190,6 +193,8 @@ class IMAP(object):
return inbox_folders
def create_user_additional_folders(self, folder, additional_folders):
+ self.connect()
+
for additional_folder in additional_folders.keys():
_add_folder = {}
if len(folder.split('@')) > 1:
@@ -275,6 +280,8 @@ class IMAP(object):
quota = auth.get_user_attribute(user, 'quota')
folder = "user/%s" %(user)
+ folder = folder.lower()
+
try:
(used,current_quota) = self.imap.lq(folder)
except:
@@ -304,6 +311,62 @@ class IMAP(object):
#log.info(_("Correcting quota for %s to %s (currently %s)") %(folder, quota, current_quota))
self.imap._setquota(folder, quota)
+ def set_user_mailhost(self, users=[], primary_domain=None, secondary_domain=[], folders=[]):
+ self.connect()
+
+ if conf.has_option(primary_domain, 'mailserver_attribute'):
+ _mailserver_attr = conf.get(primary_domain, 'mailserver_attribute')
+ else:
+ auth_mechanism = conf.get('kolab', 'auth_mechanism')
+ _mailserver_attr = conf.get(auth_mechanism, 'mailserver_attribute')
+
+ _inbox_folder_attr = conf.get('cyrus-sasl', 'result_attribute')
+
+ if len(users) == 0:
+ users = auth.list_users(primary_domain)
+
+ for user in users:
+ mailhost = None
+
+ if type(user) == dict:
+ if user.has_key(_mailserver_attr):
+ #print "user has key"
+ if type(user[_mailserver_attr]) == list:
+ _mailserver = user[_mailserver_attr].pop(0)
+ elif type(user[_mailserver_attr]) == str:
+ _mailserver = user[_mailserver_attr]
+ else:
+ _mailserver = auth.get_user_attribute(primary_domain, user, _mailserver_attr)
+
+ if not user.has_key(_inbox_folder_attr):
+ continue
+ else:
+ if type(user[_inbox_folder_attr]) == list:
+ folder = "user/%s" % user[_inbox_folder_attr].pop(0)
+ elif type(user[_inbox_folder_attr]) == str:
+ folder = "user/%s" % user[_inbox_folder_attr]
+
+ elif type(user) == str:
+ _mailserver = auth.get_user_attribute(user, _mailserver_attr)
+ folder = "user/%s" %(user)
+
+ folder = folder.lower()
+
+ _current_mailserver = self.imap.find_mailbox_server(folder)
+
+ if not _mailserver == None:
+ # TODO:
+ if not _current_mailserver == _mailserver:
+ self.imap._xfer(folder, _current_mailserver, _mailserver)
+
+ auth.set_user_attribute(primary_domain, user, _mailserver_attr, _mailserver)
+ else:
+ auth.set_user_attribute(primary_domain, user, _mailserver_attr, _current_mailserver)
+
+ def parse_mailbox(self, mailbox):
+ self.connect()
+ return self.imap.parse_mailbox(mailbox)
+
def expunge_user_folders(self, inbox_folders=None):
"""
Delete folders that have no equivalent user qualifier in the list
@@ -393,15 +456,15 @@ class IMAP(object):
def synchronize(self, users=[], primary_domain=None, secondary_domains=[]):
self.connect()
- self.users = users
+ self.users.extend(users)
self.move_user_folders(users)
- folders = self.create_user_folders(users, primary_domain, secondary_domains)
+ self.inbox_folders.extend(self.create_user_folders(users, primary_domain, secondary_domains))
- self.set_user_folder_quota(users, primary_domain, secondary_domains, folders)
+ self.set_user_folder_quota(users, primary_domain, secondary_domains, self.inbox_folders)
- return folders
+ self.set_user_mailhost(users, primary_domain, secondary_domains, self.inbox_folders)
def lm(self, *args, **kw):
return self.imap.lm(*args, **kw)
diff --git a/pykolab/imap/cyrus.py b/pykolab/imap/cyrus.py
index 90ceeb0..a3b1199 100644
--- a/pykolab/imap/cyrus.py
+++ b/pykolab/imap/cyrus.py
@@ -26,8 +26,8 @@ import pykolab
from pykolab.translate import _
-log = pykolab.getLogger('pykolab.imap.cyrus')
conf = pykolab.getConf()
+log = pykolab.getLogger('pykolab.imap.cyrus')
imap = pykolab.imap
@@ -61,10 +61,15 @@ class Cyrus(cyruslib.CYRUS):
else:
port = result.port
+ self.server = result.hostname
+
self.uri = "%s://%s:%s" %(result.scheme,result.hostname,port)
cyruslib.CYRUS.__init__(self, self.uri)
+ if conf.debuglevel > 8:
+ self.VERBOSE = True
+
# Initialize our variables
self.seperator = self.SEP
@@ -84,6 +89,13 @@ class Cyrus(cyruslib.CYRUS):
def find_mailbox_server(self, mailbox):
annotations = {}
+
+ _mailbox = self.parse_mailbox(mailbox)
+ prefix = _mailbox['path_parts'].pop(0)
+ mbox = _mailbox['path_parts'].pop(0)
+ if not _mailbox['domain'] == None:
+ mailbox = "%s%s%s@%s" %(prefix,self.seperator,mbox,_mailbox['domain'])
+
log.debug(_("Checking actual backend server for folder %s through annotations") %(mailbox), level=8)
if self.mbox.has_key(mailbox):
return self.mbox[mailbox]
@@ -92,13 +104,14 @@ class Cyrus(cyruslib.CYRUS):
num_try = 0
while 1:
num_try += 1
- annotations = self.getannotation(mailbox, "/vendor/cmu/cyrus-imapd/server")
+ annotations = self._getannotation(mailbox, "/vendor/cmu/cyrus-imapd/server")
if annotations.has_key(mailbox):
break
if max_tries <= num_try:
log.error(_("Could not get the annotations after %s tries.") %(num_try))
+ annotations = { mailbox: { '/vendor/cmu/cyrus-imapd/server': self.server }}
break
log.warning(_("No annotations for %s: %r") %(mailbox,annotations))
@@ -108,6 +121,11 @@ class Cyrus(cyruslib.CYRUS):
server = annotations[mailbox]['/vendor/cmu/cyrus-imapd/server']
self.mbox[mailbox] = server
+ if not server == self.server:
+ if imap._imap.has_key(server):
+ if not imap._imap[server].mbox.has_key(mailbox):
+ imap._imap[server].mbox[mailbox] = server
+
log.debug(_("Server for INBOX folder %s is %s") %(mailbox,server), level=8)
return server
@@ -135,6 +153,10 @@ class Cyrus(cyruslib.CYRUS):
log.debug(_("Moving INBOX folder %s to %s") %(from_mailbox,to_mailbox), level=8)
imap.rename(from_mailbox, to_mailbox, partition)
+ def _getannotation(self, *args, **kw):
+ imap.connect()
+ return imap.getannotation(*args, **kw)
+
def _setannotation(self, mailbox, annotation, value):
"""
Login to the actual backend server, then set annotation.
@@ -145,6 +167,11 @@ class Cyrus(cyruslib.CYRUS):
log.debug(_("Setting annotation %s on folder %s") %(annotation,mailbox), level=8)
imap.setannotation(mailbox, annotation, value)
+ def _xfer(self, mailbox, current_server, new_server):
+ imap.connect('imap://%s:143' %(current_server))
+ log.debug(_("Transferring folder %s from %s to %s") %(mailbox, current_server, new_server), level=8)
+ imap.xfer(mailbox, new_server)
+
def undelete(self, mailbox, to_mailbox=None, recursive=True):
"""
Login to the actual backend server, then "undelete" the mailbox.
@@ -165,10 +192,6 @@ class Cyrus(cyruslib.CYRUS):
'to_mailbox' may be the target folder to "undelete" the deleted
folder to. If not specified, the original folder name is used.
"""
- server = self.find_mailbox_server(mailbox)
-
- imap.connect('imap://%s:143' %(server))
-
# Placeholder for folders we have recovered already.
target_folders = []
@@ -253,7 +276,7 @@ class Cyrus(cyruslib.CYRUS):
if not mbox['domain'] == None:
verify_folder_search = "%s@%s" %(verify_folder_search, mbox['domain'])
- folders = self.imap.imap.lm(verify_folder_search)
+ folders = self.lm(verify_folder_search)
# NOTE: Case also covered is valid hexadecimal folders; won't be the
# actual check as intended, but doesn't give you anyone else's data
@@ -291,7 +314,7 @@ class Cyrus(cyruslib.CYRUS):
if not mbox['domain'] == None:
deleted_folder_search = "%s@%s" %(deleted_folder_search,mbox['domain'])
- folders = self.imap.lm(deleted_folder_search)
+ folders = self.lm(deleted_folder_search)
# The folders we have found at this stage include virtdomain folders.
#