--- a/VirtualMailManager/__init__.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/__init__.py Wed Nov 21 13:13:31 2012 +0000
@@ -32,4 +32,4 @@
locale.setlocale(locale.LC_ALL, 'C')
ENCODING = locale.nl_langinfo(locale.CODESET)
-gettext.install('vmm', '/usr/local/share/locale', unicode=1)
+gettext.install('vmm', '/usr/local/share/locale', str=1)
--- a/VirtualMailManager/account.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/account.py Wed Nov 21 13:13:31 2012 +0000
@@ -57,7 +57,7 @@
# TP: Hm, what “quotation marks” should be used?
# If you are unsure have a look at:
# http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage
- raise AErr(_(u"The domain '%s' does not exist.") %
+ raise AErr(_("The domain '%s' does not exist.") %
self._addr.domainname, NO_SUCH_DOMAIN)
self._uid = 0
self._mail = None
@@ -69,7 +69,7 @@
self._new = True
self._load()
- def __nonzero__(self):
+ def __bool__(self):
"""Returns `True` if the Account is known, `False` if it's new."""
return not self._new
@@ -86,11 +86,7 @@
self._uid, _mid, _qid, _ssid, _tid, _note = result
def load_helper(ctor, own, field, dbresult):
- # Py25: cur = None if own is None else getattr(own, field)
- if own is None:
- cur = None
- else:
- cur = getattr(own, field)
+ cur = None if own is None else getattr(own, field)
if cur != dbresult:
kwargs = {field: dbresult}
if dbresult is None:
@@ -120,8 +116,8 @@
information in the database.
"""
if maillocation.dovecot_version > cfg_dget('misc.dovecot_version'):
- raise AErr(_(u"The mailbox format '%(mbfmt)s' requires Dovecot "
- u">= v%(version)s.") % {
+ raise AErr(_("The mailbox format '%(mbfmt)s' requires Dovecot "
+ ">= v%(version)s.") % {
'mbfmt': maillocation.mbformat,
'version': version_str(maillocation.dovecot_version)},
INVALID_MAIL_LOCATION)
@@ -163,7 +159,7 @@
"""Raise an AccountError if the Account is new - not yet saved in the
database."""
if self._new:
- raise AErr(_(u"The account '%s' does not exist.") % self._addr,
+ raise AErr(_("The account '%s' does not exist.") % self._addr,
NO_SUCH_ACCOUNT)
@property
@@ -219,10 +215,10 @@
The password for the new Account.
"""
if not self._new:
- raise AErr(_(u"The account '%s' already exists.") % self._addr,
+ raise AErr(_("The account '%s' already exists.") % self._addr,
ACCOUNT_EXISTS)
- if not isinstance(password, basestring) or not password:
- raise AErr(_(u"Could not accept password: '%s'") % password,
+ if not isinstance(password, str) or not password:
+ raise AErr(_("Could not accept password: '%s'") % password,
ACCOUNT_MISSING_PASSWORD)
self._passwd = password
@@ -234,36 +230,29 @@
`note` : basestring or None
The note, or None to remove
"""
- assert note is None or isinstance(note, basestring)
+ assert note is None or isinstance(note, str)
self._note = note
def save(self):
"""Save the new Account in the database."""
if not self._new:
- raise AErr(_(u"The account '%s' already exists.") % self._addr,
+ raise AErr(_("The account '%s' already exists.") % self._addr,
ACCOUNT_EXISTS)
if not self._passwd:
- raise AErr(_(u"No password set for account: '%s'") % self._addr,
+ raise AErr(_("No password set for account: '%s'") % self._addr,
ACCOUNT_MISSING_PASSWORD)
self._prepare(MailLocation(self._dbh, mbfmt=cfg_dget('mailbox.format'),
directory=cfg_dget('mailbox.root')))
dbc = self._dbh.cursor()
- qid = ssid = tid = None
- if self._qlimit:
- qid = self._qlimit.qid
- if self._services:
- ssid = self._services.ssid
- if self._transport:
- tid = self._transport.tid
dbc.execute('INSERT INTO users (local_part, passwd, uid, gid, mid, '
'qid, ssid, tid, note) '
'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)',
(self._addr.localpart,
pwhash(self._passwd, user=self._addr), self._uid,
- self._domain.gid, self._mail.mid, qid, ssid, tid,
-# self._qlimit.qid if self._qlimit else None,
-# self._services.ssid if self._services else None,
-# self._transport.tid if self._transport else None,
+ self._domain.gid, self._mail.mid,
+ self._qlimit.qid if self._qlimit else None,
+ self._services.ssid if self._services else None,
+ self._transport.tid if self._transport else None,
self._note))
self._dbh.commit()
dbc.close()
@@ -282,7 +271,7 @@
The new value of the attribute.
"""
if field not in ('name', 'password', 'note'):
- raise AErr(_(u"Unknown field: '%s'") % field, INVALID_ARGUMENT)
+ raise AErr(_("Unknown field: '%s'") % field, INVALID_ARGUMENT)
self._chk_state()
dbc = self._dbh.cursor()
if field == 'password':
@@ -304,8 +293,8 @@
the new quota limit of the domain.
"""
if cfg_dget('misc.dovecot_version') < 0x10102f00:
- raise VMMError(_(u'PostgreSQL-based dictionary quota requires '
- u'Dovecot >= v1.1.2.'), VMM_ERROR)
+ raise VMMError(_('PostgreSQL-based dictionary quota requires '
+ 'Dovecot >= v1.1.2.'), VMM_ERROR)
self._chk_state()
if quotalimit == self._qlimit:
return
@@ -364,7 +353,7 @@
fmt = format_domain_default
ret = {}
- for service, state in services.iteritems():
+ for service, state in services.items():
# TP: A service (e.g. pop3 or imap) may be enabled/usable or
# disabled/unusable for a user.
ret[service] = fmt((_('disabled'), _('enabled'))[state])
@@ -387,7 +376,7 @@
info = dbc.fetchone()
dbc.close()
if info:
- info = dict(zip(('name', 'uq_bytes', 'uq_messages'), info))
+ info = dict(list(zip(('name', 'uq_bytes', 'uq_messages'), info)))
info.update(self._get_info_serviceset())
info['address'] = self._addr
info['gid'] = self._domain.gid
@@ -406,7 +395,7 @@
info['uid'] = self._uid
return info
# nearly impossible‽
- raise AErr(_(u"Could not fetch information for account: '%s'") %
+ raise AErr(_("Could not fetch information for account: '%s'") %
self._addr, NO_SUCH_ACCOUNT)
def get_aliases(self):
@@ -450,8 +439,8 @@
a_count = self._count_aliases()
if a_count > 0:
dbc.close()
- raise AErr(_(u"There are %(count)d aliases with the "
- u"destination address '%(address)s'.") %
+ raise AErr(_("There are %(count)d aliases with the "
+ "destination address '%(address)s'.") %
{'count': a_count, 'address': self._addr},
ALIAS_PRESENT)
dbc.execute('DELETE FROM users WHERE uid = %s', (self._uid,))
@@ -477,11 +466,11 @@
a database connection for the database access.
"""
try:
- uid = long(uid)
+ uid = int(uid)
except ValueError:
- raise AErr(_(u'UID must be an int/long.'), INVALID_ARGUMENT)
+ raise AErr(_('UID must be an int/long.'), INVALID_ARGUMENT)
if uid < 1:
- raise AErr(_(u'UID must be greater than 0.'), INVALID_ARGUMENT)
+ raise AErr(_('UID must be greater than 0.'), INVALID_ARGUMENT)
dbc = dbh.cursor()
dbc.execute("SELECT local_part||'@'|| domain_name.domainname AS address, "
"uid, users.gid, note FROM users LEFT JOIN domain_name ON "
@@ -490,9 +479,9 @@
info = dbc.fetchone()
dbc.close()
if not info:
- raise AErr(_(u"There is no account with the UID: '%d'") % uid,
+ raise AErr(_("There is no account with the UID: '%d'") % uid,
NO_SUCH_ACCOUNT)
- info = dict(zip(('address', 'uid', 'gid', 'note'), info))
+ info = dict(list(zip(('address', 'uid', 'gid', 'note'), info)))
return info
del _, cfg_dget
--- a/VirtualMailManager/alias.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/alias.py Wed Nov 21 13:13:31 2012 +0000
@@ -13,7 +13,6 @@
EmailAddress, DestinationEmailAddress as DestAddr
from VirtualMailManager.errors import AliasError as AErr
from VirtualMailManager.ext.postconf import Postconf
-from VirtualMailManager.pycompat import all
from VirtualMailManager.constants import \
ALIAS_EXCEEDS_EXPANSION_LIMIT, NO_SUCH_ALIAS, NO_SUCH_DOMAIN
@@ -32,7 +31,7 @@
self._dbh = dbh
self._gid = get_gid(self._dbh, self._addr.domainname)
if not self._gid:
- raise AErr(_(u"The domain '%s' does not exist.") %
+ raise AErr(_("The domain '%s' does not exist.") %
self._addr.domainname, NO_SUCH_DOMAIN)
self._dests = []
@@ -52,20 +51,20 @@
def _check_expansion(self, count_new):
"""Checks the current expansion limit of the alias."""
postconf = Postconf(cfg_dget('bin.postconf'))
- limit = long(postconf.read('virtual_alias_expansion_limit'))
+ limit = int(postconf.read('virtual_alias_expansion_limit'))
dcount = len(self._dests)
failed = False
if dcount == limit or dcount + count_new > limit:
failed = True
errmsg = _(
-u"""Cannot add %(count_new)i new destination(s) to alias '%(address)s'.
+"""Cannot add %(count_new)i new destination(s) to alias '%(address)s'.
Currently this alias expands into %(count)i/%(limit)i recipients.
%(count_new)i additional destination(s) will render this alias unusable.
Hint: Increase Postfix' virtual_alias_expansion_limit""")
elif dcount > limit:
failed = True
errmsg = _(
-u"""Cannot add %(count_new)i new destination(s) to alias '%(address)s'.
+"""Cannot add %(count_new)i new destination(s) to alias '%(address)s'.
This alias already exceeds its expansion limit (%(count)i/%(limit)i).
So its unusable, all messages addressed to this alias will be bounced.
Hint: Delete some destination addresses.""")
@@ -152,7 +151,7 @@
if not warnings is None:
warnings.append(self._addr)
if not self._dests:
- raise AErr(_(u"The alias '%s' does not exist.") % self._addr,
+ raise AErr(_("The alias '%s' does not exist.") % self._addr,
NO_SUCH_ALIAS)
unknown = destinations.difference(set(self._dests))
if unknown:
@@ -160,8 +159,8 @@
if not warnings is None:
warnings.extend(unknown)
if not destinations:
- raise AErr(_(u"No suitable destinations left to remove from alias "
- u"'%s'.") % self._addr, NO_SUCH_ALIAS)
+ raise AErr(_("No suitable destinations left to remove from alias "
+ "'%s'.") % self._addr, NO_SUCH_ALIAS)
self._delete(destinations)
for destination in destinations:
self._dests.remove(destination)
@@ -169,14 +168,14 @@
def get_destinations(self):
"""Returns an iterator for all destinations of the alias."""
if not self._dests:
- raise AErr(_(u"The alias '%s' does not exist.") % self._addr,
+ raise AErr(_("The alias '%s' does not exist.") % self._addr,
NO_SUCH_ALIAS)
return iter(self._dests)
def delete(self):
"""Deletes the alias with all its destinations."""
if not self._dests:
- raise AErr(_(u"The alias '%s' does not exist.") % self._addr,
+ raise AErr(_("The alias '%s' does not exist.") % self._addr,
NO_SUCH_ALIAS)
self._delete()
del self._dests[:]
--- a/VirtualMailManager/aliasdomain.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/aliasdomain.py Wed Nov 21 13:13:31 2012 +0000
@@ -47,7 +47,7 @@
dbc.close()
if result:
if result[1]:
- raise ADErr(_(u"The domain '%s' is a primary domain.") %
+ raise ADErr(_("The domain '%s' is a primary domain.") %
self._name, ALIASDOMAIN_ISDOMAIN)
self._gid = result[0]
@@ -66,13 +66,13 @@
def save(self):
"""Stores information about the new AliasDomain in the database."""
if self._gid > 0:
- raise ADErr(_(u"The alias domain '%s' already exists.") %
+ raise ADErr(_("The alias domain '%s' already exists.") %
self._name, ALIASDOMAIN_EXISTS)
if not self._domain:
- raise ADErr(_(u'No destination domain set for the alias domain.'),
+ raise ADErr(_('No destination domain set for the alias domain.'),
ALIASDOMAIN_NO_DOMDEST)
if self._domain.gid < 1:
- raise ADErr(_(u"The target domain '%s' does not exist.") %
+ raise ADErr(_("The target domain '%s' does not exist.") %
self._domain.name, NO_SUCH_DOMAIN)
dbc = self._dbh.cursor()
dbc.execute('INSERT INTO domain_name (domainname, gid, is_primary) '
@@ -85,7 +85,7 @@
"""Returns a dict (keys: "alias" and "domain") with the names of the
AliasDomain and its primary domain."""
if self._gid < 1:
- raise ADErr(_(u"The alias domain '%s' does not exist.") %
+ raise ADErr(_("The alias domain '%s' does not exist.") %
self._name, NO_SUCH_ALIASDOMAIN)
dbc = self._dbh.cursor()
dbc.execute('SELECT domainname FROM domain_name WHERE gid = %s AND '
@@ -95,25 +95,25 @@
if domain:
return {'alias': self._name, 'domain': domain[0]}
else: # an almost unlikely case, isn't it?
- raise ADErr(_(u'There is no primary domain for the alias domain '
- u"'%s'.") % self._name, NO_SUCH_DOMAIN)
+ raise ADErr(_('There is no primary domain for the alias domain '
+ "'%s'.") % self._name, NO_SUCH_DOMAIN)
def switch(self):
"""Switch the destination of the AliasDomain to the new destination,
set with the method `set_destination()`.
"""
if not self._domain:
- raise ADErr(_(u'No destination domain set for the alias domain.'),
+ raise ADErr(_('No destination domain set for the alias domain.'),
ALIASDOMAIN_NO_DOMDEST)
if self._domain.gid < 1:
- raise ADErr(_(u"The target domain '%s' does not exist.") %
+ raise ADErr(_("The target domain '%s' does not exist.") %
self._domain.name, NO_SUCH_DOMAIN)
if self._gid < 1:
- raise ADErr(_(u"The alias domain '%s' does not exist.") %
+ raise ADErr(_("The alias domain '%s' does not exist.") %
self._name, NO_SUCH_ALIASDOMAIN)
if self._gid == self._domain.gid:
- raise ADErr(_(u"The alias domain '%(alias)s' is already assigned "
- u"to the domain '%(domain)s'.") %
+ raise ADErr(_("The alias domain '%(alias)s' is already assigned "
+ "to the domain '%(domain)s'.") %
{'alias': self._name, 'domain': self._domain.name},
ALIASDOMAIN_EXISTS)
dbc = self._dbh.cursor()
@@ -130,7 +130,7 @@
Raises an AliasDomainError if the AliasDomain doesn't exist.
"""
if self._gid < 1:
- raise ADErr(_(u"The alias domain '%s' does not exist.") %
+ raise ADErr(_("The alias domain '%s' does not exist.") %
self._name, NO_SUCH_ALIASDOMAIN)
dbc = self._dbh.cursor()
dbc.execute('DELETE FROM domain_name WHERE domainname = %s AND NOT '
--- a/VirtualMailManager/catchall.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/catchall.py Wed Nov 21 13:13:31 2012 +0000
@@ -23,7 +23,6 @@
EmailAddress, DestinationEmailAddress as DestAddr
from VirtualMailManager.errors import AliasError as AErr
from VirtualMailManager.ext.postconf import Postconf
-from VirtualMailManager.pycompat import all
from VirtualMailManager.constants import \
ALIAS_EXCEEDS_EXPANSION_LIMIT, NO_SUCH_ALIAS, NO_SUCH_DOMAIN
@@ -41,7 +40,7 @@
self._dbh = dbh
self._gid = get_gid(self._dbh, self.domain)
if not self._gid:
- raise AErr(_(u"The domain '%s' does not exist.") %
+ raise AErr(_("The domain '%s' does not exist.") %
self.domain, NO_SUCH_DOMAIN)
self._dests = []
@@ -60,13 +59,13 @@
def _check_expansion(self, count_new):
"""Checks the current expansion limit of the alias."""
postconf = Postconf(cfg_dget('bin.postconf'))
- limit = long(postconf.read('virtual_alias_expansion_limit'))
+ limit = int(postconf.read('virtual_alias_expansion_limit'))
dcount = len(self._dests)
failed = False
if dcount == limit or dcount + count_new > limit:
failed = True
errmsg = _(
-u"""Cannot add %(count_new)i new destination(s) to catch-all alias for
+"""Cannot add %(count_new)i new destination(s) to catch-all alias for
domain '%(domain)s'. Currently this alias expands into %(count)i/%(limit)i
recipients. %(count_new)i additional destination(s) will render this alias
unusable.
@@ -74,7 +73,7 @@
elif dcount > limit:
failed = True
errmsg = _(
-u"""Cannot add %(count_new)i new destination(s) to catch-all alias for domain
+"""Cannot add %(count_new)i new destination(s) to catch-all alias for domain
'%(domain)s'. This alias already exceeds its expansion limit \
(%(count)i/%(limit)i).
So its unusable, all messages addressed to this alias will be bounced.
@@ -148,16 +147,16 @@
if not warnings is None:
assert isinstance(warnings, list)
if not self._dests:
- raise AErr(_(u"There are no catch-all aliases defined for "
- u"domain '%s'.") % self._domain, NO_SUCH_ALIAS)
+ raise AErr(_("There are no catch-all aliases defined for "
+ "domain '%s'.") % self._domain, NO_SUCH_ALIAS)
unknown = destinations.difference(set(self._dests))
if unknown:
destinations.intersection_update(set(self._dests))
if not warnings is None:
warnings.extend(unknown)
if not destinations:
- raise AErr(_(u"No suitable destinations left to remove from the "
- u"catch-all alias of domain '%s'.") % self._domain,
+ raise AErr(_("No suitable destinations left to remove from the "
+ "catch-all alias of domain '%s'.") % self._domain,
NO_SUCH_ALIAS)
self._delete(destinations)
for destination in destinations:
@@ -166,15 +165,15 @@
def get_destinations(self):
"""Returns an iterator for all destinations of the catchall alias."""
if not self._dests:
- raise AErr(_(u"There are no catch-all aliases defined for "
- u"domain '%s'.") % self._domain, NO_SUCH_ALIAS)
+ raise AErr(_("There are no catch-all aliases defined for "
+ "domain '%s'.") % self._domain, NO_SUCH_ALIAS)
return iter(self._dests)
def delete(self):
"""Deletes all catchall destinations for the domain."""
if not self._dests:
- raise AErr(_(u"There are no catch-all aliases defined for "
- u"domain '%s'.") % self._domain, NO_SUCH_ALIAS)
+ raise AErr(_("There are no catch-all aliases defined for "
+ "domain '%s'.") % self._domain, NO_SUCH_ALIAS)
self._delete()
del self._dests[:]
--- a/VirtualMailManager/cli/__init__.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/cli/__init__.py Wed Nov 21 13:13:31 2012 +0000
@@ -75,24 +75,24 @@
Throws a VMMError after the third failure.
"""
# TP: Please preserve the trailing space.
- readp_msg0 = _(u'Enter new password: ').encode(ENCODING, 'replace')
+ readp_msg0 = _('Enter new password: ').encode(ENCODING, 'replace')
# TP: Please preserve the trailing space.
- readp_msg1 = _(u'Retype new password: ').encode(ENCODING, 'replace')
+ readp_msg1 = _('Retype new password: ').encode(ENCODING, 'replace')
mismatched = True
failures = 0
while mismatched:
if failures > 2:
- raise VMMError(_(u'Too many failures - try again later.'),
+ raise VMMError(_('Too many failures - try again later.'),
VMM_TOO_MANY_FAILURES)
clear0 = getpass(prompt=readp_msg0)
clear1 = getpass(prompt=readp_msg1)
if clear0 != clear1:
failures += 1
- w_err(0, _(u'Sorry, passwords do not match.'))
+ w_err(0, _('Sorry, passwords do not match.'))
continue
if not clear0:
failures += 1
- w_err(0, _(u'Sorry, empty passwords are not permitted.'))
+ w_err(0, _('Sorry, empty passwords are not permitted.'))
continue
mismatched = False
return clear0
--- a/VirtualMailManager/cli/clihelp.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/cli/clihelp.py Wed Nov 21 13:13:31 2012 +0000
@@ -18,242 +18,242 @@
# and 'force', enclosed within single quotes. Please keep them as they are.
#
# TP: description of subcommand configget
- 'configget': (_(u"""This subcommand is used to display the actual value
+ 'configget': (_("""This subcommand is used to display the actual value
of the given configuration <option>."""),),
# TP: description of subcommand configset
- 'configset': (_(u"""Use this subcommand to set or update a single
+ 'configset': (_("""Use this subcommand to set or update a single
configuration option's value. <option> is the configuration option, <value>
is the <option>'s new value."""),
-_(u"""Note: This subcommand will create a new vmm.cfg without any comments.
+_("""Note: This subcommand will create a new vmm.cfg without any comments.
Your current configuration file will be backed as vmm.cfg.bak."""),),
# TP: description of subcommand configure
- 'configure': (_(u"""Starts the interactive configuration for all
+ 'configure': (_("""Starts the interactive configuration for all
configuration sections."""),
-_(u"""In this process the currently set value of each option will be displayed
+_("""In this process the currently set value of each option will be displayed
in square brackets. If no value is configured, the default value of each
option will be displayed in square brackets. Press the return key, to accept
the displayed value."""),
-_(u"""If the optional argument <section> is given, only the configuration
+_("""If the optional argument <section> is given, only the configuration
options from the given section will be displayed and will be configurable.
The following sections are available:
"""),
""" account, bin, database, domain, mailbox, misc""",
-_(u"""All configuration options are described in vmm.cfg(5)."""),
-_(u"""Note: This subcommand will create a new vmm.cfg without any comments.
+_("""All configuration options are described in vmm.cfg(5)."""),
+_("""Note: This subcommand will create a new vmm.cfg without any comments.
Your current configuration file will be backed as vmm.cfg.bak."""),),
# TP: description of subcommand getuser
- 'getuser': (_(u"""If only the <uid> is available, for example from process
+ 'getuser': (_("""If only the <uid> is available, for example from process
list, the subcommand getuser will show the user's address."""),),
# TP: description of subcommand listaddresses
- 'listaddresses': (_(u"""This command lists all defined addresses.
+ 'listaddresses': (_("""This command lists all defined addresses.
Addresses belonging to alias-domains are prefixed with a '-', addresses of
regular domains with a '+'. Additionally, the letters 'u', 'a', and 'r'
indicate the type of each address: user, alias and relocated respectively.
The output can be limited with an optional <pattern>."""),
-_(u"""To perform a wild card search, the % character can be used at the start
+_("""To perform a wild card search, the % character can be used at the start
and/or the end of the <pattern>."""),),
# TP: description of subcommand listaliases
- 'listaliases': (_(u"""This command lists all defined aliases. Aliases
+ 'listaliases': (_("""This command lists all defined aliases. Aliases
belonging to alias-domains are prefixed with a '-', addresses of regular
domains with a '+'. The output can be limited with an optional <pattern>."""),
-_(u"""To perform a wild card search, the % character can be used at the start
+_("""To perform a wild card search, the % character can be used at the start
and/or the end of the <pattern>."""),),
# TP: description of subcommand listdomains
- 'listdomains': (_(u"""This subcommand lists all available domains. All
+ 'listdomains': (_("""This subcommand lists all available domains. All
domain names will be prefixed either with `[+]', if the domain is a primary
domain, or with `[-]', if it is an alias domain name. The output can be
limited with an optional <pattern>."""),
-_(u"""To perform a wild card search, the % character can be used at the start
+_("""To perform a wild card search, the % character can be used at the start
and/or the end of the <pattern>."""),),
# TP: description of subcommand listpwschemes
- 'listpwschemes': (_(u"""This subcommand lists all password schemes which
+ 'listpwschemes': (_("""This subcommand lists all password schemes which
could be used in the vmm.cfg as value of the misc.password_scheme option.
The output varies, depending on the used Dovecot version and the system's
libc."""),
-_(u"""When your Dovecot installation isn't too old, you will see additionally
+_("""When your Dovecot installation isn't too old, you will see additionally
a few usable encoding suffixes. One of them can be appended to the password
scheme."""),),
# TP: description of subcommand listrelocated
- 'listrelocated': (_(u"""This command lists all defined relocated addresses.
+ 'listrelocated': (_("""This command lists all defined relocated addresses.
Relocated entries belonging to alias-domains are prefixed with a '-', addresses
of regular domains with a '+'. The output can be limited with an optional
<pattern>."""),
-_(u"""To perform a wild card search, the % character can be used at the start
+_("""To perform a wild card search, the % character can be used at the start
and/or the end of the <pattern>."""),),
# TP: description of subcommand listusers
- 'listusers': (_(u"""This command lists all user accounts. User accounts
+ 'listusers': (_("""This command lists all user accounts. User accounts
belonging to alias-domains are prefixed with a '-', addresses of regular
domains with a '+'. The output can be limited with an optional <pattern>."""),
-_(u"""To perform a wild card search, the % character can be used at the start
+_("""To perform a wild card search, the % character can be used at the start
and/or the end of the pattern."""),),
# TP: description of subcommand version
- 'version': (_(u"""Prints vmm's version and copyright information to stdout.
+ 'version': (_("""Prints vmm's version and copyright information to stdout.
After this vmm exits."""),),
# TP: description of subcommand domainadd
- 'domainadd': (_(u"""Adds the new domain into the database and creates the
+ 'domainadd': (_("""Adds the new domain into the database and creates the
domain directory."""),
-_(u"""If the optional argument <transport> is given, it will override the
+_("""If the optional argument <transport> is given, it will override the
default transport (domain.transport) from vmm.cfg. The specified <transport>
will be the default transport for all new accounts in this domain."""),
-_(u"""Configuration-related behavior:"""),
-u""" * domain.auto_postmaster""",
-_(u"""When that option is set to true (default) vmm will automatically create
+_("""Configuration-related behavior:"""),
+""" * domain.auto_postmaster""",
+_("""When that option is set to true (default) vmm will automatically create
the postmaster account for the new domain and prompt for postmaster@<fqdn>'s
password."""),
-u""" * account.random_password""",
-_(u"""When the value of that option is also set to true, vmm will automatically
+""" * account.random_password""",
+_("""When the value of that option is also set to true, vmm will automatically
create the postmaster account for the new domain and print the generated
postmaster password to stdout."""),),
# TP: description of subcommand domaindelete
- 'domaindelete': (_(u"""This subcommand deletes the domain specified by
+ 'domaindelete': (_("""This subcommand deletes the domain specified by
<fqdn>."""),
-_(u"""If there are accounts, aliases and/or relocated users assigned to the
+_("""If there are accounts, aliases and/or relocated users assigned to the
given domain, vmm will abort the requested operation and show an error
message. If you know, what you are doing, you can specify the optional keyword
'force'."""),
-_(u"""If you really always know what you are doing, edit your vmm.cfg and set
+_("""If you really always know what you are doing, edit your vmm.cfg and set
the option domain.force_deletion to true."""),),
# TP: description of subcommand domaininfo
- 'domaininfo': (_(u"""This subcommand shows some information about the
+ 'domaininfo': (_("""This subcommand shows some information about the
given domain."""),
-_(u"""For a more detailed information about the domain the optional argument
+_("""For a more detailed information about the domain the optional argument
<details> can be specified. A possible <details> value can be one of the
following six keywords:"""),
""" accounts, aliasdomains, aliases, catchall, relocated, full""",),
# TP: description of subcommand domainquota
- 'domainquota': (_(u"""This subcommand is used to configure a new quota
+ 'domainquota': (_("""This subcommand is used to configure a new quota
limit for the accounts of the domain - not for the domain itself."""),
-_(u"""The default quota limit for accounts is defined in the vmm.cfg
+_("""The default quota limit for accounts is defined in the vmm.cfg
(domain.quota_bytes and domain.quota_messages)."""),
-_(u"""The new quota limit will affect only those accounts for which the limit
+_("""The new quota limit will affect only those accounts for which the limit
has not been overridden. If you want to restore the default to all accounts,
you may pass the keyword 'force'. When the argument <messages> was omitted the
default number of messages 0 (zero) will be applied."""),),
# TP: description of subcommand domainservices
- 'domainservices': (_(u"""To define which services could be used by the
+ 'domainservices': (_("""To define which services could be used by the
users of the domain — with the given <fqdn> — use this subcommand."""),
-_(u"""Each specified <service> will be enabled/usable. All other services
+_("""Each specified <service> will be enabled/usable. All other services
will be deactivated/unusable. Possible <service> names are:"""),
-u""" imap, pop3, sieve, smtp""",
-_(u"""The new service set will affect only those accounts for which the set has
+""" imap, pop3, sieve, smtp""",
+_("""The new service set will affect only those accounts for which the set has
not been overridden. If you want to restore the default to all accounts, you
may pass the keyword 'force'."""),),
# TP: description of subcommand domaintransport
- 'domaintransport': (_(u"""A new transport for the indicated domain can be
+ 'domaintransport': (_("""A new transport for the indicated domain can be
set with this subcommand."""),
-_(u"""The new transport will affect only those accounts for which the transport
+_("""The new transport will affect only those accounts for which the transport
has not been overridden. If you want to restore the default to all accounts,
you may pass the keyword 'force'."""),),
# TP: description of subcommand domainnote
- 'domainnote': (_(u"""With this subcommand, it is possible to attach a
+ 'domainnote': (_("""With this subcommand, it is possible to attach a
note to the specified domain. Without an argument, an existing note is
removed."""),),
# TP: description of subcommand aliasdomainadd
- 'aliasdomainadd': (_(u"""This subcommand adds the new alias domain
+ 'aliasdomainadd': (_("""This subcommand adds the new alias domain
(<fqdn>) to the destination <domain> that should be aliased."""),),
# TP: description of subcommand aliasdomaindelete
- 'aliasdomaindelete': (_(u"""Use this subcommand if the alias domain
+ 'aliasdomaindelete': (_("""Use this subcommand if the alias domain
<fqdn> should be removed."""),),
# TP: description of subcommand aliasdomaininfo
- 'aliasdomaininfo': (_(u"""This subcommand shows to which domain the alias
+ 'aliasdomaininfo': (_("""This subcommand shows to which domain the alias
domain <fqdn> is assigned to."""),),
# TP: description of subcommand aliasdomainswitch
- 'aliasdomainswitch': (_(u"""If the destination of the existing alias
+ 'aliasdomainswitch': (_("""If the destination of the existing alias
domain <fqdn> should be switched to another <destination> use this
subcommand."""),),
# TP: description of subcommand useradd
- 'useradd': (_(u"""Use this subcommand to create a new e-mail account for
+ 'useradd': (_("""Use this subcommand to create a new e-mail account for
the given <address>."""),
-_(u"""If the <password> is not provided, vmm will prompt for it interactively.
+_("""If the <password> is not provided, vmm will prompt for it interactively.
When no <password> is provided and account.random_password is set to true, vmm
will generate a random password and print it to stdout after the account has
been created."""),),
# TP: description of subcommand userdelete
- 'userdelete': (_(u"""Use this subcommand to delete the account with the
+ 'userdelete': (_("""Use this subcommand to delete the account with the
given <address>."""),
-_(u"""If there are one or more aliases with an identical destination address,
+_("""If there are one or more aliases with an identical destination address,
vmm will abort the requested operation and show an error message. To prevent
this, specify the optional keyword 'force'."""),),
# TP: description of subcommand userinfo
- 'userinfo': (_(u"""This subcommand displays some information about the
+ 'userinfo': (_("""This subcommand displays some information about the
account specified by <address>."""),
-_(u"""If the optional argument <details> is given some more information will be
+_("""If the optional argument <details> is given some more information will be
displayed. Possible values for <details> are:"""),
-u""" aliases, du. full""",),
+""" aliases, du. full""",),
# TP: description of subcommand username
- 'username': (_(u"""The user's real <name> can be set/updated with this
+ 'username': (_("""The user's real <name> can be set/updated with this
subcommand."""),
-_(u"""If no <name> is given, the value stored for the account is erased."""),
+_("""If no <name> is given, the value stored for the account is erased."""),
),
# TP: description of subcommand userpassword
- 'userpassword': (_(u"""The password of an account can be updated with this
+ 'userpassword': (_("""The password of an account can be updated with this
subcommand."""),
-_(u"""If no <password> was provided, vmm will prompt for it interactively."""),
+_("""If no <password> was provided, vmm will prompt for it interactively."""),
),
# TP: description of subcommand usernote
- 'usernote': (_(u"""With this subcommand, it is possible to attach a note
+ 'usernote': (_("""With this subcommand, it is possible to attach a note
to the specified account. Without an argument, an existing note is
removed."""),),
# TP: description of subcommand userquota
- 'userquota': (_(u"""This subcommand is used to set a new quota limit for
+ 'userquota': (_("""This subcommand is used to set a new quota limit for
the given account."""),
-_(u"""When the argument <messages> was omitted the default number of messages
+_("""When the argument <messages> was omitted the default number of messages
0 (zero) will be applied."""),
-_(u"""Instead of <storage> pass the keyword 'domain' to remove the
+_("""Instead of <storage> pass the keyword 'domain' to remove the
account-specific override, causing the domain's value to be in effect."""),),
# TP: description of subcommand userservices
- 'userservices': (_(u"""To grant a user access to the specified services,
+ 'userservices': (_("""To grant a user access to the specified services,
use this command."""),
-_(u"""All omitted services will be deactivated/unusable for the user with the
+_("""All omitted services will be deactivated/unusable for the user with the
given <address>."""),
-_(u"""Instead of <service> pass 'domain' to remove the account-specific
+_("""Instead of <service> pass 'domain' to remove the account-specific
override, causing the domain's value to be in effect."""),),
# TP: description of subcommand usertransport
- 'usertransport': (_(u"""A different <transport> for an account can be
+ 'usertransport': (_("""A different <transport> for an account can be
specified with this subcommand."""),
-_(u"""Instead of <transport> pass 'domain' to remove the account-specific
+_("""Instead of <transport> pass 'domain' to remove the account-specific
override, causing the domain's value to be in effect."""),),
# TP: description of subcommand aliasadd
- 'aliasadd': (_(u"""This subcommand is used to create a new alias
+ 'aliasadd': (_("""This subcommand is used to create a new alias
<address> with one or more <destination> addresses."""),
-_(u"""Within the destination address, the placeholders '%n', '%d', and '%='
+_("""Within the destination address, the placeholders '%n', '%d', and '%='
will be replaced by the local part, the domain, or the email address with '@'
replaced by '=' respectively. In combination with alias domains, this enables
domain-specific destinations."""),),
# TP: description of subcommand aliasdelete
- 'aliasdelete': (_(u"""This subcommand is used to delete one or multiple
+ 'aliasdelete': (_("""This subcommand is used to delete one or multiple
<destination>s from the alias with the given <address>."""),
-_(u"""When no <destination> address was specified the alias with all its
+_("""When no <destination> address was specified the alias with all its
destinations will be deleted."""),),
# TP: description of subcommand aliasinfo
- 'aliasinfo': (_(u"""Information about the alias with the given <address>
+ 'aliasinfo': (_("""Information about the alias with the given <address>
can be displayed with this subcommand."""),),
# TP: description of subcommand relocatedadd
- 'relocatedadd': (_(u"""A new relocated user can be created with this
+ 'relocatedadd': (_("""A new relocated user can be created with this
subcommand."""),
-_(u"""<address> is the user's ex-email address, for example
+_("""<address> is the user's ex-email address, for example
b.user@example.com, and <newaddress> points to the new email address where
the user can be reached."""),),
# TP: description of subcommand relocatedinfo
- 'relocatedinfo': (_(u"""This subcommand shows the new address of the
+ 'relocatedinfo': (_("""This subcommand shows the new address of the
relocated user with the given <address>."""),),
# TP: description of subcommand relocateddelete
- 'relocateddelete': (_(u"""Use this subcommand in order to delete the
+ 'relocateddelete': (_("""Use this subcommand in order to delete the
relocated user with the given <address>."""),),
# TP: description of subcommand catchalladd
- 'catchalladd': (_(u"""This subcommand allows to specify destination
+ 'catchalladd': (_("""This subcommand allows to specify destination
addresses for a domain, which shall receive mail addressed to unknown
local-parts within that domain. Those catch-all aliases hence "catch all" mail
to any address in the domain (unless a more specific alias, mailbox or
relocated user exists)."""),
-_(u"""WARNING: Catch-all addresses can cause mail server flooding because
+_("""WARNING: Catch-all addresses can cause mail server flooding because
spammers like to deliver mail to all possible combinations of names, e.g.
to all addresses between abba@example.org and zztop@example.org."""),),
# TP: description of subcommand catchallinfo
- 'catchallinfo': (_(u"""This subcommand displays information about catch-all
+ 'catchallinfo': (_("""This subcommand displays information about catch-all
aliases defined for the domain <fqdn>."""),),
# TP: description of subcommand catchalldelete
- 'catchalldelete': (_(u"""With this subcommand, catch-all aliases defined
+ 'catchalldelete': (_("""With this subcommand, catch-all aliases defined
for a domain can be removed, either all of them, or those <destination>s which
were specified explicitly."""),),
}
--- a/VirtualMailManager/cli/config.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/cli/config.py Wed Nov 21 13:13:31 2012 +0000
@@ -8,7 +8,7 @@
Adds some interactive stuff to the Config class.
"""
-from ConfigParser import RawConfigParser
+from configparser import RawConfigParser
from shutil import copy2
from VirtualMailManager import ENCODING
@@ -29,33 +29,33 @@
def configure(self, sections):
"""Interactive method for configuring all options of the given
iterable ``sections`` object."""
- input_fmt = _(u'Enter new value for option %(option)s '
- u'[%(current_value)s]: ')
+ input_fmt = _('Enter new value for option %(option)s '
+ '[%(current_value)s]: ')
failures = 0
- w_std(_(u'Using configuration file: %s\n') % self._cfg_filename)
+ w_std(_('Using configuration file: %s\n') % self._cfg_filename)
for section in sections:
- w_std(_(u"* Configuration section: '%s'") % section)
+ w_std(_("* Configuration section: '%s'") % section)
for opt, val in self.items(section):
failures = 0
while True:
- newval = raw_input(input_fmt.encode(ENCODING, 'replace') %
+ newval = input(input_fmt.encode(ENCODING, 'replace') %
{'option': opt, 'current_value': val})
if newval and newval != val:
try:
LazyConfig.set(self, '%s.%s' % (section, opt),
newval)
break
- except (ValueError, ConfigValueError, VMMError), err:
- w_err(0, _(u'Warning: %s') % err)
+ except (ValueError, ConfigValueError, VMMError) as err:
+ w_err(0, _('Warning: %s') % err)
failures += 1
if failures > 2:
- raise ConfigError(_(u'Too many failures - try '
- u'again later.'),
+ raise ConfigError(_('Too many failures - try '
+ 'again later.'),
VMM_TOO_MANY_FAILURES)
else:
break
- print
+ print()
if self._modified:
self._save_changes()
@@ -72,7 +72,7 @@
val = self._cfg[section][option_].cls(value)
if self._cfg[section][option_].validate:
val = self._cfg[section][option_].validate(val)
- except (ValueError, ConfigValueError), err:
+ except (ValueError, ConfigValueError) as err:
raise ConfigError(str(err), CONF_ERROR)
# Do not write default values also skip identical values
if not self._cfg[section][option_].default is None:
@@ -89,8 +89,7 @@
def _save_changes(self):
"""Writes changes to the configuration file."""
copy2(self._cfg_filename, self._cfg_filename + '.bak')
- self._cfg_file = open(self._cfg_filename, 'w')
- self.write(self._cfg_file)
- self._cfg_file.close()
+ with open(self._cfg_filename, 'w') as self._cfg_file:
+ self.write(self._cfg_file)
del _
--- a/VirtualMailManager/cli/handler.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/cli/handler.py Wed Nov 21 13:13:31 2012 +0000
@@ -63,7 +63,7 @@
elif self._cfg.has_section(section):
self._cfg.configure([section])
else:
- raise VMMError(_(u"Invalid section: '%s'") % section,
+ raise VMMError(_("Invalid section: '%s'") % section,
INVALID_SECTION)
def user_add(self, emailaddress, password=None):
@@ -74,7 +74,7 @@
"""
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)
rand_pass = self._cfg.dget('account.random_password')
@@ -90,9 +90,9 @@
password dialog."""
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 not isinstance(password, basestring) or not password:
+ if not isinstance(password, str) or not password:
password = read_pass()
acc.modify('password', password)
--- a/VirtualMailManager/cli/main.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/cli/main.py Wed Nov 21 13:13:31 2012 +0000
@@ -8,7 +8,7 @@
VirtualMailManager's command line interface.
"""
-from ConfigParser import NoOptionError, NoSectionError
+from configparser import NoOptionError, NoSectionError
from VirtualMailManager import ENCODING, errors
from VirtualMailManager.config import BadOptionError, ConfigValueError
@@ -28,8 +28,8 @@
try:
handler = CliHandler()
except (errors.NotRootError, errors.PermissionError, errors.VMMError,
- errors.ConfigError), err:
- w_err(err.code, _(u'Error: %s') % err.msg)
+ errors.ConfigError) as err:
+ w_err(err.code, _('Error: %s') % err.msg)
else:
handler.cfg_install()
return handler
@@ -38,19 +38,19 @@
def run(argv):
update_cmd_map()
if len(argv) < 2:
- usage(EX_MISSING_ARGS, _(u"You must specify a subcommand at least."))
+ usage(EX_MISSING_ARGS, _("You must specify a subcommand at least."))
sub_cmd = argv[1].lower()
if sub_cmd in cmd_map:
cmd_func = cmd_map[sub_cmd].func
else:
- for cmd in cmd_map.itervalues():
+ for cmd in cmd_map.values():
if cmd.alias == sub_cmd:
cmd_func = cmd.func
sub_cmd = cmd.name
break
else:
- usage(EX_UNKNOWN_COMMAND, _(u"Unknown subcommand: '%s'") % sub_cmd)
+ usage(EX_UNKNOWN_COMMAND, _("Unknown subcommand: '%s'") % sub_cmd)
handler = _get_handler()
run_ctx = RunContext(argv, handler, sub_cmd)
@@ -59,24 +59,24 @@
except (EOFError, KeyboardInterrupt):
# TP: We have to cry, because root has killed/interrupted vmm
# with Ctrl+C or Ctrl+D.
- w_err(EX_USER_INTERRUPT, '', _(u'Ouch!'), '')
- except errors.VMMError, err:
+ w_err(EX_USER_INTERRUPT, '', _('Ouch!'), '')
+ except errors.VMMError as err:
if err.code != DATABASE_ERROR:
if handler.has_warnings():
- w_err(0, _(u'Warnings:'), *handler.get_warnings())
- w_err(err.code, _(u'Error: %s') % err.msg)
- w_err(err.code, unicode(err.msg, ENCODING, 'replace'))
- except (BadOptionError, ConfigValueError), err:
- w_err(INVALID_ARGUMENT, _(u'Error: %s') % err)
- except NoSectionError, err:
+ w_err(0, _('Warnings:'), *handler.get_warnings())
+ w_err(err.code, _('Error: %s') % err.msg)
+ w_err(err.code, str(err.msg, ENCODING, 'replace'))
+ except (BadOptionError, ConfigValueError) as err:
+ w_err(INVALID_ARGUMENT, _('Error: %s') % err)
+ except NoSectionError as err:
w_err(INVALID_ARGUMENT,
- _(u"Error: Unknown section: '%s'") % err.section)
- except NoOptionError, err:
+ _("Error: Unknown section: '%s'") % err.section)
+ except NoOptionError as err:
w_err(INVALID_ARGUMENT,
- _(u"Error: No option '%(option)s' in section: '%(section)s'") %
+ _("Error: No option '%(option)s' in section: '%(section)s'") %
{'option': err.option, 'section': err.section})
if handler.has_warnings():
- w_err(0, _(u'Warnings:'), *handler.get_warnings())
+ w_err(0, _('Warnings:'), *handler.get_warnings())
return EX_SUCCESS
del _
--- a/VirtualMailManager/cli/subcommands.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/cli/subcommands.py Wed Nov 21 13:13:31 2012 +0000
@@ -79,7 +79,7 @@
@property
def usage(self):
"""the command's usage info."""
- return u'%s %s %s' % (prog, self.name, self.args)
+ return '%s %s %s' % (prog, self.name, self.args)
def help_(self):
"""Print the Command's help message to stdout."""
@@ -98,19 +98,19 @@
[w_std(txt_wrpr.fill(_(para)) + '\n') for para
in help_msgs[self.name]]
except KeyError:
- w_err(1, _(u"Subcommand '%s' is not yet documented." % self.name),
+ w_err(1, _("Subcommand '%s' is not yet documented." % self.name),
'see also: vmm(1)')
class RunContext(object):
"""Contains all information necessary to run a subcommand."""
__slots__ = ('argc', 'args', 'cget', 'hdlr', 'scmd')
- plan_a_b = _(u'Plan A failed ... trying Plan B: %(subcommand)s %(object)s')
+ plan_a_b = _('Plan A failed ... trying Plan B: %(subcommand)s %(object)s')
def __init__(self, argv, handler, command):
"""Create a new RunContext"""
self.argc = len(argv)
- self.args = [unicode(arg, ENCODING) for arg in argv]
+ self.args = [str(arg, ENCODING) for arg in argv]
self.cget = handler.cfg_dget
self.hdlr = handler
self.scmd = command
@@ -119,17 +119,17 @@
def alias_add(ctx):
"""create a new alias e-mail address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing alias address and destination.'),
+ usage(EX_MISSING_ARGS, _('Missing alias address and destination.'),
ctx.scmd)
elif ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing destination address.'), ctx.scmd)
ctx.hdlr.alias_add(ctx.args[2].lower(), *ctx.args[3:])
def alias_delete(ctx):
"""delete the specified alias e-mail address or one of its destinations"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing alias address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing alias address.'), ctx.scmd)
elif ctx.argc < 4:
ctx.hdlr.alias_delete(ctx.args[2].lower())
else:
@@ -139,18 +139,18 @@
def alias_info(ctx):
"""show the destination(s) of the specified alias"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing alias address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing alias address.'), ctx.scmd)
address = ctx.args[2].lower()
try:
_print_aliase_info(address, ctx.hdlr.alias_info(address))
- except VMMError, err:
+ except VMMError as err:
if err.code is ACCOUNT_EXISTS:
- w_err(0, ctx.plan_a_b % {'subcommand': u'userinfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'userinfo',
'object': address})
ctx.scmd = ctx.args[1] = 'userinfo'
user_info(ctx)
elif err.code is RELOCATED_EXISTS:
- w_err(0, ctx.plan_a_b % {'subcommand': u'relocatedinfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'relocatedinfo',
'object': address})
ctx.scmd = ctx.args[1] = 'relocatedinfo'
relocated_info(ctx)
@@ -161,10 +161,10 @@
def aliasdomain_add(ctx):
"""create a new alias for an existing domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing alias domain name and destination '
- u'domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing alias domain name and destination '
+ 'domain name.'), ctx.scmd)
elif ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing destination domain name.'),
+ usage(EX_MISSING_ARGS, _('Missing destination domain name.'),
ctx.scmd)
ctx.hdlr.aliasdomain_add(ctx.args[2].lower(), ctx.args[3].lower())
@@ -172,19 +172,19 @@
def aliasdomain_delete(ctx):
"""delete the specified alias domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing alias domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing alias domain name.'), ctx.scmd)
ctx.hdlr.aliasdomain_delete(ctx.args[2].lower())
def aliasdomain_info(ctx):
"""show the destination of the given alias domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing alias domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing alias domain name.'), ctx.scmd)
try:
_print_aliasdomain_info(ctx.hdlr.aliasdomain_info(ctx.args[2].lower()))
- except VMMError, err:
+ except VMMError as err:
if err.code is ALIASDOMAIN_ISDOMAIN:
- w_err(0, ctx.plan_a_b % {'subcommand': u'domaininfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'domaininfo',
'object': ctx.args[2].lower()})
ctx.scmd = ctx.args[1] = 'domaininfo'
domain_info(ctx)
@@ -195,10 +195,10 @@
def aliasdomain_switch(ctx):
"""assign the given alias domain to an other domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing alias domain name and destination '
- u'domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing alias domain name and destination '
+ 'domain name.'), ctx.scmd)
elif ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing destination domain name.'),
+ usage(EX_MISSING_ARGS, _('Missing destination domain name.'),
ctx.scmd)
ctx.hdlr.aliasdomain_switch(ctx.args[2].lower(), ctx.args[3].lower())
@@ -206,17 +206,17 @@
def catchall_add(ctx):
"""create a new catchall alias e-mail address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain and destination.'),
+ usage(EX_MISSING_ARGS, _('Missing domain and destination.'),
ctx.scmd)
elif ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing destination address.'), ctx.scmd)
ctx.hdlr.catchall_add(ctx.args[2].lower(), *ctx.args[3:])
def catchall_delete(ctx):
"""delete the specified destination or all of the catchall destination"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd)
elif ctx.argc < 4:
ctx.hdlr.catchall_delete(ctx.args[2].lower())
else:
@@ -226,7 +226,7 @@
def catchall_info(ctx):
"""show the catchall destination(s) of the specified domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd)
address = ctx.args[2].lower()
_print_catchall_info(address, ctx.hdlr.catchall_info(address))
@@ -234,7 +234,7 @@
def config_get(ctx):
"""show the actual value of the configuration option"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u"Missing option name."), ctx.scmd)
+ usage(EX_MISSING_ARGS, _("Missing option name."), ctx.scmd)
noop = lambda option: option
opt_formater = {
@@ -250,9 +250,9 @@
def config_set(ctx):
"""set a new value for the configuration option"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing option and new value.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing option and new value.'), ctx.scmd)
if ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing new configuration value.'),
+ usage(EX_MISSING_ARGS, _('Missing new configuration value.'),
ctx.scmd)
ctx.hdlr.cfg_set(ctx.args[2].lower(), ctx.args[3])
@@ -268,15 +268,15 @@
def domain_add(ctx):
"""create a new domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd)
elif ctx.argc < 4:
ctx.hdlr.domain_add(ctx.args[2].lower())
else:
ctx.hdlr.domain_add(ctx.args[2].lower(), ctx.args[3])
if ctx.cget('domain.auto_postmaster'):
- w_std(_(u'Creating account for postmaster@%s') % ctx.args[2].lower())
+ w_std(_('Creating account for postmaster@%s') % ctx.args[2].lower())
ctx.scmd = 'useradd'
- ctx.args = [prog, ctx.scmd, u'postmaster@' + ctx.args[2].lower()]
+ ctx.args = [prog, ctx.scmd, 'postmaster@' + ctx.args[2].lower()]
ctx.argc = 3
user_add(ctx)
@@ -284,84 +284,84 @@
def domain_delete(ctx):
"""delete the given domain and all its alias domains"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd)
elif ctx.argc < 4:
ctx.hdlr.domain_delete(ctx.args[2].lower())
elif ctx.args[3].lower() == 'force':
ctx.hdlr.domain_delete(ctx.args[2].lower(), True)
else:
- usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[3],
+ usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % ctx.args[3],
ctx.scmd)
def domain_info(ctx):
"""display information about the given domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd)
if ctx.argc < 4:
details = None
else:
details = ctx.args[3].lower()
if details not in ('accounts', 'aliasdomains', 'aliases', 'full',
'relocated', 'catchall'):
- usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % details,
+ usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % details,
ctx.scmd)
try:
info = ctx.hdlr.domain_info(ctx.args[2].lower(), details)
- except VMMError, err:
+ except VMMError as err:
if err.code is DOMAIN_ALIAS_EXISTS:
- w_err(0, ctx.plan_a_b % {'subcommand': u'aliasdomaininfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'aliasdomaininfo',
'object': ctx.args[2].lower()})
ctx.scmd = ctx.args[1] = 'aliasdomaininfo'
aliasdomain_info(ctx)
else:
raise
else:
- q_limit = u'Storage: %(bytes)s; Messages: %(messages)s'
+ q_limit = 'Storage: %(bytes)s; Messages: %(messages)s'
if not details:
info['bytes'] = human_size(info['bytes'])
info['messages'] = locale.format('%d', info['messages'],
True).decode(ENCODING, 'replace')
info['quota limit/user'] = q_limit % info
- _print_info(ctx, info, _(u'Domain'))
+ _print_info(ctx, info, _('Domain'))
else:
info[0]['bytes'] = human_size(info[0]['bytes'])
info[0]['messages'] = locale.format('%d', info[0]['messages'],
True).decode(ENCODING,
'replace')
info[0]['quota limit/user'] = q_limit % info[0]
- _print_info(ctx, info[0], _(u'Domain'))
- if details == u'accounts':
- _print_list(info[1], _(u'accounts'))
- elif details == u'aliasdomains':
- _print_list(info[1], _(u'alias domains'))
- elif details == u'aliases':
- _print_list(info[1], _(u'aliases'))
- elif details == u'relocated':
- _print_list(info[1], _(u'relocated users'))
- elif details == u'catchall':
- _print_list(info[1], _(u'catch-all destinations'))
+ _print_info(ctx, info[0], _('Domain'))
+ if details == 'accounts':
+ _print_list(info[1], _('accounts'))
+ elif details == 'aliasdomains':
+ _print_list(info[1], _('alias domains'))
+ elif details == 'aliases':
+ _print_list(info[1], _('aliases'))
+ elif details == 'relocated':
+ _print_list(info[1], _('relocated users'))
+ elif details == 'catchall':
+ _print_list(info[1], _('catch-all destinations'))
else:
- _print_list(info[1], _(u'alias domains'))
- _print_list(info[2], _(u'accounts'))
- _print_list(info[3], _(u'aliases'))
- _print_list(info[4], _(u'relocated users'))
- _print_list(info[5], _(u'catch-all destinations'))
+ _print_list(info[1], _('alias domains'))
+ _print_list(info[2], _('accounts'))
+ _print_list(info[3], _('aliases'))
+ _print_list(info[4], _('relocated users'))
+ _print_list(info[5], _('catch-all destinations'))
def domain_quota(ctx):
"""update the quota limit of the specified domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name and storage value.'),
+ usage(EX_MISSING_ARGS, _('Missing domain name and storage value.'),
ctx.scmd)
if ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing storage value.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing storage value.'), ctx.scmd)
messages = 0
force = None
try:
bytes_ = size_in_bytes(ctx.args[3])
except (ValueError, TypeError):
- usage(INVALID_ARGUMENT, _(u"Invalid storage value: '%s'") %
+ usage(INVALID_ARGUMENT, _("Invalid storage value: '%s'") %
ctx.args[3], ctx.scmd)
if ctx.argc < 5:
pass
@@ -371,18 +371,18 @@
except ValueError:
if ctx.args[4].lower() != 'force':
usage(INVALID_ARGUMENT,
- _(u"Neither a valid number of messages nor the keyword "
- u"'force': '%s'") % ctx.args[4], ctx.scmd)
+ _("Neither a valid number of messages nor the keyword "
+ "'force': '%s'") % ctx.args[4], ctx.scmd)
force = 'force'
else:
try:
messages = int(ctx.args[4])
except ValueError:
usage(INVALID_ARGUMENT,
- _(u"Not a valid number of messages: '%s'") % ctx.args[4],
+ _("Not a valid number of messages: '%s'") % ctx.args[4],
ctx.scmd)
if ctx.args[5].lower() != 'force':
- usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[5],
+ usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % ctx.args[5],
ctx.scmd)
force = 'force'
ctx.hdlr.domain_quotalimit(ctx.args[2].lower(), bytes_, messages, force)
@@ -391,7 +391,7 @@
def domain_services(ctx):
"""allow all named service and block the uncredited."""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing domain name.'), ctx.scmd)
services = []
force = False
if ctx.argc is 3:
@@ -403,7 +403,7 @@
elif arg == 'force':
force = True
else:
- usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % arg,
+ usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % arg,
ctx.scmd)
else:
services.extend([service.lower() for service in ctx.args[3:-1]])
@@ -414,7 +414,7 @@
services.append(arg)
unknown = [service for service in services if service not in SERVICES]
if unknown:
- usage(INVALID_ARGUMENT, _(u'Invalid service arguments: %s') %
+ usage(INVALID_ARGUMENT, _('Invalid service arguments: %s') %
' '.join(unknown), ctx.scmd)
ctx.hdlr.domain_services(ctx.args[2].lower(), (None, 'force')[force],
*services)
@@ -423,16 +423,16 @@
def domain_transport(ctx):
"""update the transport of the specified domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name and new transport.'),
+ usage(EX_MISSING_ARGS, _('Missing domain name and new transport.'),
ctx.scmd)
if ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing new transport.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing new transport.'), ctx.scmd)
if ctx.argc < 5:
ctx.hdlr.domain_transport(ctx.args[2].lower(), ctx.args[3])
else:
force = ctx.args[4].lower()
if force != 'force':
- usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % force,
+ usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % force,
ctx.scmd)
ctx.hdlr.domain_transport(ctx.args[2].lower(), ctx.args[3], force)
@@ -440,7 +440,7 @@
def domain_note(ctx):
"""update the note of the given domain"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing domain name.'),
+ usage(EX_MISSING_ARGS, _('Missing domain name.'),
ctx.scmd)
elif ctx.argc < 4:
note = None
@@ -452,8 +452,8 @@
def get_user(ctx):
"""get the address of the user with the given UID"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing UID.'), ctx.scmd)
- _print_info(ctx, ctx.hdlr.user_by_uid(ctx.args[2]), _(u'Account'))
+ usage(EX_MISSING_ARGS, _('Missing UID.'), ctx.scmd)
+ _print_info(ctx, ctx.hdlr.user_by_uid(ctx.args[2]), _('Account'))
def help_(ctx):
@@ -463,14 +463,14 @@
if hlptpc in cmd_map:
topic = hlptpc
else:
- for scmd in cmd_map.itervalues():
+ for scmd in cmd_map.values():
if scmd.alias == hlptpc:
topic = scmd.name
break
else:
- usage(INVALID_ARGUMENT, _(u"Unknown help topic: '%s'") %
+ usage(INVALID_ARGUMENT, _("Unknown help topic: '%s'") %
ctx.args[2], ctx.scmd)
- if topic != u'help':
+ if topic != 'help':
return cmd_map[topic].help_()
old_ii = txt_wrpr.initial_indent
@@ -478,10 +478,9 @@
txt_wrpr.initial_indent = ' '
# len(max(_overview.iterkeys(), key=len)) #Py25
txt_wrpr.subsequent_indent = 20 * ' '
- order = cmd_map.keys()
- order.sort()
+ order = sorted(list(cmd_map.keys()))
- w_std(_(u'List of available subcommands:') + '\n')
+ w_std(_('List of available subcommands:') + '\n')
for key in order:
w_std('\n'.join(txt_wrpr.wrap('%-18s %s' % (key, cmd_map[key].descr))))
@@ -502,17 +501,12 @@
def list_pwschemes(ctx_unused):
"""Prints all usable password schemes and password encoding suffixes."""
- # TODO: Remove trailing colons from keys.
- # For now it is to late, the translators has stared their work
- keys = (_(u'Usable password schemes:'), _(u'Usable encoding suffixes:'))
+ keys = (_('Usable password schemes'), _('Usable encoding suffixes'))
old_ii, old_si = txt_wrpr.initial_indent, txt_wrpr.subsequent_indent
txt_wrpr.initial_indent = txt_wrpr.subsequent_indent = '\t'
txt_wrpr.width = txt_wrpr.width - 8
for key, value in zip(keys, list_schemes()):
- if key.endswith(':'): # who knows … (see TODO above)
- #key = key.rpartition(':')[0]
- key = key[:-1] # This one is for Py24
w_std(key, len(key) * '-')
w_std('\n'.join(txt_wrpr.wrap(' '.join(value))), '')
@@ -554,35 +548,35 @@
"""create a new record for a relocated user"""
if ctx.argc < 3:
usage(EX_MISSING_ARGS,
- _(u'Missing relocated address and destination.'), ctx.scmd)
+ _('Missing relocated address and destination.'), ctx.scmd)
elif ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing destination address.'), ctx.scmd)
ctx.hdlr.relocated_add(ctx.args[2].lower(), ctx.args[3])
def relocated_delete(ctx):
"""delete the record of the relocated user"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing relocated address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing relocated address.'), ctx.scmd)
ctx.hdlr.relocated_delete(ctx.args[2].lower())
def relocated_info(ctx):
"""print information about a relocated user"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing relocated address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing relocated address.'), ctx.scmd)
relocated = ctx.args[2].lower()
try:
_print_relocated_info(addr=relocated,
dest=ctx.hdlr.relocated_info(relocated))
- except VMMError, err:
+ except VMMError as err:
if err.code is ACCOUNT_EXISTS:
- w_err(0, ctx.plan_a_b % {'subcommand': u'userinfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'userinfo',
'object': relocated})
ctx.scmd = ctx.args[1] = 'userinfoi'
user_info(ctx)
elif err.code is ALIAS_EXISTS:
- w_err(0, ctx.plan_a_b % {'subcommand': u'aliasinfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'aliasinfo',
'object': relocated})
ctx.scmd = ctx.args[1] = 'aliasinfo'
alias_info(ctx)
@@ -593,50 +587,50 @@
def user_add(ctx):
"""create a new e-mail user with the given address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd)
elif ctx.argc < 4:
password = None
else:
password = ctx.args[3]
gen_pass = ctx.hdlr.user_add(ctx.args[2].lower(), password)
if ctx.argc < 4 and gen_pass:
- w_std(_(u"Generated password: %s") % gen_pass)
+ w_std(_("Generated password: %s") % gen_pass)
def user_delete(ctx):
"""delete the specified user"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd)
elif ctx.argc < 4:
ctx.hdlr.user_delete(ctx.args[2].lower())
elif ctx.args[3].lower() == 'force':
ctx.hdlr.user_delete(ctx.args[2].lower(), True)
else:
- usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[3],
+ usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % ctx.args[3],
ctx.scmd)
def user_info(ctx):
"""display information about the given address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd)
if ctx.argc < 4:
details = None
else:
details = ctx.args[3].lower()
if details not in ('aliases', 'du', 'full'):
- usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % details,
+ usage(INVALID_ARGUMENT, _("Invalid argument: '%s'") % details,
ctx.scmd)
try:
info = ctx.hdlr.user_info(ctx.args[2].lower(), details)
- except VMMError, err:
+ except VMMError as err:
if err.code is ALIAS_EXISTS:
- w_err(0, ctx.plan_a_b % {'subcommand': u'aliasinfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'aliasinfo',
'object': ctx.args[2].lower()})
ctx.scmd = ctx.args[1] = 'aliasinfo'
alias_info(ctx)
elif err.code is RELOCATED_EXISTS:
- w_err(0, ctx.plan_a_b % {'subcommand': u'relocatedinfo',
+ w_err(0, ctx.plan_a_b % {'subcommand': 'relocatedinfo',
'object': ctx.args[2].lower()})
ctx.scmd = ctx.args[1] = 'relocatedinfo'
relocated_info(ctx)
@@ -650,7 +644,7 @@
_format_quota_usage(info['ql_messages'],
info['uq_messages'],
domaindefault=info['ql_domaindefault'])
- _print_info(ctx, info, _(u'Account'))
+ _print_info(ctx, info, _('Account'))
else:
info[0]['quota storage'] = _format_quota_usage(info[0]['ql_bytes'],
info[0]['uq_bytes'], True, info[0]['ql_domaindefault'])
@@ -658,14 +652,14 @@
_format_quota_usage(info[0]['ql_messages'],
info[0]['uq_messages'],
domaindefault=info[0]['ql_domaindefault'])
- _print_info(ctx, info[0], _(u'Account'))
- _print_list(info[1], _(u'alias addresses'))
+ _print_info(ctx, info[0], _('Account'))
+ _print_list(info[1], _('alias addresses'))
def user_name(ctx):
"""set or update the real name for an address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u"Missing e-mail address and user's name."),
+ usage(EX_MISSING_ARGS, _("Missing e-mail address and user's name."),
ctx.scmd)
elif ctx.argc < 4:
name = None
@@ -677,7 +671,7 @@
def user_password(ctx):
"""update the password for the given address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd)
elif ctx.argc < 4:
password = None
else:
@@ -688,7 +682,7 @@
def user_note(ctx):
"""update the note of the given address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'),
+ usage(EX_MISSING_ARGS, _('Missing e-mail address.'),
ctx.scmd)
elif ctx.argc < 4:
note = None
@@ -700,15 +694,15 @@
def user_quota(ctx):
"""update the quota limit for the given address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address and storage value.'),
+ usage(EX_MISSING_ARGS, _('Missing e-mail address and storage value.'),
ctx.scmd)
elif ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing storage value.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing storage value.'), ctx.scmd)
if ctx.args[3] != 'domain':
try:
bytes_ = size_in_bytes(ctx.args[3])
except (ValueError, TypeError):
- usage(INVALID_ARGUMENT, _(u"Invalid storage value: '%s'") %
+ usage(INVALID_ARGUMENT, _("Invalid storage value: '%s'") %
ctx.args[3], ctx.scmd)
else:
bytes_ = ctx.args[3]
@@ -719,7 +713,7 @@
messages = int(ctx.args[4])
except ValueError:
usage(INVALID_ARGUMENT,
- _(u"Not a valid number of messages: '%s'") % ctx.args[4],
+ _("Not a valid number of messages: '%s'") % ctx.args[4],
ctx.scmd)
ctx.hdlr.user_quotalimit(ctx.args[2].lower(), bytes_, messages)
@@ -727,13 +721,13 @@
def user_services(ctx):
"""allow all named service and block the uncredited."""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing e-mail address.'), ctx.scmd)
services = []
if ctx.argc >= 4:
services.extend([service.lower() for service in ctx.args[3:]])
unknown = [service for service in services if service not in SERVICES]
if unknown and ctx.args[3] != 'domain':
- usage(INVALID_ARGUMENT, _(u'Invalid service arguments: %s') %
+ usage(INVALID_ARGUMENT, _('Invalid service arguments: %s') %
' '.join(unknown), ctx.scmd)
ctx.hdlr.user_services(ctx.args[2].lower(), *services)
@@ -741,10 +735,10 @@
def user_transport(ctx):
"""update the transport of the given address"""
if ctx.argc < 3:
- usage(EX_MISSING_ARGS, _(u'Missing e-mail address and transport.'),
+ usage(EX_MISSING_ARGS, _('Missing e-mail address and transport.'),
ctx.scmd)
if ctx.argc < 4:
- usage(EX_MISSING_ARGS, _(u'Missing transport.'), ctx.scmd)
+ usage(EX_MISSING_ARGS, _('Missing transport.'), ctx.scmd)
ctx.hdlr.user_transport(ctx.args[2].lower(), ctx.args[3])
@@ -753,8 +747,8 @@
When errno > 0, sys,exit(errno) will interrupt the program.
"""
if subcommand and subcommand in cmd_map:
- w_err(errno, _(u"Error: %s") % errmsg,
- _(u"usage: ") + cmd_map[subcommand].usage)
+ w_err(errno, _("Error: %s") % errmsg,
+ _("usage: ") + cmd_map[subcommand].usage)
# TP: Please adjust translated words like the original text.
# (It's a table header.) Extract from usage text:
@@ -764,16 +758,15 @@
#
# da domainadd fqdn [transport]
# dd domaindelete fqdn [force]
- u_head = _(u"""usage: %s subcommand arguments
+ u_head = _("""usage: %s subcommand arguments
short long
subcommand arguments\n""") % prog
- order = cmd_map.keys()
- order.sort()
+ order = sorted(list(cmd_map.keys()))
w_err(0, u_head)
for key in order:
scmd = cmd_map[key]
w_err(0, ' %-5s %-19s %s' % (scmd.alias, scmd.name, scmd.args))
- w_err(errno, '', _(u"Error: %s") % errmsg)
+ w_err(errno, '', _("Error: %s") % errmsg)
def version(ctx_unused):
@@ -783,12 +776,12 @@
# the version information, e.g.:
# vmm, version 0.5.2 (from 09/09/09)
# Python 2.5.4 on FreeBSD
- _(u'version'), __version__, _(u'from'),
+ _('version'), __version__, _('from'),
strftime(locale.nl_langinfo(locale.D_FMT),
strptime(__date__, '%Y-%m-%d')).decode(ENCODING, 'replace'),
- os.sys.version.split()[0], _(u'on'), os.uname()[0],
+ os.sys.version.split()[0], _('on'), os.uname()[0],
__copyright__, prog,
- _(u'is free software and comes with ABSOLUTELY NO WARRANTY.')))
+ _('is free software and comes with ABSOLUTELY NO WARRANTY.')))
def update_cmd_map():
@@ -797,119 +790,119 @@
cmd_map.update({
# Account commands
'getuser': cmd('getuser', 'gu', get_user, 'uid',
- _(u'get the address of the user with the given UID')),
+ _('get the address of the user with the given UID')),
'useradd': cmd('useradd', 'ua', user_add, 'address [password]',
- _(u'create a new e-mail user with the given address')),
+ _('create a new e-mail user with the given address')),
'userdelete': cmd('userdelete', 'ud', user_delete, 'address [force]',
- _(u'delete the specified user')),
+ _('delete the specified user')),
'userinfo': cmd('userinfo', 'ui', user_info, 'address [details]',
- _(u'display information about the given address')),
+ _('display information about the given address')),
'username': cmd('username', 'un', user_name, 'address [name]',
- _(u'set, update or delete the real name for an address')),
+ _('set, update or delete the real name for an address')),
'userpassword': cmd('userpassword', 'up', user_password,
'address [password]',
- _(u'update the password for the given address')),
+ _('update the password for the given address')),
'userquota': cmd('userquota', 'uq', user_quota,
'address storage [messages] | address domain',
- _(u'update the quota limit for the given address')),
+ _('update the quota limit for the given address')),
'userservices': cmd('userservices', 'us', user_services,
'address [service ...] | address domain',
- _(u'enables the specified services and disables all '
- u'not specified services')),
+ _('enables the specified services and disables all '
+ 'not specified services')),
'usertransport': cmd('usertransport', 'ut', user_transport,
'address transport | address domain',
- _(u'update the transport of the given address')),
+ _('update the transport of the given address')),
'usernote': cmd('usernote', 'uo', user_note, 'address [note]',
- _(u'set, update or delete the note of the given address')),
+ _('set, update or delete the note of the given address')),
# Alias commands
'aliasadd': cmd('aliasadd', 'aa', alias_add, 'address destination ...',
- _(u'create a new alias e-mail address with one or more '
- u'destinations')),
+ _('create a new alias e-mail address with one or more '
+ 'destinations')),
'aliasdelete': cmd('aliasdelete', 'ad', alias_delete,
'address [destination ...]',
- _(u'delete the specified alias e-mail address or one '
- u'of its destinations')),
+ _('delete the specified alias e-mail address or one '
+ 'of its destinations')),
'aliasinfo': cmd('aliasinfo', 'ai', alias_info, 'address',
- _(u'show the destination(s) of the specified alias')),
+ _('show the destination(s) of the specified alias')),
# AliasDomain commands
'aliasdomainadd': cmd('aliasdomainadd', 'ada', aliasdomain_add,
'fqdn destination',
- _(u'create a new alias for an existing domain')),
+ _('create a new alias for an existing domain')),
'aliasdomaindelete': cmd('aliasdomaindelete', 'add', aliasdomain_delete,
- 'fqdn', _(u'delete the specified alias domain')),
+ 'fqdn', _('delete the specified alias domain')),
'aliasdomaininfo': cmd('aliasdomaininfo', 'adi', aliasdomain_info, 'fqdn',
- _(u'show the destination of the given alias domain')),
+ _('show the destination of the given alias domain')),
'aliasdomainswitch': cmd('aliasdomainswitch', 'ads', aliasdomain_switch,
- 'fqdn destination', _(u'assign the given alias '
+ 'fqdn destination', _('assign the given alias '
'domain to an other domain')),
# CatchallAlias commands
'catchalladd': cmd('catchalladd', 'caa', catchall_add,
'fqdn destination ...',
- _(u'add one or more catch-all destinations for a '
- u'domain')),
+ _('add one or more catch-all destinations for a '
+ 'domain')),
'catchalldelete': cmd('catchalldelete', 'cad', catchall_delete,
'fqdn [destination ...]',
- _(u'delete the specified catch-all destination or all '
- u'of a domain\'s destinations')),
+ _('delete the specified catch-all destination or all '
+ 'of a domain\'s destinations')),
'catchallinfo': cmd('catchallinfo', 'cai', catchall_info, 'fqdn',
- _(u'show the catch-all destination(s) of the '
- u'specified domain')),
+ _('show the catch-all destination(s) of the '
+ 'specified domain')),
# Domain commands
'domainadd': cmd('domainadd', 'da', domain_add, 'fqdn [transport]',
- _(u'create a new domain')),
+ _('create a new domain')),
'domaindelete': cmd('domaindelete', 'dd', domain_delete, 'fqdn [force]',
- _(u'delete the given domain and all its alias domains')),
+ _('delete the given domain and all its alias domains')),
'domaininfo': cmd('domaininfo', 'di', domain_info, 'fqdn [details]',
- _(u'display information about the given domain')),
+ _('display information about the given domain')),
'domainquota': cmd('domainquota', 'dq', domain_quota,
'fqdn storage [messages] [force]',
- _(u'update the quota limit of the specified domain')),
+ _('update the quota limit of the specified domain')),
'domainservices': cmd('domainservices', 'ds', domain_services,
'fqdn [service ...] [force]',
- _(u'enables the specified services and disables all '
- u'not specified services of the given domain')),
+ _('enables the specified services and disables all '
+ 'not specified services of the given domain')),
'domaintransport': cmd('domaintransport', 'dt', domain_transport,
'fqdn transport [force]',
- _(u'update the transport of the specified domain')),
+ _('update the transport of the specified domain')),
'domainnote': cmd('domainnote', 'do', domain_note, 'fqdn [note]',
- _(u'set, update or delete the note of the given domain')),
+ _('set, update or delete the note of the given domain')),
# List commands
'listdomains': cmd('listdomains', 'ld', list_domains, '[pattern]',
- _(u'list all domains or search for domains by pattern')),
+ _('list all domains or search for domains by pattern')),
'listaddresses': cmd('listaddresses', 'll', list_addresses, '[pattern]',
- _(u'list all addresses or search for addresses by '
- u'pattern')),
+ _('list all addresses or search for addresses by '
+ 'pattern')),
'listusers': cmd('listusers', 'lu', list_users, '[pattern]',
- _(u'list all user accounts or search for accounts by '
- u'pattern')),
+ _('list all user accounts or search for accounts by '
+ 'pattern')),
'listaliases': cmd('listaliases', 'la', list_aliases, '[pattern]',
- _(u'list all aliases or search for aliases by pattern')),
+ _('list all aliases or search for aliases by pattern')),
'listrelocated': cmd('listrelocated', 'lr', list_relocated, '[pattern]',
- _(u'list all relocated users or search for relocated '
- u'users by pattern')),
+ _('list all relocated users or search for relocated '
+ 'users by pattern')),
# Relocated commands
'relocatedadd': cmd('relocatedadd', 'ra', relocated_add,
'address newaddress',
- _(u'create a new record for a relocated user')),
+ _('create a new record for a relocated user')),
'relocateddelete': cmd('relocateddelete', 'rd', relocated_delete,
'address',
- _(u'delete the record of the relocated user')),
+ _('delete the record of the relocated user')),
'relocatedinfo': cmd('relocatedinfo', 'ri', relocated_info, 'address',
- _(u'print information about a relocated user')),
+ _('print information about a relocated user')),
# cli commands
'configget': cmd('configget', 'cg', config_get, 'option',
_('show the actual value of the configuration option')),
'configset': cmd('configset', 'cs', config_set, 'option value',
_('set a new value for the configuration option')),
'configure': cmd('configure', 'cf', configure, '[section]',
- _(u'start interactive configuration mode')),
+ _('start interactive configuration mode')),
'listpwschemes': cmd('listpwschemes', 'lp', list_pwschemes, '',
- _(u'lists all usable password schemes and password '
- u'encoding suffixes')),
+ _('lists all usable password schemes and password '
+ 'encoding suffixes')),
'help': cmd('help', 'h', help_, '[subcommand]',
- _(u'show a help overview or help for the given subcommand')),
+ _('show a help overview or help for the given subcommand')),
'version': cmd('version', 'v', version, '',
- _(u'show version and copyright information')),
+ _('show version and copyright information')),
})
@@ -918,26 +911,26 @@
get a dict from the handler."""
order = ()
if ctx.scmd == 'domaininfo':
- order = ((u'domain name', 0), (u'gid', 1), (u'domain directory', 0),
- (u'quota limit/user', 0), (u'active services', 0),
- (u'transport', 0), (u'alias domains', 0), (u'accounts', 0),
- (u'aliases', 0), (u'relocated', 0), (u'catch-all dests', 0))
+ order = (('domain name', 0), ('gid', 1), ('domain directory', 0),
+ ('quota limit/user', 0), ('active services', 0),
+ ('transport', 0), ('alias domains', 0), ('accounts', 0),
+ ('aliases', 0), ('relocated', 0), ('catch-all dests', 0))
elif ctx.scmd == 'userinfo':
- if ctx.argc == 4 and ctx.args[3] != u'aliases' or \
+ if ctx.argc == 4 and ctx.args[3] != 'aliases' or \
ctx.cget('account.disk_usage'):
- order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1),
- (u'home', 0), (u'mail_location', 0),
- (u'quota storage', 0), (u'quota messages', 0),
- (u'disk usage', 0), (u'transport', 0), (u'smtp', 1),
- (u'pop3', 1), (u'imap', 1), (u'sieve', 1))
+ order = (('address', 0), ('name', 0), ('uid', 1), ('gid', 1),
+ ('home', 0), ('mail_location', 0),
+ ('quota storage', 0), ('quota messages', 0),
+ ('disk usage', 0), ('transport', 0), ('smtp', 1),
+ ('pop3', 1), ('imap', 1), ('sieve', 1))
else:
- order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1),
- (u'home', 0), (u'mail_location', 0),
- (u'quota storage', 0), (u'quota messages', 0),
- (u'transport', 0), (u'smtp', 1), (u'pop3', 1),
- (u'imap', 1), (u'sieve', 1))
+ order = (('address', 0), ('name', 0), ('uid', 1), ('gid', 1),
+ ('home', 0), ('mail_location', 0),
+ ('quota storage', 0), ('quota messages', 0),
+ ('transport', 0), ('smtp', 1), ('pop3', 1),
+ ('imap', 1), ('sieve', 1))
elif ctx.scmd == 'getuser':
- order = ((u'uid', 1), (u'gid', 1), (u'address', 0))
+ order = (('uid', 1), ('gid', 1), ('address', 0))
return order
@@ -959,34 +952,30 @@
q_usage['percent'] = locale.format('%6.2f', 100. / limit * used, True)
else:
q_usage['percent'] = locale.format('%6.2f', 0, True)
- # Py25: fmt = format_domain_default if domaindefault else lambda s: s
- if domaindefault:
- fmt = format_domain_default
- else:
- fmt = lambda s: s
+ fmt = format_domain_default if domaindefault else lambda s: s
# TP: e.g.: [ 0.00%] 21.09 KiB/1.00 GiB
- return fmt(_(u'[%(percent)s%%] %(used)s/%(limit)s') % q_usage)
+ return fmt(_('[%(percent)s%%] %(used)s/%(limit)s') % q_usage)
def _print_info(ctx, info, title):
"""Print info dicts."""
# TP: used in e.g. 'Domain information' or 'Account information'
- msg = u'%s %s' % (title, _(u'information'))
- w_std(msg, u'-' * len(msg))
+ msg = '%s %s' % (title, _('information'))
+ w_std(msg, '-' * len(msg))
for key, upper in _get_order(ctx):
if upper:
- w_std(u'\t%s: %s' % (key.upper().ljust(17, u'.'), info[key]))
+ w_std('\t%s: %s' % (key.upper().ljust(17, '.'), info[key]))
else:
- w_std(u'\t%s: %s' % (key.title().ljust(17, u'.'), info[key]))
- print
+ w_std('\t%s: %s' % (key.title().ljust(17, '.'), info[key]))
+ print()
note = info.get('note')
if note:
_print_note(note + '\n')
def _print_note(note):
- msg = _(u'Note')
- w_std(msg, u'-' * len(msg))
+ msg = _('Note')
+ w_std(msg, '-' * len(msg))
old_ii = txt_wrpr.initial_indent
old_si = txt_wrpr.subsequent_indent
txt_wrpr.initial_indent = txt_wrpr.subsequent_indent = '\t'
@@ -1001,63 +990,60 @@
def _print_list(alist, title):
"""Print a list."""
# TP: used in e.g. 'Existing alias addresses' or 'Existing accounts'
- msg = u'%s %s' % (_(u'Existing'), title)
- w_std(msg, u'-' * len(msg))
+ msg = '%s %s' % (_('Existing'), title)
+ w_std(msg, '-' * len(msg))
if alist:
- if title != _(u'alias domains'):
- w_std(*(u'\t%s' % item for item in alist))
+ if title != _('alias domains'):
+ w_std(*('\t%s' % item for item in alist))
else:
for domain in alist:
if not domain.startswith('xn--'):
- w_std(u'\t%s' % domain)
+ w_std('\t%s' % domain)
else:
- w_std(u'\t%s (%s)' % (domain, domain.decode('idna')))
- print
+ w_std('\t%s (%s)' % (domain, domain.decode('idna')))
+ print()
else:
- w_std(_(u'\tNone'), '')
+ w_std(_('\tNone'), '')
def _print_aliase_info(alias, destinations):
"""Print the alias address and all its destinations"""
- title = _(u'Alias information')
- w_std(title, u'-' * len(title))
- w_std(_(u'\tMail for %s will be redirected to:') % alias)
- w_std(*(u'\t * %s' % dest for dest in destinations))
- print
+ title = _('Alias information')
+ w_std(title, '-' * len(title))
+ w_std(_('\tMail for %s will be redirected to:') % alias)
+ w_std(*('\t * %s' % dest for dest in destinations))
+ print()
def _print_catchall_info(domain, destinations):
"""Print the catchall destinations of a domain"""
- title = _(u'Catch-all information')
- w_std(title, u'-' * len(title))
- w_std(_(u'\tMail to unknown local-parts in domain %s will be sent to:')
+ title = _('Catch-all information')
+ w_std(title, '-' * len(title))
+ w_std(_('\tMail to unknown local-parts in domain %s will be sent to:')
% domain)
- w_std(*(u'\t * %s' % dest for dest in destinations))
- print
+ w_std(*('\t * %s' % dest for dest in destinations))
+ print()
def _print_relocated_info(**kwargs):
"""Print the old and new addresses of a relocated user."""
- title = _(u'Relocated information')
- w_std(title, u'-' * len(title))
- w_std(_(u"\tUser '%(addr)s' has moved to '%(dest)s'") % kwargs, '')
+ title = _('Relocated information')
+ w_std(title, '-' * len(title))
+ w_std(_("\tUser '%(addr)s' has moved to '%(dest)s'") % kwargs, '')
def _format_domain(domain, main=True):
"""format (prefix/convert) the domain name."""
if domain.startswith('xn--'):
- domain = u'%s (%s)' % (domain, domain.decode('idna'))
+ domain = '%s (%s)' % (domain, domain.decode('idna'))
if main:
- return u'\t[+] %s' % domain
- return u'\t[-] %s' % domain
+ return '\t[+] %s' % domain
+ return '\t[-] %s' % domain
def _print_domain_list(dids, domains, matching):
"""Print a list of (matching) domains/alias domains."""
- if matching:
- title = _(u'Matching domains')
- else:
- title = _(u'Existing domains')
+ title = _('Matching domains') if matching else _('Existing domains')
w_std(title, '-' * len(title))
if domains:
for did in dids:
@@ -1067,7 +1053,7 @@
w_std(*(_format_domain(a, False) for a in domains[did][1:]))
else:
w_std(_('\tNone'))
- print
+ print()
def _print_address_list(which, dids, addresses, matching):
@@ -1083,9 +1069,9 @@
}
try:
if matching:
- title = _(u'Matching %s') % _trans[which]
+ title = _('Matching %s') % _trans[which]
else:
- title = _(u'Existing %s') % _trans[which]
+ title = _('Existing %s') % _trans[which]
w_std(title, '-' * len(title))
except KeyError:
raise VMMError(_("Invalid address type for list: '%s'") % which,
@@ -1111,15 +1097,15 @@
w_std('\t%s %s' % (leader, addr))
else:
w_std(_('\tNone'))
- print
+ print()
def _print_aliasdomain_info(info):
"""Print alias domain information."""
- title = _(u'Alias domain information')
+ title = _('Alias domain information')
for key in ('alias', 'domain'):
if info[key].startswith('xn--'):
- info[key] = u'%s (%s)' % (info[key], info[key].decode('idna'))
+ info[key] = '%s (%s)' % (info[key], info[key].decode('idna'))
w_std(title, '-' * len(title),
_('\tThe alias domain %(alias)s belongs to:\n\t * %(domain)s') %
info, '')
--- a/VirtualMailManager/common.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/common.py Wed Nov 21 13:13:31 2012 +0000
@@ -36,9 +36,9 @@
def get_unicode(string):
"""Converts `string` to `unicode`, if necessary."""
- if isinstance(string, unicode):
+ if isinstance(string, str):
return string
- return unicode(string, ENCODING, 'replace')
+ return str(string, ENCODING, 'replace')
def lisdir(path):
@@ -60,19 +60,19 @@
"""
binary = expand_path(binary)
if not os.path.isfile(binary):
- raise VMMError(_(u"No such file: '%s'") % get_unicode(binary),
+ raise VMMError(_("No such file: '%s'") % get_unicode(binary),
NO_SUCH_BINARY)
if not os.access(binary, os.X_OK):
- raise VMMError(_(u"File is not executable: '%s'") %
+ raise VMMError(_("File is not executable: '%s'") %
get_unicode(binary), NOT_EXECUTABLE)
return binary
def human_size(size):
"""Converts the `size` in bytes in human readable format."""
- if not isinstance(size, (long, int)):
+ if not isinstance(size, int):
try:
- size = long(size)
+ size = int(size)
except ValueError:
raise TypeError("'size' must be a positive long or int.")
if size < 0:
@@ -80,12 +80,12 @@
if size < 1024:
return str(size)
# TP: abbreviations of gibibyte, tebibyte kibibyte and mebibyte
- prefix_multiply = ((_(u'TiB'), 1 << 40), (_(u'GiB'), 1 << 30),
- (_(u'MiB'), 1 << 20), (_(u'KiB'), 1 << 10))
+ prefix_multiply = ((_('TiB'), 1 << 40), (_('GiB'), 1 << 30),
+ (_('MiB'), 1 << 20), (_('KiB'), 1 << 10))
for prefix, multiply in prefix_multiply:
if size >= multiply:
# TP: e.g.: '%(size)s %(prefix)s' -> '118.30 MiB'
- return _(u'%(size)s %(prefix)s') % {
+ return _('%(size)s %(prefix)s') % {
'size': locale.format('%.2f', float(size) / multiply,
True).decode(ENCODING, 'replace'),
'prefix': prefix}
@@ -97,7 +97,7 @@
The string `size` can be suffixed with *b* (bytes), *k* (kilobytes),
*M* (megabytes) or *G* (gigabytes).
"""
- if not isinstance(size, basestring) or not size:
+ if not isinstance(size, str) or not size:
raise TypeError('size must be a non empty string.')
if size[-1].upper() in ('B', 'K', 'M', 'G'):
try:
@@ -108,11 +108,11 @@
if unit == 'B':
return num
elif unit == 'K':
- return num << 10L
+ return num << 10
elif unit == 'M':
- return num << 20L
+ return num << 20
else:
- return num << 30L
+ return num << 30
else:
try:
num = int(size)
@@ -136,8 +136,8 @@
"""
if transport.transport in ('virtual', 'virtual:') and \
not maillocation.postfix:
- raise VMMError(_(u"Invalid transport '%(transport)s' for mailbox "
- u"format '%(mbfmt)s'.") %
+ raise VMMError(_("Invalid transport '%(transport)s' for mailbox "
+ "format '%(mbfmt)s'.") %
{'transport': transport.transport,
'mbfmt': maillocation.mbformat}, INVALID_MAIL_LOCATION)
@@ -189,7 +189,7 @@
global _version_cache
if version in _version_cache:
return _version_cache[version]
- if not isinstance(version, (int, long)):
+ if not isinstance(version, int):
raise TypeError('Argument is not a int/long: %r', version)
major = (version >> 28) & 0xFF
minor = (version >> 20) & 0xFF
@@ -197,7 +197,7 @@
level = (version >> 8) & 0x0F
serial = version & 0xFF
- levels = dict(zip(_version_level.values(), _version_level.keys()))
+ levels = dict(list(zip(list(_version_level.values()), list(_version_level.keys()))))
if level == 0xF and not serial:
version_string = '%u.%u.%u' % (major, minor, patch)
elif level in levels and not patch:
@@ -214,7 +214,7 @@
# TP: [domain default] indicates that a user's setting is the same as
# configured in the user's domain.
# e.g.: [ 0.84%] 42/5,000 [domain default]
- return _(u'%s [domain default]') % domaindata
+ return _('%s [domain default]') % domaindata
def search_addresses(dbh, typelimit=None, lpattern=None, llike=False,
--- a/VirtualMailManager/config.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/config.py Wed Nov 21 13:13:31 2012 +0000
@@ -8,10 +8,10 @@
VMM's configuration module for simplified configuration access.
"""
-from ConfigParser import \
+from configparser import \
Error, MissingSectionHeaderError, NoOptionError, NoSectionError, \
ParsingError, RawConfigParser
-from cStringIO import StringIO
+from io import StringIO
from VirtualMailManager.common import VERSION_RE, \
exec_ok, expand_path, get_unicode, lisdir, size_in_bytes, version_hex
@@ -19,6 +19,7 @@
from VirtualMailManager.errors import ConfigError, VMMError
from VirtualMailManager.maillocation import known_format
from VirtualMailManager.password import verify_scheme as _verify_scheme
+import collections
DB_MODULES = ('psycopg2', 'pypgsql')
DB_SSL_MODES = ('allow', 'disabled', 'prefer', 'require', 'verify-ca',
@@ -86,7 +87,7 @@
if value.lower() in self._boolean_states:
return self._boolean_states[value.lower()]
else:
- raise ConfigValueError(_(u"Not a boolean: '%s'") %
+ raise ConfigValueError(_("Not a boolean: '%s'") %
get_unicode(value))
def getboolean(self, section, option):
@@ -124,8 +125,8 @@
sect_opt = section_option.lower().split('.')
# TODO: cache it
if len(sect_opt) != 2 or not sect_opt[0] or not sect_opt[1]:
- raise BadOptionError(_(u"Bad format: '%s' - expected: "
- u"section.option") %
+ raise BadOptionError(_("Bad format: '%s' - expected: "
+ "section.option") %
get_unicode(section_option))
if not sect_opt[0] in self._cfg:
raise NoSectionError(sect_opt[0])
@@ -143,14 +144,14 @@
raise NoSectionError(section)
else:
return ((k, self._cfg[section][k].default)
- for k in self._cfg[section].iterkeys())
+ for k in self._cfg[section].keys())
# still here? Get defaults and merge defaults with configured setting
defaults = dict((k, self._cfg[section][k].default)
- for k in self._cfg[section].iterkeys())
+ for k in self._cfg[section].keys())
defaults.update(sect)
if '__name__' in defaults:
del defaults['__name__']
- return defaults.iteritems()
+ return iter(defaults.items())
def dget(self, option):
"""Returns the value of the `option`.
@@ -216,7 +217,7 @@
def sections(self):
"""Returns an iterator object for all configuration sections."""
- return self._cfg.iterkeys()
+ return iter(self._cfg.keys())
class LazyConfigOption(object):
@@ -246,15 +247,12 @@
check the value, when `LazyConfig.set()` is called.
"""
self.__cls = cls
- if not default is None: # enforce the type of the default value
- self.__default = self.__cls(default)
- else:
- self.__default = default
- if not callable(getter):
+ self.__default = default if default is None else self.__cls(default)
+ if not isinstance(getter, collections.Callable):
raise TypeError('getter has to be a callable, got a %r' %
getter.__class__.__name__)
self.__getter = getter
- if validate and not callable(validate):
+ if validate and not isinstance(validate, collections.Callable):
raise TypeError('validate has to be callable or None, got a %r' %
validate.__class__.__name__)
self.__validate = validate
@@ -337,9 +335,9 @@
},
'mailbox': {
'folders': LCO(str, 'Drafts:Sent:Templates:Trash',
- self.unicode),
+ self.str),
'format': LCO(str, 'maildir', self.get, check_mailbox_format),
- 'root': LCO(str, 'Maildir', self.unicode),
+ 'root': LCO(str, 'Maildir', self.str),
'subscribe': LCO(bool_t, True, self.getboolean),
},
'misc': {
@@ -360,12 +358,11 @@
Raises a ConfigError if the configuration syntax is
invalid.
"""
- self._cfg_file = open(self._cfg_filename, 'r')
- try:
- self.readfp(self._cfg_file)
- except (MissingSectionHeaderError, ParsingError), err:
- raise ConfigError(str(err), CONF_ERROR)
- self._cfg_file.close()
+ with open(self._cfg_filename, 'r') as self._cfg_file:
+ try:
+ self.readfp(self._cfg_file)
+ except (MissingSectionHeaderError, ParsingError) as err:
+ raise ConfigError(str(err), CONF_ERROR)
def check(self):
"""Performs a configuration check.
@@ -374,9 +371,9 @@
Or some settings have a invalid value.
"""
def iter_dict():
- for section, options in self._missing.iteritems():
- errmsg.write(_(u'* Section: %s\n') % section)
- errmsg.writelines(u' %s\n' % option for option in options)
+ for section, options in self._missing.items():
+ errmsg.write(_('* Section: %s\n') % section)
+ errmsg.writelines(' %s\n' % option for option in options)
self._missing.clear()
errmsg = None
@@ -385,19 +382,19 @@
'dovecot_version' in self._missing['misc']
if self._missing:
errmsg = StringIO()
- errmsg.write(_(u'Check of configuration file %s failed.\n') %
+ errmsg.write(_('Check of configuration file %s failed.\n') %
self._cfg_filename)
- errmsg.write(_(u'Missing options, which have no default value.\n'))
+ errmsg.write(_('Missing options, which have no default value.\n'))
iter_dict()
self._chk_possible_values(miss_vers)
if self._missing:
if not errmsg:
errmsg = StringIO()
- errmsg.write(_(u'Check of configuration file %s failed.\n') %
+ errmsg.write(_('Check of configuration file %s failed.\n') %
self._cfg_filename)
- errmsg.write(_(u'Invalid configuration values.\n'))
+ errmsg.write(_('Invalid configuration values.\n'))
else:
- errmsg.write('\n' + _(u'Invalid configuration values.\n'))
+ errmsg.write('\n' + _('Invalid configuration values.\n'))
iter_dict()
if errmsg:
raise ConfigError(errmsg.getvalue(), CONF_ERROR)
@@ -412,7 +409,7 @@
value to a long"""
return size_in_bytes(self.get(section, option))
- def unicode(self, section, option):
+ def str(self, section, option):
"""Returns the value of the `option` from `section`, converted
to Unicode."""
return get_unicode(self.get(section, option))
@@ -421,9 +418,9 @@
"""Checks all section's options for settings w/o a default
value. Missing items will be stored in _missing.
"""
- for section in self._cfg.iterkeys():
+ for section in self._cfg.keys():
missing = []
- for option, value in self._cfg[section].iteritems():
+ for option, value in self._cfg[section].items():
if (value.default is None and
not RawConfigParser.has_option(self, section, option)):
missing.append(option)
@@ -436,30 +433,30 @@
value = self.get('misc', 'dovecot_version')
if not VERSION_RE.match(value):
self._missing['misc'] = ['version: ' +
- _(u"Not a valid Dovecot version: '%s'") % value]
+ _("Not a valid Dovecot version: '%s'") % value]
# section database
db_err = []
value = self.dget('database.module').lower()
if value not in DB_MODULES:
db_err.append('module: ' +
- _(u"Unsupported database module: '%s'") % value)
+ _("Unsupported database module: '%s'") % value)
if value == 'psycopg2':
value = self.dget('database.sslmode')
if value not in DB_SSL_MODES:
db_err.append('sslmode: ' +
- _(u"Unknown pgsql SSL mode: '%s'") % value)
+ _("Unknown pgsql SSL mode: '%s'") % value)
if db_err:
self._missing['database'] = db_err
# section mailbox
value = self.dget('mailbox.format')
if not known_format(value):
self._missing['mailbox'] = ['format: ' +
- _(u"Unsupported mailbox format: '%s'") % value]
+ _("Unsupported mailbox format: '%s'") % value]
# section domain
try:
value = self.dget('domain.quota_bytes')
- except (ValueError, TypeError), err:
- self._missing['domain'] = [u'quota_bytes: ' + str(err)]
+ except (ValueError, TypeError) as err:
+ self._missing['domain'] = ['quota_bytes: ' + str(err)]
def is_dir(path):
@@ -470,14 +467,14 @@
path = expand_path(path)
if lisdir(path):
return path
- raise ConfigValueError(_(u"No such directory: %s") % get_unicode(path))
+ raise ConfigValueError(_("No such directory: %s") % get_unicode(path))
def check_db_module(module):
"""Check if the *module* is a supported pgsql module."""
if module.lower() in DB_MODULES:
return module
- raise ConfigValueError(_(u"Unsupported database module: '%s'") %
+ raise ConfigValueError(_("Unsupported database module: '%s'") %
get_unicode(module))
@@ -485,7 +482,7 @@
"""Check if the *ssl_mode* is one of the SSL modes, known by pgsql."""
if ssl_mode in DB_SSL_MODES:
return ssl_mode
- raise ConfigValueError(_(u"Unknown pgsql SSL mode: '%s'") %
+ raise ConfigValueError(_("Unknown pgsql SSL mode: '%s'") %
get_unicode(ssl_mode))
@@ -498,7 +495,7 @@
format = format.lower()
if known_format(format):
return format
- raise ConfigValueError(_(u"Unsupported mailbox format: '%s'") %
+ raise ConfigValueError(_("Unsupported mailbox format: '%s'") %
get_unicode(format))
@@ -508,8 +505,8 @@
Otherwise a `ConfigValueError` will be raised."""
try:
tmp = size_in_bytes(value)
- except (TypeError, ValueError), err:
- raise ConfigValueError(_(u"Not a valid size value: '%s'") %
+ except (TypeError, ValueError) as err:
+ raise ConfigValueError(_("Not a valid size value: '%s'") %
get_unicode(value))
return value
@@ -520,7 +517,7 @@
Otherwise a `ConfigValueError` will be raised.
"""
if not VERSION_RE.match(version_string):
- raise ConfigValueError(_(u"Not a valid Dovecot version: '%s'") %
+ raise ConfigValueError(_("Not a valid Dovecot version: '%s'") %
get_unicode(version_string))
return version_string
@@ -531,7 +528,7 @@
"""
try:
scheme, encoding = _verify_scheme(scheme)
- except VMMError, err: # 'cast' it
+ except VMMError as err: # 'cast' it
raise ConfigValueError(err.msg)
if not encoding:
return scheme
--- a/VirtualMailManager/domain.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/domain.py Wed Nov 21 13:13:31 2012 +0000
@@ -18,7 +18,6 @@
from VirtualMailManager.common import validate_transport
from VirtualMailManager.errors import VMMError, DomainError as DomErr
from VirtualMailManager.maillocation import MailLocation
-from VirtualMailManager.pycompat import all, any
from VirtualMailManager.quotalimit import QuotaLimit
from VirtualMailManager.serviceset import ServiceSet
from VirtualMailManager.transport import Transport
@@ -79,7 +78,7 @@
dbc.close()
if result:
if not result[5]:
- raise DomErr(_(u"The domain '%s' is an alias domain.") %
+ raise DomErr(_("The domain '%s' is an alias domain.") %
self._name, DOMAIN_ALIAS_EXISTS)
self._gid, self._directory = result[0], result[4]
self._qlimit = QuotaLimit(self._dbh, qid=result[1])
@@ -114,9 +113,9 @@
result = result[0]
if any(result):
keys = ('account_count', 'alias_count', 'relocated_count')
- raise DomErr(_(u'There are %(account_count)u accounts, '
- u'%(alias_count)u aliases and %(relocated_count)u '
- u'relocated users.') % dict(zip(keys, result)),
+ raise DomErr(_('There are %(account_count)u accounts, '
+ '%(alias_count)u aliases and %(relocated_count)u '
+ 'relocated users.') % dict(list(zip(keys, result))),
ACCOUNT_AND_ALIAS_PRESENT)
def _chk_state(self, must_exist=True):
@@ -126,10 +125,10 @@
- or *must_exist* is `False` and the domain exists
"""
if must_exist and self._new:
- raise DomErr(_(u"The domain '%s' does not exist.") % self._name,
+ raise DomErr(_("The domain '%s' does not exist.") % self._name,
NO_SUCH_DOMAIN)
elif not must_exist and not self._new:
- raise DomErr(_(u"The domain '%s' already exists.") % self._name,
+ raise DomErr(_("The domain '%s' already exists.") % self._name,
DOMAIN_EXISTS)
def _update_tables(self, column, value):
@@ -264,7 +263,7 @@
The note, or None to remove
"""
self._chk_state(False)
- assert note is None or isinstance(note, basestring)
+ assert note is None or isinstance(note, str)
self._note = note
def save(self):
@@ -326,8 +325,8 @@
enforce new quota limit for all accounts, default `False`
"""
if cfg_dget('misc.dovecot_version') < 0x10102f00:
- raise VMMError(_(u'PostgreSQL-based dictionary quota requires '
- u'Dovecot >= v1.1.2.'), VMM_ERROR)
+ raise VMMError(_('PostgreSQL-based dictionary quota requires '
+ 'Dovecot >= v1.1.2.'), VMM_ERROR)
self._chk_state()
assert isinstance(quotalimit, QuotaLimit)
if not force and quotalimit == self._qlimit:
@@ -389,7 +388,7 @@
the new note
"""
self._chk_state()
- assert note is None or isinstance(note, basestring)
+ assert note is None or isinstance(note, str)
if note == self._note:
return
self._update_tables('note', note)
@@ -406,7 +405,7 @@
dbc.close()
keys = ('alias domains', 'accounts', 'aliases', 'relocated',
'catch-all dests')
- info = dict(zip(keys, info))
+ info = dict(list(zip(keys, info)))
info['gid'] = self._gid
info['domain name'] = self._name
info['transport'] = self._transport.transport
@@ -433,7 +432,7 @@
dbc.close()
accounts = []
if users:
- addr = u'@'.join
+ addr = '@'.join
_dom = self._name
accounts = [addr((account[0], _dom)) for account in users]
return accounts
@@ -448,7 +447,7 @@
dbc.close()
aliases = []
if addresses:
- addr = u'@'.join
+ addr = '@'.join
_dom = self._name
aliases = [addr((alias[0], _dom)) for alias in addresses]
return aliases
@@ -463,7 +462,7 @@
dbc.close()
relocated = []
if addresses:
- addr = u'@'.join
+ addr = '@'.join
_dom = self._name
relocated = [addr((address[0], _dom)) for address in addresses]
return relocated
@@ -502,9 +501,9 @@
if not RE_DOMAIN.match(domainname):
domainname = domainname.encode('idna')
if len(domainname) > 255:
- raise DomErr(_(u'The domain name is too long'), DOMAIN_TOO_LONG)
+ raise DomErr(_('The domain name is too long'), DOMAIN_TOO_LONG)
if not RE_DOMAIN.match(domainname):
- raise DomErr(_(u"The domain name '%s' is invalid") % domainname,
+ raise DomErr(_("The domain name '%s' is invalid") % domainname,
DOMAIN_INVALID)
return domainname
--- a/VirtualMailManager/emailaddress.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/emailaddress.py Wed Nov 21 13:13:31 2012 +0000
@@ -26,7 +26,7 @@
def __init__(self, address, _validate=True):
"""Creates a new instance from the string/unicode ``address``."""
- assert isinstance(address, basestring)
+ assert isinstance(address, str)
self._localpart = None
self._domainname = None
if _validate:
@@ -70,16 +70,16 @@
parts = address.split('@')
p_len = len(parts)
if p_len < 2:
- raise EAErr(_(u"Missing the '@' sign in address: '%s'") % address,
+ raise EAErr(_("Missing the '@' sign in address: '%s'") % address,
INVALID_ADDRESS)
elif p_len > 2:
- raise EAErr(_(u"Too many '@' signs in address: '%s'") % address,
+ raise EAErr(_("Too many '@' signs in address: '%s'") % address,
INVALID_ADDRESS)
if not parts[0]:
- raise EAErr(_(u"Missing local-part in address: '%s'") % address,
+ raise EAErr(_("Missing local-part in address: '%s'") % address,
LOCALPART_INVALID)
if not parts[1]:
- raise EAErr(_(u"Missing domain name in address: '%s'") % address,
+ raise EAErr(_("Missing domain name in address: '%s'") % address,
DOMAIN_NO_NAME)
self._localpart = check_localpart(parts[0])
self._domainname = check_domainname(parts[1])
@@ -105,7 +105,7 @@
if not _validate:
try:
self._chk_address(address)
- except DomainError, err:
+ except DomainError as err:
if err.code is DOMAIN_INVALID and \
address.split('@')[1] == 'localhost':
self._localhost = True
@@ -142,13 +142,13 @@
invalid characters.
"""
if len(localpart) > 64:
- raise EAErr(_(u"The local-part '%s' is too long.") % localpart,
+ raise EAErr(_("The local-part '%s' is too long.") % localpart,
LOCALPART_TOO_LONG)
invalid_chars = set(RE_LOCALPART.findall(localpart))
if invalid_chars:
- i_chars = u''.join((u'"%s" ' % c for c in invalid_chars))
- raise EAErr(_(u"The local-part '%(l_part)s' contains invalid "
- u"characters: %(i_chars)s") % {'l_part': localpart,
+ i_chars = ''.join(('"%s" ' % c for c in invalid_chars))
+ raise EAErr(_("The local-part '%(l_part)s' contains invalid "
+ "characters: %(i_chars)s") % {'l_part': localpart,
'i_chars': i_chars}, LOCALPART_INVALID)
return localpart
--- a/VirtualMailManager/ext/postconf.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/ext/postconf.py Wed Nov 21 13:13:31 2012 +0000
@@ -81,8 +81,8 @@
"""Check that the `parameter` looks like a configuration parameter.
If not, a VMMError will be raised."""
if not self.__class__._parameter_re.match(parameter):
- raise VMMError(_(u"The value '%s' does not look like a valid "
- u"Postfix configuration parameter name.") %
+ raise VMMError(_("The value '%s' does not look like a valid "
+ "Postfix configuration parameter name.") %
parameter, VMM_ERROR)
def _expand_vars(self):
@@ -99,7 +99,7 @@
def _expand_multi_vars(self, old_new):
"""Replace all $vars in self._val with their values."""
- for old, new in old_new.iteritems():
+ for old, new in old_new.items():
self._val = self._val.replace('$' + old, new)
def _read(self, parameter):
--- a/VirtualMailManager/handler.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/handler.py Wed Nov 21 13:13:31 2012 +0000
@@ -37,7 +37,6 @@
from VirtualMailManager.errors import \
DomainError, NotRootError, PermissionError, VMMError
from VirtualMailManager.mailbox import new as new_mailbox
-from VirtualMailManager.pycompat import all, any
from VirtualMailManager.quotalimit import QuotaLimit
from VirtualMailManager.relocated import Relocated
from VirtualMailManager.serviceset import ServiceSet, SERVICES
@@ -51,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),
}
@@ -79,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)
@@ -99,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
@@ -125,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:
@@ -154,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
@@ -181,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):
@@ -202,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):
@@ -240,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])
@@ -293,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'))
@@ -315,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'))
@@ -332,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)
@@ -349,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):
@@ -384,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):
@@ -426,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."""
@@ -439,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'),
@@ -452,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)
@@ -469,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
@@ -484,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)
@@ -518,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()
@@ -597,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)
@@ -616,13 +615,10 @@
dpattern = parts[1]
dlike = dpattern.startswith('%') or dpattern.endswith('%')
- if llike:
- checkp = lpattern.strip('%')
- else:
- checkp = lpattern
+ 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
@@ -630,13 +626,10 @@
dpattern = parts[0]
dlike = dpattern.startswith('%') or dpattern.endswith('%')
- if dlike:
- checkp = dpattern.strip('%')
- else:
- checkp = dpattern
+ 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,
@@ -647,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)
@@ -670,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(...)"""
@@ -679,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
@@ -689,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'
@@ -708,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):
@@ -725,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:'))
@@ -747,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`
@@ -769,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:'))
@@ -780,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'):
@@ -806,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)
@@ -819,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)
@@ -827,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)
@@ -835,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_,
@@ -849,24 +842,22 @@
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)
- if transport == 'domain':
- transport = None
- else:
- transport = Transport(self._dbh, transport=transport)
+ transport = None if transport == 'domain' \
+ else Transport(self._dbh, transport=transport)
acc.update_transport(transport)
def user_services(self, emailaddress, *services):
"""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
@@ -874,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)
@@ -891,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
@@ -901,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):
--- a/VirtualMailManager/mailbox.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/mailbox.py Wed Nov 21 13:13:31 2012 +0000
@@ -35,7 +35,7 @@
def _mbase64_to_unicode(mb64):
- return unicode(a2b_base64(mb64.replace(',', '/') + '==='), 'utf-16be')
+ return str(a2b_base64(mb64.replace(',', '/') + '==='), 'utf-16be')
def utf8_to_mutf7(src):
@@ -86,7 +86,7 @@
class Mailbox(object):
"""Base class of all mailbox classes."""
__slots__ = ('_boxes', '_root', '_sep', '_user')
- FILE_MODE = 0600
+ FILE_MODE = 0o600
_ctrl_chr_re = re.compile('[\x00-\x1F\x7F-\x9F]')
_box_name_re = re.compile('^[\x20-\x25\x27-\x7E]+$')
@@ -206,11 +206,9 @@
"""Writes all created mailboxes to the subscriptions file."""
if not self._boxes:
return
- subscriptions = open('subscriptions', 'w')
- subscriptions.write('\n'.join(self._boxes))
- subscriptions.write('\n')
- subscriptions.flush()
- subscriptions.close()
+ with open('subscriptions', 'w') as subscriptions:
+ subscriptions.write('\n'.join(self._boxes))
+ subscriptions.write('\n')
os.chown('subscriptions', self._user.uid, self._user.gid)
os.chmod('subscriptions', self.__class__.FILE_MODE)
del self._boxes[:]
@@ -257,7 +255,7 @@
process = Popen(cmd_args, stderr=PIPE)
stderr = process.communicate()[1]
if process.returncode:
- e_msg = _(u'Failed to create mailboxes: %r\n') % mailboxes
+ e_msg = _('Failed to create mailboxes: %r\n') % mailboxes
raise VMMError(e_msg + stderr.strip(), VMM_ERROR)
def create(self):
--- a/VirtualMailManager/maillocation.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/maillocation.py Wed Nov 21 13:13:31 2012 +0000
@@ -12,7 +12,6 @@
from VirtualMailManager.constants import MAILLOCATION_INIT
from VirtualMailManager.errors import MailLocationError as MLErr
-from VirtualMailManager.pycompat import all
__all__ = ('MailLocation', 'known_format')
@@ -56,29 +55,29 @@
self._mbfmt = None
self._mid = 0
- for key in kwargs.iterkeys():
+ for key in kwargs.keys():
if key not in self.__class__._kwargs:
raise ValueError('unrecognized keyword: %r' % key)
mid = kwargs.get('mid')
if mid:
- assert isinstance(mid, (int, long))
+ assert isinstance(mid, int)
self._load_by_mid(mid)
else:
args = kwargs.get('mbfmt'), kwargs.get('directory')
- assert all(isinstance(arg, basestring) for arg in args)
+ assert all(isinstance(arg, str) for arg in args)
if args[0].lower() not in _format_info:
- raise MLErr(_(u"Unsupported mailbox format: '%s'") % args[0],
+ raise MLErr(_("Unsupported mailbox format: '%s'") % args[0],
MAILLOCATION_INIT)
directory = args[1].strip()
if not directory:
- raise MLErr(_(u"Empty directory name"), MAILLOCATION_INIT)
+ raise MLErr(_("Empty directory name"), MAILLOCATION_INIT)
if len(directory) > 20:
- raise MLErr(_(u"Directory name is too long: '%s'") % directory,
+ raise MLErr(_("Directory name is too long: '%s'") % directory,
MAILLOCATION_INIT)
self._load_by_names(args[0].lower(), directory)
def __str__(self):
- return u'%s:~/%s' % (self._mbfmt, self._directory)
+ return '%s:~/%s' % (self._mbfmt, self._directory)
@property
def directory(self):
--- a/VirtualMailManager/network.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/network.py Wed Nov 21 13:13:31 2012 +0000
@@ -81,7 +81,7 @@
`(address_family, address_as_long)` will be returned. The
`address_family`will be either `socket.AF_INET` or `socket.AF_INET6`.
"""
- if not isinstance(ip_address, basestring) or not ip_address:
+ if not isinstance(ip_address, str) or not ip_address:
raise TypeError('ip_address must be a non empty string.')
if not ip_address.count(':'):
family = socket.AF_INET
@@ -97,4 +97,4 @@
address = socket.inet_pton(family, ip_address)
except socket.error:
raise ValueError('Not a valid IPv6 address: %r' % ip_address)
- return (family, long(address.encode('hex'), 16))
+ return (family, int(address.encode('hex'), 16))
--- a/VirtualMailManager/password.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/password.py Wed Nov 21 13:13:31 2012 +0000
@@ -15,22 +15,18 @@
schemes, encodings = list_schemes()
"""
+import hashlib
+
from crypt import crypt
from random import SystemRandom
from subprocess import Popen, PIPE
-try:
- import hashlib
-except ImportError:
- from VirtualMailManager.pycompat import hashlib
-
from VirtualMailManager import ENCODING
from VirtualMailManager.emailaddress import EmailAddress
from VirtualMailManager.common import get_unicode, version_str
from VirtualMailManager.constants import VMM_ERROR
from VirtualMailManager.errors import VMMError
-COMPAT = hasattr(hashlib, 'compat')
SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
PASSWDCHARS = '._-+#*23456789abcdefghikmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
DEFAULT_B64 = (None, 'B64', 'BASE64')
@@ -55,7 +51,7 @@
cfg_dget = lambda option: None
_sys_rand = SystemRandom()
_choice = _sys_rand.choice
-_get_salt = lambda s_len: ''.join(_choice(SALTCHARS) for x in xrange(s_len))
+_get_salt = lambda s_len: ''.join(_choice(SALTCHARS) for x in range(s_len))
def _dovecotpw(password, scheme, encoding):
@@ -81,33 +77,17 @@
def _md4_new():
"""Returns an new MD4-hash object if supported by the hashlib or
- provided by PyCrypto - other `None`.
+ provided by PyCrypto - otherwise `None`.
"""
try:
return hashlib.new('md4')
- except ValueError, err:
+ except ValueError as err:
if str(err) == 'unsupported hash type':
- if not COMPAT:
- try:
- from Crypto.Hash import MD4
- return MD4.new()
- except ImportError:
- return None
- else:
- raise
-
-
-def _sha256_new(data=''):
- """Returns a new sha256 object from the hashlib.
-
- Returns `None` if the PyCrypto in pycompat.hashlib is too old."""
- if not COMPAT:
- return hashlib.sha256(data)
- try:
- return hashlib.new('sha256', data)
- except ValueError, err:
- if str(err) == 'unsupported hash type':
- return None
+ try:
+ from Crypto.Hash import MD4
+ return MD4.new()
+ except ImportError:
+ return None
else:
raise
@@ -248,26 +228,22 @@
def _sha256_hash(password, scheme, encoding):
"""Generates SHA256 hashes."""
- sha256 = _sha256_new(password)
- if sha256:
- if encoding in DEFAULT_B64:
- digest = sha256.digest().encode('base64').rstrip()
- else:
- digest = sha256.hexdigest()
- return _format_digest(digest, scheme, encoding)
- return _dovecotpw(password, scheme, encoding)
+ sha256 = hashlib.sha256(password)
+ if encoding in DEFAULT_B64:
+ digest = sha256.digest().encode('base64').rstrip()
+ else:
+ digest = sha256.hexdigest()
+ return _format_digest(digest, scheme, encoding)
def _sha512_hash(password, scheme, encoding):
"""Generates SHA512 hashes."""
- if not COMPAT:
- sha512 = hashlib.sha512(password)
- if encoding in DEFAULT_B64:
- digest = sha512.digest().encode('base64').replace('\n', '')
- else:
- digest = sha512.hexdigest()
- return _format_digest(digest, scheme, encoding)
- return _dovecotpw(password, scheme, encoding)
+ sha512 = hashlib.sha512(password)
+ if encoding in DEFAULT_B64:
+ digest = sha512.digest().encode('base64').replace('\n', '')
+ else:
+ digest = sha512.hexdigest()
+ return _format_digest(digest, scheme, encoding)
def _smd5_hash(password, scheme, encoding):
@@ -296,30 +272,25 @@
def _ssha256_hash(password, scheme, encoding):
"""Generates SSHA256 (salted SHA256) hashes."""
- sha256 = _sha256_new(password)
- if sha256:
- salt = _get_salt(SALTED_ALGO_SALT_LEN)
- sha256.update(salt)
- if encoding in DEFAULT_B64:
- digest = (sha256.digest() + salt).encode('base64').rstrip()
- else:
- digest = sha256.hexdigest() + salt.encode('hex')
- return _format_digest(digest, scheme, encoding)
- return _dovecotpw(password, scheme, encoding)
+ sha256 = hashlib.sha256(password)
+ salt = _get_salt(SALTED_ALGO_SALT_LEN)
+ sha256.update(salt)
+ if encoding in DEFAULT_B64:
+ digest = (sha256.digest() + salt).encode('base64').rstrip()
+ else:
+ digest = sha256.hexdigest() + salt.encode('hex')
+ return _format_digest(digest, scheme, encoding)
def _ssha512_hash(password, scheme, encoding):
"""Generates SSHA512 (salted SHA512) hashes."""
- if not COMPAT:
- salt = _get_salt(SALTED_ALGO_SALT_LEN)
- sha512 = hashlib.sha512(password + salt)
- if encoding in DEFAULT_B64:
- digest = (sha512.digest() + salt).encode('base64').replace('\n',
- '')
- else:
- digest = sha512.hexdigest() + salt.encode('hex')
- return _format_digest(digest, scheme, encoding)
- return _dovecotpw(password, scheme, encoding)
+ salt = _get_salt(SALTED_ALGO_SALT_LEN)
+ sha512 = hashlib.sha512(password + salt)
+ if encoding in DEFAULT_B64:
+ digest = (sha512.digest() + salt).encode('base64').replace('\n', '')
+ else:
+ digest = sha512.hexdigest() + salt.encode('hex')
+ return _format_digest(digest, scheme, encoding)
_scheme_info = {
'CLEARTEXT': (_clear_hash, 0x10000f00),
@@ -359,11 +330,8 @@
be empty.
"""
dcv = cfg_dget('misc.dovecot_version')
- schemes = (k for (k, v) in _scheme_info.iteritems() if v[1] <= dcv)
- if dcv >= 0x10100a01:
- encodings = ('.B64', '.BASE64', '.HEX')
- else:
- encodings = ()
+ schemes = (k for (k, v) in _scheme_info.items() if v[1] <= dcv)
+ encodings = ('.B64', '.BASE64', '.HEX') if dcv >= 0x10100a01 else ()
return schemes, encodings
@@ -382,23 +350,23 @@
* depends on a newer Dovecot version
* has a unknown encoding suffix
"""
- assert isinstance(scheme, basestring), 'Not a str/unicode: %r' % scheme
+ assert isinstance(scheme, str), 'Not a str/unicode: %r' % scheme
scheme_encoding = scheme.upper().split('.')
scheme = scheme_encoding[0]
if scheme not in _scheme_info:
- raise VMMError(_(u"Unsupported password scheme: '%s'") % scheme,
+ raise VMMError(_("Unsupported password scheme: '%s'") % scheme,
VMM_ERROR)
if cfg_dget('misc.dovecot_version') < _scheme_info[scheme][1]:
- raise VMMError(_(u"The password scheme '%(scheme)s' requires Dovecot "
- u">= v%(version)s.") % {'scheme': scheme,
+ raise VMMError(_("The password scheme '%(scheme)s' requires Dovecot "
+ ">= v%(version)s.") % {'scheme': scheme,
'version': version_str(_scheme_info[scheme][1])},
VMM_ERROR)
if len(scheme_encoding) > 1:
if cfg_dget('misc.dovecot_version') < 0x10100a01:
- raise VMMError(_(u'Encoding suffixes for password schemes require '
- u'Dovecot >= v1.1.alpha1.'), VMM_ERROR)
+ raise VMMError(_('Encoding suffixes for password schemes require '
+ 'Dovecot >= v1.1.alpha1.'), VMM_ERROR)
if scheme_encoding[1] not in ('B64', 'BASE64', 'HEX'):
- raise VMMError(_(u"Unsupported password encoding: '%s'") %
+ raise VMMError(_("Unsupported password encoding: '%s'") %
scheme_encoding[1], VMM_ERROR)
encoding = scheme_encoding[1]
else:
@@ -413,9 +381,9 @@
be used for the hash generation. When 'DIGEST-MD5' is used as scheme,
also an EmailAddress instance must be given as *user* argument.
"""
- if not isinstance(password, basestring):
+ if not isinstance(password, str):
raise TypeError('Password is not a string: %r' % password)
- if isinstance(password, unicode):
+ if isinstance(password, str):
password = password.encode(ENCODING)
password = password.strip()
if not password:
--- a/VirtualMailManager/pycompat/__init__.py Wed Nov 21 12:53:56 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-# -*- coding: UTF-8 -*-
-# Copyright (c) 2010 - 2012, Pascal Volk
-# See COPYING for distribution information.
-
-"""
- VirtualMailManager.pycompat
-
- VirtualMailManager's compatibility stuff for Python 2.4
-"""
-
-# http://docs.python.org/library/functions.html#all
-try:
- all = all
-except NameError:
- def all(iterable):
- """Return True if all elements of the *iterable* are true
- (or if the iterable is empty).
-
- """
- for element in iterable:
- if not element:
- return False
- return True
-
-
-# http://docs.python.org/library/functions.html#any
-try:
- any = any
-except NameError:
- def any(iterable):
- """Return True if any element of the *iterable* is true. If the
- iterable is empty, return False.
-
- """
- for element in iterable:
- if element:
- return True
- return False
--- a/VirtualMailManager/pycompat/hashlib.py Wed Nov 21 12:53:56 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-# -*- coding: UTF-8 -*-
-# Copyright (c) 2010 - 2012, Pascal Volk
-# See COPYING for distribution information.
-
-"""
- VirtualMailManager.pycompat.hashlib
-
- VirtualMailManager's minimal hashlib emulation for Python 2.4
-
- hashlib.md5(...), hashlib.sha1(...), hashlib.new('md5', ...) and
- hashlib.new('sha1', ...) will work always.
-
- When the PyCrypto module <http://www.pycrypto.org/> could be found in
- sys.path hashlib.new('md4', ...) will also work.
-
- With PyCrypto >= 2.1.0alpha1 hashlib.new('sha256', ...) and
- hashlib.sha256(...) becomes functional.
-"""
-
-
-import md5 as _md5
-import sha as _sha1
-
-try:
- import Crypto
-except ImportError:
- _md4 = None
- SHA256 = None
-else:
- from Crypto.Hash import MD4 as _md4
- if hasattr(Crypto, 'version_info'): # <- Available since v2.1.0alpha1
- from Crypto.Hash import SHA256 # SHA256 works since v2.1.0alpha1
- sha256 = SHA256.new
- else:
- SHA256 = None
- del Crypto
-
-
-compat = 0x01
-md5 = _md5.new
-sha1 = _sha1.new
-
-
-def new(name, string=''):
- """Return a new hashing object using the named algorithm, optionally
- initialized with the provided string.
- """
- if name in ('md5', 'MD5'):
- return _md5.new(string)
- if name in ('sha1', 'SHA1'):
- return _sha1.new(string)
- if not _md4:
- raise ValueError('unsupported hash type')
- if name in ('md4', 'MD4'):
- return _md4.new(string)
- if name in ('sha256', 'SHA256') and SHA256:
- return SHA256.new(string)
- raise ValueError('unsupported hash type')
--- a/VirtualMailManager/quotalimit.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/quotalimit.py Wed Nov 21 13:13:31 2012 +0000
@@ -9,8 +9,6 @@
for domains and accounts.
"""
-from VirtualMailManager.pycompat import all
-
_ = lambda msg: msg
@@ -44,24 +42,18 @@
self._bytes = 0
self._messages = 0
- for key in kwargs.iterkeys():
+ for key in kwargs.keys():
if key not in self.__class__._kwargs:
raise ValueError('unrecognized keyword: %r' % key)
qid = kwargs.get('qid')
if qid is not None:
- assert isinstance(qid, (int, long))
+ assert isinstance(qid, int)
self._load_by_qid(qid)
else:
bytes_, msgs = kwargs.get('bytes'), kwargs.get('messages')
- assert all(isinstance(i, (int, long)) for i in (bytes_, msgs))
- if bytes_ < 0:
- self._bytes = -bytes_
- else:
- self._bytes = bytes_
- if msgs < 0:
- self._messages = -msgs
- else:
- self._messages = msgs
+ assert all(isinstance(i, int) for i in (bytes_, msgs))
+ self._bytes = -bytes_ if bytes_ < 0 else bytes_
+ self._messages = -msgs if msgs < 0 else msgs
self._load_by_limit()
@property
--- a/VirtualMailManager/relocated.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/relocated.py Wed Nov 21 13:13:31 2012 +0000
@@ -36,13 +36,13 @@
self._dbh = dbh
self._gid = get_gid(self._dbh, self._addr.domainname)
if not self._gid:
- raise RErr(_(u"The domain '%s' does not exist.") %
+ raise RErr(_("The domain '%s' does not exist.") %
self._addr.domainname, NO_SUCH_DOMAIN)
self._dest = None
self._load()
- def __nonzero__(self):
+ def __bool__(self):
"""Returns `True` if the Relocated is known, `False` if it's new."""
return self._dest is not None
@@ -59,8 +59,8 @@
if destination:
destination = DestinationEmailAddress(destination[0], self._dbh)
if destination.at_localhost:
- raise RErr(_(u"The destination address' domain name must not "
- u"be localhost."), DOMAIN_INVALID)
+ raise RErr(_("The destination address' domain name must not "
+ "be localhost."), DOMAIN_INVALID)
self._dest = destination
@property
@@ -73,14 +73,14 @@
update = False
assert isinstance(destination, DestinationEmailAddress)
if destination.at_localhost:
- raise RErr(_(u"The destination address' domain name must not be "
- u"localhost."), DOMAIN_INVALID)
+ raise RErr(_("The destination address' domain name must not be "
+ "localhost."), DOMAIN_INVALID)
if self._addr == destination:
- raise RErr(_(u'Address and destination are identical.'),
+ raise RErr(_('Address and destination are identical.'),
RELOCATED_ADDR_DEST_IDENTICAL)
if self._dest:
if self._dest == destination:
- raise RErr(_(u"The relocated user '%s' already exists.") %
+ raise RErr(_("The relocated user '%s' already exists.") %
self._addr, RELOCATED_EXISTS)
else:
self._dest = destination
@@ -103,14 +103,14 @@
def get_info(self):
"""Returns the address to which mails should be sent."""
if not self._dest:
- raise RErr(_(u"The relocated user '%s' does not exist.") %
+ raise RErr(_("The relocated user '%s' does not exist.") %
self._addr, NO_SUCH_RELOCATED)
return self._dest
def delete(self):
"""Deletes the relocated entry from the database."""
if not self._dest:
- raise RErr(_(u"The relocated user '%s' does not exist.") %
+ raise RErr(_("The relocated user '%s' does not exist.") %
self._addr, NO_SUCH_RELOCATED)
dbc = self._dbh.cursor()
dbc.execute('DELETE FROM relocated WHERE gid = %s AND address = %s',
--- a/VirtualMailManager/serviceset.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/serviceset.py Wed Nov 21 13:13:31 2012 +0000
@@ -65,12 +65,12 @@
else:
self._sieve_col = 'sieve'
- for key in kwargs.iterkeys():
+ for key in kwargs.keys():
if key not in self.__class__._kwargs:
raise ValueError('unrecognized keyword: %r' % key)
if key == 'ssid':
assert not isinstance(kwargs[key], bool) and \
- isinstance(kwargs[key], (int, long)) and kwargs[key] > 0
+ isinstance(kwargs[key], int) and kwargs[key] > 0
self._load_by_ssid(kwargs[key])
break
else:
@@ -101,13 +101,13 @@
def __repr__(self):
return '%s(%s, %s)' % (self.__class__.__name__, self._dbh,
- ', '.join('%s=%r' % s for s in self._services.iteritems()))
+ ', '.join('%s=%r' % s for s in self._services.items()))
def _load_by_services(self):
"""Try to load the service_set by it's service combination."""
sql = ('SELECT ssid FROM service_set WHERE %s' %
' AND '.join('%s = %s' %
- (k, str(v).upper()) for k, v in self._services.iteritems()))
+ (k, str(v).upper()) for k, v in self._services.items()))
if self._sieve_col == 'managesieve':
sql = sql.replace('sieve', self._sieve_col)
dbc = self._dbh.cursor()
@@ -131,10 +131,7 @@
self._ssid = result[0]
#self._services.update(zip(SERVICES, result[1:]))
for key, value in zip(SERVICES, result[1:]): # pyPgSQL compatible
- if value:
- self._services[key] = True
- else:
- self._services[key] = False
+ self._services[key] = True if value else False
def _save(self):
"""Store a new service_set in the database."""
--- a/VirtualMailManager/transport.py Wed Nov 21 12:53:56 2012 +0000
+++ b/VirtualMailManager/transport.py Wed Nov 21 13:13:31 2012 +0000
@@ -9,8 +9,6 @@
domains and accounts.
"""
-from VirtualMailManager.pycompat import any
-
_ = lambda msg: msg
@@ -34,10 +32,10 @@
self._tid = 0
assert any((tid, transport))
if tid:
- assert not isinstance(tid, bool) and isinstance(tid, (int, long))
+ assert not isinstance(tid, bool) and isinstance(tid, int)
self._load_by_id(tid)
else:
- assert isinstance(transport, basestring)
+ assert isinstance(transport, str)
self._transport = transport
self._load_by_name()
--- a/pgsql/set-permissions.py Wed Nov 21 12:53:56 2012 +0000
+++ b/pgsql/set-permissions.py Wed Nov 21 13:13:31 2012 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# coding: utf-8
# Copyright 2012, Pascal Volk
# See COPYING for distribution information.
@@ -119,10 +119,10 @@
(dc_rw_tbls, db['dovecot']))
dbc.execute('GRANT SELECT ON %s TO %s' % (dc_ro_tbls, db['dovecot']))
dbc.execute('GRANT SELECT ON %s TO %s' % (pf_ro_tbls, db['postfix']))
- for table, columns in db['dovecot_tbls'].iteritems():
+ for table, columns in db['dovecot_tbls'].items():
dbc.execute('GRANT SELECT (%s) ON %s TO %s' % (columns, table,
db['dovecot']))
- for table, columns in db['postfix_tbls'].iteritems():
+ for table, columns in db['postfix_tbls'].items():
dbc.execute('GRANT SELECT (%s) ON %s TO %s' % (columns, table,
db['postfix']))
dbc.close()
--- a/setup.py Wed Nov 21 12:53:56 2012 +0000
+++ b/setup.py Wed Nov 21 13:13:31 2012 +0000
@@ -1,11 +1,10 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2007 - 2012, Pascal Volk
# See COPYING for distribution information.
import os
from distutils.core import setup
-from distutils.dist import DistributionMetadata
VERSION = '0.6.1'
@@ -20,7 +19,6 @@
'VirtualMailManager',
'VirtualMailManager.cli',
'VirtualMailManager.ext',
- 'VirtualMailManager.pycompat',
]
# http://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers = ['Development Status :: 5 - Production/Stable',
@@ -44,7 +42,7 @@
'Topic :: Utilities']
# sucessfuly tested on:
-platforms = ['freebsd7', 'linux2', 'openbsd4']
+platforms = ['freebsd7', 'linux2', 'openbsd5']
# remove existing MANIFEST
if os.path.exists('MANIFEST'):
@@ -58,12 +56,10 @@
'author': 'Pascal Volk',
'author_email': 'user+vmm@localhost.localdomain.org',
'license': 'BSD License',
+ 'requires': ['psycopg2 (>=2.0)'],
'url': 'http://vmm.localdomain.org/',
- 'download_url':'http://sf.net/projects/vmm/files/',
+ 'download_url': 'http://sf.net/projects/vmm/files/',
'platforms': platforms,
'classifiers': classifiers}
-if 'requires' in DistributionMetadata._METHOD_BASENAMES:
- setup_args['requires'] = ['psycopg2 (>=2.0)', 'pyPgSQL (>=2.5.1)']
-
setup(**setup_args)
--- a/update_config.py Wed Nov 21 12:53:56 2012 +0000
+++ b/update_config.py Wed Nov 21 13:13:31 2012 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# Copyright (c) 2008 - 2012, Pascal Volk
# See COPYING for distribution information.
@@ -6,7 +6,7 @@
import os
os.sys.path.remove(os.sys.path[0])
from time import time
-from ConfigParser import ConfigParser
+from configparser import ConfigParser
from shutil import copy2
pre_060 = False
@@ -161,18 +161,20 @@
if len(sect_opt):
update_cfg_file(cp, cf)
sect_opt.sort()
- print 'Please have a look at your configuration: %s' % cf
- print 'This are your Modified/Renamed/New settings:'
+ print('Please have a look at your configuration: %s' % cf)
+ print('This are your Modified/Renamed/New settings:')
for s_o, st in sect_opt:
- print '%s %s = %s' % (st, s_o, get_option(cp, s_o))
+ print('%s %s = %s' % (st, s_o, get_option(cp, s_o)))
if had_config:
- print '\nRemoved section "config" with option "done" (obsolte)'
+ print('\nRemoved section "config" with option "done" (obsolte)')
if had_gid_mail:
- print '\nRemoved option "gid_mail" from section "misc" (obsolte)\n'
+ print('\nRemoved option "gid_mail" from section "misc"',
+ '(obsolte)\n')
os.sys.exit(0)
if had_config or had_gid_mail:
update_cfg_file(cp, cf)
if had_config:
- print '\nRemoved section "config" with option "done" (obsolte)'
+ print('\nRemoved section "config" with option "done" (obsolte)')
if had_gid_mail:
- print '\nRemoved option "gid_mail" from section "misc" (obsolte)\n'
+ print('\nRemoved option "gid_mail" from section "misc"',
+ '(obsolte)\n')
--- a/vmm Wed Nov 21 12:53:56 2012 +0000
+++ b/vmm Wed Nov 21 13:13:31 2012 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# Copyright 2007 - 2012, Pascal Volk
# See COPYING for distribution information.