diff --git a/pykolab/cli/cmd_mailbox_cleanup.py b/pykolab/cli/cmd_mailbox_cleanup.py index ee12c1e..30a03a8 100644 --- a/pykolab/cli/cmd_mailbox_cleanup.py +++ b/pykolab/cli/cmd_mailbox_cleanup.py @@ -1,205 +1,228 @@ # -*- coding: utf-8 -*- # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) # # Jeroen van Meeuwen (Kolab Systems) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -import ldap -import sys - import commands import pykolab from pykolab import imap_utf7 from pykolab.auth import Auth from pykolab.imap import IMAP from pykolab.translate import _ log = pykolab.getLogger('pykolab.cli') conf = pykolab.getConf() + def __init__(): commands.register('mailbox_cleanup', execute, description=description()) + def cli_options(): my_option_group = conf.add_cli_parser_option_group(_("CLI Options")) my_option_group.add_option( '--dry-run', - dest = "dryrun", - action = "store_true", - default = False, - help = _( + dest="dryrun", + action="store_true", + default=False, + help=_( "Do not actually delete mailboxes, but report what mailboxes would have been deleted." ) ) my_option_group.add_option( '--server', - dest = "connect_server", - action = "store", - default = None, - metavar = "SERVER", - help = _("Evaluate mailboxes on server SERVER only.") + dest="connect_server", + action="store", + default=None, + metavar="SERVER", + help=_("Evaluate mailboxes on server SERVER only.") + ) + + my_option_group.add_option( + '--with-acls', + dest="with_acls", + action="store", + default=False, + help=_("Evaluate ACLs on mailboxes as well.") ) + def description(): return _("Clean up mailboxes that do no longer have an owner.") + +# pylint: disable=too-many-branches,too-many-locals,too-many-statements def execute(*args, **kw): """ List mailboxes """ auth = Auth() domains = auth.list_domains() imap = IMAP() - if not conf.connect_server == None: + if conf.connect_server is not None: imap.connect(server=conf.connect_server) else: imap.connect() domain_folders = {} subjects = [] # Placeholder for subjects that would have already been deleted subjects_deleted = [] - for domain in domains.keys(): + for domain in domains: domain_folders[domain] = imap.lm("user/%%@%s" % (domain)) - for domain in domain_folders.keys(): + for domain in domain_folders: auth = Auth(domain=domain) auth.connect(domain) for folder in domain_folders[domain]: - user = folder.replace('user/','') + user = folder.replace('user/', '') try: recipient = auth.find_recipient(user) - except ldap.NO_SUCH_OBJECT, errmsg: - if not user in subjects_deleted and conf.dryrun: + # pylint: disable=bare-except + except: + if user not in subjects_deleted and conf.dryrun: subjects_deleted.append(user) if conf.dryrun: log.info(_("Would have deleted folder 'user/%s' (dryrun)") % (user)) else: log.info(_("Deleting folder 'user/%s'") % (user)) continue if len(recipient) == 0 or recipient == []: - if not user in subjects_deleted and conf.dryrun: + if user not in subjects_deleted and conf.dryrun: subjects_deleted.append(user) if conf.dryrun: log.info(_("Would have deleted folder 'user/%s' (dryrun)") % (user)) else: log.info(_("Deleting folder 'user/%s'") % (user)) try: imap.dm(folder) + # pylint: disable=bare-except except: log.error(_("Error deleting folder 'user/%s'") % (user)) else: log.debug(_("Valid recipient found for 'user/%s'") % (user), level=6) - if not user in subjects: + if user not in subjects: subjects.append(user) imap_domains = [] folders = imap.lm() + for folder in folders: - namespace = folder.split('/')[0] + components = folder.split('/') + + if len(components) < 2: + log.error("Not enough components for folder %s" % (folder)) + continue + mailbox = folder.split('/')[1] if len(mailbox.split('@')) > 1: domain = mailbox.split('@')[1] - if not domain in domains.keys() and not domain in imap_domains: + if domain not in domains and domain not in imap_domains: imap_domains.append(domain) for domain in imap_domains: for folder in imap.lm('user/%%@%s' % (domain)): user = folder.replace('user/', '') - if not user in subjects_deleted and conf.dryrun: + if user not in subjects_deleted and conf.dryrun: subjects_deleted.append(user) if conf.dryrun: log.info(_("Would have deleted folder '%s' (dryrun)") % (folder)) else: log.info(_("Deleting folder '%s'") % (folder)) try: imap.dm(folder) + # pylint: disable=bare-except except: log.error(_("Error deleting folder '%s'") % (folder)) for folder in imap.lm('shared/%%@%s' % (domain)): if conf.dryrun: log.info(_("Would have deleted folder '%s' (dryrun)") % (folder)) else: log.info(_("Deleting folder '%s'") % (folder)) try: imap.dm(folder) + # pylint: disable=bare-except except: log.error(_("Error deleting folder '%s'") % (folder)) + if not conf.with_acls: + return + for folder in [x for x in imap.lm() if not x.startswith('DELETED/')]: folder = imap_utf7.decode(folder) acls = imap.list_acls(folder) for subject in acls.keys(): if subject == 'anyone': log.info( - _("Skipping removal of ACL %s for subject %s on folder %s") % ( - acls[subject], - subject, - folder - ) + _("Skipping removal of ACL %s for subject %s on folder %s") % ( + acls[subject], + subject, + folder ) + ) continue - if not subject in subjects and not subject in subjects_deleted: + if subject not in subjects and subject not in subjects_deleted: if conf.dryrun: log.info( - _("Would have deleted ACL %s for subject %s on folder %s") % ( - acls[subject], - subject, - folder - ) + _("Would have deleted ACL %s for subject %s on folder %s") % ( + acls[subject], + subject, + folder ) + ) else: log.info( - _("Deleting ACL %s for subject %s on folder %s") % ( - acls[subject], - subject, - folder - ) + _("Deleting ACL %s for subject %s on folder %s") % ( + acls[subject], + subject, + folder ) + ) try: - imap.set_acl(folder, aci_subject, '') + imap.set_acl(folder, subject, '') + # pylint: disable=bare-except except: log.error( - _("Error removing ACL %s for subject %s from folder %s") % ( - acls[subject], - subject, - folder - ) + _("Error removing ACL %s for subject %s from folder %s") % ( + acls[subject], + subject, + folder ) - + )