Here's the promised patch in my previous email, that enables Mailman to send out properly MIME-ified, localized emails, with the correct encoding and charset conversion for each language. This patch is against Mailman CVS. Ben Index: Mailman/Bouncer.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Bouncer.py,v retrieving revision 2.14 diff -u -r2.14 Bouncer.py --- Mailman/Bouncer.py 2001/10/15 20:39:56 2.14 +++ Mailman/Bouncer.py 2001/11/19 11:00:14 @@ -208,7 +208,8 @@ rname = self.real_name msg0 = Message.UserNotification( recipient, Utils.get_site_email(self.host_name, '-admin'), - _('%(rname)s member %(addr)s bouncing - %(negative)s%(did)s')) + _('%(rname)s member %(addr)s bouncing - %(negative)s%(did)s'), + lang=self.preferred_language) msg0['MIME-Version'] = '1.0' msg0['Content-Type'] = 'multipart/mixed' msg1 = MIMEText(text, Index: Mailman/Deliverer.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Deliverer.py,v retrieving revision 2.10 diff -u -r2.10 Deliverer.py --- Mailman/Deliverer.py 2001/10/21 06:24:56 2.10 +++ Mailman/Deliverer.py 2001/11/19 11:00:14 @@ -65,7 +65,7 @@ msg = Message.UserNotification( self.GetMemberAdminEmail(name), self.GetRequestEmail(), _('Welcome to the "%(realname)s" mailing list%(digmode)s'), - text) + text, pluser) msg['X-No-Archive'] = 'yes' msg.send(self) @@ -74,7 +74,7 @@ msg = Message.UserNotification( self.GetMemberAdminEmail(addr), self.GetAdminEmail(), _('You have been unsubscribed from the %(realname)s mailing list'), - Utils.wrap(self.goodbye_msg)) + Utils.wrap(self.goodbye_msg), self.GetMemberLanguage(addr)) msg.send(self) def MailUserPassword(self, user): @@ -101,6 +101,7 @@ cpuser = self.getMemberCPAddress(user) recipient = self.GetMemberAdminEmail(cpuser) subject = _('%(listfullname)s mailing list reminder') + mem_lang = self.getMemberLanguage(user) # get the text from the template text = Utils.maketext( 'userpass.txt', @@ -111,7 +112,8 @@ 'options_url': self.GetOptionsURL(user, absolute=1), 'requestaddr': requestaddr, 'owneraddr' : self.GetOwnerEmail(), - }, lang=self.getMemberLanguage(user), mlist=self) - msg = Message.UserNotification(recipient, adminaddr, subject, text) + }, lang=mem_lang, mlist=self) + msg = Message.UserNotification(recipient, adminaddr, subject, text, + mem_lang) msg['X-No-Archive'] = 'yes' msg.send(self) Index: Mailman/ListAdmin.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/ListAdmin.py,v retrieving revision 2.22 diff -u -r2.22 ListAdmin.py --- Mailman/ListAdmin.py 2001/11/06 22:49:36 2.22 +++ Mailman/ListAdmin.py 2001/11/19 11:00:14 @@ -30,6 +30,8 @@ import cPickle import email from email.MIMEMessage import MIMEMessage +from email.Encoders import encode_header +from email.Charset import Charset from cStringIO import StringIO from Mailman import mm_cfg @@ -281,9 +283,13 @@ except IOError, e: if e.errno <> errno.ENOENT: raise raise Errors.LostHeldMessage(path) + # We have to call email.Encoders.encode_header directly, we + # don't want to mess with the message + subject = encode_header(_('Forward of moderated message'), + Charset(self.preferred_language)) fmsg = Message.UserNotification(addr, self.GetAdminEmail(), - _('Forward of moderated message')) + subject) fmsg.add_header('Content-Type', 'message/rfc822') fmsg.add_payload(copy) fmsg.send(self) @@ -351,7 +357,8 @@ # This message should appear to come from the <list>-owner so as # to avoid any useless bounce processing. owneraddr = self.GetOwnerEmail() - msg = Message.UserNotification(owneraddr, owneraddr, subject, text) + msg = Message.UserNotification(owneraddr, owneraddr, subject, text, + lang) msg.send(self, **{'tomoderators': 1}) def __handlesubscription(self, record, value, comment): @@ -401,7 +408,8 @@ # This message should appear to come from the <list>-owner so as # to avoid any useless bounce processing. owneraddr = self.GetOwnerEmail() - msg = Message.UserNotification(owneraddr, owneraddr, subject, text) + msg = Message.UserNotification(owneraddr, owneraddr, subject, text, + self.preferred_language) msg.send(self, **{'tomoderators': 1}) def __handleunsubscription(self, record, value, comment): @@ -441,7 +449,7 @@ str(origmsg) ]) subject = _('Request to mailing list %(realname)s rejected') - msg = Message.UserNotification(recip, adminaddr, subject, text) + msg = Message.UserNotification(recip, adminaddr, subject, text, lang) msg.send(self) Index: Mailman/MailCommandHandler.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/MailCommandHandler.py,v retrieving revision 2.23 diff -u -r2.23 MailCommandHandler.py --- Mailman/MailCommandHandler.py 2001/10/21 22:11:20 2.23 +++ Mailman/MailCommandHandler.py 2001/11/19 11:00:14 @@ -270,18 +270,16 @@ syslog('error', 'Unexpected Mailman error:\n%s', tbmsg) # and send the traceback to the user + lang = msgdata.get('lang', + self.getMemberLanguage(admin)) responsemsg = Message.UserNotification( admin, admin, _('Unexpected Mailman error'), _('''\ An unexpected Mailman error has occurred in MailCommandHandler.ParseMailCommands(). Here is the traceback: -''') + tbmsg) +''') + tbmsg, lang) responsemsg['X-No-Archive'] = 'yes' - lang = msgdata.get('lang', - self.getMemberLanguage(admin)) - responsemsg.add_header('Content-Type', 'text/plain', - charset=Utils.GetCharSet(lang)) responsemsg.send(self) break # send the response @@ -313,7 +311,7 @@ responsemsg = Message.UserNotification(msg.get_sender(), self.GetRequestEmail(), subject, - self.__respbuf) + self.__respbuf, lang) responsemsg.add_header('Content-Type', 'text/plain', charset=Utils.GetCharSet(lang)) responsemsg.send(self) Index: Mailman/MailList.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/MailList.py,v retrieving revision 2.48 diff -u -r2.48 MailList.py --- Mailman/MailList.py 2001/10/27 01:59:41 2.48 +++ Mailman/MailList.py 2001/11/19 11:00:15 @@ -666,7 +666,7 @@ msg = Message.UserNotification( recipient, self.GetRequestEmail(), 'confirm %s' % cookie, - text) + text, lang) msg['Reply-To'] = self.GetRequestEmail() msg.send(self) if recipient <> email: @@ -748,7 +748,7 @@ }, lang=lang, mlist=self) msg = Message.UserNotification( self.owner, Utils.get_site_email(self.host_name, '-admin'), - subject, text) + subject, text, lang) msg.send(self) def DeleteMember(self, name, whence=None, admin_notif=0, userack=1): @@ -786,7 +786,7 @@ }, mlist=self) msg = Message.UserNotification( self.owner, Utils.get_site_email(self.host_name, '-admin'), - subject, text) + subject, text, lang) msg.send(self) if whence: whence = "; %s" % whence @@ -850,7 +850,7 @@ msg = Message.UserNotification( newaddr, self.GetRequestEmail(), 'confirm %s' % cookie, - text) + text, self.getMemberLanguage(oldaddr)) msg['Reply-To'] = self.GetRequestEmail() msg.send(self) @@ -994,7 +994,7 @@ msg = Message.UserNotification( addr, self.GetRequestEmail(), 'confirm %s' % cookie, - text) + text, lang) msg['Reply-To'] = self.GetRequestEmail() msg.send(self) Index: Mailman/Message.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Message.py,v retrieving revision 2.9 diff -u -r2.9 Message.py --- Mailman/Message.py 2001/10/15 21:38:01 2.9 +++ Mailman/Message.py 2001/11/19 11:00:15 @@ -22,6 +22,9 @@ import email.Message import email.Utils +from email.Encoders import encode_body, encode_header +from email.Charset import Charset, QP, BASE64 + from types import ListType from Mailman import mm_cfg @@ -92,8 +95,22 @@ class UserNotification(Message): """Class for internally crafted messages.""" - def __init__(self, recip, sender, subject=None, text=None): + def __init__(self, recip, sender, subject=None, text=None, lang=None): Message.__init__(self) + + if lang is not None: + cset = Charset(Utils.GetCharSet(lang)) + text = encode_body(text, cset) + subject = encode_header(subject, cset) + self.add_header('MIME-Version', '1.0') + self.add_header('Content-Type', 'text/plain', + charset=cset.output_charset) + cte = '7bit' + if cset.body_encoding is QP: + cte = 'quoted-printable' + elif cset.body_encoding is BASE64: + cte = 'base64' + self.add_header('Content-Transfer-Encoding', cte) if text is not None: self.set_payload(text) if subject is None: @@ -106,6 +123,7 @@ else: self['To'] = recip self.recips = [recip] + self.lang = lang def send(self, mlist, **_kws): """Sends the message by enqueuing it to the `virgin' queue. @@ -117,6 +135,7 @@ # this is useful for logging to logs/smtp. if not self.has_key('message-id'): self['Message-ID'] = Utils.unique_message_id(mlist) + # Not imported at module scope to avoid import loop from Mailman.Queue.sbcache import get_switchboard virginq = get_switchboard(mm_cfg.VIRGINQUEUE_DIR) Index: Mailman/Cgi/create.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/create.py,v retrieving revision 2.13 diff -u -r2.13 create.py --- Mailman/Cgi/create.py 2001/11/06 23:29:19 2.13 +++ Mailman/Cgi/create.py 2001/11/19 11:00:15 @@ -219,7 +219,7 @@ msg = Message.UserNotification( owner, siteadmin, _('Your new mailing list: %(listname)s'), - text) + text, mlist.preferred_language) msg.send(mlist) # Success! Index: Mailman/Cgi/subscribe.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/subscribe.py,v retrieving revision 2.15 diff -u -r2.15 subscribe.py --- Mailman/Cgi/subscribe.py 2001/10/12 05:14:25 2.15 +++ Mailman/Cgi/subscribe.py 2001/11/19 11:00:15 @@ -230,7 +230,7 @@ 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) msg.send(mlist) # These shouldn't happen unless someone's tampering with the form except Errors.MMCantDigestError: Index: Mailman/Handlers/Acknowledge.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Handlers/Acknowledge.py,v retrieving revision 2.10 diff -u -r2.10 Acknowledge.py --- Mailman/Handlers/Acknowledge.py 2001/10/01 16:32:06 2.10 +++ Mailman/Handlers/Acknowledge.py 2001/11/19 11:00:15 @@ -63,7 +63,5 @@ # queue. subject = _('%(realname)s post acknowledgement') usermsg = Message.UserNotification(sender, mlist.GetAdminEmail(), - subject, text) - usermsg.add_header('Content-Type', 'text/plain', - charset=Utils.GetCharSet(lang)) + subject, text, lang) usermsg.send(mlist) Index: Mailman/Handlers/Hold.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Handlers/Hold.py,v retrieving revision 2.18 diff -u -r2.18 Hold.py --- Mailman/Handlers/Hold.py 2001/10/15 22:22:08 2.18 +++ Mailman/Handlers/Hold.py 2001/11/19 11:00:15 @@ -217,9 +217,8 @@ lang = msgdata.get('lang', mlist.getMemberLanguage(sender)) subject = _('Your message to %(listname)s awaits moderator approval') text = Utils.maketext('postheld.txt', d, lang=lang, mlist=mlist) - nmsg = Message.UserNotification(sender, adminaddr, subject, text) - nmsg.add_header('Content-Type', 'text/plain', - charset=Utils.GetCharSet(lang)) + nmsg = Message.UserNotification(sender, adminaddr, subject, text, + lang) nmsg.send(mlist) # Now the message for the list owners. Be sure to include the list # moderators in this message. This one should appear to come from @@ -237,7 +236,8 @@ d['subject'] = usersubject # craft the admin notification message and deliver it subject = _('%(listname)s post from %(sender)s requires approval') - nmsg = Message.UserNotification(owneraddr, owneraddr, subject) + nmsg = Message.UserNotification(owneraddr, owneraddr, subject, + lang=lang) nmsg['Content-Type'] = 'multipart/mixed' nmsg['MIME-Version'] = '1.0' text = MIMEText( Index: Mailman/Handlers/Moderate.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Handlers/Moderate.py,v retrieving revision 2.0 diff -u -r2.0 Moderate.py --- Mailman/Handlers/Moderate.py 2001/10/15 22:23:17 2.0 +++ Mailman/Handlers/Moderate.py 2001/11/19 11:00:15 @@ -93,7 +93,8 @@ mlist.GetScriptURL('admin', absolute=1) nmsg = Message.UserNotification(mlist.GetOwnerEmail(), mlist.GetAdminEmail(), - _('Auto-discard notification')) + _('Auto-discard notification'), + mlist.preferred_language) nmsg['Content-Type'] = 'multipart/mixed' nmsg['MIME-Version'] = '1.0' text = MIMEText(Utils.wrap(_("""\ Index: Mailman/Handlers/Replybot.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Handlers/Replybot.py,v retrieving revision 2.4 diff -u -r2.4 Replybot.py --- Mailman/Handlers/Replybot.py 2001/07/13 17:00:34 2.4 +++ Mailman/Handlers/Replybot.py 2001/11/19 11:00:15 @@ -48,6 +48,7 @@ # means always autorespond, as does an "X-Ack: yes" header (useful for # debugging). sender = msg.get_sender() + lang = mlist.getMemberLanguage(sender) now = time.time() graceperiod = mlist.autoresponse_graceperiod if graceperiod > 0 and ack <> 'yes': @@ -90,7 +91,7 @@ # Wrap the response. text = Utils.wrap(text) outmsg = Message.UserNotification(sender, mlist.GetAdminEmail(), - subject, text) + subject, text, lang) outmsg['X-Mailer'] = _('The Mailman Replybot') # prevent recursions and mail loops! outmsg['X-Ack'] = 'No' Index: Mailman/MTA/Manual.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/MTA/Manual.py,v retrieving revision 2.2 diff -u -r2.2 Manual.py --- Mailman/MTA/Manual.py 2001/09/04 15:09:56 2.2 +++ Mailman/MTA/Manual.py 2001/11/19 11:00:15 @@ -65,7 +65,7 @@ msg = Message.UserNotification( siteowner, siteowner, _('Mailing list creation request for list %(listname)s'), - sfp.getvalue()) + sfp.getvalue(), mlist.preferred_language) outq = get_switchboard(mm_cfg.OUTQUEUE_DIR) outq.enqueue(msg, recips=[siteowner]) @@ -108,6 +108,6 @@ msg = Message.UserNotification( siteowner, siteowner, _('Mailing list removal request for list %(listname)s'), - sfp.getvalue()) + sfp.getvalue(), mlist.preferred_language) outq = get_switchboard(mm_cfg.OUTQUEUE_DIR) outq.enqueue(msg, recips=[siteowner]) Index: bin/newlist =================================================================== RCS file: /cvsroot/mailman/mailman/bin/newlist,v retrieving revision 2.10 diff -u -r2.10 newlist --- bin/newlist 2001/09/07 23:18:47 2.10 +++ bin/newlist 2001/11/19 11:00:15 @@ -179,7 +179,7 @@ msg = Message.UserNotification( owner_mail, siteadmin, _('Your new mailing list: %(listname)s'), - text) + text, mlist.preferred_language) msg.send(mlist) -- Ben Gertzfield ベン・ガーツフィールド Global Media Online INC. グロバルメディアオンライン株式会社 System Division システム本部 Sysadmin Team Programmer シスアドミニチームプログラマー
participants (1)
-
Ben Gertzfield