diff -r 4cd9d0a9f42f -r df1e3b67882a VirtualMailManager/handler.py --- a/VirtualMailManager/handler.py Sun Nov 11 16:53:52 2012 +0000 +++ b/VirtualMailManager/handler.py Tue Nov 20 13:40:32 2012 +0000 @@ -50,9 +50,9 @@ CFG_PATH = '/root:/usr/local/etc:/etc' RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$""" OTHER_TYPES = { - TYPE_ACCOUNT: (_(u'an account'), ACCOUNT_EXISTS), - TYPE_ALIAS: (_(u'an alias'), ALIAS_EXISTS), - TYPE_RELOCATED: (_(u'a relocated user'), RELOCATED_EXISTS), + TYPE_ACCOUNT: (_('an account'), ACCOUNT_EXISTS), + TYPE_ALIAS: (_('an alias'), ALIAS_EXISTS), + TYPE_RELOCATED: (_('a relocated user'), RELOCATED_EXISTS), } @@ -78,7 +78,7 @@ self._db_connect = None if os.geteuid(): - raise NotRootError(_(u"You are not root.\n\tGood bye!\n"), + raise NotRootError(_("You are not root.\n\tGood bye!\n"), CONF_NOPERM) if self._check_cfg_file(): self._cfg = Cfg(self._cfg_fname) @@ -98,21 +98,21 @@ self._cfg_fname = tmp break if not self._cfg_fname: - raise VMMError(_(u"Could not find '%(cfg_file)s' in: " - u"'%(cfg_path)s'") % {'cfg_file': CFG_FILE, + raise VMMError(_("Could not find '%(cfg_file)s' in: " + "'%(cfg_path)s'") % {'cfg_file': CFG_FILE, 'cfg_path': CFG_PATH}, CONF_NOFILE) def _check_cfg_file(self): """Checks the configuration file, returns bool""" self._find_cfg_file() fstat = os.stat(self._cfg_fname) - fmode = int(oct(fstat.st_mode & 0777)) + fmode = int(oct(fstat.st_mode & 0o777)) if fmode % 100 and fstat.st_uid != fstat.st_gid or \ fmode % 10 and fstat.st_uid == fstat.st_gid: # TP: Please keep the backticks around the command. `chmod 0600 …` - raise PermissionError(_(u"wrong permissions for '%(file)s': " - u"%(perms)s\n`chmod 0600 %(file)s` would " - u"be great.") % {'file': self._cfg_fname, + raise PermissionError(_("wrong permissions for '%(file)s': " + "%(perms)s\n`chmod 0600 %(file)s` would " + "be great.") % {'file': self._cfg_fname, 'perms': fmode}, CONF_WRONGPERM) else: return True @@ -124,23 +124,23 @@ dir_created = False basedir = self._cfg.dget('misc.base_directory') if not os.path.exists(basedir): - old_umask = os.umask(0006) - os.makedirs(basedir, 0771) + old_umask = os.umask(0o006) + os.makedirs(basedir, 0o771) os.chown(basedir, 0, 0) os.umask(old_umask) dir_created = True if not dir_created and not lisdir(basedir): - raise VMMError(_(u"'%(path)s' is not a directory.\n(%(cfg_file)s: " - u"section 'misc', option 'base_directory')") % + raise VMMError(_("'%(path)s' is not a directory.\n(%(cfg_file)s: " + "section 'misc', option 'base_directory')") % {'path': basedir, 'cfg_file': self._cfg_fname}, NO_SUCH_DIRECTORY) for opt, val in self._cfg.items('bin'): try: exec_ok(val) - except VMMError, err: + except VMMError as err: if err.code in (NO_SUCH_BINARY, NOT_EXECUTABLE): - raise VMMError(err.msg + _(u"\n(%(cfg_file)s: section " - u"'bin', option '%(option)s')") % + raise VMMError(err.msg + _("\n(%(cfg_file)s: section " + "'bin', option '%(option)s')") % {'cfg_file': self._cfg_fname, 'option': opt}, err.code) else: @@ -153,14 +153,14 @@ try: _db_mod = __import__('psycopg2') except ImportError: - raise VMMError(_(u"Unable to import database module '%s'.") % + raise VMMError(_("Unable to import database module '%s'.") % 'psycopg2', VMM_ERROR) self._db_connect = self._psycopg2_connect else: try: tmp = __import__('pyPgSQL', globals(), locals(), ['PgSQL']) except ImportError: - raise VMMError(_(u"Unable to import database module '%s'.") % + raise VMMError(_("Unable to import database module '%s'.") % 'pyPgSQL', VMM_ERROR) _db_mod = tmp.PgSQL self._db_connect = self._pypgsql_connect @@ -180,7 +180,7 @@ dbc = self._dbh.cursor() dbc.execute("SET NAMES 'UTF8'") dbc.close() - except _db_mod.libpq.DatabaseError, err: + except _db_mod.libpq.DatabaseError as err: raise VMMError(str(err), DATABASE_ERROR) def _psycopg2_connect(self): @@ -201,7 +201,7 @@ dbc = self._dbh.cursor() dbc.execute("SET NAMES 'UTF8'") dbc.close() - except _db_mod.DatabaseError, err: + except _db_mod.DatabaseError as err: raise VMMError(str(err), DATABASE_ERROR) def _chk_other_address_types(self, address, exclude): @@ -239,7 +239,7 @@ return False # TP: %(a_type)s will be one of: 'an account', 'an alias' or # 'a relocated user' - msg = _(u"There is already %(a_type)s with the address '%(address)s'.") + msg = _("There is already %(a_type)s with the address '%(address)s'.") raise VMMError(msg % {'a_type': OTHER_TYPES[other][0], 'address': address}, OTHER_TYPES[other][1]) @@ -292,16 +292,16 @@ hashdir, domdir = domain.directory.split(os.path.sep)[-2:] dir_created = False os.chdir(self._cfg.dget('misc.base_directory')) - old_umask = os.umask(0022) + old_umask = os.umask(0o022) if not os.path.exists(hashdir): - os.mkdir(hashdir, 0711) + os.mkdir(hashdir, 0o711) os.chown(hashdir, 0, 0) dir_created = True if not dir_created and not lisdir(hashdir): - raise VMMError(_(u"'%s' is not a directory.") % hashdir, + raise VMMError(_("'%s' is not a directory.") % hashdir, NO_SUCH_DIRECTORY) if os.path.exists(domain.directory): - raise VMMError(_(u"The file/directory '%s' already exists.") % + raise VMMError(_("The file/directory '%s' already exists.") % domain.directory, VMM_ERROR) os.mkdir(os.path.join(hashdir, domdir), self._cfg.dget('domain.directory_mode')) @@ -314,7 +314,7 @@ domdir = account.domain.directory if not lisdir(domdir): self._make_domain_dir(account.domain) - os.umask(0007) + os.umask(0o007) uid = account.uid os.chdir(domdir) os.mkdir('%s' % uid, self._cfg.dget('account.directory_mode')) @@ -331,7 +331,7 @@ bad = mailbox.add_boxes(folders, self._cfg.dget('mailbox.subscribe')) if bad: - self._warnings.append(_(u"Skipped mailbox folders:") + + self._warnings.append(_("Skipped mailbox folders:") + '\n\t- ' + '\n\t- '.join(bad)) os.chdir(oldpwd) @@ -348,29 +348,29 @@ `gid` : int/long The user's GID (commonly AccountObj.gid) """ - assert all(isinstance(xid, (long, int)) for xid in (uid, gid)) and \ - isinstance(domdir, basestring) + assert all(isinstance(xid, int) for xid in (uid, gid)) and \ + isinstance(domdir, str) if uid < MIN_UID or gid < MIN_GID: - raise VMMError(_(u"UID '%(uid)u' and/or GID '%(gid)u' are less " - u"than %(min_uid)u/%(min_gid)u.") % {'uid': uid, + raise VMMError(_("UID '%(uid)u' and/or GID '%(gid)u' are less " + "than %(min_uid)u/%(min_gid)u.") % {'uid': uid, 'gid': gid, 'min_gid': MIN_GID, 'min_uid': MIN_UID}, MAILDIR_PERM_MISMATCH) if domdir.count('..'): - raise VMMError(_(u'Found ".." in domain directory path: %s') % + raise VMMError(_('Found ".." in domain directory path: %s') % domdir, FOUND_DOTS_IN_PATH) if not lisdir(domdir): - raise VMMError(_(u"No such directory: %s") % domdir, + raise VMMError(_("No such directory: %s") % domdir, NO_SUCH_DIRECTORY) os.chdir(domdir) userdir = '%s' % uid if not lisdir(userdir): - self._warnings.append(_(u"No such directory: %s") % + self._warnings.append(_("No such directory: %s") % os.path.join(domdir, userdir)) return mdstat = os.lstat(userdir) if (mdstat.st_uid, mdstat.st_gid) != (uid, gid): - raise VMMError(_(u'Detected owner/group mismatch in home ' - u'directory.'), MAILDIR_PERM_MISMATCH) + raise VMMError(_('Detected owner/group mismatch in home ' + 'directory.'), MAILDIR_PERM_MISMATCH) rmtree(userdir, ignore_errors=True) def _delete_domain_dir(self, domdir, gid): @@ -383,21 +383,21 @@ `gid` : int/long The domain's GID (commonly DomainObj.gid) """ - assert isinstance(domdir, basestring) and isinstance(gid, (long, int)) + assert isinstance(domdir, str) and isinstance(gid, int) if gid < MIN_GID: - raise VMMError(_(u"GID '%(gid)u' is less than '%(min_gid)u'.") % + raise VMMError(_("GID '%(gid)u' is less than '%(min_gid)u'.") % {'gid': gid, 'min_gid': MIN_GID}, DOMAINDIR_GROUP_MISMATCH) if domdir.count('..'): - raise VMMError(_(u'Found ".." in domain directory path: %s') % + raise VMMError(_('Found ".." in domain directory path: %s') % domdir, FOUND_DOTS_IN_PATH) if not lisdir(domdir): self._warnings.append(_('No such directory: %s') % domdir) return dirst = os.lstat(domdir) if dirst.st_gid != gid: - raise VMMError(_(u'Detected group mismatch in domain directory: ' - u'%s') % domdir, DOMAINDIR_GROUP_MISMATCH) + raise VMMError(_('Detected group mismatch in domain directory: ' + '%s') % domdir, DOMAINDIR_GROUP_MISMATCH) rmtree(domdir, ignore_errors=True) def has_warnings(self): @@ -425,9 +425,9 @@ def cfg_install(self): """Installs the cfg_dget method as ``cfg_dget`` into the built-in namespace.""" - import __builtin__ - assert 'cfg_dget' not in __builtin__.__dict__ - __builtin__.__dict__['cfg_dget'] = self._cfg.dget + import builtins + assert 'cfg_dget' not in builtins.__dict__ + builtins.__dict__['cfg_dget'] = self._cfg.dget def domain_add(self, domainname, transport=None): """Wrapper around Domain's set_quotalimit, set_transport and save.""" @@ -438,7 +438,7 @@ else: dom.set_transport(Transport(self._dbh, transport=transport)) dom.set_quotalimit(QuotaLimit(self._dbh, - bytes=long(self._cfg.dget('domain.quota_bytes')), + bytes=int(self._cfg.dget('domain.quota_bytes')), messages=self._cfg.dget('domain.quota_messages'))) dom.set_serviceset(ServiceSet(self._dbh, imap=self._cfg.dget('domain.imap'), @@ -451,11 +451,11 @@ def domain_quotalimit(self, domainname, bytes_, messages=0, force=None): """Wrapper around Domain.update_quotalimit().""" - if not all(isinstance(i, (int, long)) for i in (bytes_, messages)): + if not all(isinstance(i, int) for i in (bytes_, messages)): raise TypeError("'bytes_' and 'messages' have to be " "integers or longs.") if force is not None and force != 'force': - raise DomainError(_(u"Invalid argument: '%s'") % force, + raise DomainError(_("Invalid argument: '%s'") % force, INVALID_ARGUMENT) dom = self._get_domain(domainname) quotalimit = QuotaLimit(self._dbh, bytes=bytes_, messages=messages) @@ -468,11 +468,11 @@ """Wrapper around Domain.update_serviceset().""" kwargs = dict.fromkeys(SERVICES, False) if force is not None and force != 'force': - raise DomainError(_(u"Invalid argument: '%s'") % force, + raise DomainError(_("Invalid argument: '%s'") % force, INVALID_ARGUMENT) for service in set(services): if service not in SERVICES: - raise DomainError(_(u"Unknown service: '%s'") % service, + raise DomainError(_("Unknown service: '%s'") % service, UNKNOWN_SERVICE) kwargs[service] = True @@ -483,7 +483,7 @@ def domain_transport(self, domainname, transport, force=None): """Wrapper around Domain.update_transport()""" if force is not None and force != 'force': - raise DomainError(_(u"Invalid argument: '%s'") % force, + raise DomainError(_("Invalid argument: '%s'") % force, INVALID_ARGUMENT) dom = self._get_domain(domainname) trsp = Transport(self._dbh, transport=transport) @@ -517,7 +517,7 @@ Domain.get_relocated.""" if details not in [None, 'accounts', 'aliasdomains', 'aliases', 'full', 'relocated', 'catchall']: - raise VMMError(_(u"Invalid argument: '%s'") % details, + raise VMMError(_("Invalid argument: '%s'") % details, INVALID_ARGUMENT) dom = self._get_domain(domainname) dominfo = dom.get_info() @@ -596,8 +596,8 @@ if pattern and (pattern.startswith('%') or pattern.endswith('%')): like = True if not re.match(RE_DOMAIN_SEARCH, pattern.strip('%')): - raise VMMError(_(u"The pattern '%s' contains invalid " - u"characters.") % pattern, DOMAIN_INVALID) + raise VMMError(_("The pattern '%s' contains invalid " + "characters.") % pattern, DOMAIN_INVALID) self._db_connect() return search(self._dbh, pattern=pattern, like=like) @@ -617,8 +617,8 @@ checkp = lpattern.strip('%') if llike else lpattern if len(checkp) > 0 and re.search(RE_LOCALPART, checkp): - raise VMMError(_(u"The pattern '%s' contains invalid " - u"characters.") % pattern, + raise VMMError(_("The pattern '%s' contains invalid " + "characters.") % pattern, LOCALPART_INVALID) else: # else just match on domains @@ -628,8 +628,8 @@ checkp = dpattern.strip('%') if dlike else dpattern if len(checkp) > 0 and not re.match(RE_DOMAIN_SEARCH, checkp): - raise VMMError(_(u"The pattern '%s' contains invalid " - u"characters.") % pattern, DOMAIN_INVALID) + raise VMMError(_("The pattern '%s' contains invalid " + "characters.") % pattern, DOMAIN_INVALID) self._db_connect() from VirtualMailManager.common import search_addresses return search_addresses(self._dbh, typelimit=typelimit, @@ -640,7 +640,7 @@ """Wrapper around Account.set_password() and Account.save().""" acc = self._get_account(emailaddress) if acc: - raise VMMError(_(u"The account '%s' already exists.") % + raise VMMError(_("The account '%s' already exists.") % acc.address, ACCOUNT_EXISTS) self._is_other_address(acc.address, TYPE_ACCOUNT) acc.set_password(password) @@ -663,8 +663,8 @@ for destination in destinations: if destination.gid and \ not self._chk_other_address_types(destination, TYPE_RELOCATED): - self._warnings.append(_(u"The destination account/alias '%s' " - u"does not exist.") % destination) + self._warnings.append(_("The destination account/alias '%s' " + "does not exist.") % destination) def user_delete(self, emailaddress, force=False): """Wrapper around Account.delete(...)""" @@ -672,7 +672,7 @@ raise TypeError('force must be a bool') acc = self._get_account(emailaddress) if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) uid = acc.uid gid = acc.gid @@ -682,10 +682,10 @@ if self._cfg.dget('account.delete_directory'): try: self._delete_home(dom_dir, uid, gid) - except VMMError, err: + except VMMError as err: if err.code in (FOUND_DOTS_IN_PATH, MAILDIR_PERM_MISMATCH, NO_SUCH_DIRECTORY): - warning = _(u"""\ + warning = _("""\ The account has been successfully deleted from the database. But an error occurred while deleting the following directory: '%(directory)s' @@ -701,7 +701,7 @@ if alias: return alias.get_destinations() if not self._is_other_address(alias.address, TYPE_ALIAS): - raise VMMError(_(u"The alias '%s' does not exist.") % + raise VMMError(_("The alias '%s' does not exist.") % alias.address, NO_SUCH_ALIAS) def alias_delete(self, aliasaddress, targetaddresses=None): @@ -718,7 +718,7 @@ warnings = [] try: alias.del_destinations(destinations, warnings) - except VMMError, err: + except VMMError as err: error = err if warnings: self._warnings.append(_('Ignored destination addresses:')) @@ -740,8 +740,8 @@ for destination in destinations: if destination.gid and \ not self._chk_other_address_types(destination, TYPE_RELOCATED): - self._warnings.append(_(u"The destination account/alias '%s' " - u"does not exist.") % destination) + self._warnings.append(_("The destination account/alias '%s' " + "does not exist.") % destination) def catchall_info(self, domain): """Returns an iterator object for all destinations (`EmailAddress` @@ -762,7 +762,7 @@ warnings = [] try: catchall.del_destinations(destinations, warnings) - except VMMError, err: + except VMMError as err: error = err if warnings: self._warnings.append(_('Ignored destination addresses:')) @@ -773,12 +773,12 @@ def user_info(self, emailaddress, details=None): """Wrapper around Account.get_info(...)""" if details not in (None, 'du', 'aliases', 'full'): - raise VMMError(_(u"Invalid argument: '%s'") % details, + raise VMMError(_("Invalid argument: '%s'") % details, INVALID_ARGUMENT) acc = self._get_account(emailaddress) if not acc: if not self._is_other_address(acc.address, TYPE_ACCOUNT): - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) info = acc.get_info() if self._cfg.dget('account.disk_usage') or details in ('du', 'full'): @@ -799,12 +799,12 @@ def user_password(self, emailaddress, password): """Wrapper for Account.modify('password' ...).""" - if not isinstance(password, basestring) or not password: - raise VMMError(_(u"Could not accept password: '%s'") % password, + if not isinstance(password, str) or not password: + raise VMMError(_("Could not accept password: '%s'") % password, INVALID_ARGUMENT) acc = self._get_account(emailaddress) if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) acc.modify('password', password) @@ -812,7 +812,7 @@ """Wrapper for Account.modify('name', ...).""" acc = self._get_account(emailaddress) if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) acc.modify('name', name) @@ -820,7 +820,7 @@ """Wrapper for Account.modify('note', ...).""" acc = self._get_account(emailaddress) if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) acc.modify('note', note) @@ -828,12 +828,12 @@ """Wrapper for Account.update_quotalimit(QuotaLimit).""" acc = self._get_account(emailaddress) if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) if bytes_ == 'domain': quotalimit = None else: - if not all(isinstance(i, (int, long)) for i in (bytes_, messages)): + if not all(isinstance(i, int) for i in (bytes_, messages)): raise TypeError("'bytes_' and 'messages' have to be " "integers or longs.") quotalimit = QuotaLimit(self._dbh, bytes=bytes_, @@ -842,12 +842,12 @@ def user_transport(self, emailaddress, transport): """Wrapper for Account.update_transport(Transport).""" - if not isinstance(transport, basestring) or not transport: - raise VMMError(_(u"Could not accept transport: '%s'") % transport, + if not isinstance(transport, str) or not transport: + raise VMMError(_("Could not accept transport: '%s'") % transport, INVALID_ARGUMENT) acc = self._get_account(emailaddress) if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) transport = None if transport == 'domain' \ else Transport(self._dbh, transport=transport) @@ -857,7 +857,7 @@ """Wrapper around Account.update_serviceset().""" acc = self._get_account(emailaddress) if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % + raise VMMError(_("The account '%s' does not exist.") % acc.address, NO_SUCH_ACCOUNT) if len(services) == 1 and services[0] == 'domain': serviceset = None @@ -865,7 +865,7 @@ kwargs = dict.fromkeys(SERVICES, False) for service in set(services): if service not in SERVICES: - raise VMMError(_(u"Unknown service: '%s'") % service, + raise VMMError(_("Unknown service: '%s'") % service, UNKNOWN_SERVICE) kwargs[service] = True serviceset = ServiceSet(self._dbh, **kwargs) @@ -882,8 +882,8 @@ relocated.set_destination(destination) if destination.gid and \ not self._chk_other_address_types(destination, TYPE_RELOCATED): - self._warnings.append(_(u"The destination account/alias '%s' " - u"does not exist.") % destination) + self._warnings.append(_("The destination account/alias '%s' " + "does not exist.") % destination) def relocated_info(self, emailaddress): """Returns the target address of the relocated user with the given @@ -892,7 +892,7 @@ if relocated: return relocated.get_info() if not self._is_other_address(relocated.address, TYPE_RELOCATED): - raise VMMError(_(u"The relocated user '%s' does not exist.") % + raise VMMError(_("The relocated user '%s' does not exist.") % relocated.address, NO_SUCH_RELOCATED) def relocated_delete(self, emailaddress):