summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2007-09-19 07:28:58 -0400
committerBarry Warsaw2007-09-19 07:28:58 -0400
commit4c517789fa8b29d2a23791e6f390d9f1173c3125 (patch)
tree9b5c1ed27416cbec12665a1cea5206336d72c039
parent39c87b16da60a5274bfc7494d0a121b3162b56fb (diff)
downloadmailman-4c517789fa8b29d2a23791e6f390d9f1173c3125.tar.gz
mailman-4c517789fa8b29d2a23791e6f390d9f1173c3125.tar.zst
mailman-4c517789fa8b29d2a23791e6f390d9f1173c3125.zip
-rw-r--r--Mailman/Archiver/HyperArch.py55
-rw-r--r--Mailman/Cgi/subscribe.py8
-rw-r--r--Mailman/Deliverer.py14
-rw-r--r--Mailman/Handlers/Hold.py8
-rw-r--r--Mailman/Handlers/ToDigest.py8
-rw-r--r--Mailman/MailList.py12
-rw-r--r--Mailman/Queue/Runner.py10
-rw-r--r--Mailman/app/membership.py8
-rw-r--r--Mailman/app/moderator.py14
-rw-r--r--Mailman/bin/add_members.py9
-rw-r--r--Mailman/bin/change_pw.py8
-rw-r--r--Mailman/bin/newlist.py8
-rw-r--r--Mailman/i18n.py15
-rw-r--r--TODO.txt1
14 files changed, 64 insertions, 114 deletions
diff --git a/Mailman/Archiver/HyperArch.py b/Mailman/Archiver/HyperArch.py
index 628f5da6d..80d4ea7a4 100644
--- a/Mailman/Archiver/HyperArch.py
+++ b/Mailman/Archiver/HyperArch.py
@@ -26,6 +26,8 @@
(probably in the 'update_dirty_archives' method).
"""
+from __future__ import with_statement
+
import os
import re
import sys
@@ -114,13 +116,8 @@ def sizeof(filename, lang):
if e.errno <> errno.ENOENT: raise
return _('size not available')
if size < 1000:
- # Avoid i18n side-effects
- otrans = i18n.get_translation()
- try:
- i18n.set_language(lang)
+ with i18n.using_language(lang):
out = _(' %(size)i bytes ')
- finally:
- i18n.set_translation(otrans)
return out
elif size < 1000000:
return ' %d KB ' % (size / 1000)
@@ -269,17 +266,12 @@ 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.
- otrans = i18n.get_translation()
- try:
- i18n.set_language(lang)
+ with i18n.using_language(lang):
if self.author == self.email:
self.author = self.email = re.sub('@', _(' at '),
self.email)
else:
self.email = re.sub('@', _(' at '), self.email)
- finally:
- i18n.set_translation(otrans)
-
# Snag the content-* headers. RFC 1521 states that their values are
# case insensitive.
ctype = message.get('Content-Type', 'text/plain')
@@ -401,14 +393,10 @@ class Article(pipermail.Article):
self.decoded['email'] = email
if subject:
if config.ARCHIVER_OBSCURES_EMAILADDRS:
- otrans = i18n.get_translation()
- try:
- i18n.set_language(self._lang)
+ with i18n.using_language(self._lang):
atmark = unicode(_(' at '), Utils.GetCharSet(self._lang))
subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
'\g<1>' + atmark + '\g<2>', subject)
- finally:
- i18n.set_translation(otrans)
self.decoded['subject'] = subject
self.decoded['stripped'] = self.strip_subject(subject or self.subject)
@@ -443,9 +431,7 @@ class Article(pipermail.Article):
def as_html(self):
d = self.__dict__.copy()
# avoid i18n side-effects
- otrans = i18n.get_translation()
- i18n.set_language(self._lang)
- try:
+ with i18n.using_language(self._lang):
d["prev"], d["prev_wsubj"] = self._get_prev()
d["next"], d["next_wsubj"] = self._get_next()
@@ -468,9 +454,6 @@ class Article(pipermail.Article):
d['listurl'] = self._mlist.GetScriptURL('listinfo', absolute=1)
d['listname'] = self._mlist.real_name
d['encoding'] = ''
- finally:
- i18n.set_translation(otrans)
-
charset = Utils.GetCharSet(self._lang)
d["encoding"] = html_charset % charset
@@ -562,14 +545,10 @@ class Article(pipermail.Article):
if not isinstance(body, unicode):
body = unicode(body, cset, 'replace')
if config.ARCHIVER_OBSCURES_EMAILADDRS:
- otrans = i18n.get_translation()
- try:
+ with i18n.using_language(self._lang):
atmark = unicode(_(' at '), cset)
- i18n.set_language(self._lang)
body = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
'\g<1>' + atmark + '\g<2>', body)
- finally:
- i18n.set_translation(otrans)
# Return body to character set of article.
body = body.encode(cset, 'replace')
return NL.join(headers) % d + '\n\n' + body + '\n'
@@ -668,12 +647,10 @@ class HyperArchive(pipermail.T):
def html_foot(self):
# avoid i18n side-effects
mlist = self.maillist
- otrans = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
# Convenience
def quotetime(s):
return html_quote(i18n.ctime(s), self.lang)
- try:
+ with i18n.using_language(mlist.preferred_language):
d = {"lastdate": quotetime(self.lastdate),
"archivedate": quotetime(self.archivedate),
"listinfo": mlist.GetScriptURL('listinfo', absolute=1),
@@ -684,9 +661,6 @@ class HyperArchive(pipermail.T):
"author": _("author"),
"date": _("date")
}
- finally:
- i18n.set_translation(otrans)
-
for t in i.keys():
cap = t[0].upper() + t[1:]
if self.type == cap:
@@ -701,12 +675,10 @@ class HyperArchive(pipermail.T):
def html_head(self):
# avoid i18n side-effects
mlist = self.maillist
- otrans = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
# Convenience
def quotetime(s):
return html_quote(i18n.ctime(s), self.lang)
- try:
+ with i18n.using_language(mlist.preferred_language):
d = {"listname": html_quote(mlist.real_name, self.lang),
"archtype": self.type,
"archive": self.volNameToDesc(self.archive),
@@ -720,9 +692,6 @@ class HyperArchive(pipermail.T):
"author": _("author"),
"date": _("date"),
}
- finally:
- i18n.set_translation(otrans)
-
for t in i.keys():
cap = t[0].upper() + t[1:]
if self.type == cap:
@@ -750,9 +719,7 @@ class HyperArchive(pipermail.T):
'meta': '',
}
# Avoid i18n side-effects
- otrans = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
- try:
+ with i18n.using_language(mlist.preferred_language):
if not self.archives:
d["noarchive_msg"] = _(
'<P>Currently, there are no archives. </P>')
@@ -773,8 +740,6 @@ class HyperArchive(pipermail.T):
for a in self.archives:
accum.append(self.html_TOC_entry(a))
d["archive_listing"] = EMPTYSTRING.join(accum)
- finally:
- i18n.set_translation(otrans)
# The TOC is always in the charset of the list's preferred language
d['meta'] += html_charset % Utils.GetCharSet(mlist.preferred_language)
# The site can disable public access to the mbox file.
diff --git a/Mailman/Cgi/subscribe.py b/Mailman/Cgi/subscribe.py
index e703dd59a..cd4c2373b 100644
--- a/Mailman/Cgi/subscribe.py
+++ b/Mailman/Cgi/subscribe.py
@@ -17,6 +17,8 @@
"""Process subscription or roster requests from listinfo form."""
+from __future__ import with_statement
+
import os
import cgi
import sys
@@ -199,9 +201,7 @@ moderator's decision when they get to your request.""")
listaddr = mlist.GetListEmail()
# Set the language for this email message to the member's language.
mlang = mlist.getMemberLanguage(email)
- otrans = i18n.get_translation()
- i18n.set_language(mlang)
- try:
+ with i18n.using_language(mlang):
msg = Message.UserNotification(
mlist.getMemberCPAddress(email),
mlist.GetBouncesEmail(),
@@ -220,8 +220,6 @@ an attempt is being made to covertly discover whether you are a member of this
list, and you are worried about your privacy, then feel free to send a message
to the list administrator at %(listowner)s.
"""), lang=mlang)
- finally:
- i18n.set_translation(otrans)
msg.send(mlist)
# These shouldn't happen unless someone's tampering with the form
except Errors.MMCantDigestError:
diff --git a/Mailman/Deliverer.py b/Mailman/Deliverer.py
index c9b044286..e543f5793 100644
--- a/Mailman/Deliverer.py
+++ b/Mailman/Deliverer.py
@@ -18,6 +18,8 @@
"""Mixin class with message delivery routines."""
+from __future__ import with_statement
+
import logging
from email.MIMEMessage import MIMEMessage
@@ -126,9 +128,7 @@ action by you is required.""")))
except Errors.MMListError:
# Oh well
return
- otrans = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
- try:
+ with i18n.using_language(mlist.preferred_language):
msg = Message.OwnerNotification(
mlist,
_('Hostile subscription attempt detected'),
@@ -137,8 +137,6 @@ deliberate malicious attempt, they tried to confirm the invitation to a
different list. We just thought you'd like to know. No further action by you
is required.""")))
msg.send(mlist)
- finally:
- i18n.set_translation(otrans)
def sendProbe(self, member, msg):
listname = self.real_name
@@ -162,12 +160,8 @@ is required.""")))
self.host_name)
# Calculate the Subject header, in the member's preferred language
ulang = self.getMemberLanguage(member)
- otrans = i18n.get_translation()
- i18n.set_language(ulang)
- try:
+ with i18n.using_language(ulang):
subject = _('%(listname)s mailing list probe message')
- finally:
- i18n.set_translation(otrans)
outer = Message.UserNotification(member, probeaddr, subject,
lang=ulang)
outer.set_type('multipart/mixed')
diff --git a/Mailman/Handlers/Hold.py b/Mailman/Handlers/Hold.py
index 6801c720e..75f7b6386 100644
--- a/Mailman/Handlers/Hold.py
+++ b/Mailman/Handlers/Hold.py
@@ -28,6 +28,8 @@ Finally an exception is raised to let the pipeline machinery know that further
message handling should stop.
"""
+from __future__ import with_statement
+
import email
import logging
import email.utils
@@ -272,9 +274,7 @@ def hold_for_approval(mlist, msg, msgdata, exc):
if mlist.admin_immed_notify:
# Now let's temporarily set the language context to that which the
# admin is expecting.
- otranslation = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
- try:
+ with i18n.using_language(mlist.preferred_language):
lang = mlist.preferred_language
charset = Utils.GetCharSet(lang)
# We need to regenerate or re-translate a few values in d
@@ -304,8 +304,6 @@ also appear in the first line of the body of the reply.""")),
nmsg.attach(MIMEMessage(msg))
nmsg.attach(MIMEMessage(dmsg))
nmsg.send(mlist, **{'tomoderators': 1})
- finally:
- i18n.set_translation(otranslation)
# Log the held message
log.info('%s post from %s held, message-id=%s: %s',
listname, sender, message_id, reason)
diff --git a/Mailman/Handlers/ToDigest.py b/Mailman/Handlers/ToDigest.py
index ece052f14..5fd08852f 100644
--- a/Mailman/Handlers/ToDigest.py
+++ b/Mailman/Handlers/ToDigest.py
@@ -25,6 +25,8 @@
# directory and the DigestRunner will craft the MIME, rfc1153, and
# (eventually) URL-subject linked digests from the mbox.
+from __future__ import with_statement
+
import os
import re
import copy
@@ -129,12 +131,8 @@ def send_digests(mlist, mboxfp):
mlist.digest_last_sent_at = time.time()
# Wrapper around actually digest crafter to set up the language context
# properly. All digests are translated to the list's preferred language.
- otranslation = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
- try:
+ with i18n.using_language(mlist.preferred_language):
send_i18n_digests(mlist, mboxfp)
- finally:
- i18n.set_translation(otranslation)
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index 80d946634..70ae98067 100644
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -21,6 +21,8 @@
Mixes in many task-specific classes.
"""
+from __future__ import with_statement
+
import os
import re
import sys
@@ -722,19 +724,15 @@ class MailList(object, HTMLFormatter, Deliverer,
slog.info('%s: changed member address from %s to %s',
self.internal_name(), oldaddr, newaddr)
if self.admin_notify_mchanges:
- lang = self.preferred_language
- otrans = i18n.get_translation()
- i18n.set_language(lang)
- try:
+ with i18n.using_language(self.preferred_language):
realname = self.real_name
subject = _('%(realname)s address change notification')
- finally:
- i18n.set_translation(otrans)
name = self.getMemberName(newaddr)
if name is None:
name = ''
if isinstance(name, unicode):
- name = name.encode(Utils.GetCharSet(lang), 'replace')
+ name = name.encode(Utils.GetCharSet(self.preferred_language),
+ 'replace')
text = Utils.maketext(
'adminaddrchgack.txt',
{'name' : name,
diff --git a/Mailman/Queue/Runner.py b/Mailman/Queue/Runner.py
index 7ca3cfbe5..b4d8f7912 100644
--- a/Mailman/Queue/Runner.py
+++ b/Mailman/Queue/Runner.py
@@ -17,6 +17,8 @@
"""Generic queue runner class."""
+from __future__ import with_statement
+
import time
import weakref
import logging
@@ -162,19 +164,15 @@ class Runner:
# special care to reset the defaults, otherwise subsequent messages
# may be translated incorrectly. BAW: I'm not sure I like this
# approach, but I can't think of anything better right now.
- otranslation = i18n.get_translation()
sender = msg.get_sender()
member = mlist.members.get_member(sender)
if member:
lang = member.preferred_language
else:
lang = mlist.preferred_language
- i18n.set_language(lang)
- msgdata['lang'] = lang
- try:
+ with i18n.using_language(lang):
+ msgdata['lang'] = lang
keepqueued = self._dispose(mlist, msg, msgdata)
- finally:
- i18n.set_translation(otranslation)
# Keep tabs on any child processes that got spawned.
kids = msgdata.get('_kids')
if kids:
diff --git a/Mailman/app/membership.py b/Mailman/app/membership.py
index 695366b91..0f12a1d29 100644
--- a/Mailman/app/membership.py
+++ b/Mailman/app/membership.py
@@ -17,6 +17,8 @@
"""Application support for membership management."""
+from __future__ import with_statement
+
from email.utils import formataddr
from Mailman import Message
@@ -102,12 +104,8 @@ def add_member(mlist, address, realname, password, delivery_mode, language,
if ack:
send_welcome_message(mlist, address, language, delivery_mode, text)
if admin_notif:
- otrans = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
- try:
+ with i18n.using_language(mlist.preferred_language):
subject = _('$mlist.real_name subscription notification')
- finally:
- i18n.set_translation(otrans)
if isinstance(realname, unicode):
realname = name.encode(Utils.GetCharSet(language), 'replace')
text = Utils.maketext(
diff --git a/Mailman/app/moderator.py b/Mailman/app/moderator.py
index 823832184..266092cdb 100644
--- a/Mailman/app/moderator.py
+++ b/Mailman/app/moderator.py
@@ -17,6 +17,8 @@
"""Application support for moderators."""
+from __future__ import with_statement
+
__all__ = [
'handle_message',
'handle_subscription',
@@ -149,15 +151,11 @@ def handle_message(mlist, id, action,
member = mlist.members.get_member(addresses[0])
if member:
language = member.preferred_language
- otrans = i18n.get_translation()
- i18n.set_language(language)
- try:
+ with i18n.using_language(language):
fmsg = Message.UserNotification(
addresses, mlist.bounces_address,
_('Forward of moderated message'),
lang=language)
- finally:
- i18n.set_translation(otrans)
fmsg.set_type('message/rfc822')
fmsg.attach(msg)
fmsg.send(mlist)
@@ -318,9 +316,7 @@ def _refuse(mlist, request, recip, comment, origmsg=None, lang=None):
'reason' : comment,
'adminaddr': mlist.owner_address,
}, lang=lang, mlist=mlist)
- otrans = i18n.get_translation()
- i18n.set_language(lang)
- try:
+ with i18n.using_language(lang):
# add in original message, but not wrap/filled
if origmsg:
text = NL.join(
@@ -329,8 +325,6 @@ def _refuse(mlist, request, recip, comment, origmsg=None, lang=None):
str(origmsg)
])
subject = _('Request to mailing list "$realname" rejected')
- finally:
- i18n.set_translation(otrans)
msg = Message.UserNotification(recip, mlist.bounces_address,
subject, text, lang)
msg.send(mlist)
diff --git a/Mailman/bin/add_members.py b/Mailman/bin/add_members.py
index 96abbc74d..e27304aaf 100644
--- a/Mailman/bin/add_members.py
+++ b/Mailman/bin/add_members.py
@@ -15,6 +15,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
+from __future__ import with_statement
+
import os
import sys
import optparse
@@ -177,9 +179,7 @@ def main():
else:
admin_notify = opts.admin_notify
- otrans = i18n.get_translation()
- # Read the regular and digest member files
- try:
+ with i18n.using_language(mlist.preferred_language):
if opts.digest:
dmembers = readfile(opts.digest)
else:
@@ -194,7 +194,6 @@ def main():
sys.exit(0)
s = StringIO()
- i18n.set_language(mlist.preferred_language)
if nmembers:
addall(mlist, nmembers, False, send_welcome_msg, s)
@@ -211,7 +210,7 @@ def main():
mlist.Save()
finally:
mlist.Unlock()
- i18n.set_translation(otrans)
+
if __name__ == '__main__':
diff --git a/Mailman/bin/change_pw.py b/Mailman/bin/change_pw.py
index 3830b76ae..9c89ef5cd 100644
--- a/Mailman/bin/change_pw.py
+++ b/Mailman/bin/change_pw.py
@@ -15,6 +15,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
+from __future__ import with_statement
+
import sha
import sys
import optparse
@@ -150,9 +152,7 @@ def main():
# Notification
print _('New $listname password: $notifypassword')
if not opts.quiet:
- otrans = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
- try:
+ with i18n.using_language(mlist.preferred_language):
hostname = mlist.host_name
adminurl = mlist.GetScriptURL('admin', absolute=True)
msg = Message.UserNotification(
@@ -171,8 +171,6 @@ liking. Visit your list admin page at
$adminurl
'''),
mlist.preferred_language)
- finally:
- i18n.set_translation(otrans)
msg.send(mlist)
diff --git a/Mailman/bin/newlist.py b/Mailman/bin/newlist.py
index 6847cc16f..3897f73dc 100644
--- a/Mailman/bin/newlist.py
+++ b/Mailman/bin/newlist.py
@@ -15,6 +15,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
+from __future__ import with_statement
+
import sha
import sys
import getpass
@@ -131,13 +133,9 @@ 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.
- otrans = i18n.get_translation()
- i18n.set_language(mlist.preferred_language)
- try:
+ with i18n.using_language(mlist.preferred_language):
msg = Message.UserNotification(
owner_mail, mlist.no_reply_address,
_('Your new mailing list: $listname'),
text, mlist.preferred_language)
msg.send(mlist)
- finally:
- i18n.set_translation(otrans)
diff --git a/Mailman/i18n.py b/Mailman/i18n.py
index 120e861ad..4cae80fb3 100644
--- a/Mailman/i18n.py
+++ b/Mailman/i18n.py
@@ -69,6 +69,21 @@ 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
+ self._old_translation = None
+
+ def __enter__(self):
+ self._old_translation = _translation
+ set_language(self._language)
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ global _translation
+ _translation = self._old_translation
+
+
# Set up the global translation based on environment variables. Mostly used
# for command line scripts.
if _translation is None:
diff --git a/TODO.txt b/TODO.txt
index e7f578bab..365db3c32 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -13,5 +13,4 @@ Address XXX and FIXME
Fix the roster creation cruft for mailing lists
Suss out the IDomain stuff
Remove Date: header from messagestore requirements (see list thread)
-Make i18n.get_translation() a context manager
Handle moderation flag (see Mailman.app.membership)