summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/Archiver/HyperArch.py35
-rw-r--r--src/mailman/Archiver/pipermail.py2
-rw-r--r--src/mailman/Utils.py4
-rw-r--r--src/mailman/__init__.py5
-rw-r--r--src/mailman/app/bounces.py2
-rw-r--r--src/mailman/app/membership.py4
-rw-r--r--src/mailman/app/moderator.py7
-rw-r--r--src/mailman/app/notifications.py7
-rw-r--r--src/mailman/app/registrar.py2
-rw-r--r--src/mailman/app/replybot.py3
-rw-r--r--src/mailman/bin/arch.py9
-rw-r--r--src/mailman/bin/bumpdigests.py2
-rw-r--r--src/mailman/bin/check_perms.py2
-rw-r--r--src/mailman/bin/checkdbs.py22
-rw-r--r--src/mailman/bin/cleanarch.py2
-rw-r--r--src/mailman/bin/config_list.py9
-rw-r--r--src/mailman/bin/disabled.py2
-rw-r--r--src/mailman/bin/dumpdb.py2
-rw-r--r--src/mailman/bin/export.py2
-rw-r--r--src/mailman/bin/find_member.py2
-rw-r--r--src/mailman/bin/gate_news.py2
-rw-r--r--src/mailman/bin/genaliases.py2
-rw-r--r--src/mailman/bin/import.py4
-rw-r--r--src/mailman/bin/list_members.py2
-rw-r--r--src/mailman/bin/list_owners.py2
-rw-r--r--src/mailman/bin/mailman.py2
-rw-r--r--src/mailman/bin/master.py2
-rw-r--r--src/mailman/bin/mmsitepass.py2
-rw-r--r--src/mailman/bin/nightly_gzip.py2
-rw-r--r--src/mailman/bin/qrunner.py2
-rw-r--r--src/mailman/bin/senddigests.py2
-rw-r--r--src/mailman/bin/set_members.py6
-rw-r--r--src/mailman/bin/show_config.py2
-rw-r--r--src/mailman/bin/show_qfiles.py2
-rw-r--r--src/mailman/bin/unshunt.py2
-rw-r--r--src/mailman/bin/update.py2
-rw-r--r--src/mailman/bin/withlist.py2
-rw-r--r--src/mailman/chains/accept.py2
-rw-r--r--src/mailman/chains/builtin.py2
-rw-r--r--src/mailman/chains/discard.py2
-rw-r--r--src/mailman/chains/headers.py2
-rw-r--r--src/mailman/chains/hold.py7
-rw-r--r--src/mailman/chains/reject.py2
-rw-r--r--src/mailman/commands/cli_control.py2
-rw-r--r--src/mailman/commands/cli_info.py2
-rw-r--r--src/mailman/commands/cli_inject.py2
-rw-r--r--src/mailman/commands/cli_lists.py4
-rw-r--r--src/mailman/commands/cli_members.py2
-rw-r--r--src/mailman/commands/eml_echo.py2
-rw-r--r--src/mailman/commands/eml_end.py2
-rw-r--r--src/mailman/commands/eml_join.py2
-rw-r--r--src/mailman/config/config.py3
-rw-r--r--src/mailman/core/i18n.py111
-rw-r--r--src/mailman/core/initialize.py1
-rw-r--r--src/mailman/core/pipelines.py2
-rw-r--r--src/mailman/i18n.py259
-rw-r--r--src/mailman/interfaces/domain.py2
-rw-r--r--src/mailman/interfaces/mailinglist.py2
-rw-r--r--src/mailman/interfaces/system.py2
-rw-r--r--src/mailman/mta/postfix.py2
-rw-r--r--src/mailman/options.py2
-rw-r--r--src/mailman/pipeline/acknowledge.py2
-rw-r--r--src/mailman/pipeline/after_delivery.py2
-rw-r--r--src/mailman/pipeline/avoid_duplicates.py2
-rw-r--r--src/mailman/pipeline/calculate_recipients.py2
-rw-r--r--src/mailman/pipeline/cleanse.py2
-rw-r--r--src/mailman/pipeline/cleanse_dkim.py2
-rw-r--r--src/mailman/pipeline/cook_headers.py2
-rw-r--r--src/mailman/pipeline/decorate.py2
-rw-r--r--src/mailman/pipeline/file_recipients.py2
-rw-r--r--src/mailman/pipeline/mime_delete.py3
-rw-r--r--src/mailman/pipeline/moderate.py2
-rw-r--r--src/mailman/pipeline/replybot.py2
-rw-r--r--src/mailman/pipeline/scrubber.py2
-rw-r--r--src/mailman/pipeline/tagger.py2
-rw-r--r--src/mailman/pipeline/to_archive.py2
-rw-r--r--src/mailman/pipeline/to_digest.py2
-rw-r--r--src/mailman/pipeline/to_outgoing.py2
-rw-r--r--src/mailman/pipeline/to_usenet.py2
-rw-r--r--src/mailman/queue/__init__.py4
-rw-r--r--src/mailman/queue/bounce.py7
-rw-r--r--src/mailman/queue/command.py2
-rw-r--r--src/mailman/queue/digest.py7
-rw-r--r--src/mailman/rules/administrivia.py2
-rw-r--r--src/mailman/rules/any.py2
-rw-r--r--src/mailman/rules/approved.py2
-rw-r--r--src/mailman/rules/emergency.py2
-rw-r--r--src/mailman/rules/implicit_dest.py2
-rw-r--r--src/mailman/rules/loop.py2
-rw-r--r--src/mailman/rules/max_recipients.py2
-rw-r--r--src/mailman/rules/max_size.py2
-rw-r--r--src/mailman/rules/moderation.py2
-rw-r--r--src/mailman/rules/news_moderation.py2
-rw-r--r--src/mailman/rules/no_subject.py2
-rw-r--r--src/mailman/rules/suspicious.py2
-rw-r--r--src/mailman/rules/truth.py2
-rw-r--r--src/mailman/styles/default.py2
-rw-r--r--src/mailman/testing/layers.py2
98 files changed, 260 insertions, 413 deletions
diff --git a/src/mailman/Archiver/HyperArch.py b/src/mailman/Archiver/HyperArch.py
index c7b1b0045..67c62a682 100644
--- a/src/mailman/Archiver/HyperArch.py
+++ b/src/mailman/Archiver/HyperArch.py
@@ -46,21 +46,18 @@ from string import Template
from zope.component import getUtility
from mailman import Utils
-from mailman import i18n
from mailman.Archiver import HyperDatabase
from mailman.Archiver import pipermail
from mailman.config import config
+from mailman.core.i18n import _, ctime
from mailman.interfaces.listmanager import IListManager
log = logging.getLogger('mailman.error')
-
-# Set up i18n. Assume the current language has already been set in the caller.
-_ = i18n._
-
EMPTYSTRING = ''
NL = '\n'
+
# MacOSX has a default stack size that is too small for deeply recursive
# regular expressions. We see this as crashes in the Python test suite when
# running test_re.py and test_sre.py. The fix is to set the stack limit to
@@ -109,7 +106,7 @@ def sizeof(filename, lang):
if e.errno <> errno.ENOENT: raise
return _('size not available')
if size < 1000:
- with i18n.using_language(lang.code):
+ with _.using(lang.code):
out = _(' %(size)i bytes ')
return out
elif size < 1000000:
@@ -256,7 +253,7 @@ class Article(pipermail.Article):
# article (for this list) could be different from the site-wide
# preferred language, so we need to ensure no side-effects will
# occur. Think what happens when executing bin/arch.
- with i18n.using_language(lang.code):
+ with _.using(lang.code):
if self.author == self.email:
self.author = self.email = re.sub('@', _(' at '),
self.email)
@@ -359,7 +356,7 @@ class Article(pipermail.Article):
self.decoded['email'] = email
if subject:
if as_boolean(config.archiver.pipermail.obscure_email_addresses):
- with i18n.using_language(self._lang.code):
+ with _.using(self._lang.code):
atmark = _(' at ')
subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
'\g<1>' + atmark + '\g<2>', subject)
@@ -396,8 +393,8 @@ class Article(pipermail.Article):
def as_html(self):
d = self.__dict__.copy()
- # avoid i18n side-effects
- with i18n.using_language(self._lang.code):
+ # Avoid i18n side-effects
+ with _.using(self._lang.code):
d["prev"], d["prev_wsubj"] = self._get_prev()
d["next"], d["next_wsubj"] = self._get_next()
@@ -415,7 +412,7 @@ class Article(pipermail.Article):
emailurl = self.email
d["author_html"] = self.quote(author)
d["email_url"] = url_quote(emailurl)
- d["datestr_html"] = self.quote(i18n.ctime(int(self.date)))
+ d["datestr_html"] = self.quote(ctime(int(self.date)))
d["body"] = self._get_body()
d['listurl'] = self._mlist.script_url('listinfo')
d['listname'] = self._mlist.real_name
@@ -511,7 +508,7 @@ class Article(pipermail.Article):
if not isinstance(body, unicode):
body = unicode(body, cset, 'replace')
if as_boolean(config.archiver.pipermail.obscure_email_addresses):
- with i18n.using_language(self._lang.code):
+ with _.using(self._lang.code):
atmark = _(' at ')
body = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
'\g<1>' + atmark + '\g<2>', body)
@@ -608,12 +605,12 @@ class HyperArchive(pipermail.T):
mlist=self.maillist)
def html_foot(self):
- # avoid i18n side-effects
mlist = self.maillist
# Convenience
def quotetime(s):
- return html_quote(i18n.ctime(s), self.lang.code)
- with i18n.using_language(mlist.preferred_language.code):
+ return html_quote(ctime(s), self.lang.code)
+ # Avoid i18n side-effects
+ with _.using(mlist.preferred_language.code):
d = {"lastdate": quotetime(self.lastdate),
"archivedate": quotetime(self.archivedate),
"listinfo": mlist.script_url('listinfo'),
@@ -636,12 +633,12 @@ class HyperArchive(pipermail.T):
mlist=mlist)
def html_head(self):
- # avoid i18n side-effects
mlist = self.maillist
# Convenience
def quotetime(s):
- return html_quote(i18n.ctime(s), self.lang.code)
- with i18n.using_language(mlist.preferred_language.code):
+ return html_quote(ctime(s), self.lang.code)
+ # Avoid i18n side-effects
+ with _.using(mlist.preferred_language.code):
d = {"listname": html_quote(mlist.real_name, self.lang.code),
"archtype": self.type,
"archive": self.volNameToDesc(self.archive),
@@ -682,7 +679,7 @@ class HyperArchive(pipermail.T):
'meta': '',
}
# Avoid i18n side-effects
- with i18n.using_language(mlist.preferred_language.code):
+ with _.using(mlist.preferred_language.code):
if not self.archives:
d["noarchive_msg"] = _(
'<P>Currently, there are no archives. </P>')
diff --git a/src/mailman/Archiver/pipermail.py b/src/mailman/Archiver/pipermail.py
index e6c87baa0..f47600eb1 100644
--- a/src/mailman/Archiver/pipermail.py
+++ b/src/mailman/Archiver/pipermail.py
@@ -18,7 +18,7 @@ VERSION = __version__
CACHESIZE = 100 # Number of slots in the cache
from mailman.core import errors
-from mailman.i18n import _
+from mailman.core.i18n import _
SPACE = ' '
diff --git a/src/mailman/Utils.py b/src/mailman/Utils.py
index 7f2fd2a8f..bde703cf4 100644
--- a/src/mailman/Utils.py
+++ b/src/mailman/Utils.py
@@ -50,6 +50,7 @@ import mailman.templates
from mailman import passwords
from mailman.config import config
from mailman.core import errors
+from mailman.core.i18n import _
from mailman.utilities.string import expand
@@ -398,10 +399,9 @@ def findtext(templatefile, raw_dict=None, raw=False, lang=None, mlist=None):
# We never found the template. BAD!
raise IOError(errno.ENOENT, 'No template file found', templatefile)
else:
- from mailman.i18n import get_translation
# XXX BROKEN HACK
data = fp.read()[:-1]
- template = get_translation().ugettext(data)
+ template = _(data)
fp.close()
else:
template = fp.read()
diff --git a/src/mailman/__init__.py b/src/mailman/__init__.py
index e5f46e3d4..5f1ced22f 100644
--- a/src/mailman/__init__.py
+++ b/src/mailman/__init__.py
@@ -38,3 +38,8 @@ try:
except ImportError:
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
+
+
+# We have to initialize the i18n subsystem before anything else happens.
+from mailman.core.i18n import initialize
+initialize()
diff --git a/src/mailman/app/bounces.py b/src/mailman/app/bounces.py
index 3972e2e6d..34939edc4 100644
--- a/src/mailman/app/bounces.py
+++ b/src/mailman/app/bounces.py
@@ -30,8 +30,8 @@ from email.mime.message import MIMEMessage
from email.mime.text import MIMEText
from mailman.Utils import oneline
+from mailman.core.i18n import _
from mailman.email.message import UserNotification
-from mailman.i18n import _
log = logging.getLogger('mailman.config')
diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py
index 5f58b66d5..f8234f808 100644
--- a/src/mailman/app/membership.py
+++ b/src/mailman/app/membership.py
@@ -30,16 +30,14 @@ from email.utils import formataddr
from zope.component import getUtility
from mailman import Utils
-from mailman import i18n
from mailman.app.notifications import send_goodbye_message
from mailman.core import errors
+from mailman.core.i18n import _
from mailman.email.message import OwnerNotification
from mailman.email.validate import validate
from mailman.interfaces.member import AlreadySubscribedError, MemberRole
from mailman.interfaces.usermanager import IUserManager
-_ = i18n._
-
def add_member(mlist, address, realname, password, delivery_mode, language):
diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py
index 1a09567e7..3151e91c8 100644
--- a/src/mailman/app/moderator.py
+++ b/src/mailman/app/moderator.py
@@ -36,12 +36,12 @@ from email.utils import formataddr, formatdate, getaddresses, make_msgid
from zope.component import getUtility
from mailman import Utils
-from mailman import i18n
from mailman.app.membership import add_member, delete_member
from mailman.app.notifications import (
send_admin_subscription_notice, send_welcome_message)
from mailman.config import config
from mailman.core import errors
+from mailman.core.i18n import _
from mailman.email.message import UserNotification
from mailman.interfaces.action import Action
from mailman.interfaces.member import AlreadySubscribedError, DeliveryMode
@@ -49,7 +49,6 @@ from mailman.interfaces.messages import IMessageStore
from mailman.interfaces.requests import IRequests, RequestType
-_ = i18n._
NL = '\n'
vlog = logging.getLogger('mailman.vette')
@@ -169,7 +168,7 @@ def handle_message(mlist, id, action,
member = mlist.members.get_member(addresses[0])
if member:
language = member.preferred_language
- with i18n.using_language(language.code):
+ with _.using(language.code):
fmsg = UserNotification(
addresses, mlist.bounces_address,
_('Forward of moderated message'),
@@ -343,7 +342,7 @@ def _refuse(mlist, request, recip, comment, origmsg=None, lang=None):
'reason' : comment,
'adminaddr': mlist.owner_address,
}, lang=lang.code, mlist=mlist)
- with i18n.using_language(lang.code):
+ with _.using(lang.code):
# add in original message, but not wrap/filled
if origmsg:
text = NL.join(
diff --git a/src/mailman/app/notifications.py b/src/mailman/app/notifications.py
index ac57a2154..bb72e8bc4 100644
--- a/src/mailman/app/notifications.py
+++ b/src/mailman/app/notifications.py
@@ -31,15 +31,12 @@ from email.utils import formataddr
from lazr.config import as_boolean
from mailman import Utils
-from mailman import i18n
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import OwnerNotification, UserNotification
from mailman.interfaces.member import DeliveryMode
-_ = i18n._
-
-
def send_welcome_message(mlist, address, language, delivery_mode, text=''):
"""Send a welcome message to a subscriber.
@@ -124,7 +121,7 @@ def send_admin_subscription_notice(mlist, address, full_name, language):
:param language: the language of the address's realname
:type language: string
"""
- with i18n.using_language(mlist.preferred_language.code):
+ with _.using(mlist.preferred_language.code):
subject = _('$mlist.real_name subscription notification')
full_name = full_name.encode(language.charset, 'replace')
text = Utils.maketext(
diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py
index 9fc9b8bac..c24376494 100644
--- a/src/mailman/app/registrar.py
+++ b/src/mailman/app/registrar.py
@@ -32,9 +32,9 @@ from zope.component import getUtility
from zope.interface import implements
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import UserNotification
from mailman.email.validate import validate
-from mailman.i18n import _
from mailman.interfaces.domain import IDomain
from mailman.interfaces.listmanager import IListManager
from mailman.interfaces.member import MemberRole
diff --git a/src/mailman/app/replybot.py b/src/mailman/app/replybot.py
index 2233378da..4d6cb23a4 100644
--- a/src/mailman/app/replybot.py
+++ b/src/mailman/app/replybot.py
@@ -30,11 +30,10 @@ __all__ = [
import logging
-from mailman import i18n
+from mailman.core.i18n import _
log = logging.getLogger('mailman.vette')
-_ = i18n._
diff --git a/src/mailman/bin/arch.py b/src/mailman/bin/arch.py
index abf057c3f..d4231fa26 100644
--- a/src/mailman/bin/arch.py
+++ b/src/mailman/bin/arch.py
@@ -25,15 +25,13 @@ import optparse
from locknix.lockfile import Lock
-from mailman import i18n
from mailman.Archiver.HyperArch import HyperArchive
from mailman.Defaults import hours
from mailman.configuration import config
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.version import MAILMAN_VERSION
-_ = i18n._
-
def parseargs():
@@ -93,8 +91,6 @@ def main():
parser, opts, args = parseargs()
initialize(opts.config)
- i18n.set_language(config.DEFAULT_SERVER_LANGUAGE)
-
listname = args[0].lower().strip()
if len(args) < 2:
mbox = None
@@ -108,7 +104,8 @@ def main():
if mbox is None:
mbox = mlist.ArchiveFileName()
- i18n.set_language(mlist.preferred_language)
+ # Set the default language to the list's preferred language.
+ _.default = mlist.preferred_language
# Lay claim to the archive's lock file. This is so no other post can
# mess up the archive while we're processing it. Try to pick a
# suitably long period of time for the lock lifetime even though we
diff --git a/src/mailman/bin/bumpdigests.py b/src/mailman/bin/bumpdigests.py
index b1ed37a21..5cce668cb 100644
--- a/src/mailman/bin/bumpdigests.py
+++ b/src/mailman/bin/bumpdigests.py
@@ -21,7 +21,7 @@ import optparse
from mailman import errors
from mailman import MailList
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.version import MAILMAN_VERSION
# Work around known problems with some RedHat cron daemons
diff --git a/src/mailman/bin/check_perms.py b/src/mailman/bin/check_perms.py
index 4b75aa9f6..9937eb637 100644
--- a/src/mailman/bin/check_perms.py
+++ b/src/mailman/bin/check_perms.py
@@ -25,7 +25,7 @@ import optparse
from stat import *
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/checkdbs.py b/src/mailman/bin/checkdbs.py
index fd116522e..c8ab7b83b 100644
--- a/src/mailman/bin/checkdbs.py
+++ b/src/mailman/bin/checkdbs.py
@@ -24,15 +24,14 @@ from zope.component import getUtility
from mailman import MailList
from mailman import Utils
-from mailman import i18n
from mailman.app.requests import handle_request
from mailman.configuration import config
+from mailman.core.i18n import _
from mailman.email.message import UserNotification
+from mailman.initialize import initialize
from mailman.interfaces.requests import IRequests
from mailman.version import MAILMAN_VERSION
-_ = i18n._
-
# Work around known problems with some RedHat cron daemons
import signal
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
@@ -153,9 +152,7 @@ def midnight(date=None):
def main():
opts, args, parser = parseargs()
- config.load(opts.config)
-
- i18n.set_language(config.DEFAULT_SERVER_LANGUAGE)
+ initialize(opts.config)
for name in config.list_manager.names:
# The list must be locked in order to open the requests database
@@ -175,13 +172,14 @@ def main():
# This is the only place we've changed the list's database
mlist.Save()
if count:
- i18n.set_language(mlist.preferred_language)
+ # Set the default language the the list's preferred language.
+ _.default = mlist.preferred_language
realname = mlist.real_name
discarded = auto_discard(mlist)
if discarded:
count = count - discarded
- text = _(
- 'Notice: $discarded old request(s) automatically expired.\n\n')
+ text = _('Notice: $discarded old request(s) '
+ 'automatically expired.\n\n')
else:
text = ''
if count:
@@ -189,11 +187,13 @@ def main():
'checkdbs.txt',
{'count' : count,
'host_name': mlist.host_name,
- 'adminDB' : mlist.GetScriptURL('admindb', absolute=1),
+ 'adminDB' : mlist.GetScriptURL('admindb',
+ absolute=1),
'real_name': realname,
}, mlist=mlist)
text += '\n' + pending_requests(mlist)
- subject = _('$count $realname moderator request(s) waiting')
+ subject = _('$count $realname moderator '
+ 'request(s) waiting')
else:
subject = _('$realname moderator request check result')
msg = UserNotification(mlist.GetOwnerEmail(),
diff --git a/src/mailman/bin/cleanarch.py b/src/mailman/bin/cleanarch.py
index 325fad91a..d861b3bfc 100644
--- a/src/mailman/bin/cleanarch.py
+++ b/src/mailman/bin/cleanarch.py
@@ -22,7 +22,7 @@ import sys
import mailbox
import optparse
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/config_list.py b/src/mailman/bin/config_list.py
index 89a9892cd..e2ed46ed3 100644
--- a/src/mailman/bin/config_list.py
+++ b/src/mailman/bin/config_list.py
@@ -22,12 +22,12 @@ import optparse
from mailman import MailList
from mailman import errors
-from mailman import i18n
from mailman.Utils import wrap
from mailman.configuration import config
+from mailman.core.i18n import _
+from mailman.initialize import initialize
from mailman.version import MAILMAN_VERSION
-_ = i18n._
NL = '\n'
nonasciipat = re.compile(r'[\x80-\xff]')
@@ -101,7 +101,8 @@ def do_output(listname, outfile, parser):
parser.error(_('No such list: $listname'))
# Preamble for the config info. PEP 263 charset and capture time.
charset = mlist.preferred_language.charset
- i18n.set_language(mlist.preferred_language.code)
+ # Set the system's default language.
+ _.default = mlist.preferred_language.code
if not charset:
charset = 'us-ascii'
when = time.ctime(time.time())
@@ -310,7 +311,7 @@ def do_input(listname, infile, checkonly, verbose, parser):
def main():
parser, opts, args = parseargs()
- config.load(opts.config)
+ initialize(opts.config)
listname = args[0]
# Sanity check
diff --git a/src/mailman/bin/disabled.py b/src/mailman/bin/disabled.py
index cc8eb2c69..1ff59ac5e 100644
--- a/src/mailman/bin/disabled.py
+++ b/src/mailman/bin/disabled.py
@@ -26,7 +26,7 @@ from mailman import Pending
from mailman import loginit
from mailman.Bouncer import _BounceInfo
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/dumpdb.py b/src/mailman/bin/dumpdb.py
index 6657602e4..6c3ac5414 100644
--- a/src/mailman/bin/dumpdb.py
+++ b/src/mailman/bin/dumpdb.py
@@ -19,7 +19,7 @@ import pprint
import cPickle
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interact import interact
from mailman.options import Options
diff --git a/src/mailman/bin/export.py b/src/mailman/bin/export.py
index d1992b4b4..ecd8ff3a9 100644
--- a/src/mailman/bin/export.py
+++ b/src/mailman/bin/export.py
@@ -29,7 +29,7 @@ from mailman import errors
from mailman import MemberAdaptor
from mailman.MailList import MailList
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/find_member.py b/src/mailman/bin/find_member.py
index 0982724a0..2788c5e8f 100644
--- a/src/mailman/bin/find_member.py
+++ b/src/mailman/bin/find_member.py
@@ -22,7 +22,7 @@ import optparse
from mailman import errors
from mailman import MailList
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/gate_news.py b/src/mailman/bin/gate_news.py
index eac30422d..2ca70a341 100644
--- a/src/mailman/bin/gate_news.py
+++ b/src/mailman/bin/gate_news.py
@@ -32,7 +32,7 @@ from mailman import Message
from mailman import Utils
from mailman import loginit
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.queue import Switchboard
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/genaliases.py b/src/mailman/bin/genaliases.py
index 8fe37f543..d09dc2a22 100644
--- a/src/mailman/bin/genaliases.py
+++ b/src/mailman/bin/genaliases.py
@@ -24,7 +24,7 @@ __all__ = [
import sys
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.options import Options
from mailman.utilities.modules import call_name
diff --git a/src/mailman/bin/import.py b/src/mailman/bin/import.py
index bc26e441b..6270faa15 100644
--- a/src/mailman/bin/import.py
+++ b/src/mailman/bin/import.py
@@ -30,7 +30,7 @@ from mailman import MemberAdaptor
from mailman import Utils
from mailman import passwords
from mailman.MailList import MailList
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.interfaces.domain import BadDomainSpecificationError
from mailman.version import MAILMAN_VERSION
@@ -230,7 +230,7 @@ def create(all_listdata):
'pass_filename_extensions'):
value = value.splitlines()
if option == 'available_languages':
- mlist.set_languages(*value)
+ mlist.os(*value)
else:
setattr(mlist, option, value)
for member in list_roster:
diff --git a/src/mailman/bin/list_members.py b/src/mailman/bin/list_members.py
index e715bfdcb..a94eda4a5 100644
--- a/src/mailman/bin/list_members.py
+++ b/src/mailman/bin/list_members.py
@@ -21,8 +21,8 @@ from email.Utils import formataddr
from zope.component import getUtility
from mailman.core import errors
+from mailman.core.i18n import _
from mailman.email.validate import is_valid
-from mailman.i18n import _
from mailman.interfaces.listmanager import IListManager
from mailman.interfaces.members import DeliveryStatus
from mailman.interfaces.usermanager import IUserManager
diff --git a/src/mailman/bin/list_owners.py b/src/mailman/bin/list_owners.py
index b683dcae6..fef6926c1 100644
--- a/src/mailman/bin/list_owners.py
+++ b/src/mailman/bin/list_owners.py
@@ -21,7 +21,7 @@ import optparse
from zope.component import getUtility
from mailman.MailList import MailList
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.interfaces.listmanager import IListManager
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/mailman.py b/src/mailman/bin/mailman.py
index c1b2931a4..d25ba2649 100644
--- a/src/mailman/bin/mailman.py
+++ b/src/mailman/bin/mailman.py
@@ -31,8 +31,8 @@ import argparse
from zope.interface.verify import verifyObject
from mailman.app.finder import find_components
+from mailman.core.i18n import _
from mailman.core.initialize import initialize
-from mailman.i18n import _
from mailman.interfaces.command import ICLISubCommand
from mailman.version import MAILMAN_VERSION_FULL
diff --git a/src/mailman/bin/master.py b/src/mailman/bin/master.py
index 910bad3e6..be1e24b2a 100644
--- a/src/mailman/bin/master.py
+++ b/src/mailman/bin/master.py
@@ -39,8 +39,8 @@ from locknix import lockfile
from munepy import Enum
from mailman.config import config
+from mailman.core.i18n import _
from mailman.core.logging import reopen
-from mailman.i18n import _
from mailman.options import Options
diff --git a/src/mailman/bin/mmsitepass.py b/src/mailman/bin/mmsitepass.py
index 132803fc9..3d1531196 100644
--- a/src/mailman/bin/mmsitepass.py
+++ b/src/mailman/bin/mmsitepass.py
@@ -22,7 +22,7 @@ import optparse
from mailman import Utils
from mailman import passwords
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/nightly_gzip.py b/src/mailman/bin/nightly_gzip.py
index f886e5801..5fb04b0f7 100644
--- a/src/mailman/bin/nightly_gzip.py
+++ b/src/mailman/bin/nightly_gzip.py
@@ -26,7 +26,7 @@ except ImportError:
from mailman import MailList
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/qrunner.py b/src/mailman/bin/qrunner.py
index 73e701f16..3ecdeb441 100644
--- a/src/mailman/bin/qrunner.py
+++ b/src/mailman/bin/qrunner.py
@@ -30,8 +30,8 @@ import signal
import logging
from mailman.config import config
+from mailman.core.i18n import _
from mailman.core.logging import reopen
-from mailman.i18n import _
from mailman.options import Options
from mailman.utilities.modules import find_name
diff --git a/src/mailman/bin/senddigests.py b/src/mailman/bin/senddigests.py
index fb057d6b9..31d91c1df 100644
--- a/src/mailman/bin/senddigests.py
+++ b/src/mailman/bin/senddigests.py
@@ -20,7 +20,7 @@ import sys
import optparse
from mailman import MailList
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/set_members.py b/src/mailman/bin/set_members.py
index 001e5e1d3..c4a8060b4 100644
--- a/src/mailman/bin/set_members.py
+++ b/src/mailman/bin/set_members.py
@@ -22,20 +22,18 @@ from zope.component import getUtility
from mailman import Message
from mailman import Utils
-from mailman import i18n
from mailman import passwords
from mailman.app.membership import add_member
from mailman.app.notifications import (
send_admin_subscription_notice, send_welcome_message)
from mailman.configuration import config
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.interfaces.members import DeliveryMode
from mailman.interfaces.usermanager import IUserManager
from mailman.version import MAILMAN_VERSION
-_ = i18n._
-
DELIVERY_MODES = {
'regular': DeliveryMode.regular,
'plain': DeliveryMode.plaintext_digests,
@@ -155,7 +153,7 @@ def main():
delete_members = current_members - future_members
change_members = current_members & future_members
- with i18n.using_language(mlist.preferred_language):
+ with _.using(mlist.preferred_language):
# Start by removing all the delete members.
for address in delete_members:
print _('deleting address: $address')
diff --git a/src/mailman/bin/show_config.py b/src/mailman/bin/show_config.py
index 8d26c5c97..61776ff68 100644
--- a/src/mailman/bin/show_config.py
+++ b/src/mailman/bin/show_config.py
@@ -21,7 +21,7 @@ import pprint
import optparse
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/bin/show_qfiles.py b/src/mailman/bin/show_qfiles.py
index e4b64e0cd..81d576e3d 100644
--- a/src/mailman/bin/show_qfiles.py
+++ b/src/mailman/bin/show_qfiles.py
@@ -21,7 +21,7 @@ import sys
from cPickle import load
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.options import Options
diff --git a/src/mailman/bin/unshunt.py b/src/mailman/bin/unshunt.py
index fc889377c..2a4558fd4 100644
--- a/src/mailman/bin/unshunt.py
+++ b/src/mailman/bin/unshunt.py
@@ -24,7 +24,7 @@ __all__ = [
import sys
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.options import Options
diff --git a/src/mailman/bin/update.py b/src/mailman/bin/update.py
index 34ea6cda3..bb2cc294a 100644
--- a/src/mailman/bin/update.py
+++ b/src/mailman/bin/update.py
@@ -37,7 +37,7 @@ from mailman.MemberAdaptor import BYBOUNCE, ENABLED
from mailman.OldStyleMemberships import OldStyleMemberships
from mailman.Queue.Switchboard import Switchboard
from mailman.configuration import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.initialize import initialize
from mailman.utilities.filesystem import makedirs
diff --git a/src/mailman/bin/withlist.py b/src/mailman/bin/withlist.py
index 2b236eaec..3c89ffc40 100644
--- a/src/mailman/bin/withlist.py
+++ b/src/mailman/bin/withlist.py
@@ -23,8 +23,8 @@ from zope.component import getUtility
from mailman import interact
from mailman.config import config
+from mailman.core.i18n import _
from mailman.core.initialize import initialize
-from mailman.i18n import _
from mailman.interfaces.listmanager import IListManager
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/chains/accept.py b/src/mailman/chains/accept.py
index bd47f42c8..b9bba07f5 100644
--- a/src/mailman/chains/accept.py
+++ b/src/mailman/chains/accept.py
@@ -28,7 +28,7 @@ import logging
from mailman.chains.base import TerminalChainBase
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
log = logging.getLogger('mailman.vette')
diff --git a/src/mailman/chains/builtin.py b/src/mailman/chains/builtin.py
index 05912a2f2..02ca6e0d8 100644
--- a/src/mailman/chains/builtin.py
+++ b/src/mailman/chains/builtin.py
@@ -31,7 +31,7 @@ from zope.interface import implements
from mailman.chains.base import Link
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.chain import IChain, LinkAction
diff --git a/src/mailman/chains/discard.py b/src/mailman/chains/discard.py
index 1899e0340..d6a381a9c 100644
--- a/src/mailman/chains/discard.py
+++ b/src/mailman/chains/discard.py
@@ -28,7 +28,7 @@ __all__ = [
import logging
from mailman.chains.base import TerminalChainBase
-from mailman.i18n import _
+from mailman.core.i18n import _
log = logging.getLogger('mailman.vette')
diff --git a/src/mailman/chains/headers.py b/src/mailman/chains/headers.py
index 2f85d78d0..31e982294 100644
--- a/src/mailman/chains/headers.py
+++ b/src/mailman/chains/headers.py
@@ -33,7 +33,7 @@ from zope.interface import implements
from mailman.chains.base import Chain, Link
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.chain import IChainIterator, LinkAction
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py
index b4b510d3b..32e2ce0b3 100644
--- a/src/mailman/chains/hold.py
+++ b/src/mailman/chains/hold.py
@@ -33,12 +33,12 @@ from email.utils import formatdate, make_msgid
from zope.component import getUtility
from zope.interface import implements
-from mailman import i18n
from mailman.Utils import maketext, oneline, wrap
from mailman.app.moderator import hold_message
from mailman.app.replybot import can_acknowledge
from mailman.chains.base import TerminalChainBase
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import UserNotification
from mailman.interfaces.autorespond import IAutoResponseSet, Response
from mailman.interfaces.pending import IPendable, IPendings
@@ -47,7 +47,6 @@ from mailman.interfaces.usermanager import IUserManager
log = logging.getLogger('mailman.vette')
SEMISPACE = '; '
-_ = i18n._
@@ -104,7 +103,7 @@ def autorespond_to_sender(mlist, sender, lang=None):
'owneremail': mlist.owner_address,
},
lang=lang)
- with i18n.using_language(lang.code):
+ with _.using(lang.code):
msg = Message.UserNotification(
sender, mlist.owner_address,
_('Last autoresponse notification for today'),
@@ -199,7 +198,7 @@ class HoldChain(TerminalChainBase):
if mlist.admin_immed_notify:
# Now let's temporarily set the language context to that which the
# administrators are expecting.
- with i18n.using_language(mlist.preferred_language.code):
+ with _.using(mlist.preferred_language.code):
language = mlist.preferred_language
charset = language.charset
# We need to regenerate or re-translate a few values in the
diff --git a/src/mailman/chains/reject.py b/src/mailman/chains/reject.py
index 3faf563da..6467cf949 100644
--- a/src/mailman/chains/reject.py
+++ b/src/mailman/chains/reject.py
@@ -29,7 +29,7 @@ import logging
from mailman.app.bounces import bounce_message
from mailman.chains.base import TerminalChainBase
-from mailman.i18n import _
+from mailman.core.i18n import _
log = logging.getLogger('mailman.vette')
diff --git a/src/mailman/commands/cli_control.py b/src/mailman/commands/cli_control.py
index cab3d0fd9..3b4bae9b9 100644
--- a/src/mailman/commands/cli_control.py
+++ b/src/mailman/commands/cli_control.py
@@ -36,7 +36,7 @@ import logging
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.command import ICLISubCommand
diff --git a/src/mailman/commands/cli_info.py b/src/mailman/commands/cli_info.py
index b5a0e8e5d..8d08e93b9 100644
--- a/src/mailman/commands/cli_info.py
+++ b/src/mailman/commands/cli_info.py
@@ -30,7 +30,7 @@ import sys
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.command import ICLISubCommand
from mailman.version import MAILMAN_VERSION_FULL
diff --git a/src/mailman/commands/cli_inject.py b/src/mailman/commands/cli_inject.py
index d1b1a9795..025dcb036 100644
--- a/src/mailman/commands/cli_inject.py
+++ b/src/mailman/commands/cli_inject.py
@@ -31,7 +31,7 @@ from zope.component import getUtility
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.inject import inject_text
from mailman.interfaces.command import ICLISubCommand
from mailman.interfaces.listmanager import IListManager
diff --git a/src/mailman/commands/cli_lists.py b/src/mailman/commands/cli_lists.py
index 212dba8af..d5686eca5 100644
--- a/src/mailman/commands/cli_lists.py
+++ b/src/mailman/commands/cli_lists.py
@@ -35,8 +35,8 @@ from mailman.app.lifecycle import create_list, remove_list
from mailman.config import config
from mailman.core.constants import system_preferences
from mailman.core.errors import InvalidEmailAddress
+from mailman.core.i18n import _
from mailman.email.message import UserNotification
-from mailman.i18n import _, using_language
from mailman.interfaces.command import ICLISubCommand
from mailman.interfaces.domain import (
BadDomainSpecificationError, IDomainManager)
@@ -210,7 +210,7 @@ class Create:
# Set the I18N language to the list's preferred language so the
# header will match the template language. Stashing and restoring
# the old translation context is just (healthy? :) paranoia.
- with using_language(mlist.preferred_language.code):
+ with _.using(mlist.preferred_language.code):
msg = UserNotification(
args.owners, mlist.no_reply_address,
_('Your new mailing list: $fqdn_listname'),
diff --git a/src/mailman/commands/cli_members.py b/src/mailman/commands/cli_members.py
index d818d2853..b26216785 100644
--- a/src/mailman/commands/cli_members.py
+++ b/src/mailman/commands/cli_members.py
@@ -34,7 +34,7 @@ from zope.interface import implements
from mailman.app.membership import add_member
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.command import ICLISubCommand
from mailman.interfaces.listmanager import IListManager
from mailman.interfaces.member import DeliveryMode
diff --git a/src/mailman/commands/eml_echo.py b/src/mailman/commands/eml_echo.py
index 30590acf8..77c944cda 100644
--- a/src/mailman/commands/eml_echo.py
+++ b/src/mailman/commands/eml_echo.py
@@ -25,7 +25,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.command import ContinueProcessing, IEmailCommand
diff --git a/src/mailman/commands/eml_end.py b/src/mailman/commands/eml_end.py
index a9298bc92..e47712030 100644
--- a/src/mailman/commands/eml_end.py
+++ b/src/mailman/commands/eml_end.py
@@ -26,7 +26,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.command import ContinueProcessing, IEmailCommand
diff --git a/src/mailman/commands/eml_join.py b/src/mailman/commands/eml_join.py
index d1f9dd816..f29684b93 100644
--- a/src/mailman/commands/eml_join.py
+++ b/src/mailman/commands/eml_join.py
@@ -28,7 +28,7 @@ from email.utils import formataddr, parseaddr
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.command import ContinueProcessing, IEmailCommand
from mailman.interfaces.domain import IDomainManager
from mailman.interfaces.member import DeliveryMode
diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py
index 736417b24..c64eb3ef5 100644
--- a/src/mailman/config/config.py
+++ b/src/mailman/config/config.py
@@ -152,6 +152,9 @@ class Configuration:
assert self._config.mailman.default_language in self.languages
self.ensure_directories_exist()
self.style_manager.populate()
+ # Set the default system language.
+ from mailman.core.i18n import _
+ _.default = self.mailman.default_language
@property
def logger_configs(self):
diff --git a/src/mailman/core/i18n.py b/src/mailman/core/i18n.py
new file mode 100644
index 000000000..8083fd987
--- /dev/null
+++ b/src/mailman/core/i18n.py
@@ -0,0 +1,111 @@
+# Copyright (C) 2009 by the Free Software Foundation, Inc.
+#
+# This file is part of GNU Mailman.
+#
+# GNU Mailman is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
+
+"""Internationalization."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ '_',
+ 'ctime',
+ 'initialize',
+ 'set_language',
+ ]
+
+
+import time
+from flufl.i18n import PackageStrategy, registry
+
+import mailman.messages
+
+
+_ = None
+
+
+
+def initialize():
+ """Initialize the i18n subsystem."""
+ global _
+ strategy = PackageStrategy('mailman', mailman.messages)
+ application = registry.register(strategy)
+ _ = application._
+
+
+
+def ctime(date):
+ """Translate a ctime.
+
+ :param date: The date to translate.
+ :type date: str or time float
+ :return: The translated date.
+ :rtype: string
+ """
+ # Don't make these module globals since we have to do runtime translation
+ # of the strings anyway.
+ daysofweek = [
+ _('Mon'), _('Tue'), _('Wed'), _('Thu'),
+ _('Fri'), _('Sat'), _('Sun')
+ ]
+ months = [
+ '',
+ _('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'),
+ _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')
+ ]
+
+ # pylint: disable-msg=W0612
+ tzname = _('Server Local Time')
+ if isinstance(date, str):
+ try:
+ year, mon, day, hh, mm, ss, wday, ydat, dst = time.strptime(date)
+ if dst in (0, 1):
+ tzname = time.tzname[dst]
+ else:
+ # MAS: No exception but dst = -1 so try
+ return ctime(time.mktime((year, mon, day, hh, mm, ss, wday,
+ ydat, dst)))
+ except (ValueError, AttributeError):
+ try:
+ wday, mon, day, hms, year = date.split()
+ hh, mm, ss = hms.split(':')
+ year = int(year)
+ day = int(day)
+ hh = int(hh)
+ mm = int(mm)
+ ss = int(ss)
+ except ValueError:
+ return date
+ else:
+ for i in range(0, 7):
+ wconst = (1999, 1, 1, 0, 0, 0, i, 1, 0)
+ if wday.lower() == time.strftime('%a', wconst).lower():
+ wday = i
+ break
+ for i in range(1, 13):
+ mconst = (1999, i, 1, 0, 0, 0, 0, 1, 0)
+ if mon.lower() == time.strftime('%b', mconst).lower():
+ mon = i
+ break
+ else:
+ # pylint: disable-msg=W0612
+ year, mon, day, hh, mm, ss, wday, yday, dst = time.localtime(date)
+ if dst in (0, 1):
+ tzname = time.tzname[dst]
+
+ wday = daysofweek[wday]
+ mon = months[mon]
+ return _('$wday $mon $day $hh:$mm:$ss $tzname $year')
diff --git a/src/mailman/core/initialize.py b/src/mailman/core/initialize.py
index 8fc2150fb..707bb3f66 100644
--- a/src/mailman/core/initialize.py
+++ b/src/mailman/core/initialize.py
@@ -61,6 +61,7 @@ def initialize_1(config_path=None, propagate_logs=None):
* The configuration system
* Run-time directories
* The logging subsystem
+ * Internationalization
:param config_path: The path to the configuration file.
:type config_path: string
diff --git a/src/mailman/core/pipelines.py b/src/mailman/core/pipelines.py
index cdfd1a462..b15ce0533 100644
--- a/src/mailman/core/pipelines.py
+++ b/src/mailman/core/pipelines.py
@@ -31,7 +31,7 @@ from zope.interface.verify import verifyObject
from mailman.app.finder import find_components
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.interfaces.pipeline import IPipeline
diff --git a/src/mailman/i18n.py b/src/mailman/i18n.py
deleted file mode 100644
index 23877a881..000000000
--- a/src/mailman/i18n.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Copyright (C) 2000-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Internationalization support."""
-
-from __future__ import absolute_import, unicode_literals
-
-__metaclass__ = type
-__all__ = [
- 'Translator',
- '_',
- 'get_translation',
- 'set_language',
- 'set_translation',
- 'using_language',
- ]
-
-
-import os
-import sys
-import time
-import string
-import gettext
-
-from textwrap import dedent
-
-import mailman.messages
-from mailman.utilities.string import expand
-
-
-_translation = None
-_missing = object()
-
-
-
-class Template(string.Template):
- """Match any attribute path."""
- idpattern = r'[_a-z][_a-z0-9.]*'
-
-
-class attrdict(dict):
- """Follow attribute paths."""
- def __getitem__(self, key):
- parts = key.split('.')
- value = super(attrdict, self).__getitem__(parts.pop(0))
- while parts:
- value = getattr(value, parts.pop(0), _missing)
- if value is _missing:
- raise KeyError(key)
- return value
-
-
-
-def set_language(language_code=None):
- """Set the global translation context from a language code.
-
- :param language_code: The two letter language code to set.
- :type language_code: str
- """
- messages_dir = os.path.dirname(mailman.messages.__file__)
- # pylint: disable-msg=W0603
- global _translation
- # gettext.translation() API requires None or a sequence.
- codes = (None if language_code is None else [language_code])
- try:
- _translation = gettext.translation('mailman', messages_dir, codes)
- except IOError:
- # The selected language was not installed in messages, so fall back to
- # untranslated English.
- _translation = gettext.NullTranslations()
-
-
-def get_translation():
- """Return the global translation context.
-
- :return: The global translation context.
- :rtype: `GNUTranslation`
- """
- return _translation
-
-
-def set_translation(translation):
- """Set the global translation context.
-
- :param translation: The translation context.
- :type translation: `GNUTranslation`.
- """
- # pylint: disable-msg=W0603
- global _translation
- _translation = translation
-
-
-class using_language:
- """Context manager for Python's `with` statement."""
- def __init__(self, language_code):
- self._language_code = language_code
- self._old_translation = None
-
- def __enter__(self):
- self._old_translation = _translation
- set_language(self._language_code)
-
- # pylint: disable-msg=W0613
- def __exit__(self, *exc_info):
- # pylint: disable-msg=W0603
- global _translation
- _translation = self._old_translation
- # Do not suppress exceptions.
- return False
-
-
-# Set up the global translation based on environment variables. Mostly used
-# for command line scripts.
-if _translation is None:
- _translation = gettext.NullTranslations()
-
-
-
-class Translator:
- def __init__(self, dedent=True):
- """Create a translation context.
-
- :param dedent: Whether the input string should be dedented.
- :type dedent: bool
- """
- self.dedent = dedent
-
- def _(self, original):
- """Translate the string.
-
- :param original: The original string to translate.
- :type original: string
- :return: The translated string.
- :rtype: string
- """
- if original == '':
- return ''
- assert original, 'Cannot translate: {0}'.format(s)
- # Because the original string is what the text extractors put into the
- # catalog, we must first look up the original unadulterated string in
- # the catalog. Use the global translation context for this.
- #
- # Mailman must be unicode safe internally (i.e. all strings inside
- # Mailman are unicodes). The translation service is one boundary to
- # the outside world, so to honor this constraint, make sure that all
- # strings to come out of _() are unicodes, even if the translated
- # string or dictionary values are 8-bit strings.
- tns = _translation.ugettext(original)
- charset = _translation.charset() or 'us-ascii'
- # Do PEP 292 style $-string interpolation into the resulting string.
- #
- # This lets you write something like:
- #
- # now = time.ctime(time.time())
- # print _('The current time is: $now')
- #
- # and have it Just Work. Note that the lookup order for keys in the
- # original string is 1) locals dictionary, 2) globals dictionary.
- #
- # Get the frame of the caller.
- # pylint: disable-msg=W0212
- frame = sys._getframe(1)
- # A 'safe' dictionary is used so we won't get an exception if there's
- # a missing key in the dictionary.
- raw_dict = frame.f_globals.copy()
- raw_dict.update(frame.f_locals)
- # Python requires ** dictionaries to have str, not unicode keys. For
- # our purposes, keys should always be ascii. Values though should be
- # unicode.
- translated_string = expand(tns, attrdict(raw_dict), Template)
- if isinstance(translated_string, str):
- translated_string = unicode(translated_string, charset)
- # Dedent the string if so desired.
- if self.dedent:
- translated_string = dedent(translated_string)
- return translated_string
-
-
-# Global defaults.
-_ = Translator()._
-
-
-
-def ctime(date):
- """Translate a ctime.
-
- :param date: The date to translate.
- :type date: str or time float
- :return: The translated date.
- :rtype: string
- """
- # Don't make these module globals since we have to do runtime translation
- # of the strings anyway.
- daysofweek = [
- _('Mon'), _('Tue'), _('Wed'), _('Thu'),
- _('Fri'), _('Sat'), _('Sun')
- ]
- months = [
- '',
- _('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'),
- _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')
- ]
-
- # pylint: disable-msg=W0612
- tzname = _('Server Local Time')
- if isinstance(date, str):
- try:
- year, mon, day, hh, mm, ss, wday, ydat, dst = time.strptime(date)
- if dst in (0, 1):
- tzname = time.tzname[dst]
- else:
- # MAS: No exception but dst = -1 so try
- return ctime(time.mktime((year, mon, day, hh, mm, ss, wday,
- ydat, dst)))
- except (ValueError, AttributeError):
- try:
- wday, mon, day, hms, year = date.split()
- hh, mm, ss = hms.split(':')
- year = int(year)
- day = int(day)
- hh = int(hh)
- mm = int(mm)
- ss = int(ss)
- except ValueError:
- return date
- else:
- for i in range(0, 7):
- wconst = (1999, 1, 1, 0, 0, 0, i, 1, 0)
- if wday.lower() == time.strftime('%a', wconst).lower():
- wday = i
- break
- for i in range(1, 13):
- mconst = (1999, i, 1, 0, 0, 0, 0, 1, 0)
- if mon.lower() == time.strftime('%b', mconst).lower():
- mon = i
- break
- else:
- # pylint: disable-msg=W0612
- year, mon, day, hh, mm, ss, wday, yday, dst = time.localtime(date)
- if dst in (0, 1):
- tzname = time.tzname[dst]
-
- wday = daysofweek[wday]
- mon = months[mon]
- return _('$wday $mon $day $hh:$mm:$ss $tzname $year')
diff --git a/src/mailman/interfaces/domain.py b/src/mailman/interfaces/domain.py
index 12b58c57b..538cd0f74 100644
--- a/src/mailman/interfaces/domain.py
+++ b/src/mailman/interfaces/domain.py
@@ -35,7 +35,7 @@ from zope.interface import Interface, Attribute
from zope.schema import TextLine
from mailman.core.errors import MailmanError
-from mailman.i18n import _
+from mailman.core.i18n import _
diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py
index a2bd29e36..610e697db 100644
--- a/src/mailman/interfaces/mailinglist.py
+++ b/src/mailman/interfaces/mailinglist.py
@@ -36,7 +36,7 @@ from munepy import Enum
from zope.interface import Interface, Attribute
from zope.schema import TextLine
-from mailman.i18n import _
+from mailman.core.i18n import _
diff --git a/src/mailman/interfaces/system.py b/src/mailman/interfaces/system.py
index 6088f7624..a901f9bf8 100644
--- a/src/mailman/interfaces/system.py
+++ b/src/mailman/interfaces/system.py
@@ -29,7 +29,7 @@ from lazr.restful.declarations import export_as_webservice_entry, exported
from zope.interface import Interface
from zope.schema import TextLine
-from mailman.i18n import _
+from mailman.core.i18n import _
diff --git a/src/mailman/mta/postfix.py b/src/mailman/mta/postfix.py
index 4ddf444af..ca327dd1c 100644
--- a/src/mailman/mta/postfix.py
+++ b/src/mailman/mta/postfix.py
@@ -39,9 +39,9 @@ from zope.interface import implements
from mailman import Utils
from mailman.config import config
+from mailman.core.i18n import _
from mailman.interfaces.listmanager import IListManager
from mailman.interfaces.mta import IMailTransportAgentAliases
-from mailman.i18n import _
log = logging.getLogger('mailman.error')
diff --git a/src/mailman/options.py b/src/mailman/options.py
index 41c3651e4..6ab7532f6 100644
--- a/src/mailman/options.py
+++ b/src/mailman/options.py
@@ -34,8 +34,8 @@ from copy import copy
from optparse import Option, OptionParser, OptionValueError
from mailman.config import config
+from mailman.core.i18n import _
from mailman.core.initialize import initialize
-from mailman.i18n import _
from mailman.version import MAILMAN_VERSION
diff --git a/src/mailman/pipeline/acknowledge.py b/src/mailman/pipeline/acknowledge.py
index 5daf30003..2d0efd808 100644
--- a/src/mailman/pipeline/acknowledge.py
+++ b/src/mailman/pipeline/acknowledge.py
@@ -32,8 +32,8 @@ from zope.interface import implements
from mailman import Utils
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import Message, UserNotification
-from mailman.i18n import _
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/after_delivery.py b/src/mailman/pipeline/after_delivery.py
index 4626ba292..ce64e7a9f 100644
--- a/src/mailman/pipeline/after_delivery.py
+++ b/src/mailman/pipeline/after_delivery.py
@@ -29,7 +29,7 @@ import datetime
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/avoid_duplicates.py b/src/mailman/pipeline/avoid_duplicates.py
index 840d5f8b2..ca4dbe11b 100644
--- a/src/mailman/pipeline/avoid_duplicates.py
+++ b/src/mailman/pipeline/avoid_duplicates.py
@@ -34,7 +34,7 @@ __all__ = [
from email.Utils import getaddresses, formataddr
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/calculate_recipients.py b/src/mailman/pipeline/calculate_recipients.py
index ccbc069d1..d044d9587 100644
--- a/src/mailman/pipeline/calculate_recipients.py
+++ b/src/mailman/pipeline/calculate_recipients.py
@@ -35,7 +35,7 @@ from zope.interface import implements
from mailman import Utils
from mailman.config import config
from mailman.core import errors
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.interfaces.member import DeliveryStatus
diff --git a/src/mailman/pipeline/cleanse.py b/src/mailman/pipeline/cleanse.py
index 330f415c2..2b746e34a 100644
--- a/src/mailman/pipeline/cleanse.py
+++ b/src/mailman/pipeline/cleanse.py
@@ -30,7 +30,7 @@ import logging
from email.Utils import formataddr
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.pipeline.cook_headers import uheader
diff --git a/src/mailman/pipeline/cleanse_dkim.py b/src/mailman/pipeline/cleanse_dkim.py
index 38623079c..c96dde192 100644
--- a/src/mailman/pipeline/cleanse_dkim.py
+++ b/src/mailman/pipeline/cleanse_dkim.py
@@ -37,7 +37,7 @@ from lazr.config import as_boolean
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/cook_headers.py b/src/mailman/pipeline/cook_headers.py
index 3c67d0193..c9115c468 100644
--- a/src/mailman/pipeline/cook_headers.py
+++ b/src/mailman/pipeline/cook_headers.py
@@ -33,7 +33,7 @@ from email.utils import parseaddr, formataddr, getaddresses
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.interfaces.mailinglist import Personalization, ReplyToMunging
from mailman.version import VERSION
diff --git a/src/mailman/pipeline/decorate.py b/src/mailman/pipeline/decorate.py
index f9e41e177..65badcd4a 100644
--- a/src/mailman/pipeline/decorate.py
+++ b/src/mailman/pipeline/decorate.py
@@ -33,8 +33,8 @@ from zope.component import getUtility
from zope.interface import implements
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import Message
-from mailman.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.interfaces.usermanager import IUserManager
from mailman.utilities.string import expand
diff --git a/src/mailman/pipeline/file_recipients.py b/src/mailman/pipeline/file_recipients.py
index c3d995a9c..fdc09068a 100644
--- a/src/mailman/pipeline/file_recipients.py
+++ b/src/mailman/pipeline/file_recipients.py
@@ -30,7 +30,7 @@ import errno
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/mime_delete.py b/src/mailman/pipeline/mime_delete.py
index 17da13c4a..158b46ad1 100644
--- a/src/mailman/pipeline/mime_delete.py
+++ b/src/mailman/pipeline/mime_delete.py
@@ -44,11 +44,12 @@ from zope.interface import implements
from mailman.Utils import oneline
from mailman.config import config
from mailman.core import errors
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.queue import Switchboard
from mailman.version import VERSION
+
log = logging.getLogger('mailman.error')
diff --git a/src/mailman/pipeline/moderate.py b/src/mailman/pipeline/moderate.py
index 3714f3bfc..1481ca9ad 100644
--- a/src/mailman/pipeline/moderate.py
+++ b/src/mailman/pipeline/moderate.py
@@ -33,8 +33,8 @@ from email.MIMEText import MIMEText
from mailman.Utils import wrap
from mailman.config import config
from mailman.core import errors
+from mailman.core.i18n import _
from mailman.email.message import UserNotification
-from mailman.i18n import _
diff --git a/src/mailman/pipeline/replybot.py b/src/mailman/pipeline/replybot.py
index e7834eb2c..cf559cfcc 100644
--- a/src/mailman/pipeline/replybot.py
+++ b/src/mailman/pipeline/replybot.py
@@ -33,8 +33,8 @@ from zope.interface import implements
from mailman import Utils
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import Message, UserNotification
-from mailman.i18n import _
from mailman.interfaces.autorespond import (
ALWAYS_REPLY, IAutoResponseSet, Response, ResponseAction)
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/scrubber.py b/src/mailman/pipeline/scrubber.py
index e5510e0ab..8465702d2 100644
--- a/src/mailman/pipeline/scrubber.py
+++ b/src/mailman/pipeline/scrubber.py
@@ -46,7 +46,7 @@ from zope.interface import implements
from mailman.Utils import oneline, websafe
from mailman.config import config
from mailman.core.errors import DiscardMessage
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.utilities.filesystem import makedirs
from mailman.utilities.modules import find_name
diff --git a/src/mailman/pipeline/tagger.py b/src/mailman/pipeline/tagger.py
index 9a0acc1e3..babf395dc 100644
--- a/src/mailman/pipeline/tagger.py
+++ b/src/mailman/pipeline/tagger.py
@@ -33,7 +33,7 @@ import email.Parser
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/to_archive.py b/src/mailman/pipeline/to_archive.py
index 7f1702fe9..827c4f93c 100644
--- a/src/mailman/pipeline/to_archive.py
+++ b/src/mailman/pipeline/to_archive.py
@@ -28,7 +28,7 @@ __all__ = [
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
diff --git a/src/mailman/pipeline/to_digest.py b/src/mailman/pipeline/to_digest.py
index 78d8e1970..e859af4f1 100644
--- a/src/mailman/pipeline/to_digest.py
+++ b/src/mailman/pipeline/to_digest.py
@@ -31,8 +31,8 @@ import datetime
from zope.interface import implements
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import Message
-from mailman.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.interfaces.mailinglist import DigestFrequency
from mailman.utilities.mailbox import Mailbox
diff --git a/src/mailman/pipeline/to_outgoing.py b/src/mailman/pipeline/to_outgoing.py
index ef6908ab8..d9894238b 100644
--- a/src/mailman/pipeline/to_outgoing.py
+++ b/src/mailman/pipeline/to_outgoing.py
@@ -34,7 +34,7 @@ from lazr.config import as_boolean
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
from mailman.interfaces.mailinglist import Personalization
diff --git a/src/mailman/pipeline/to_usenet.py b/src/mailman/pipeline/to_usenet.py
index 220374348..1095ea1d7 100644
--- a/src/mailman/pipeline/to_usenet.py
+++ b/src/mailman/pipeline/to_usenet.py
@@ -30,7 +30,7 @@ import logging
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.handler import IHandler
COMMASPACE = ', '
diff --git a/src/mailman/queue/__init__.py b/src/mailman/queue/__init__.py
index f3a0b04e9..a0af49355 100644
--- a/src/mailman/queue/__init__.py
+++ b/src/mailman/queue/__init__.py
@@ -50,8 +50,8 @@ from lazr.config import as_boolean, as_timedelta
from zope.component import getUtility
from zope.interface import implements
-from mailman import i18n
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import Message
from mailman.interfaces.listmanager import IListManager
from mailman.interfaces.runner import IRunner
@@ -438,7 +438,7 @@ class Runner:
else mlist.preferred_language)
else:
language = mlist.preferred_language
- with i18n.using_language(language.code):
+ with _.using(language.code):
msgdata['lang'] = language.code
keepqueued = self._dispose(mlist, msg, msgdata)
if keepqueued:
diff --git a/src/mailman/queue/bounce.py b/src/mailman/queue/bounce.py
index 3d2ef6140..f293e6508 100644
--- a/src/mailman/queue/bounce.py
+++ b/src/mailman/queue/bounce.py
@@ -28,14 +28,15 @@ from lazr.config import as_timedelta
from mailman.Bouncers import BouncerAPI
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.utils import split_email
-from mailman.i18n import _
from mailman.queue import Runner
+
COMMASPACE = ', '
-log = logging.getLogger('mailman.bounce')
-elog = logging.getLogger('mailman.error')
+log = logging.getLogger('mailman.bounce')
+elog = logging.getLogger('mailman.error')
diff --git a/src/mailman/queue/command.py b/src/mailman/queue/command.py
index d32361cf9..178d2ba0b 100644
--- a/src/mailman/queue/command.py
+++ b/src/mailman/queue/command.py
@@ -38,8 +38,8 @@ from email.Iterators import typed_subpart_iterator
from zope.interface import implements
from mailman.config import config
+from mailman.core.i18n import _
from mailman.email.message import Message, UserNotification
-from mailman.i18n import _
from mailman.interfaces.command import ContinueProcessing, IEmailResults
from mailman.queue import Runner
diff --git a/src/mailman/queue/digest.py b/src/mailman/queue/digest.py
index 3dbfc7917..479eb5350 100644
--- a/src/mailman/queue/digest.py
+++ b/src/mailman/queue/digest.py
@@ -38,11 +38,10 @@ from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate, getaddresses, make_msgid
-from mailman import i18n
from mailman.Utils import maketext, oneline, wrap
from mailman.config import config
from mailman.core.errors import DiscardMessage
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.member import DeliveryMode, DeliveryStatus
from mailman.pipeline.decorate import decorate
from mailman.pipeline.scrubber import process as scrubber
@@ -299,8 +298,8 @@ class DigestRunner(Runner):
volume = msgdata['volume']
digest_number = msgdata['digest_number']
with nested(Mailbox(msgdata['digest_path']),
- i18n.using_language(mlist.preferred_language.code)) as (
- mailbox, language_code):
+ _.using(mlist.preferred_language.code)) as (mailbox,
+ language_code):
# Create the digesters.
mime_digest = MIMEDigester(mlist, volume, digest_number)
rfc1153_digest = RFC1153Digester(mlist, volume, digest_number)
diff --git a/src/mailman/rules/administrivia.py b/src/mailman/rules/administrivia.py
index 8807ef952..6549faac0 100644
--- a/src/mailman/rules/administrivia.py
+++ b/src/mailman/rules/administrivia.py
@@ -29,7 +29,7 @@ from email.iterators import typed_subpart_iterator
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/any.py b/src/mailman/rules/any.py
index c337df7f1..866845765 100644
--- a/src/mailman/rules/any.py
+++ b/src/mailman/rules/any.py
@@ -27,7 +27,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/approved.py b/src/mailman/rules/approved.py
index f81c1ad04..717dd7bfd 100644
--- a/src/mailman/rules/approved.py
+++ b/src/mailman/rules/approved.py
@@ -29,7 +29,7 @@ import re
from email.iterators import typed_subpart_iterator
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/emergency.py b/src/mailman/rules/emergency.py
index c2cee06c4..988206782 100644
--- a/src/mailman/rules/emergency.py
+++ b/src/mailman/rules/emergency.py
@@ -27,7 +27,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/implicit_dest.py b/src/mailman/rules/implicit_dest.py
index f2e1f5446..67aff1080 100644
--- a/src/mailman/rules/implicit_dest.py
+++ b/src/mailman/rules/implicit_dest.py
@@ -29,7 +29,7 @@ import re
from email.utils import getaddresses
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.mailinglist import IAcceptableAliasSet
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/loop.py b/src/mailman/rules/loop.py
index 564d20dc6..7bbf4b8ba 100644
--- a/src/mailman/rules/loop.py
+++ b/src/mailman/rules/loop.py
@@ -27,7 +27,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/max_recipients.py b/src/mailman/rules/max_recipients.py
index a9cfd4a7f..e4b1fb62a 100644
--- a/src/mailman/rules/max_recipients.py
+++ b/src/mailman/rules/max_recipients.py
@@ -28,7 +28,7 @@ __all__ = [
from email.utils import getaddresses
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/max_size.py b/src/mailman/rules/max_size.py
index bac79bbab..36db34ee2 100644
--- a/src/mailman/rules/max_size.py
+++ b/src/mailman/rules/max_size.py
@@ -27,7 +27,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/moderation.py b/src/mailman/rules/moderation.py
index c4d0a1bfb..752df036f 100644
--- a/src/mailman/rules/moderation.py
+++ b/src/mailman/rules/moderation.py
@@ -28,7 +28,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/news_moderation.py b/src/mailman/rules/news_moderation.py
index e6c5047e9..5e5f5bd83 100644
--- a/src/mailman/rules/news_moderation.py
+++ b/src/mailman/rules/news_moderation.py
@@ -27,7 +27,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.nntp import NewsModeration
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/no_subject.py b/src/mailman/rules/no_subject.py
index 2487867e7..e08ff2013 100644
--- a/src/mailman/rules/no_subject.py
+++ b/src/mailman/rules/no_subject.py
@@ -27,7 +27,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/rules/suspicious.py b/src/mailman/rules/suspicious.py
index 00e9a5e9e..3e5a0cd9e 100644
--- a/src/mailman/rules/suspicious.py
+++ b/src/mailman/rules/suspicious.py
@@ -30,7 +30,7 @@ import logging
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
log = logging.getLogger('mailman.error')
diff --git a/src/mailman/rules/truth.py b/src/mailman/rules/truth.py
index 45b5560c2..7b3929145 100644
--- a/src/mailman/rules/truth.py
+++ b/src/mailman/rules/truth.py
@@ -27,7 +27,7 @@ __all__ = [
from zope.interface import implements
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.rules import IRule
diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py
index d1904a150..b61f66803 100644
--- a/src/mailman/styles/default.py
+++ b/src/mailman/styles/default.py
@@ -31,7 +31,7 @@ import datetime
from zope.interface import implements
from mailman.config import config
-from mailman.i18n import _
+from mailman.core.i18n import _
from mailman.interfaces.action import Action
from mailman.interfaces.autorespond import ResponseAction
from mailman.interfaces.mailinglist import (
diff --git a/src/mailman/testing/layers.py b/src/mailman/testing/layers.py
index 4bc98161e..0cc1a2e32 100644
--- a/src/mailman/testing/layers.py
+++ b/src/mailman/testing/layers.py
@@ -42,8 +42,8 @@ from zope.component import getUtility
from mailman.config import config
from mailman.core import initialize
+from mailman.core.i18n import _
from mailman.core.logging import get_handler
-from mailman.i18n import _
from mailman.interfaces.domain import IDomainManager
from mailman.interfaces.messages import IMessageStore
from mailman.testing.helpers import TestableMaster