"""Decorate a message by sticking the header and footer around it."""
import re
from types import ListType
from email.MIMEText import MIMEText
from Mailman import mm_cfg
from Mailman import Utils
from Mailman import Errors
from Mailman.Message import Message
from Mailman.i18n import _
from Mailman.SafeDict import SafeDict
from Mailman.Logging.Syslog import syslog
try:
True, False
except:
True = 1
False = 0
def process(mlist, msg, msgdata):
if msgdata.get('isdigest') or msgdata.get('nodecorate'):
return
d = {}
if msgdata.get('personalize'):
recips = msgdata.get('recips')
assert type(recips) == ListType and len(recips) == 1
member = recips[0].lower()
d['user_address'] = member
try:
d['user_delivered_to'] = mlist.getMemberCPAddress(member)
d['user_password'] = mlist.getMemberPassword(member)
d['user_language'] = mlist.getMemberLanguage(member)
username = mlist.getMemberName(member) or None
try:
username = username.encode(Utils.GetCharSet(d['user_language']))
except (AttributeError, UnicodeError):
username = member
d['user_name'] = username
d['user_optionsurl'] = mlist.GetOptionsURL(member)
except Errors.NotAMemberError:
pass
d.update(msgdata.get('decoration-data', {}))
header = decorate(mlist, mlist.msg_header, 'non-digest header', d)
footer = decorate(mlist, mlist.msg_footer, 'non-digest footer', d)
if not header and not footer:
return
mcset = msg.get_content_charset() or 'us-ascii'
lcset = Utils.GetCharSet(mlist.preferred_language)
msgtype = msg.get_content_type()
wrap = True
if not msg.is_multipart() and msgtype == 'text/plain':
if isinstance(header, unicode):
uheader = header
else:
uheader = unicode(header, lcset, 'ignore')
if isinstance(footer, unicode):
ufooter = footer
else:
ufooter = unicode(footer, lcset, 'ignore')
try:
oldpayload = unicode(msg.get_payload(decode=True), mcset)
frontsep = endsep = u''
if header and not header.endswith('\n'):
frontsep = u'\n'
if footer and not oldpayload.endswith('\n'):
endsep = u'\n'
payload = uheader + frontsep + oldpayload + endsep + ufooter
try:
payload = payload.encode(lcset)
newcset = lcset
except UnicodeError:
if lcset != mcset:
payload = payload.encode(mcset)
newcset = mcset
format = msg.get_param('format')
delsp = msg.get_param('delsp')
del msg['content-transfer-encoding']
del msg['content-type']
msg.set_payload(payload, newcset)
if format:
msg.set_param('Format', format)
if delsp:
msg.set_param('DelSp', delsp)
wrap = False
except (LookupError, UnicodeError):
pass
elif msg.get_content_type() == 'multipart/mixed':
payload = msg.get_payload()
if not isinstance(payload, ListType):
payload = [payload]
if footer:
mimeftr = MIMEText(footer, 'plain', lcset)
mimeftr['Content-Disposition'] = 'inline'
payload.append(mimeftr)
if header:
mimehdr = MIMEText(header, 'plain', lcset)
mimehdr['Content-Disposition'] = 'inline'
payload.insert(0, mimehdr)
msg.set_payload(payload)
wrap = False
if not wrap:
return
inner = Message()
copied = False
for h, v in msg.items():
if h.lower().startswith('content-'):
inner[h] = v
copied = True
inner.set_payload(msg.get_payload())
inner.set_unixfrom(msg.get_unixfrom())
inner.preamble = msg.preamble
inner.epilogue = msg.epilogue
inner.set_default_type(msg.get_default_type())
if not copied:
inner['Content-Type'] = inner.get_content_type()
if msg['mime-version'] == None:
msg['MIME-Version'] = '1.0'
if hasattr(msg, '__version__'):
inner.__version__ = msg.__version__
payload = [inner]
if header:
mimehdr = MIMEText(header, 'plain', lcset)
mimehdr['Content-Disposition'] = 'inline'
payload.insert(0, mimehdr)
if footer:
mimeftr = MIMEText(footer, 'plain', lcset)
mimeftr['Content-Disposition'] = 'inline'
payload.append(mimeftr)
msg.set_payload(payload)
del msg['content-type']
del msg['content-transfer-encoding']
del msg['content-disposition']
msg['Content-Type'] = 'multipart/mixed'
def decorate(mlist, template, what, extradict=None):
d = SafeDict({'real_name' : mlist.real_name,
'list_name' : mlist.internal_name(),
'_internal_name': mlist.internal_name(),
'host_name' : mlist.host_name,
'web_page_url' : mlist.web_page_url,
'description' : mlist.description,
'info' : mlist.info,
'cgiext' : mm_cfg.CGIEXT,
})
if extradict is not None:
d.update(extradict)
if getattr(mlist, 'use_dollar_strings', 0):
template = Utils.to_percent(template)
try:
text = re.sub(r'(?m)(?<!^--) +(?=\n)', '',
re.sub(r'\r\n', r'\n', template % d))
except (ValueError, TypeError), e:
syslog('error', 'Exception while calculating %s:\n%s', what, e)
what = what.upper()
text = template
return text