diff options
Diffstat (limited to 'Mailman/Handlers/ToDigest.py')
| -rw-r--r-- | Mailman/Handlers/ToDigest.py | 71 |
1 files changed, 47 insertions, 24 deletions
diff --git a/Mailman/Handlers/ToDigest.py b/Mailman/Handlers/ToDigest.py index 1fc8928b2..0e4bb94d9 100644 --- a/Mailman/Handlers/ToDigest.py +++ b/Mailman/Handlers/ToDigest.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2003 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2005 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -37,13 +37,15 @@ from email.Generator import Generator from email.MIMEBase import MIMEBase from email.MIMEText import MIMEText from email.MIMEMessage import MIMEMessage -from email.Utils import getaddresses +from email.Utils import getaddresses, formatdate from email.Header import decode_header, make_header, Header +from email.Charset import Charset from Mailman import mm_cfg from Mailman import Utils from Mailman import Message from Mailman import i18n +from Mailman import Errors from Mailman.Mailbox import Mailbox from Mailman.MemberAdaptor import ENABLED from Mailman.Handlers.Decorate import decorate @@ -86,9 +88,20 @@ def process(mlist, msg, msgdata): if size / 1024.0 >= mlist.digest_size_threshhold: # This is a bit of a kludge to get the mbox file moved to the digest # queue directory. - mboxfp.seek(0) - send_digests(mlist, mboxfp) - os.unlink(mboxfile) + try: + # Let's close in try - except here because a error in send_digest + # can stop regular delivery silently. Unsuccessful digest + # delivery should be tried again by cron and the site + # administrator will be notified of any error explicitly by the + # cron error message. + mboxfp.seek(0) + send_digests(mlist, mboxfp) + os.unlink(mboxfile) + except Exception, errmsg: + # I know bare except is prohibited in mailman coding but we can't + # forcast what new exception can occur here. + syslog('error', 'send_digests() failed: %s', errmsg) + pass mboxfp.close() @@ -136,9 +149,11 @@ def send_digests(mlist, mboxfp): def send_i18n_digests(mlist, mboxfp): mbox = Mailbox(mboxfp) - # Prepare common information + # Prepare common information (first lang/charset) lang = mlist.preferred_language lcset = Utils.GetCharSet(lang) + lcset_out = Charset(lcset).output_charset or lcset + # Common Information (contd) realname = mlist.real_name volume = mlist.volume issue = mlist.next_digest_number @@ -146,6 +161,7 @@ def send_i18n_digests(mlist, mboxfp): digestsubj = Header(digestid, lcset, header_name='Subject') # Set things up for the MIME digest. Only headers not added by # CookHeaders need be added here. + # Date/Message-ID should be added here also. mimemsg = Message.Message() mimemsg['Content-Type'] = 'multipart/mixed' mimemsg['MIME-Version'] = '1.0' @@ -153,6 +169,8 @@ def send_i18n_digests(mlist, mboxfp): mimemsg['Subject'] = digestsubj mimemsg['To'] = mlist.GetListEmail() mimemsg['Reply-To'] = mlist.GetListEmail() + mimemsg['Date'] = formatdate(localtime=1) + mimemsg['Message-ID'] = Utils.unique_message_id(mlist) # Set things up for the rfc1153 digest plainmsg = StringIO() rfc1153msg = Message.Message() @@ -160,6 +178,8 @@ def send_i18n_digests(mlist, mboxfp): rfc1153msg['Subject'] = digestsubj rfc1153msg['To'] = mlist.GetListEmail() rfc1153msg['Reply-To'] = mlist.GetListEmail() + rfc1153msg['Date'] = formatdate(localtime=1) + rfc1153msg['Message-ID'] = Utils.unique_message_id(mlist) separator70 = '-' * 70 separator30 = '-' * 30 # In the rfc1153 digest, the masthead contains the digest boilerplate plus @@ -210,18 +230,19 @@ def send_i18n_digests(mlist, mboxfp): if msg == '': # It was an unparseable message msg = mbox.next() + continue msgcount += 1 messages.append(msg) # Get the Subject header msgsubj = msg.get('subject', _('(no subject)')) - subject = oneline(msgsubj, lcset) + subject = Utils.oneline(msgsubj, lcset) # Don't include the redundant subject prefix in the toc mo = re.match('(re:? *)?(%s)' % re.escape(mlist.subject_prefix), subject, re.IGNORECASE) if mo: subject = subject[:mo.start(2)] + subject[mo.end(2):] username = '' - addresses = getaddresses([oneline(msg.get('from', ''), lcset)]) + addresses = getaddresses([Utils.oneline(msg.get('from', ''), lcset)]) # Take only the first author we find if isinstance(addresses, ListType) and addresses: username = addresses[0][0] @@ -301,15 +322,30 @@ def send_i18n_digests(mlist, mboxfp): print >> plainmsg, separator30 print >> plainmsg # Use Mailman.Handlers.Scrubber.process() to get plain text - msg = scrubber(mlist, msg) + try: + msg = scrubber(mlist, msg) + except Errors.DiscardMessage: + print >> plainmsg, _('[Message discarded by content filter]') + continue # Honor the default setting for h in mm_cfg.PLAIN_DIGEST_KEEP_HEADERS: if msg[h]: - uh = Utils.wrap('%s: %s' % (h, oneline(msg[h], lcset))) + uh = Utils.wrap('%s: %s' % (h, Utils.oneline(msg[h], lcset))) uh = '\n\t'.join(uh.split('\n')) print >> plainmsg, uh print >> plainmsg - payload = msg.get_payload(decode=True) + payload = msg.get_payload(decode=True)\ + or msg.as_string().split('\n\n',1)[1] + mcset = msg.get_content_charset('') + if mcset and mcset <> lcset and mcset <> lcset_out: + try: + payload = unicode(payload, mcset, 'replace' + ).encode(lcset, 'replace') + except LookupError: + # TK: Message has something unknown charset. + # _out means charset in 'outer world'. + payload = unicode(payload, lcset_out, 'replace' + ).encode(lcset, 'replace') print >> plainmsg, payload if not payload.endswith('\n'): print >> plainmsg @@ -375,16 +411,3 @@ def send_i18n_digests(mlist, mboxfp): recips=plainrecips, listname=mlist.internal_name(), isdigest=True) - - - -def oneline(s, cset): - # Decode header string in one line and convert into specified charset - try: - h = make_header(decode_header(s)) - ustr = h.__unicode__() - oneline = UEMPTYSTRING.join(ustr.splitlines()) - return oneline.encode(cset, 'replace') - except (LookupError, UnicodeError): - # possibly charset problem. return with undecoded string in one line. - return EMPTYSTRING.join(s.splitlines()) |
