diff options
| author | Barry Warsaw | 2011-03-16 15:14:48 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2011-03-16 15:14:48 -0400 |
| commit | e2e7e4a3e43a1a7fcf9f909f0d0aaaeedf27f3fa (patch) | |
| tree | d1fc27c3f95826c88edad4ae18b482b5d13377d2 | |
| parent | 8f51ea23f187707f92e4ed689ef5ccb0fe292427 (diff) | |
| download | mailman-e2e7e4a3e43a1a7fcf9f909f0d0aaaeedf27f3fa.tar.gz mailman-e2e7e4a3e43a1a7fcf9f909f0d0aaaeedf27f3fa.tar.zst mailman-e2e7e4a3e43a1a7fcf9f909f0d0aaaeedf27f3fa.zip | |
| -rw-r--r-- | src/mailman/Archiver/Archiver.py | 12 | ||||
| -rw-r--r-- | src/mailman/Archiver/HyperArch.py | 5 | ||||
| -rw-r--r-- | src/mailman/Utils.py | 128 | ||||
| -rw-r--r-- | src/mailman/app/membership.py | 12 | ||||
| -rw-r--r-- | src/mailman/app/moderator.py | 40 | ||||
| -rw-r--r-- | src/mailman/app/notifications.py | 36 | ||||
| -rw-r--r-- | src/mailman/chains/hold.py | 33 | ||||
| -rw-r--r-- | src/mailman/commands/cli_lists.py | 4 | ||||
| -rw-r--r-- | src/mailman/commands/docs/info.txt | 1 | ||||
| -rw-r--r-- | src/mailman/pipeline/acknowledge.py | 18 | ||||
| -rw-r--r-- | src/mailman/queue/digest.py | 20 | ||||
| -rw-r--r-- | src/mailman/utilities/i18n.py | 10 | ||||
| -rw-r--r-- | src/mailman/utilities/tests/test_templates.py | 3 |
13 files changed, 100 insertions, 222 deletions
diff --git a/src/mailman/Archiver/Archiver.py b/src/mailman/Archiver/Archiver.py index f8d1baa46..fe1dec252 100644 --- a/src/mailman/Archiver/Archiver.py +++ b/src/mailman/Archiver/Archiver.py @@ -32,9 +32,9 @@ from cStringIO import StringIO from string import Template from zope.component import getUtility -from mailman import Utils from mailman.config import config from mailman.interfaces.domain import IDomainManager +from mailman.utilities.i18n import make log = logging.getLogger('mailman.error') @@ -111,11 +111,11 @@ class Archiver: fp = open(indexfile, 'w') finally: os.umask(omask) - fp.write(Utils.maketext( - 'emptyarchive.html', - {'listname': self.real_name, - 'listinfo': self.GetScriptURL('listinfo'), - }, mlist=self)) + fp.write(make('emptyarchive.html', + mailing_list=self, + listname=self.real_name, + listinfo=self.GetScriptURL('listinfo'), + )) if fp: fp.close() finally: diff --git a/src/mailman/Archiver/HyperArch.py b/src/mailman/Archiver/HyperArch.py index 218c46875..92b9de2f0 100644 --- a/src/mailman/Archiver/HyperArch.py +++ b/src/mailman/Archiver/HyperArch.py @@ -50,6 +50,7 @@ from mailman.Archiver import pipermail from mailman.config import config from mailman.core.i18n import _, ctime from mailman.interfaces.listmanager import IListManager +from mailman.utilities.i18n import find from mailman.utilities.string import uncanonstr, websafe @@ -183,8 +184,8 @@ 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.code, - raw=True, mlist=mlist) + template, filepath = find(templatefile, mailing_list=mlist, + language=lang.code) _templatefilepathcache[cachekey] = filepath _templatecache[filepath] = template # Copied from Utils.maketext() diff --git a/src/mailman/Utils.py b/src/mailman/Utils.py index a26025fa3..cfd61eb7a 100644 --- a/src/mailman/Utils.py +++ b/src/mailman/Utils.py @@ -31,20 +31,13 @@ __all__ = [ import os import re -import errno import logging # pylint: disable-msg=E0611,W0403 from string import ascii_letters, digits, whitespace -from zope.component import getUtility import mailman.templates -from mailman.config import config -from mailman.core.i18n import _ -from mailman.interfaces.languages import ILanguageManager -from mailman.utilities.string import expand - AT = '@' CR = '\r' @@ -139,124 +132,3 @@ def wrap(text, column=70, honor_leading_ws=True): # end for text in lines # the last two newlines are bogus return wrapped[:-2] - - - -class OuterExit(Exception): - pass - -def findtext(templatefile, raw_dict=None, raw=False, lang=None, mlist=None): - # Make some text from a template file. The order of searches depends on - # whether mlist and lang are provided. Once the templatefile is found, - # string substitution is performed by interpolation in `dict'. If `raw' - # is false, the resulting text is wrapped/filled by calling wrap(). - # - # When looking for a template in a specific language, there are 4 places - # that are searched, in this order: - # - # 1. the list-specific language directory - # lists/<listname>/<language> - # - # 2. the domain-specific language directory - # templates/<list.host_name>/<language> - # - # 3. the site-wide language directory - # templates/site/<language> - # - # 4. the global default language directory - # templates/<language> - # - # The first match found stops the search. In this way, you can specialize - # templates at the desired level, or, if you use only the default - # templates, you don't need to change anything. You should never modify - # files in the templates/<language> subdirectory, since Mailman will - # overwrite these when you upgrade. That's what the templates/site - # language directories are for. - # - # A further complication is that the language to search for is determined - # by both the `lang' and `mlist' arguments. The search order there is - # that if lang is given, then the 4 locations above are searched, - # substituting lang for <language>. If no match is found, and mlist is - # given, then the 4 locations are searched using the list's preferred - # language. After that, the server default language is used for - # <language>. If that still doesn't yield a template, then the standard - # distribution's English language template is used as an ultimate - # fallback, and when lang is not 'en', the resulting template is passed - # through the translation service. If this template is missing you've got - # big problems. ;) - # - # A word on backwards compatibility: Mailman versions prior to 2.1 stored - # templates in templates/*.{html,txt} and lists/<listname>/*.{html,txt}. - # Those directories are no longer searched so if you've got customizations - # in those files, you should move them to the appropriate directory based - # on the above description. Mailman's upgrade script cannot do this for - # you. - # - # The function has been revised and renamed as it now returns both the - # template text and the path from which it retrieved the template. The - # original function is now a wrapper which just returns the template text - # as before, by calling this renamed function and discarding the second - # item returned. - # - # Calculate the languages to scan - languages = set() - if lang is not None: - languages.add(lang) - if mlist is not None: - 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 - searchdirs = [] - if mlist is not None: - searchdirs.append(mlist.data_path) - searchdirs.append(os.path.join(config.TEMPLATE_DIR, mlist.host_name)) - searchdirs.append(os.path.join(config.TEMPLATE_DIR, 'site')) - searchdirs.append(config.TEMPLATE_DIR) - # Start scanning - fp = None - try: - for lang in languages: - for dir in searchdirs: - filename = os.path.join(dir, lang, templatefile) - try: - fp = open(filename) - raise OuterExit - except IOError, e: - if e.errno != errno.ENOENT: - raise - # Okay, it doesn't exist, keep looping - fp = None - except OuterExit: - pass - if fp is None: - # Try one last time with the distro English template, which, unless - # you've got a really broken installation, must be there. - try: - filename = os.path.join(TEMPLATE_DIR, 'en', templatefile) - fp = open(filename) - except IOError, e: - if e.errno != errno.ENOENT: - raise - # We never found the template. BAD! - raise IOError(errno.ENOENT, 'No template file found', templatefile) - else: - # XXX BROKEN HACK - data = fp.read()[:-1] - template = _(data) - fp.close() - else: - template = fp.read() - fp.close() - charset = getUtility(ILanguageManager)[lang].charset - template = unicode(template, charset, 'replace') - text = template - if raw_dict is not None: - text = expand(template, raw_dict) - if raw: - return text, filename - return wrap(text), filename - - -def maketext(templatefile, dict=None, raw=False, lang=None, mlist=None): - return findtext(templatefile, dict, raw, lang, mlist)[0] diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py index 8723fd781..fcbedc2f5 100644 --- a/src/mailman/app/membership.py +++ b/src/mailman/app/membership.py @@ -29,7 +29,6 @@ __all__ = [ from email.utils import formataddr from zope.component import getUtility -from mailman import Utils from mailman.app.notifications import send_goodbye_message from mailman.core.i18n import _ from mailman.email.message import OwnerNotification @@ -39,6 +38,7 @@ from mailman.interfaces.member import ( AlreadySubscribedError, MemberRole, MembershipIsBannedError, NotAMemberError) from mailman.interfaces.usermanager import IUserManager +from mailman.utilities.i18n import make @@ -149,10 +149,10 @@ def delete_member(mlist, address, admin_notif=None, userack=None): user = getUtility(IUserManager).get_user(address) realname = user.real_name subject = _('$mlist.real_name unsubscription notification') - text = Utils.maketext( - 'adminunsubscribeack.txt', - {'listname': mlist.real_name, - 'member' : formataddr((realname, address)), - }, mlist=mlist) + text = make('adminunsubscribeack.txt', + mailing_list=mlist, + listname=mlist.real_name, + member=formataddr((realname, address)), + ) msg = OwnerNotification(mlist, subject, text) msg.send(mlist) diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py index cdfedd44b..50a03c833 100644 --- a/src/mailman/app/moderator.py +++ b/src/mailman/app/moderator.py @@ -48,6 +48,7 @@ from mailman.interfaces.member import ( AlreadySubscribedError, DeliveryMode, NotAMemberError) from mailman.interfaces.messages import IMessageStore from mailman.interfaces.requests import IRequests, RequestType +from mailman.utilities.i18n import make NL = '\n' @@ -209,12 +210,12 @@ def hold_subscription(mlist, address, realname, password, mode, language): if mlist.admin_immed_notify: subject = _( 'New subscription request to list $mlist.real_name from $address') - text = Utils.maketext( - 'subauth.txt', - {'username' : address, - 'listname' : mlist.fqdn_listname, - 'admindb_url': mlist.script_url('admindb'), - }, mlist=mlist) + text = make('subauth.txt', + mailing_list=mlist, + username=address, + listname=mlist.fqdn_listname, + admindb_url=mlist.script_url('admindb'), + ) # This message should appear to come from the <list>-owner so as # to avoid any useless bounce processing. msg = UserNotification( @@ -281,12 +282,12 @@ def hold_unsubscription(mlist, address): if mlist.admin_immed_notify: subject = _( 'New unsubscription request from $mlist.real_name by $address') - text = Utils.maketext( - 'unsubauth.txt', - {'address' : address, - 'listname' : mlist.fqdn_listname, - 'admindb_url': mlist.script_url('admindb'), - }, mlist=mlist) + text = make('unsubauth.txt', + mailing_list=mlist, + address=address, + listname=mlist.fqdn_listname, + admindb_url=mlist.script_url('admindb'), + ) # This message should appear to come from the <list>-owner so as # to avoid any useless bounce processing. msg = UserNotification( @@ -336,13 +337,14 @@ def _refuse(mlist, request, recip, comment, origmsg=None, lang=None): lang = (mlist.preferred_language if member is None else member.preferred_language) - text = Utils.maketext( - 'refuse.txt', - {'listname' : mlist.fqdn_listname, - 'request' : request, - 'reason' : comment, - 'adminaddr': mlist.owner_address, - }, lang=lang.code, mlist=mlist) + text = make('refuse.txt', + mailing_list=mlist, + language=lang.code, + listname=mlist.fqdn_listname, + request=request, + reason=comment, + adminaddr=mlist.owner_address, + ) with _.using(lang.code): # add in original message, but not wrap/filled if origmsg: diff --git a/src/mailman/app/notifications.py b/src/mailman/app/notifications.py index 985f4eece..d7e64a020 100644 --- a/src/mailman/app/notifications.py +++ b/src/mailman/app/notifications.py @@ -30,11 +30,12 @@ __all__ = [ from email.utils import formataddr from lazr.config import as_boolean -from mailman import Utils +from mailman.Utils import wrap from mailman.config import config from mailman.core.i18n import _ from mailman.email.message import OwnerNotification, UserNotification from mailman.interfaces.member import DeliveryMode +from mailman.utilities.i18n import make @@ -54,7 +55,7 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''): :type delivery_mode: DeliveryMode """ if mlist.welcome_msg: - welcome = Utils.wrap(mlist.welcome_msg) + '\n' + welcome = wrap(mlist.welcome_msg) + '\n' else: welcome = '' # Find the IMember object which is subscribed to the mailing list, because @@ -62,15 +63,16 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''): member = mlist.members.get_member(address) options_url = member.options_url # Get the text from the template. - text += Utils.maketext( - 'subscribeack.txt', { - 'real_name' : mlist.real_name, - 'posting_address' : mlist.fqdn_listname, - 'listinfo_url' : mlist.script_url('listinfo'), - 'optionsurl' : options_url, - 'request_address' : mlist.request_address, - 'welcome' : welcome, - }, lang=language.code, mlist=mlist) + text += make('subscribeack.txt', + mailing_list=mlist, + language=language.code, + real_name=mlist.real_name, + posting_address=mlist.fqdn_listname, + listinfo_url=mlist.script_url('listinfo'), + optionsurl=options_url, + request_address=mlist.request_address, + welcome=welcome, + ) if delivery_mode is not DeliveryMode.regular: digmode = _(' (Digest mode)') else: @@ -98,7 +100,7 @@ def send_goodbye_message(mlist, address, language): :type language: string """ if mlist.goodbye_msg: - goodbye = Utils.wrap(mlist.goodbye_msg) + '\n' + goodbye = wrap(mlist.goodbye_msg) + '\n' else: goodbye = '' msg = UserNotification( @@ -124,10 +126,10 @@ def send_admin_subscription_notice(mlist, address, full_name, language): with _.using(mlist.preferred_language.code): subject = _('$mlist.real_name subscription notification') full_name = full_name.encode(language.charset, 'replace') - text = Utils.maketext( - 'adminsubscribeack.txt', - {'listname' : mlist.real_name, - 'member' : formataddr((full_name, address)), - }, mlist=mlist) + text = make('adminsubscribeack.txt', + mailing_list=mlist, + listname=mlist.real_name, + member=formataddr((full_name, address)), + ) msg = OwnerNotification(mlist, subject, text) msg.send(mlist) diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py index ff53621ab..fcd11ca72 100644 --- a/src/mailman/chains/hold.py +++ b/src/mailman/chains/hold.py @@ -35,7 +35,7 @@ from zope.component import getUtility from zope.event import notify from zope.interface import implements -from mailman.Utils import maketext, wrap +from mailman.Utils import wrap from mailman.app.moderator import hold_message from mailman.app.replybot import can_acknowledge from mailman.chains.base import ChainNotification, TerminalChainBase @@ -46,6 +46,7 @@ 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 +from mailman.utilities.i18n import make from mailman.utilities.string import oneline @@ -103,14 +104,13 @@ def autorespond_to_sender(mlist, sender, lang=None): log.info('hold autoresponse limit hit: %s', sender) response_set.response_sent(address, Response.hold) # Send this notification message instead. - text = maketext( - 'nomoretoday.txt', - {'sender' : sender, - 'listname': mlist.fqdn_listname, - 'num' : todays_count, - 'owneremail': mlist.owner_address, - }, - lang=lang) + text = make('nomoretoday.txt', + language=lang, + sender=sender, + listname=mlist.fqdn_listname, + num=todays_count, + owneremail=mlist.owner_address, + ) with _.using(lang.code): msg = UserNotification( sender, mlist.owner_address, @@ -194,8 +194,10 @@ class HoldChain(TerminalChainBase): subject = _( 'Your message to $mlist.fqdn_listname awaits moderator approval') send_language_code = msgdata.get('lang', language.code) - text = maketext('postheld.txt', substitutions, - lang=send_language_code, mlist=mlist) + text = make('postheld.txt', + mailing_list=mlist, + language=send_language_code, + **substitutions) adminaddr = mlist.bounces_address nmsg = UserNotification( msg.sender, adminaddr, subject, text, @@ -222,10 +224,11 @@ class HoldChain(TerminalChainBase): mlist.owner_address, subject, lang=language) nmsg.set_type('multipart/mixed') - text = MIMEText( - maketext('postauth.txt', substitutions, - raw=True, mlist=mlist), - _charset=charset) + text = MIMEText(make('postauth.txt', + mailing_list=mlist, + wrap=False, + **substitutions), + _charset=charset) dmsg = MIMEText(wrap(_("""\ If you reply to this message, keeping the Subject: header intact, Mailman will discard the held message. Do this if the message is spam. If you reply to diff --git a/src/mailman/commands/cli_lists.py b/src/mailman/commands/cli_lists.py index a127dd816..021ce5991 100644 --- a/src/mailman/commands/cli_lists.py +++ b/src/mailman/commands/cli_lists.py @@ -30,7 +30,6 @@ __all__ = [ from zope.component import getUtility from zope.interface import implements -from mailman.Utils import maketext from mailman.app.lifecycle import create_list, remove_list from mailman.config import config from mailman.core.constants import system_preferences @@ -42,6 +41,7 @@ from mailman.interfaces.domain import ( BadDomainSpecificationError, IDomainManager) from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.listmanager import IListManager, ListAlreadyExistsError +from mailman.utilities.i18n import make @@ -213,7 +213,7 @@ class Create: requestaddr = mlist.request_address, siteowner = mlist.no_reply_address, ) - text = maketext('newlist.txt', d, mlist=mlist) + text = make('newlist.txt', mailing_list=mlist, **d) # 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. diff --git a/src/mailman/commands/docs/info.txt b/src/mailman/commands/docs/info.txt index bccb78fda..12fce3223 100644 --- a/src/mailman/commands/docs/info.txt +++ b/src/mailman/commands/docs/info.txt @@ -74,6 +74,7 @@ The File System Hierarchy layout is the same every by definition. PUBLIC_ARCHIVE_FILE_DIR = /var/lib/mailman/archives/public QUEUE_DIR = /var/spool/mailman SITE_PW_FILE = /var/lib/mailman/data/adm.pw + TEMPLATE_DIR = .../mailman/templates VAR_DIR = /var/lib/mailman diff --git a/src/mailman/pipeline/acknowledge.py b/src/mailman/pipeline/acknowledge.py index fcde6d6a5..e5b49ffa0 100644 --- a/src/mailman/pipeline/acknowledge.py +++ b/src/mailman/pipeline/acknowledge.py @@ -31,11 +31,11 @@ __all__ = [ from zope.component import getUtility from zope.interface import implements -from mailman import Utils from mailman.core.i18n import _ from mailman.email.message import UserNotification from mailman.interfaces.handler import IHandler from mailman.interfaces.languages import ILanguageManager +from mailman.utilities.i18n import make from mailman.utilities.string import oneline @@ -71,13 +71,15 @@ class Acknowledge: charset = language_manager[language.code].charset # Now get the acknowledgement template. realname = mlist.real_name - text = Utils.maketext( - 'postack.txt', - {'subject' : oneline(original_subject, charset), - 'listname' : realname, - 'listinfo_url': mlist.script_url('listinfo'), - 'optionsurl' : member.options_url, - }, lang=language.code, mlist=mlist, raw=True) + text = make('postack.txt', + mailing_list=mlist, + language=language.code, + wrap=False, + subject=oneline(original_subject, charset), + listname=realname, + listinfo_url=mlist.script_url('listinfo'), + optionsurl=member.options_url, + ) # Craft the outgoing message, with all headers and attributes # necessary for general delivery. Then enqueue it to the outgoing # queue. diff --git a/src/mailman/queue/digest.py b/src/mailman/queue/digest.py index a2feff448..2541e14ed 100644 --- a/src/mailman/queue/digest.py +++ b/src/mailman/queue/digest.py @@ -38,7 +38,7 @@ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import formatdate, getaddresses, make_msgid -from mailman.Utils import maketext, wrap +from mailman.Utils import wrap from mailman.config import config from mailman.core.errors import DiscardMessage from mailman.core.i18n import _ @@ -46,6 +46,7 @@ from mailman.interfaces.member import DeliveryMode, DeliveryStatus from mailman.pipeline.decorate import decorate from mailman.pipeline.scrubber import process as scrubber from mailman.queue import Runner +from mailman.utilities.i18n import make from mailman.utilities.mailbox import Mailbox from mailman.utilities.string import oneline @@ -76,15 +77,14 @@ class Digester: # digest header are separate MIME subobjects. In either case, it's # the first thing in the digest, and we can calculate it now, so go # ahead and add it now. - self._masthead = maketext( - 'masthead.txt', dict( - real_name=mlist.real_name, - got_list_email=mlist.posting_address, - got_listinfo_url=mlist.script_url('listinfo'), - got_request_email=mlist.request_address, - got_owner_email=mlist.owner_address, - ), - mlist=mlist) + self._masthead = make('masthead.txt', + mailing_list=mlist, + real_name=mlist.real_name, + got_list_email=mlist.posting_address, + got_listinfo_url=mlist.script_url('listinfo'), + got_request_email=mlist.request_address, + got_owner_email=mlist.owner_address, + ) # Set things up for the table of contents. self._header = decorate(mlist, mlist.digest_header) self._toc = StringIO() diff --git a/src/mailman/utilities/i18n.py b/src/mailman/utilities/i18n.py index bb826e853..f84baa7c6 100644 --- a/src/mailman/utilities/i18n.py +++ b/src/mailman/utilities/i18n.py @@ -35,6 +35,7 @@ from zope.component import getUtility from mailman.config import config from mailman.core.constants import system_preferences +from mailman.core.i18n import _ from mailman.interfaces.languages import ILanguageManager from mailman.utilities.string import expand @@ -184,14 +185,11 @@ def make(template_file, mailing_list=None, language=None, wrap=True, **kw): """ path, fp = find(template_file, mailing_list, language) try: - raw_text = fp.read() + # XXX BROKEN HACK + template = _(fp.read()[:-1]) finally: fp.close() - # The language is always the second to last path component. - parts = path.split(os.sep) - language_code = parts[-2] - charset = getUtility(ILanguageManager)[language_code].charset - template = unicode(raw_text, charset, 'replace') + assert isinstance(template, unicode), 'Translated template is not unicode' text = expand(template, kw) if wrap: return wrap_text(text) diff --git a/src/mailman/utilities/tests/test_templates.py b/src/mailman/utilities/tests/test_templates.py index b95b181f7..2de43ae3c 100644 --- a/src/mailman/utilities/tests/test_templates.py +++ b/src/mailman/utilities/tests/test_templates.py @@ -260,7 +260,6 @@ It will not be wrapped. self.assertEqual(make('nosub.txt', self.mlist), """\ This is a global template. It has no substitutions. It will be wrapped. - """) def test_substitutions(self): @@ -269,7 +268,6 @@ wrapped. howmany='a few'), """\ This is a very nice template. It has a few substitutions. It will be wrapped. - """) def test_substitutions_no_wrap(self): @@ -279,7 +277,6 @@ wrapped. This is a very nice template. It has a few substitutions. It will not be wrapped. - """) |
