summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/Utils.py6
-rw-r--r--src/mailman/app/moderator.py5
-rw-r--r--src/mailman/app/registrar.py2
-rw-r--r--src/mailman/bin/master.py16
-rw-r--r--src/mailman/chains/hold.py6
-rw-r--r--src/mailman/commands/cli_control.py5
-rw-r--r--src/mailman/commands/cli_lists.py5
-rw-r--r--src/mailman/commands/docs/create.txt3
-rw-r--r--src/mailman/config/config.py13
-rw-r--r--src/mailman/config/configure.zcml5
-rw-r--r--src/mailman/core/constants.py4
-rw-r--r--src/mailman/core/initialize.py6
-rw-r--r--src/mailman/docs/languages.txt33
-rw-r--r--src/mailman/docs/message.txt3
-rw-r--r--src/mailman/docs/users.txt3
-rw-r--r--src/mailman/interfaces/languages.py3
-rw-r--r--src/mailman/languages/manager.py4
-rw-r--r--src/mailman/model/domain.py16
-rw-r--r--src/mailman/model/mailinglist.py3
-rw-r--r--src/mailman/model/preferences.py4
-rw-r--r--src/mailman/pipeline/acknowledge.py7
-rw-r--r--src/mailman/queue/__init__.py19
-rw-r--r--src/mailman/queue/command.py10
23 files changed, 124 insertions, 57 deletions
diff --git a/src/mailman/Utils.py b/src/mailman/Utils.py
index bde703cf4..2ea22cee4 100644
--- a/src/mailman/Utils.py
+++ b/src/mailman/Utils.py
@@ -44,6 +44,7 @@ from email.errors import HeaderParseError
from email.header import decode_header, make_header
from lazr.config import as_boolean
from string import ascii_letters, digits, whitespace
+from zope.component import getUtility
import mailman.templates
@@ -51,6 +52,7 @@ from mailman import passwords
from mailman.config import config
from mailman.core import errors
from mailman.core.i18n import _
+from mailman.interfaces.languages import ILanguageManager
from mailman.utilities.string import expand
@@ -406,7 +408,7 @@ def findtext(templatefile, raw_dict=None, raw=False, lang=None, mlist=None):
else:
template = fp.read()
fp.close()
- charset = config.languages[lang].charset
+ charset = getUtility(ILanguageManager)[lang].charset
template = unicode(template, charset, 'replace')
text = template
if raw_dict is not None:
@@ -431,7 +433,7 @@ def uncanonstr(s, lang=None):
if lang is None:
charset = 'us-ascii'
else:
- charset = config.languages[lang].charset
+ charset = getUtility(ILanguageManager)[lang].charset
# See if the string contains characters only in the desired character
# set. If so, return it unchanged, except for coercing it to a byte
# string.
diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py
index 3151e91c8..e29213f3f 100644
--- a/src/mailman/app/moderator.py
+++ b/src/mailman/app/moderator.py
@@ -44,6 +44,7 @@ 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.languages import ILanguageManager
from mailman.interfaces.member import AlreadySubscribedError, DeliveryMode
from mailman.interfaces.messages import IMessageStore
from mailman.interfaces.requests import IRequests, RequestType
@@ -237,14 +238,14 @@ def handle_subscription(mlist, id, action, comment=None):
_refuse(mlist, _('Subscription request'),
data['address'],
comment or _('[No reason given]'),
- lang=config.languages[data['language']])
+ lang=getUtility(ILanguageManager)[data['language']])
elif action is Action.accept:
key, data = requestdb.get_request(id)
enum_value = data['delivery_mode'].split('.')[-1]
delivery_mode = DeliveryMode(enum_value)
address = data['address']
realname = data['realname']
- language = config.languages[data['language']]
+ language = getUtility(ILanguageManager)[data['language']]
password = data['password']
try:
add_member(mlist, address, realname, password,
diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py
index c24376494..1a7a985c6 100644
--- a/src/mailman/app/registrar.py
+++ b/src/mailman/app/registrar.py
@@ -83,7 +83,7 @@ class Registrar:
# Send a verification email to the address.
text = _(resource_string('mailman.templates.en', 'verify.txt'))
msg = UserNotification(address, confirm_address, subject, text)
- msg.send(mlist=None)
+ msg.send(mlist=mlist)
return token
def confirm(self, token):
diff --git a/src/mailman/bin/master.py b/src/mailman/bin/master.py
index 5ce003690..a6091e834 100644
--- a/src/mailman/bin/master.py
+++ b/src/mailman/bin/master.py
@@ -194,14 +194,15 @@ def acquire_lock(force):
if status == WatcherState.conflict:
# Hostname matches and process exists.
message = _("""\
-The master queue runner lock could not be acquired because it appears as
-though another master is already running.""")
+The master queue runner lock could not be acquired because it
+appears as though another master is already running.""")
elif status == WatcherState.stale_lock:
# Hostname matches but the process does not exist.
program = sys.argv[0]
message = _("""\
-The master queue runner lock could not be acquired. It appears as though
-there is a stale master lock. Try re-running $program with the -s flag.""")
+The master queue runner lock could not be acquired. It appears
+as though there is a stale master lock. Try re-running $program
+with the -s flag.""")
else:
# Hostname doesn't even match.
assert status == WatcherState.host_mismatch, (
@@ -209,9 +210,10 @@ there is a stale master lock. Try re-running $program with the -s flag.""")
# pylint: disable-msg=W0612
hostname, pid, tempfile = get_lock_data()
message = _("""\
-The master qrunner lock could not be acquired, because it appears as if some
-process on some other host may have acquired it. We can't test for stale
-locks across host boundaries, so you'll have to clean this up manually.
+The master qrunner lock could not be acquired, because it appears
+as if some process on some other host may have acquired it. We
+can't test for stale locks across host boundaries, so you'll have
+to clean this up manually.
Lock file: $config.LOCK_FILE
Lock host: $hostname
diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py
index 32e2ce0b3..2726535d1 100644
--- a/src/mailman/chains/hold.py
+++ b/src/mailman/chains/hold.py
@@ -41,6 +41,7 @@ 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.languages import ILanguageManager
from mailman.interfaces.pending import IPendable, IPendings
from mailman.interfaces.usermanager import IUserManager
@@ -189,8 +190,9 @@ class HoldChain(TerminalChainBase):
text = maketext('postheld.txt', substitutions,
lang=send_language_code, mlist=mlist)
adminaddr = mlist.bounces_address
- nmsg = UserNotification(msg.sender, adminaddr, subject, text,
- config.languages[send_language_code])
+ nmsg = UserNotification(
+ msg.sender, adminaddr, subject, text,
+ getUtility(ILanguageManager)[send_language_code])
nmsg.send(mlist)
# Now the message for the list moderators. This one should appear to
# come from <list>-owner since we really don't need to do bounce
diff --git a/src/mailman/commands/cli_control.py b/src/mailman/commands/cli_control.py
index e2c450b71..f484b196c 100644
--- a/src/mailman/commands/cli_control.py
+++ b/src/mailman/commands/cli_control.py
@@ -30,6 +30,7 @@ __all__ = [
import os
import sys
+import errno
import signal
import logging
@@ -137,10 +138,10 @@ def kill_watcher(sig):
try:
os.kill(pid, sig)
except OSError as error:
- if e.errno != errno.ESRCH:
+ if error.errno != errno.ESRCH:
raise
print >> sys.stderr, _('No child with pid: $pid')
- print >> sys.stderr, e
+ print >> sys.stderr, error
print >> sys.stderr, _('Stale pid file removed.')
os.unlink(config.PIDFILE)
diff --git a/src/mailman/commands/cli_lists.py b/src/mailman/commands/cli_lists.py
index d3833c2b0..93749c45a 100644
--- a/src/mailman/commands/cli_lists.py
+++ b/src/mailman/commands/cli_lists.py
@@ -40,6 +40,7 @@ from mailman.email.message import UserNotification
from mailman.interfaces.command import ICLISubCommand
from mailman.interfaces.domain import (
BadDomainSpecificationError, IDomainManager)
+from mailman.interfaces.languages import ILanguageManager
from mailman.interfaces.listmanager import IListManager, ListAlreadyExistsError
@@ -174,7 +175,7 @@ class Create:
if args.language is not None
else system_preferences.preferred_language.code)
# Make sure that the selected language code is known.
- if language_code not in config.languages.codes:
+ if language_code not in getUtility(ILanguageManager).codes:
self.parser.error(_('Invalid language code: $language_code'))
return
assert len(args.listname) == 1, (
@@ -199,7 +200,7 @@ class Create:
# Find the language associated with the code, then set the mailing
# list's preferred language to that. The changes then must be
# committed to the database.
- mlist.preferred_language = config.languages[language_code]
+ mlist.preferred_language = getUtility(ILanguageManager)[language_code]
config.db.commit()
# Do the notification.
if not args.quiet:
diff --git a/src/mailman/commands/docs/create.txt b/src/mailman/commands/docs/create.txt
index 9c2331418..7c7b43805 100644
--- a/src/mailman/commands/docs/create.txt
+++ b/src/mailman/commands/docs/create.txt
@@ -116,7 +116,8 @@ The language must be known to Mailman.
>>> command.process(args)
Invalid language code: ee
- >>> config.languages.add('ee', 'iso-8859-1', 'Freedonian')
+ >>> from mailman.interfaces.languages import ILanguageManager
+ >>> getUtility(ILanguageManager).add('ee', 'iso-8859-1', 'Freedonian')
>>> args.quiet = False
>>> args.listname = ['test3@example.com']
diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py
index c64eb3ef5..11b2d78b6 100644
--- a/src/mailman/config/config.py
+++ b/src/mailman/config/config.py
@@ -32,11 +32,12 @@ import logging
from lazr.config import ConfigSchema, as_boolean
from pkg_resources import resource_stream
+from zope.component import getUtility
from zope.interface import Interface, implements
from mailman import version
from mailman.core import errors
-from mailman.languages.manager import LanguageManager
+from mailman.interfaces.languages import ILanguageManager
from mailman.styles.manager import StyleManager
from mailman.utilities.filesystem import makedirs
from mailman.utilities.modules import call_name
@@ -58,7 +59,6 @@ class Configuration:
def __init__(self):
self.switchboards = {}
- self.languages = LanguageManager()
self.style_manager = StyleManager()
self.QFILE_SCHEMA_VERSION = version.QFILE_SCHEMA_VERSION
self._config = None
@@ -73,7 +73,7 @@ class Configuration:
def _clear(self):
"""Clear the cached configuration variables."""
self.switchboards.clear()
- self.languages = LanguageManager()
+ getUtility(ILanguageManager).clear()
def __getattr__(self, name):
"""Delegate to the configuration object."""
@@ -143,13 +143,16 @@ class Configuration:
Switchboard.initialize()
# Set up all the languages.
languages = self._config.getByCategory('language', [])
+ language_manager = getUtility(ILanguageManager)
for language in languages:
if language.enabled:
code = language.name.split('.')[1]
- self.languages.add(
+ language_manager.add(
code, language.charset, language.description)
# The default language must always be available.
- assert self._config.mailman.default_language in self.languages
+ assert self._config.mailman.default_language in language_manager, (
+ 'System default language code not defined: %s' %
+ self._config.mailman.default_language)
self.ensure_directories_exist()
self.style_manager.populate()
# Set the default system language.
diff --git a/src/mailman/config/configure.zcml b/src/mailman/config/configure.zcml
index 807698f16..378feebf9 100644
--- a/src/mailman/config/configure.zcml
+++ b/src/mailman/config/configure.zcml
@@ -28,6 +28,11 @@
/>
<utility
+ factory="mailman.languages.manager.LanguageManager"
+ provides="mailman.interfaces.languages.ILanguageManager"
+ />
+
+ <utility
factory="mailman.model.listmanager.ListManager"
provides="mailman.interfaces.listmanager.IListManager"
/>
diff --git a/src/mailman/core/constants.py b/src/mailman/core/constants.py
index 1701c93f7..5eac8f0d6 100644
--- a/src/mailman/core/constants.py
+++ b/src/mailman/core/constants.py
@@ -25,9 +25,11 @@ __all__ = [
]
+from zope.component import getUtility
from zope.interface import implements
from mailman.config import config
+from mailman.interfaces.languages import ILanguageManager
from mailman.interfaces.member import DeliveryMode, DeliveryStatus
from mailman.interfaces.preferences import IPreferences
@@ -52,7 +54,7 @@ class SystemDefaultPreferences:
@property
def preferred_language(self):
"""Return the system preferred language."""
- return config.languages['en']
+ return getUtility(ILanguageManager)[config.mailman.default_language]
diff --git a/src/mailman/core/initialize.py b/src/mailman/core/initialize.py
index 707bb3f66..5da2209fd 100644
--- a/src/mailman/core/initialize.py
+++ b/src/mailman/core/initialize.py
@@ -58,6 +58,7 @@ from mailman.utilities.modules import call_name
def initialize_1(config_path=None, propagate_logs=None):
"""First initialization step.
+ * Zope component architecture
* The configuration system
* Run-time directories
* The logging subsystem
@@ -68,6 +69,8 @@ def initialize_1(config_path=None, propagate_logs=None):
:param propagate_logs: Should the log output propagate to stderr?
:type propagate_logs: boolean or None
"""
+ zcml = resource_string('mailman.config', 'configure.zcml')
+ xmlconfig.string(zcml)
# By default, set the umask so that only owner and group can read and
# write our files. Specifically we must have g+rw and we probably want
# o-rwx although I think in most cases it doesn't hurt if other can read
@@ -120,11 +123,8 @@ def initialize_2(debug=False):
def initialize_3():
"""Third initialization step.
- * Zope component architecture
* Post-hook
"""
- zcml = resource_string('mailman.config', 'configure.zcml')
- xmlconfig.string(zcml)
# Run the post-hook if there is one.
config = mailman.config.config
if config.mailman.post_hook:
diff --git a/src/mailman/docs/languages.txt b/src/mailman/docs/languages.txt
index 77b51cbeb..a724a0510 100644
--- a/src/mailman/docs/languages.txt
+++ b/src/mailman/docs/languages.txt
@@ -1,3 +1,4 @@
+=========
Languages
=========
@@ -6,12 +7,16 @@ languages at run time, as well as enabling those languages for use in a
running Mailman instance.
>>> from mailman.interfaces.languages import ILanguageManager
- >>> from mailman.languages.manager import LanguageManager
+ >>> from zope.component import getUtility
>>> from zope.interface.verify import verifyObject
- >>> mgr = LanguageManager()
+
+ >>> mgr = getUtility(ILanguageManager)
>>> verifyObject(ILanguageManager, mgr)
True
+ # The language manager component comes pre-populated; clear it out.
+ >>> mgr.clear()
+
A language manager keeps track of the languages it knows about.
>>> list(mgr.codes)
@@ -21,7 +26,7 @@ A language manager keeps track of the languages it knows about.
Adding languages
-----------------
+================
Adding a new language requires three pieces of information, the 2-character
language code, the English description of the language, and the character set
@@ -43,7 +48,7 @@ And you can get information for all known languages.
Other iterations
-----------------
+================
You can iterate over all the known language codes.
@@ -83,3 +88,23 @@ You can get a particular language by its code.
None
>>> print mgr.get('xx', 'missing')
missing
+
+
+Clearing the known languages
+============================
+
+The language manager can forget about all the language codes it knows about.
+
+ >>> 'en' in mgr
+ True
+
+ # Make a copy of the language manager's dictionary, so we can restore it
+ # after the test. Currently the test layer doesn't manage this.
+ >>> saved = mgr._languages.copy()
+
+ >>> mgr.clear()
+ >>> 'en' in mgr
+ False
+
+ # Restore the data.
+ >>> mgr._languages = saved
diff --git a/src/mailman/docs/message.txt b/src/mailman/docs/message.txt
index 84b0eaf3e..41607ff44 100644
--- a/src/mailman/docs/message.txt
+++ b/src/mailman/docs/message.txt
@@ -1,3 +1,4 @@
+========
Messages
========
@@ -6,7 +7,7 @@ email.message.Message class, but providing additional useful methods.
User notifications
-------------------
+==================
When Mailman needs to send a message to a user, it creates a UserNotification
instance, and then calls the .send() method on this object. This method
diff --git a/src/mailman/docs/users.txt b/src/mailman/docs/users.txt
index 73e4f3b77..bb0301772 100644
--- a/src/mailman/docs/users.txt
+++ b/src/mailman/docs/users.txt
@@ -135,7 +135,8 @@ Users have preferences, but these preferences have no default settings.
Some of these preferences are booleans and they can be set to True or False.
- >>> config.languages.add('it', 'iso-8859-1', 'Italian')
+ >>> from mailman.interfaces.languages import ILanguageManager
+ >>> getUtility(ILanguageManager).add('it', 'iso-8859-1', 'Italian')
>>> from mailman.core.constants import DeliveryMode
>>> prefs = user_1.preferences
diff --git a/src/mailman/interfaces/languages.py b/src/mailman/interfaces/languages.py
index 7be5fca7b..18e93ea81 100644
--- a/src/mailman/interfaces/languages.py
+++ b/src/mailman/interfaces/languages.py
@@ -93,3 +93,6 @@ class ILanguageManager(Interface):
:return: A flag indicating whether the language code is known or not.
:rtype: bool
"""
+
+ def clear():
+ """Remove all language code mappings."""
diff --git a/src/mailman/languages/manager.py b/src/mailman/languages/manager.py
index 96c00d09f..03978da4e 100644
--- a/src/mailman/languages/manager.py
+++ b/src/mailman/languages/manager.py
@@ -68,3 +68,7 @@ class LanguageManager:
def __contains__(self, code):
"""See `ILanguageManager`."""
return code in self._languages
+
+ def clear(self):
+ """See `ILanguageManager`."""
+ self._languages.clear()
diff --git a/src/mailman/model/domain.py b/src/mailman/model/domain.py
index 06aef62cf..a30c9c581 100644
--- a/src/mailman/model/domain.py
+++ b/src/mailman/model/domain.py
@@ -106,10 +106,6 @@ class DomainManager:
implements(IDomainManager)
- def __init__(self):
- """Create a domain manager."""
- self.store = config.db.store
-
def add(self, email_host,
description=None,
base_url=None,
@@ -121,17 +117,17 @@ class DomainManager:
raise BadDomainSpecificationError(
'Duplicate email host: %s' % email_host)
domain = Domain(email_host, description, base_url, contact_address)
- self.store.add(domain)
+ config.db.store.add(domain)
return domain
def remove(self, email_host):
domain = self[email_host]
- self.store.remove(domain)
+ config.db.store.remove(domain)
return domain
def get(self, email_host, default=None):
"""See `IDomainManager`."""
- domains = self.store.find(Domain, email_host=email_host)
+ domains = config.db.store.find(Domain, email_host=email_host)
if domains.count() < 1:
return default
assert domains.count() == 1, (
@@ -147,13 +143,13 @@ class DomainManager:
return domain
def __len__(self):
- return self.store.find(Domain).count()
+ return config.db.store.find(Domain).count()
def __iter__(self):
"""See `IDomainManager`."""
- for domain in self.store.find(Domain):
+ for domain in config.db.store.find(Domain):
yield domain
def __contains__(self, email_host):
"""See `IDomainManager`."""
- return self.store.find(Domain, email_host=email_host).count() > 0
+ return config.db.store.find(Domain, email_host=email_host).count() > 0
diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py
index 77da90b09..25880bebc 100644
--- a/src/mailman/model/mailinglist.py
+++ b/src/mailman/model/mailinglist.py
@@ -39,6 +39,7 @@ from mailman.config import config
from mailman.database.model import Model
from mailman.database.types import Enum
from mailman.interfaces.domain import IDomainManager
+from mailman.interfaces.languages import ILanguageManager
from mailman.interfaces.mailinglist import (
IAcceptableAlias, IAcceptableAliasSet, IMailingList, Personalization)
from mailman.interfaces.mime import FilterType
@@ -288,7 +289,7 @@ class MailingList(Model):
@property
def preferred_language(self):
"""See `IMailingList`."""
- return config.languages[self._preferred_language]
+ return getUtility(ILanguageManager)[self._preferred_language]
@preferred_language.setter
def preferred_language(self, language):
diff --git a/src/mailman/model/preferences.py b/src/mailman/model/preferences.py
index 31f9ce280..550568e96 100644
--- a/src/mailman/model/preferences.py
+++ b/src/mailman/model/preferences.py
@@ -26,11 +26,13 @@ __all__ = [
from storm.locals import *
+from zope.component import getUtility
from zope.interface import implements
from mailman.config import config
from mailman.database.model import Model
from mailman.database.types import Enum
+from mailman.interfaces.languages import ILanguageManager
from mailman.interfaces.preferences import IPreferences
@@ -54,7 +56,7 @@ class Preferences(Model):
def preferred_language(self):
if self._preferred_language is None:
return None
- return config.languages[self._preferred_language]
+ return getUtility(ILanguageManager)[self._preferred_language]
@preferred_language.setter
def preferred_language(self, language):
diff --git a/src/mailman/pipeline/acknowledge.py b/src/mailman/pipeline/acknowledge.py
index 2d0efd808..5ef7f18d5 100644
--- a/src/mailman/pipeline/acknowledge.py
+++ b/src/mailman/pipeline/acknowledge.py
@@ -28,6 +28,7 @@ __all__ = [
]
+from zope.component import getUtility
from zope.interface import implements
from mailman import Utils
@@ -35,6 +36,7 @@ from mailman.config import config
from mailman.core.i18n import _
from mailman.email.message import Message, UserNotification
from mailman.interfaces.handler import IHandler
+from mailman.interfaces.languages import ILanguageManager
@@ -61,10 +63,11 @@ class Acknowledge:
original_subject = msgdata.get(
'origsubj', msg.get('subject', _('(no subject)')))
# Get the user's preferred language.
- language = (config.languages[msgdata['lang']]
+ language_manager = getUtility(ILanguageManager)
+ language = (language_manager[msgdata['lang']]
if 'lang' in msgdata
else member.preferred_language)
- charset = config.languages[language.code].charset
+ charset = language_manager[language.code].charset
# Now get the acknowledgement template.
realname = mlist.real_name
text = Utils.maketext(
diff --git a/src/mailman/queue/__init__.py b/src/mailman/queue/__init__.py
index a6d930c9d..4d9053ac3 100644
--- a/src/mailman/queue/__init__.py
+++ b/src/mailman/queue/__init__.py
@@ -53,6 +53,7 @@ from zope.interface import implements
from mailman.config import config
from mailman.core.i18n import _
from mailman.email.message import Message
+from mailman.interfaces.languages import ILanguageManager
from mailman.interfaces.listmanager import IListManager
from mailman.interfaces.runner import IRunner
from mailman.interfaces.switchboard import ISwitchboard
@@ -421,11 +422,16 @@ class Runner:
# them out of our sight.
#
# Find out which mailing list this message is destined for.
- listname = unicode(msgdata.get('listname'))
- mlist = getUtility(IListManager).get(listname)
+ missing = object()
+ listname = msgdata.get('listname', missing)
+ mlist = (None
+ if listname is missing
+ else getUtility(IListManager).get(unicode(listname)))
if mlist is None:
- elog.error('Dequeuing message destined for missing list: %s',
- listname)
+ elog.error(
+ '%s runner "%s" shunting message for missing list: %s',
+ msg['message-id'], self.name,
+ ('n/a' if listname is missing else listname))
config.switchboards['shunt'].enqueue(msg, msgdata)
return
# Now process this message. We also want to set up the language
@@ -434,7 +440,10 @@ class Runner:
# will be the list's preferred language. However, we must take
# special care to reset the defaults, otherwise subsequent messages
# may be translated incorrectly.
- if msg.sender:
+ if mlist is None:
+ language_manager = getUtility(ILanguageManager)
+ language = language_manager[config.mailman.default_language]
+ elif msg.sender:
member = mlist.members.get_member(msg.sender)
language = (member.preferred_language
if member is not None
diff --git a/src/mailman/queue/command.py b/src/mailman/queue/command.py
index d5ce708b1..401730e73 100644
--- a/src/mailman/queue/command.py
+++ b/src/mailman/queue/command.py
@@ -32,15 +32,17 @@ import re
import logging
from StringIO import StringIO
-from email.Errors import HeaderParseError
-from email.Header import decode_header, make_header
-from email.Iterators import typed_subpart_iterator
+from email.errors import HeaderParseError
+from email.header import decode_header, make_header
+from email.iterators import typed_subpart_iterator
+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, UserNotification
from mailman.interfaces.command import ContinueProcessing, IEmailResults
+from mailman.interfaces.languages import ILanguageManager
from mailman.queue import Runner
@@ -198,7 +200,7 @@ class CommandRunner(Runner):
# Send a reply, but do not attach the original message. This is a
# compromise because the original message is often helpful in tracking
# down problems, but it's also a vector for backscatter spam.
- language = config.languages[msgdata['lang']]
+ language = getUtility(ILanguageManager)[msgdata['lang']]
reply = UserNotification(msg.sender, mlist.bounces_address,
_('The results of your email commands'),
lang=language)