diff options
| author | Barry Warsaw | 2009-02-12 20:36:21 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2009-02-12 20:36:21 -0500 |
| commit | 62f4c909f90535986614a411db982bdcccaec3a1 (patch) | |
| tree | 2fe5dd3316cea73f63cb34230d848758050eade3 | |
| parent | 2b28803e7165e91d812cd9e9e3804a6d9bdce8a1 (diff) | |
| download | mailman-62f4c909f90535986614a411db982bdcccaec3a1.tar.gz mailman-62f4c909f90535986614a411db982bdcccaec3a1.tar.zst mailman-62f4c909f90535986614a411db982bdcccaec3a1.zip | |
Much clean up of the language code, though more can be done. Factor out the
language manager stuff into a separate Language class, and be clearer in the
APIs about whether we want a language code or a Language instance.
The impetus to this was to get rid of Utils.GetCharSet(), which is done.
35 files changed, 228 insertions, 162 deletions
diff --git a/.bzrignore b/.bzrignore index 8672761e7..19610a565 100644 --- a/.bzrignore +++ b/.bzrignore @@ -16,3 +16,4 @@ develop-eggs parts ./bin eggs +diff.txt diff --git a/src/mailman/Archiver/HyperArch.py b/src/mailman/Archiver/HyperArch.py index 26f32bdd0..d78831e8e 100644 --- a/src/mailman/Archiver/HyperArch.py +++ b/src/mailman/Archiver/HyperArch.py @@ -80,14 +80,14 @@ if sys.platform == 'darwin': -def html_quote(s, lang=None): +def html_quote(s, langcode=None): repls = ( ('&', '&'), ("<", '<'), (">", '>'), ('"', '"')) for thing, repl in repls: s = s.replace(thing, repl) - return Utils.uncanonstr(s, lang) + return Utils.uncanonstr(s, langcode) def url_quote(s): @@ -107,7 +107,7 @@ def sizeof(filename, lang): if e.errno <> errno.ENOENT: raise return _('size not available') if size < 1000: - with i18n.using_language(lang): + with i18n.using_language(lang.code): out = _(' %(size)i bytes ') return out elif size < 1000000: @@ -124,7 +124,7 @@ def CGIescape(arg, lang=None): s = Utils.websafe(arg) else: s = Utils.websafe(str(arg)) - return Utils.uncanonstr(s.replace('"', '"'), lang) + return Utils.uncanonstr(s.replace('"', '"'), lang.code) # Parenthesized human name paren_name_pat = re.compile(r'([(].*[)])') @@ -184,7 +184,7 @@ def quick_maketext(templatefile, dict=None, lang=None, mlist=None): template = _templatecache.get(filepath) if filepath is None or template is None: # Use the basic maketext, with defaults to get the raw template - template, filepath = Utils.findtext(templatefile, lang=lang, + template, filepath = Utils.findtext(templatefile, lang=lang.code, raw=True, mlist=mlist) _templatefilepathcache[cachekey] = filepath _templatecache[filepath] = template @@ -196,16 +196,14 @@ def quick_maketext(templatefile, dict=None, lang=None, mlist=None): text = Template(template).safe_substitute(**dict) except UnicodeError: # Try again after coercing the template to unicode - utemplate = unicode(template, - Utils.GetCharSet(lang), - 'replace') + utemplate = unicode(template, lang.charset, 'replace') text = Template(utemplate).safe_substitute(**dict) except (TypeError, ValueError): # The template is really screwed up pass # Make sure the text is in the given character set, or html-ify any bogus # characters. - return Utils.uncanonstr(text, lang) + return Utils.uncanonstr(text, lang.code) @@ -256,7 +254,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): + with i18n.using_language(lang.code): if self.author == self.email: self.author = self.email = re.sub('@', _(' at '), self.email) @@ -269,7 +267,7 @@ class Article(pipermail.Article): self.ctype = ctype.lower() self.cenc = cenc.lower() self.decoded = {} - cset = Utils.GetCharSet(mlist.preferred_language) + cset = mlist.preferred_language.charset cset_out = Charset(cset).output_charset or cset charset = message.get_content_charset(cset_out) if charset: @@ -282,7 +280,7 @@ class Article(pipermail.Article): body = message.get_payload(decode=True) except binascii.Error: body = None - if body and charset != Utils.GetCharSet(self._lang): + if body and charset != self._lang.charset: # decode body try: body = unicode(body, charset) @@ -337,7 +335,7 @@ class Article(pipermail.Article): self._mlist = mlist def quote(self, buf): - return html_quote(buf, self._lang) + return html_quote(buf, self._lang.code) def decode_headers(self): """MIME-decode headers. @@ -359,7 +357,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): + with i18n.using_language(self._lang.code): atmark = _(' at ') subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)', '\g<1>' + atmark + '\g<2>', subject) @@ -388,7 +386,7 @@ class Article(pipermail.Article): ustr = make_header(pairs).__unicode__() except (LookupError, UnicodeError, ValueError, HeaderParseError): # assume list's language - cset = Utils.GetCharSet(self._mlist.preferred_language) + cset = self._mlist.preferred_language.charset if cset == 'us-ascii': cset = 'iso-8859-1' # assume this for English list ustr = unicode(field, cset, 'replace') @@ -397,7 +395,7 @@ class Article(pipermail.Article): def as_html(self): d = self.__dict__.copy() # avoid i18n side-effects - with i18n.using_language(self._lang): + with i18n.using_language(self._lang.code): d["prev"], d["prev_wsubj"] = self._get_prev() d["next"], d["next_wsubj"] = self._get_next() @@ -420,7 +418,7 @@ class Article(pipermail.Article): d['listurl'] = self._mlist.script_url('listinfo') d['listname'] = self._mlist.real_name d['encoding'] = '' - charset = Utils.GetCharSet(self._lang) + charset = self._lang.charset d["encoding"] = html_charset % charset self._add_decoded(d) @@ -506,12 +504,12 @@ class Article(pipermail.Article): if d['_message_id']: headers.append('Message-ID: %(_message_id)s') body = EMPTYSTRING.join(self.body) - cset = Utils.GetCharSet(self._lang) + cset = self._lang.charset # Coerce the body to Unicode and replace any invalid characters. 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): + with i18n.using_language(self._lang.code): atmark = _(' at ') body = re.sub(r'([-+,.\w]+)@([-+.\w]+)', '\g<1>' + atmark + '\g<2>', body) @@ -577,7 +575,7 @@ class HyperArchive(pipermail.T): self.maillist = maillist self._lock_file = None self.lang = maillist.preferred_language - self.charset = Utils.GetCharSet(maillist.preferred_language) + self.charset = maillist.preferred_language.charset if hasattr(self.maillist,'archive_volume_frequency'): if self.maillist.archive_volume_frequency == 0: @@ -612,8 +610,8 @@ class HyperArchive(pipermail.T): mlist = self.maillist # Convenience def quotetime(s): - return html_quote(i18n.ctime(s), self.lang) - with i18n.using_language(mlist.preferred_language): + return html_quote(i18n.ctime(s), self.lang.code) + with i18n.using_language(mlist.preferred_language.code): d = {"lastdate": quotetime(self.lastdate), "archivedate": quotetime(self.archivedate), "listinfo": mlist.script_url('listinfo'), @@ -640,9 +638,9 @@ class HyperArchive(pipermail.T): mlist = self.maillist # Convenience def quotetime(s): - return html_quote(i18n.ctime(s), self.lang) - with i18n.using_language(mlist.preferred_language): - d = {"listname": html_quote(mlist.real_name, self.lang), + return html_quote(i18n.ctime(s), self.lang.code) + with i18n.using_language(mlist.preferred_language.code): + d = {"listname": html_quote(mlist.real_name, self.lang.code), "archtype": self.type, "archive": self.volNameToDesc(self.archive), "listinfo": mlist.script_url('listinfo'), @@ -682,7 +680,7 @@ class HyperArchive(pipermail.T): 'meta': '', } # Avoid i18n side-effects - with i18n.using_language(mlist.preferred_language): + with i18n.using_language(mlist.preferred_language.code): if not self.archives: d["noarchive_msg"] = _( '<P>Currently, there are no archives. </P>') @@ -704,7 +702,7 @@ class HyperArchive(pipermail.T): accum.append(self.html_TOC_entry(a)) d["archive_listing"] = EMPTYSTRING.join(accum) # The TOC is always in the charset of the list's preferred language - d['meta'] += html_charset % Utils.GetCharSet(mlist.preferred_language) + d['meta'] += html_charset % mlist.preferred_language.charset # The site can disable public access to the mbox file. if as_boolean(config.archiver.pipermail.public_mbox): template = 'archtoc.html' @@ -1096,7 +1094,7 @@ class HyperArchive(pipermail.T): # TK: Prepare for unicode obscure. atmark = _(' at ') if lines and isinstance(lines[0], unicode): - atmark = unicode(atmark, Utils.GetCharSet(self.lang), 'replace') + atmark = unicode(atmark, self.lang.charset, 'replace') source = lines[:] dest = lines last_line_was_quoted = 0 diff --git a/src/mailman/Utils.py b/src/mailman/Utils.py index 74582a7ad..866fa89ad 100644 --- a/src/mailman/Utils.py +++ b/src/mailman/Utils.py @@ -425,7 +425,7 @@ def findtext(templatefile, raw_dict=None, raw=False, lang=None, mlist=None): if lang is not None: languages.add(lang) if mlist is not None: - languages.add(mlist.preferred_language) + languages.add(mlist.preferred_language.code) languages.add(config.mailman.default_language) assert None not in languages, 'None in languages' # Calculate the locations to scan @@ -471,7 +471,8 @@ def findtext(templatefile, raw_dict=None, raw=False, lang=None, mlist=None): else: template = fp.read() fp.close() - template = unicode(template, GetCharSet(lang), 'replace') + charset = config.languages[lang].charset + template = unicode(template, charset, 'replace') text = template if raw_dict is not None: text = expand(template, raw_dict) @@ -485,13 +486,6 @@ def maketext(templatefile, dict=None, raw=False, lang=None, mlist=None): -# XXX Replace this with direct calls. For now, existing uses of GetCharSet() -# are too numerous to change. -def GetCharSet(lang): - return config.languages[lang].charset - - - # Figure out epoch seconds of midnight at the start of today (or the given # 3-tuple date of (year, month, day). def midnight(date=None): @@ -512,7 +506,7 @@ def uncanonstr(s, lang=None): if lang is None: charset = 'us-ascii' else: - charset = GetCharSet(lang) + charset = config.languages[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/bounces.py b/src/mailman/app/bounces.py index aa7f51c77..cea91b2e2 100644 --- a/src/mailman/app/bounces.py +++ b/src/mailman/app/bounces.py @@ -29,7 +29,7 @@ import logging from email.mime.message import MIMEMessage from email.mime.text import MIMEText -from mailman import Utils +from mailman.Utils import oneline from mailman.email.message import Message, UserNotification from mailman.i18n import _ @@ -45,8 +45,7 @@ def bounce_message(mlist, msg, e=None): # to. return subject = msg.get('subject', _('(no subject)')) - subject = Utils.oneline(subject, - Utils.GetCharSet(mlist.preferred_language)) + subject = oneline(subject, mlist.preferred_language.charset) if e is None: notice = _('[No bounce details are available]') else: @@ -57,8 +56,7 @@ def bounce_message(mlist, msg, e=None): # BAW: Be sure you set the type before trying to attach, or you'll get # a MultipartConversionError. bmsg.set_type('multipart/mixed') - txt = MIMEText(notice, - _charset=Utils.GetCharSet(mlist.preferred_language)) + txt = MIMEText(notice, _charset=mlist.preferred_language.charset) bmsg.attach(txt) bmsg.attach(MIMEMessage(msg)) bmsg.send(mlist) diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py index 1f66e00ac..ffe0f779e 100644 --- a/src/mailman/app/moderator.py +++ b/src/mailman/app/moderator.py @@ -165,7 +165,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): + with i18n.using_language(language.code): fmsg = UserNotification( addresses, mlist.bounces_address, _('Forward of moderated message'), @@ -234,14 +234,14 @@ def handle_subscription(mlist, id, action, comment=None): _refuse(mlist, _('Subscription request'), data['address'], comment or _('[No reason given]'), - lang=data['language']) + lang=config.languages[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 = data['language'] + language = config.languages[data['language']] password = data['password'] try: add_member(mlist, address, realname, password, @@ -329,16 +329,16 @@ def _refuse(mlist, request, recip, comment, origmsg=None, lang=None): realname = mlist.real_name if lang is None: member = mlist.members.get_member(recip) - if member: - lang = member.preferred_language + lang = (member.preferred_language if member + else mlist.preferred_language) text = Utils.maketext( 'refuse.txt', {'listname' : mlist.fqdn_listname, 'request' : request, 'reason' : comment, 'adminaddr': mlist.owner_address, - }, lang=lang, mlist=mlist) - with i18n.using_language(lang): + }, lang=lang.code, mlist=mlist) + with i18n.using_language(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 b1d77dc6f..fcbfe95be 100644 --- a/src/mailman/app/notifications.py +++ b/src/mailman/app/notifications.py @@ -73,7 +73,7 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''): 'optionsurl' : options_url, 'request_address' : mlist.request_address, 'welcome' : welcome, - }, lang=language, mlist=mlist) + }, lang=language.code, mlist=mlist) if delivery_mode is not DeliveryMode.regular: digmode = _(' (Digest mode)') else: @@ -124,9 +124,9 @@ 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): + with i18n.using_language(mlist.preferred_language.code): subject = _('$mlist.real_name subscription notification') - full_name = full_name.encode(Utils.GetCharSet(language), 'replace') + full_name = full_name.encode(language.charset, 'replace') text = Utils.maketext( 'adminsubscribeack.txt', {'listname' : mlist.real_name, diff --git a/src/mailman/app/replybot.py b/src/mailman/app/replybot.py index 0537f6645..b558e96aa 100644 --- a/src/mailman/app/replybot.py +++ b/src/mailman/app/replybot.py @@ -80,7 +80,7 @@ def autorespond_to_sender(mlist, sender, lang=None): 'owneremail': mlist.owner_address, }, lang=lang) - with i18n.using_language(lang): + with i18n.using_language(lang.code): msg = Message.UserNotification( sender, mlist.owner_address, _('Last autoresponse notification for today'), diff --git a/src/mailman/bin/add_members.py b/src/mailman/bin/add_members.py index 9c87f4af9..540c0facb 100644 --- a/src/mailman/bin/add_members.py +++ b/src/mailman/bin/add_members.py @@ -22,12 +22,12 @@ import codecs from cStringIO import StringIO from email.utils import parseaddr -from mailman import Message from mailman import Utils from mailman import i18n from mailman.app.membership import add_member from mailman.config import config from mailman.core import errors +from mailman.email.message import UserNotification from mailman.interfaces.member import AlreadySubscribedError, DeliveryMode from mailman.options import SingleMailingListOptions @@ -175,7 +175,7 @@ def main(): if admin_notify: subject = _('$mlist.real_name subscription notification') - msg = Message.UserNotification( + msg = UserNotification( mlist.owner, mlist.no_reply_address, subject, outfp.getvalue(), mlist.preferred_language) msg.send(mlist) diff --git a/src/mailman/bin/checkdbs.py b/src/mailman/bin/checkdbs.py index 2ce08aab7..10d34aa22 100644 --- a/src/mailman/bin/checkdbs.py +++ b/src/mailman/bin/checkdbs.py @@ -22,11 +22,11 @@ import optparse from email.Charset import Charset from mailman import MailList -from mailman import Message from mailman import Utils from mailman import i18n from mailman.app.requests import handle_request from mailman.configuration import config +from mailman.email.message import UserNotification from mailman.version import MAILMAN_VERSION _ = i18n._ @@ -59,7 +59,7 @@ Check for pending admin requests and mail the list owners if necessary.""")) def pending_requests(mlist): # Must return a byte string - lcset = Utils.GetCharSet(mlist.preferred_language) + lcset = mlist.preferred_language.charset pending = [] first = True requestsdb = config.db.get_list_requests(mlist) @@ -101,7 +101,7 @@ Cause: $reason""")) pending.append('') # Coerce all items in pending to a Unicode so we can join them upending = [] - charset = Utils.GetCharSet(mlist.preferred_language) + charset = mlist.preferred_language.charset for s in pending: if isinstance(s, unicode): upending.append(s) @@ -112,7 +112,7 @@ Cause: $reason""")) # example, the request was pended while the list's language was French, # but then it was changed to English before checkdbs ran. text = NL.join(upending) - charset = Charset(Utils.GetCharSet(mlist.preferred_language)) + charset = Charset(mlist.preferred_language.charset) incodec = charset.input_codec or 'ascii' outcodec = charset.output_codec or 'ascii' if isinstance(text, unicode): @@ -185,10 +185,10 @@ def main(): subject = _('$count $realname moderator request(s) waiting') else: subject = _('$realname moderator request check result') - msg = Message.UserNotification(mlist.GetOwnerEmail(), - mlist.GetBouncesEmail(), - subject, text, - mlist.preferred_language) + msg = UserNotification(mlist.GetOwnerEmail(), + mlist.GetBouncesEmail(), + subject, text, + mlist.preferred_language) msg.send(mlist, **{'tomoderators': True}) finally: mlist.Unlock() diff --git a/src/mailman/bin/config_list.py b/src/mailman/bin/config_list.py index a5cec9480..89a9892cd 100644 --- a/src/mailman/bin/config_list.py +++ b/src/mailman/bin/config_list.py @@ -20,10 +20,10 @@ import sys import time import optparse -from mailman import errors from mailman import MailList -from mailman import Utils +from mailman import errors from mailman import i18n +from mailman.Utils import wrap from mailman.configuration import config from mailman.version import MAILMAN_VERSION @@ -100,9 +100,8 @@ def do_output(listname, outfile, parser): except errors.MMListError: parser.error(_('No such list: $listname')) # Preamble for the config info. PEP 263 charset and capture time. - language = mlist.preferred_language - charset = Utils.GetCharSet(language) - i18n.set_language(language) + charset = mlist.preferred_language.charset + i18n.set_language(mlist.preferred_language.code) if not charset: charset = 'us-ascii' when = time.ctime(time.time()) @@ -132,7 +131,7 @@ def do_list_categories(mlist, k, subcat, outfp): label, gui = mlist.GetConfigCategories()[k] if info is None: return - charset = Utils.GetCharSet(mlist.preferred_language) + charset = mlist.preferred_language.charset print >> outfp, '##', k.capitalize(), _('options') print >> outfp, '#' # First, massage the descripton text, which could have obnoxious diff --git a/src/mailman/bin/create_list.py b/src/mailman/bin/create_list.py index 8058a7d67..59be836a2 100644 --- a/src/mailman/bin/create_list.py +++ b/src/mailman/bin/create_list.py @@ -17,12 +17,12 @@ import sys -from mailman import Message from mailman import Utils from mailman import i18n from mailman.app.lifecycle import create_list from mailman.config import config from mailman.core import errors +from mailman.email.message import UserNotification from mailman.interfaces.listmanager import ListAlreadyExistsError from mailman.options import SingleMailingListOptions @@ -121,8 +121,8 @@ def main(): # 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 i18n.using_language(mlist.preferred_language): - msg = Message.UserNotification( + with i18n.using_language(mlist.preferred_language.code): + msg = UserNotification( owner_mail, mlist.no_reply_address, _('Your new mailing list: $fqdn_listname'), text, mlist.preferred_language) diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py index 162834791..dd5b69db0 100644 --- a/src/mailman/chains/hold.py +++ b/src/mailman/chains/hold.py @@ -33,7 +33,7 @@ from email.utils import formatdate, make_msgid from zope.interface import implements from mailman import i18n -from mailman.Utils import maketext, oneline, wrap, GetCharSet +from mailman.Utils import maketext, oneline, wrap from mailman.app.moderator import hold_message from mailman.app.replybot import autorespond_to_sender, can_acknowledge from mailman.chains.base import TerminalChainBase @@ -86,7 +86,7 @@ class HoldChain(TerminalChainBase): language = (member.preferred_language if member else mlist.preferred_language) # A substitution dictionary for the email templates. - charset = GetCharSet(mlist.preferred_language) + charset = mlist.preferred_language.charset original_subject = msg.get('subject') if original_subject is None: original_subject = _('(no subject)') @@ -122,12 +122,12 @@ class HoldChain(TerminalChainBase): # posting was held. subject = _( 'Your message to $mlist.fqdn_listname awaits moderator approval') - send_language = msgdata.get('lang', language) + send_language_code = msgdata.get('lang', language.code) text = maketext('postheld.txt', substitutions, - lang=send_language, mlist=mlist) + lang=send_language_code, mlist=mlist) adminaddr = mlist.bounces_address nmsg = UserNotification(msg.sender, adminaddr, subject, text, - send_language) + config.languages[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 @@ -135,9 +135,9 @@ 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): + with i18n.using_language(mlist.preferred_language.code): language = mlist.preferred_language - charset = GetCharSet(language) + charset = language.charset # We need to regenerate or re-translate a few values in the # substitution dictionary. #d['reason'] = _(reason) # XXX reason @@ -160,7 +160,7 @@ discard the held message. Do this if the message is spam. If you reply to this message and include an Approved: header with the list password in it, the message will be approved for posting to the list. The Approved: header can also appear in the first line of the body of the reply.""")), - _charset=GetCharSet(language)) + _charset=language.charset) dmsg['Subject'] = 'confirm ' + token dmsg['Sender'] = mlist.request_address dmsg['From'] = mlist.request_address diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py index 4af4ada4e..8ce5d3886 100644 --- a/src/mailman/config/config.py +++ b/src/mailman/config/config.py @@ -149,7 +149,7 @@ class Configuration(object): for language in languages: if language.enabled: code = language.name.split('.')[1] - self.languages.add_language( + self.languages.add( code, language.charset, language.description) # The default language must always be available. assert self._config.mailman.default_language in self.languages diff --git a/src/mailman/constants.py b/src/mailman/constants.py index 39c4547f8..2cd48270c 100644 --- a/src/mailman/constants.py +++ b/src/mailman/constants.py @@ -17,7 +17,7 @@ """Various constants and enumerations.""" -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ @@ -27,6 +27,7 @@ __all__ = [ from zope.interface import implements +from mailman.config import config from mailman.interfaces.member import DeliveryMode, DeliveryStatus from mailman.interfaces.preferences import IPreferences @@ -37,7 +38,7 @@ class SystemDefaultPreferences: acknowledge_posts = False hide_address = True - preferred_language = 'en' + preferred_language = config.languages['en'] receive_list_copy = True receive_own_postings = True delivery_mode = DeliveryMode.regular diff --git a/src/mailman/database/mailinglist.py b/src/mailman/database/mailinglist.py index e380a71b1..605c51cd6 100644 --- a/src/mailman/database/mailinglist.py +++ b/src/mailman/database/mailinglist.py @@ -151,7 +151,7 @@ class MailingList(Model): personalize = Enum() pipeline = Unicode() post_id = Int() - preferred_language = Unicode() + _preferred_language = Unicode(name='preferred_language') private_roster = Bool() real_name = Unicode() reject_these_nonmembers = Pickle() @@ -200,6 +200,10 @@ class MailingList(Model): self.digest_members = roster.DigestMemberRoster(self) self.subscribers = roster.Subscribers(self) + def __repr__(self): + return '<mailing list "{0}" at {1:#x}>'.format( + self.fqdn_listname, id(self)) + @property def fqdn_listname(self): """See `IMailingList`.""" @@ -267,6 +271,14 @@ class MailingList(Model): cookie = cookie)) return '{0}@{1}'.format(local_part, self.host_name) - def __repr__(self): - return '<mailing list "{0}" at {1:#x}>'.format( - self.fqdn_listname, id(self)) + @property + def preferred_language(self): + return config.languages[self._preferred_language] + + @preferred_language.setter + def preferred_language(self, language): + # Accept both a language code and a `Language` instance. + try: + self._preferred_language = language.code + except AttributeError: + self._preferred_language = language diff --git a/src/mailman/database/preferences.py b/src/mailman/database/preferences.py index f3ee55673..31f9ce280 100644 --- a/src/mailman/database/preferences.py +++ b/src/mailman/database/preferences.py @@ -28,6 +28,7 @@ __all__ = [ from storm.locals import * 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.preferences import IPreferences @@ -40,7 +41,7 @@ class Preferences(Model): id = Int(primary=True) acknowledge_posts = Bool() hide_address = Bool() - preferred_language = Unicode() + _preferred_language = Unicode(name='preferred_language') receive_list_copy = Bool() receive_own_postings = Bool() delivery_mode = Enum() @@ -48,3 +49,19 @@ class Preferences(Model): def __repr__(self): return '<Preferences object at {0:#x}>'.format(id(self)) + + @property + def preferred_language(self): + if self._preferred_language is None: + return None + return config.languages[self._preferred_language] + + @preferred_language.setter + def preferred_language(self, language): + if language is None: + self._preferred_language = None + # Accept both a language code and a `Language` instance. + try: + self._preferred_language = language.code + except AttributeError: + self._preferred_language = language diff --git a/src/mailman/docs/languages.txt b/src/mailman/docs/languages.txt index a429345a5..87c68f034 100644 --- a/src/mailman/docs/languages.txt +++ b/src/mailman/docs/languages.txt @@ -27,8 +27,8 @@ Adding a new language requires three pieces of information, the 2-character language code, the English description of the language, and the character set used by the language. - >>> mgr.add_language('en', 'us-ascii', 'English') - >>> mgr.add_language('it', 'iso-8859-1', 'Italian') + >>> mgr.add('en', 'us-ascii', 'English') + >>> mgr.add('it', 'iso-8859-1', 'Italian') And you can get information for all known languages. @@ -47,7 +47,7 @@ Other iterations You can iterate over all the known language codes. - >>> mgr.add_language('pl', 'iso-8859-2', 'Polish') + >>> mgr.add('pl', 'iso-8859-2', 'Polish') >>> sorted(mgr.codes) ['en', 'it', 'pl'] diff --git a/src/mailman/docs/requests.txt b/src/mailman/docs/requests.txt index 87b835fb8..a620338db 100644 --- a/src/mailman/docs/requests.txt +++ b/src/mailman/docs/requests.txt @@ -39,7 +39,7 @@ mailing list you need to get its requests object. >>> from zope.interface.verify import verifyObject >>> verifyObject(IRequests, config.db.requests) True - >>> mlist = config.db.list_manager.create(u'test@example.com') + >>> mlist = create_list(u'test@example.com') >>> requests = config.db.requests.get_list_requests(mlist) >>> verifyObject(IListRequests, requests) True @@ -215,7 +215,7 @@ Holding messages For this section, we need a mailing list and at least one message. - >>> mlist = config.db.list_manager.create(u'alist@example.com') + >>> mlist = create_list(u'alist@example.com') >>> mlist.preferred_language = u'en' >>> mlist.real_name = u'A Test List' >>> msg = message_from_string("""\ @@ -678,7 +678,7 @@ Frank Person is now a member of the mailing list. <Member: Frank Person <fperson@example.org> on alist@example.com as MemberRole.member> >>> member.preferred_language - u'en' + <Language [en] English (USA)> >>> print member.delivery_mode DeliveryMode.regular >>> user = config.db.user_manager.get_user(member.address.address) diff --git a/src/mailman/docs/users.txt b/src/mailman/docs/users.txt index ff7b9ca84..b557a280d 100644 --- a/src/mailman/docs/users.txt +++ b/src/mailman/docs/users.txt @@ -132,6 +132,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(u'it', u'iso-8859-1', u'Italian') + >>> from mailman.constants import DeliveryMode >>> prefs = user_1.preferences >>> prefs.acknowledge_posts = True @@ -141,7 +143,7 @@ Some of these preferences are booleans and they can be set to True or False. >>> prefs.delivery_mode = DeliveryMode.regular >>> show_prefs(user_1.preferences) acknowledge_posts : True - preferred_language : it + preferred_language : <Language [it] Italian> receive_list_copy : False receive_own_postings : False delivery_mode : DeliveryMode.regular diff --git a/src/mailman/email/message.py b/src/mailman/email/message.py index 2b552cd8c..984c58c76 100644 --- a/src/mailman/email/message.py +++ b/src/mailman/email/message.py @@ -42,7 +42,6 @@ from email.charset import Charset from email.header import Header from lazr.config import as_boolean -from mailman.Utils import GetCharSet from mailman.config import config @@ -167,13 +166,10 @@ class UserNotification(Message): def __init__(self, recip, sender, subject=None, text=None, lang=None): Message.__init__(self) - charset = 'us-ascii' - if lang is not None: - charset = GetCharSet(lang) + charset = (lang.charset if lang is not None else 'us-ascii') + subject = ('(no subject)' if subject is None else subject) if text is not None: self.set_payload(text.encode(charset), charset) - if subject is None: - subject = '(no subject)' self['Subject'] = Header(subject.encode(charset), charset, header_name='Subject', errors='replace') self['From'] = sender @@ -233,8 +229,8 @@ class OwnerNotification(UserNotification): roster = mlist.owners recips = [address.address for address in roster.addresses] sender = config.mailman.site_owner - lang = mlist.preferred_language - UserNotification.__init__(self, recips, sender, subject, text, lang) + UserNotification.__init__(self, recips, sender, subject, + text, mlist.preferred_language) # Hack the To header to look like it's going to the -owner address del self['to'] self['To'] = mlist.owner_address diff --git a/src/mailman/i18n.py b/src/mailman/i18n.py index 12a06dc02..d06db4cb8 100644 --- a/src/mailman/i18n.py +++ b/src/mailman/i18n.py @@ -61,12 +61,12 @@ class attrdict(dict): -def set_language(language=None): +def set_language(language_code=None): global _translation - if language is not None: - language = [language] + # 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, language) + _translation = gettext.translation('mailman', MESSAGES_DIR, codes) except IOError: # The selected language was not installed in messages, so fall back to # untranslated English. @@ -82,15 +82,15 @@ def set_translation(translation): _translation = translation -class using_language(object): - """Context manager for Python 2.5's `with` statement.""" - def __init__(self, language): - self._language = language +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) + set_language(self._language_code) def __exit__(self, *exc_info): global _translation diff --git a/src/mailman/interfaces/languages.py b/src/mailman/interfaces/languages.py index a41a6e80e..7be5fca7b 100644 --- a/src/mailman/interfaces/languages.py +++ b/src/mailman/interfaces/languages.py @@ -47,7 +47,7 @@ class ILanguageManager(Interface): Current, disabling languages is not supported. """ - def add_language(code, charset, description): + def add(code, charset, description): """Teach the language manager about a language. :param code: The short two-character language code for the diff --git a/src/mailman/languages/language.py b/src/mailman/languages/language.py new file mode 100644 index 000000000..f5e83c255 --- /dev/null +++ b/src/mailman/languages/language.py @@ -0,0 +1,47 @@ +# 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/>. + +"""The representation of a language.""" + + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'Language', + ] + + +from zope.interface import implements +from mailman.interfaces.languages import ILanguage + + + +class Language: + """The representation of a language.""" + + implements(ILanguage) + + def __init__(self, code, charset, description): + self.code = code + self.charset = charset + self.description = description + + def __str__(self): + return '<Language [{0.code}] {0.description}>'.format(self) + + __repr__ = __str__ diff --git a/src/mailman/languages/manager.py b/src/mailman/languages/manager.py index a5a3d02f2..96c00d09f 100644 --- a/src/mailman/languages/manager.py +++ b/src/mailman/languages/manager.py @@ -40,7 +40,7 @@ class LanguageManager: # Mapping from 2-letter code to Language instance. self._languages = {} - def add_language(self, code, charset, description): + def add(self, code, charset, description): """See `ILanguageManager`.""" if code in self._languages: raise ValueError('Language code already registered: ' + code) diff --git a/src/mailman/mta/smtp_direct.py b/src/mailman/mta/smtp_direct.py index 64694cfc5..d45bf15d6 100644 --- a/src/mailman/mta/smtp_direct.py +++ b/src/mailman/mta/smtp_direct.py @@ -45,7 +45,7 @@ from email.Header import Header from email.Utils import formataddr from zope.interface import implements -from mailman import Utils +from mailman.Utils import ParseEmail from mailman.config import config from mailman.core import errors from mailman.i18n import _ @@ -304,8 +304,8 @@ def verpdeliver(mlist, msg, msgdata, envsender, failures, conn): handler.process(mlist, msgcopy, msgdata) # Calculate the envelope sender, which we may be VERPing if msgdata.get('verp'): - bmailbox, bdomain = Utils.ParseEmail(envsender) - rmailbox, rdomain = Utils.ParseEmail(recip) + bmailbox, bdomain = ParseEmail(envsender) + rmailbox, rdomain = ParseEmail(recip) if rdomain is None: # The recipient address is not fully-qualified. We can't # deliver it to this person, nor can we craft a valid verp @@ -330,7 +330,7 @@ def verpdeliver(mlist, msg, msgdata, envsender, failures, conn): # characters for which we can do nothing about. Once we have # the name as Unicode, we can create a Header instance for it # so that it's properly encoded for email transport. - charset = Utils.GetCharSet(mlist.getMemberLanguage(recip)) + charset = mlist.getMemberLanguage(recip).charset if charset == 'us-ascii': # Since Header already tries both us-ascii and utf-8, # let's add something a bit more useful. diff --git a/src/mailman/pipeline/acknowledge.py b/src/mailman/pipeline/acknowledge.py index 2ee27a5ae..5daf30003 100644 --- a/src/mailman/pipeline/acknowledge.py +++ b/src/mailman/pipeline/acknowledge.py @@ -31,6 +31,7 @@ __all__ = [ from zope.interface import implements from mailman import Utils +from mailman.config import config from mailman.email.message import Message, UserNotification from mailman.i18n import _ from mailman.interfaces.handler import IHandler @@ -60,21 +61,23 @@ class Acknowledge: original_subject = msgdata.get( 'origsubj', msg.get('subject', _('(no subject)'))) # Get the user's preferred language. - lang = msgdata.get('lang', member.preferred_language) + language = (config.languages[msgdata['lang']] + if 'lang' in msgdata + else member.preferred_language) + charset = config.languages[language.code].charset # Now get the acknowledgement template. realname = mlist.real_name text = Utils.maketext( 'postack.txt', - {'subject' : Utils.oneline(original_subject, - Utils.GetCharSet(lang)), + {'subject' : Utils.oneline(original_subject, charset), 'listname' : realname, 'listinfo_url': mlist.script_url('listinfo'), 'optionsurl' : member.options_url, - }, lang=lang, mlist=mlist, raw=True) + }, lang=language.code, mlist=mlist, raw=True) # Craft the outgoing message, with all headers and attributes # necessary for general delivery. Then enqueue it to the outgoing # queue. subject = _('$realname post acknowledgment') usermsg = UserNotification(sender, mlist.bounces_address, - subject, text, lang) + subject, text, language) usermsg.send(mlist) diff --git a/src/mailman/pipeline/cook_headers.py b/src/mailman/pipeline/cook_headers.py index 7da413cd2..4d3e12eb1 100644 --- a/src/mailman/pipeline/cook_headers.py +++ b/src/mailman/pipeline/cook_headers.py @@ -32,7 +32,6 @@ from email.header import Header, decode_header, make_header from email.utils import parseaddr, formataddr, getaddresses from zope.interface import implements -from mailman import Utils from mailman.config import config from mailman.i18n import _ from mailman.interfaces.handler import IHandler @@ -53,7 +52,7 @@ def uheader(mlist, s, header_name=None, continuation_ws='\t', maxlinelen=None): # non-ascii character is in the string. If there is and the charset is # us-ascii then we use iso-8859-1 instead. If the string is ascii only # we use 'us-ascii' if another charset is specified. - charset = Utils.GetCharSet(mlist.preferred_language) + charset = mlist.preferred_language.charset if nonascii.search(s): # use list charset but ... if charset == 'us-ascii': @@ -181,7 +180,7 @@ def process(mlist, msg, msgdata): return # This will act like an email address for purposes of formataddr() listid = '{0}.{1}'.format(mlist.list_name, mlist.host_name) - cset = Utils.GetCharSet(mlist.preferred_language) + cset = mlist.preferred_language.charset if mlist.description: # Don't wrap the header since here we just want to get it properly RFC # 2047 encoded. @@ -288,7 +287,7 @@ def prefix_subject(mlist, msg, msgdata): # subject: [subject prefix] if subject.strip() == '': subject = _('(no subject)') - cset = Utils.GetCharSet(mlist.preferred_language) + cset = mlist.preferred_language.charset # and substitute %d in prefix with post_id try: prefix = prefix % mlist.post_id @@ -312,9 +311,8 @@ def prefix_subject(mlist, msg, msgdata): def ch_oneline(headerstr): - # Decode header string in one line and convert into single charset - # copied and modified from ToDigest.py and Utils.py - # return (string, cset) tuple as check for failure + # Decode header string in one line and convert into single charset. + # Return (string, cset) tuple as check for failure. try: d = decode_header(headerstr) # At this point, we should rstrip() every string because some diff --git a/src/mailman/pipeline/decorate.py b/src/mailman/pipeline/decorate.py index 87313446d..3941c6509 100644 --- a/src/mailman/pipeline/decorate.py +++ b/src/mailman/pipeline/decorate.py @@ -31,7 +31,6 @@ import logging from email.MIMEText import MIMEText from zope.interface import implements -from mailman import Utils from mailman.config import config from mailman.email.message import Message from mailman.i18n import _ @@ -91,7 +90,7 @@ def process(mlist, msg, msgdata): # TK: Message with 'charset=' cause trouble. So, instead of # mgs.get_content_charset('us-ascii') ... mcset = msg.get_content_charset() or 'us-ascii' - lcset = Utils.GetCharSet(mlist.preferred_language) + lcset = mlist.preferred_language.charset msgtype = msg.get_content_type() # BAW: If the charsets don't match, should we add the header and footer by # MIME multipart chroming the message? diff --git a/src/mailman/pipeline/docs/replybot.txt b/src/mailman/pipeline/docs/replybot.txt index f3c3281b3..3de6679dd 100644 --- a/src/mailman/pipeline/docs/replybot.txt +++ b/src/mailman/pipeline/docs/replybot.txt @@ -6,8 +6,7 @@ it receives on its posting address, or special robot addresses. Automatic responses are subject to various conditions, such as headers in the original message or the amount of time since the last auto-response. - >>> from mailman.pipeline.replybot import process - >>> mlist = config.db.list_manager.create(u'_xtest@example.com') + >>> mlist = create_list(u'_xtest@example.com') >>> mlist.real_name = u'XTest' >>> # Ensure that the virgin queue is empty, since we'll be checking this @@ -36,6 +35,8 @@ will be sent, with 0 meaning "there is no grace period". ... ... help ... """) + + >>> from mailman.pipeline.replybot import process >>> process(mlist, msg, dict(toowner=True)) >>> len(virginq.files) 1 diff --git a/src/mailman/pipeline/moderate.py b/src/mailman/pipeline/moderate.py index 8d6fc7d65..3714f3bfc 100644 --- a/src/mailman/pipeline/moderate.py +++ b/src/mailman/pipeline/moderate.py @@ -30,10 +30,10 @@ import re from email.MIMEMessage import MIMEMessage from email.MIMEText import MIMEText -from mailman import Utils +from mailman.Utils import wrap from mailman.config import config from mailman.core import errors -from mailman.email.message import Message +from mailman.email.message import UserNotification from mailman.i18n import _ @@ -156,17 +156,16 @@ error, contact the mailing list owner at %(listowner)s.""")) def do_discard(mlist, msg): # Do we forward auto-discards to the list owners? if mlist.forward_auto_discards: - lang = mlist.preferred_language varhelp = '%s/?VARHELP=privacy/sender/discard_these_nonmembers' % \ mlist.GetScriptURL('admin', absolute=1) - nmsg = Message.UserNotification(mlist.GetOwnerEmail(), - mlist.GetBouncesEmail(), - _('Auto-discard notification'), - lang=lang) + nmsg = UserNotification(mlist.GetOwnerEmail(), + mlist.GetBouncesEmail(), + _('Auto-discard notification'), + lang=mlist.preferred_language) nmsg.set_type('multipart/mixed') text = MIMEText(Utils.wrap(_( 'The attached message has been automatically discarded.')), - _charset=Utils.GetCharSet(lang)) + _charset=mlist.preferred_language.charset) nmsg.attach(text) nmsg.attach(MIMEMessage(msg)) nmsg.send(mlist) diff --git a/src/mailman/pipeline/scrubber.py b/src/mailman/pipeline/scrubber.py index 3ee68612f..1148c6518 100644 --- a/src/mailman/pipeline/scrubber.py +++ b/src/mailman/pipeline/scrubber.py @@ -42,7 +42,7 @@ from mimetypes import guess_all_extensions from string import Template from zope.interface import implements -from mailman import Utils +from mailman.Utils import oneline, websafe from mailman.config import config from mailman.core.errors import DiscardMessage from mailman.core.plugins import get_plugin @@ -175,7 +175,7 @@ def process(mlist, msg, msgdata=None): return dir = calculate_attachments_dir(mlist, msg, msgdata) charset = format = delsp = None - lcset = Utils.GetCharSet(mlist.preferred_language) + lcset = mlist.preferred_language.charset lcset_out = Charset(lcset).output_charset or lcset # Now walk over all subparts of this message and scrub out various types for part in msg.walk(): @@ -206,7 +206,7 @@ def process(mlist, msg, msgdata=None): not part.get_content_charset(): url = save_attachment(mlist, part, dir) filename = part.get_filename(_('not available')) - filename = Utils.oneline(filename, lcset) + filename = oneline(filename, lcset) replace_payload_by_text(part, _("""\ An embedded and charset-unspecified text was scrubbed... Name: $filename @@ -236,7 +236,7 @@ URL: $url else: # HTML-escape it and store it as an attachment, but make it # look a /little/ bit prettier. :( - payload = Utils.websafe(part.get_payload(decode=True)) + payload = websafe(part.get_payload(decode=True)) # For whitespace in the margin, change spaces into # non-breaking spaces, and tabs into 8 of those. Then use a # mono-space font. Still looks hideous to me, but then I'd @@ -287,9 +287,9 @@ URL: $url size = len(payload) url = save_attachment(mlist, part, dir) desc = part.get('content-description', _('not available')) - desc = Utils.oneline(desc, lcset) + desc = oneline(desc, lcset) filename = part.get_filename(_('not available')) - filename = Utils.oneline(filename, lcset) + filename = oneline(filename, lcset) replace_payload_by_text(part, _("""\ A non-text attachment was scrubbed... Name: $filename @@ -390,8 +390,8 @@ def save_attachment(mlist, msg, dir, filter_html=True): # things as application/octet-streams since that seems the safest. ctype = msg.get_content_type() # i18n file name is encoded - lcset = Utils.GetCharSet(mlist.preferred_language) - filename = Utils.oneline(msg.get_filename(''), lcset) + lcset = mlist.preferred_language.charset + filename = oneline(msg.get_filename(''), lcset) filename, fnext = os.path.splitext(filename) # For safety, we should confirm this is valid ext for content-type # but we can use fnext if we introduce fnext filtering @@ -481,7 +481,7 @@ def save_attachment(mlist, msg, dir, filter_html=True): elif ctype == 'message/rfc822': submsg = msg.get_payload() # BAW: I'm sure we can eventually do better than this. :( - decodedpayload = Utils.websafe(str(submsg)) + decodedpayload = websafe(str(submsg)) fp = open(path, 'w') fp.write(decodedpayload) fp.close() diff --git a/src/mailman/queue/__init__.py b/src/mailman/queue/__init__.py index 1f284ba4d..b7c6eb1a5 100644 --- a/src/mailman/queue/__init__.py +++ b/src/mailman/queue/__init__.py @@ -434,8 +434,8 @@ class Runner: else mlist.preferred_language) else: language = mlist.preferred_language - with i18n.using_language(language): - msgdata['lang'] = language + with i18n.using_language(language.code): + msgdata['lang'] = language.code keepqueued = self._dispose(mlist, msg, msgdata) if keepqueued: self.switchboard.enqueue(msg, msgdata) diff --git a/src/mailman/queue/command.py b/src/mailman/queue/command.py index 8a7793e9e..d32361cf9 100644 --- a/src/mailman/queue/command.py +++ b/src/mailman/queue/command.py @@ -195,9 +195,10 @@ 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']] reply = UserNotification(msg.sender, mlist.bounces_address, _('The results of your email commands'), - lang=msgdata['lang']) + lang=language) # Find a charset for the response body. Try ascii first, then # latin-1 and finally falling back to utf-8. reply_body = unicode(results) diff --git a/src/mailman/queue/digest.py b/src/mailman/queue/digest.py index e066be993..a590a9997 100644 --- a/src/mailman/queue/digest.py +++ b/src/mailman/queue/digest.py @@ -39,7 +39,7 @@ from email.mime.text import MIMEText from email.utils import formatdate, getaddresses, make_msgid from mailman import i18n -from mailman.Utils import GetCharSet, maketext, oneline, wrap +from mailman.Utils import maketext, oneline, wrap from mailman.config import config from mailman.core.errors import DiscardMessage from mailman.i18n import _ @@ -55,7 +55,7 @@ class Digester: def __init__(self, mlist, volume, digest_number): self._mlist = mlist - self._charset = GetCharSet(mlist.preferred_language) + self._charset = mlist.preferred_language.charset # This will be used in the Subject, so use $-strings. realname = mlist.real_name issue = digest_number @@ -298,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)) as ( - mailbox, language): + i18n.using_language(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/styles/default.py b/src/mailman/styles/default.py index 0f7869a75..ea4e1a342 100644 --- a/src/mailman/styles/default.py +++ b/src/mailman/styles/default.py @@ -30,7 +30,7 @@ import datetime from zope.interface import implements -from mailman import Utils +from mailman.config import config from mailman.i18n import _ from mailman.interfaces import Action, NewsModeration from mailman.interfaces.mailinglist import ( @@ -157,8 +157,8 @@ $fqdn_listname ${listinfo_page} """ # Set this to Never if the list's preferred language uses us-ascii, - # otherwise set it to As Needed - if Utils.GetCharSet(mlist.preferred_language) == 'us-ascii': + # otherwise set it to As Needed. + if mlist.preferred_language.charset == 'us-ascii': mlist.encode_ascii_prefixes = 0 else: mlist.encode_ascii_prefixes = 2 |
