39
Decorating simple text messages
40
===============================
42
Text messages that have no declared content type character set are by default,
43
encoded in us-ascii. When the mailing list's preferred language is ``en``
44
(i.e. English), the character set of the mailing list and of the message will
45
match. In this case, and when the header and footer have no interpolation
46
placeholder variables, the message's payload will be prepended by the verbatim
47
header, and appended with the verbatim footer.
49
>>> msg = message_from_string(msg_text)
50
>>> mlist.msg_header = 'header\n'
51
>>> mlist.msg_footer = 'footer'
42
Message decorations are specified by URI and can be specialized by the mailing
43
list and language. Internal Mailman decorations can be referenced by using
44
the ``mailman://`` URL scheme. Here we create a simple English header and
45
footer for all mailing lists in our site.
48
>>> import os, tempfile
49
>>> template_dir = tempfile.mkdtemp()
50
>>> site_dir = os.path.join(template_dir, 'site', 'en')
51
>>> os.makedirs(site_dir)
52
>>> config.push('templates', """
55
... """.format(template_dir))
57
>>> myheader_path = os.path.join(site_dir, 'myheader.txt')
58
>>> with open(myheader_path, 'w') as fp:
59
... print >> fp, 'header'
60
>>> myfooter_path = os.path.join(site_dir, 'myfooter.txt')
61
>>> with open(myfooter_path, 'w') as fp:
62
... print >> fp, 'footer'
64
Setting these attributes on the mailing list causes it to use these
65
templates. Since these are site-global templates, we can use a shorter path.
67
>>> mlist.header_uri = 'mailman:///myheader.txt'
68
>>> mlist.footer_uri = 'mailman:///myfooter.txt'
70
Text messages that have no declared content type are, by default encoded in
71
ASCII. When the mailing list's preferred language is ``en`` (i.e. English),
72
the character set of the mailing list and of the message will match, allowing
73
Mailman to simply prepend the header and append the footer verbatim.
52
75
>>> mlist.preferred_language = 'en'
53
76
>>> process(mlist, msg, {})
54
77
>>> print msg.as_string()
63
86
header and footer for information to be filled in with mailing list specific
64
87
data. An example of such information is the mailing list's `real name` (a
65
88
short descriptive name for the mailing list).
91
>>> with open(myheader_path, 'w') as fp:
92
... print >> fp, '$list_name header'
93
>>> with open(myfooter_path, 'w') as fp:
94
... print >> fp, '$list_name footer'
67
96
>>> msg = message_from_string(msg_text)
68
>>> mlist.msg_header = '$real_name header\n'
69
>>> mlist.msg_footer = '$real_name footer'
70
97
>>> mlist.real_name = 'XTest'
71
98
>>> process(mlist, msg, {})
72
99
>>> print msg.as_string()
79
106
You can't just pick any interpolation variable though; if you do, the variable
80
107
will remain in the header or footer unchanged.
110
>>> with open(myheader_path, 'w') as fp:
111
... print >> fp, '$dummy header'
112
>>> with open(myfooter_path, 'w') as fp:
113
... print >> fp, '$dummy footer'
82
115
>>> msg = message_from_string(msg_text)
83
>>> mlist.msg_header = '$dummy header\n'
84
>>> mlist.msg_footer = '$dummy footer'
85
116
>>> process(mlist, msg, {})
86
117
>>> print msg.as_string()
87
118
From: aperson@example.org
103
134
When Mailman sees text/plain messages with such RFC 3676 parameters, it
104
135
preserves these parameters when it concatenates headers and footers to the
107
>>> mlist.msg_header = 'header'
108
>>> mlist.msg_footer = 'footer'
139
>>> with open(myheader_path, 'w') as fp:
140
... print >> fp, 'header'
141
>>> with open(myfooter_path, 'w') as fp:
142
... print >> fp, 'footer'
109
144
>>> mlist.preferred_language = 'en'
110
145
>>> msg = message_from_string("""\
111
146
... From: aperson@example.org
112
147
... Content-Type: text/plain; format=flowed; delsp=no
114
149
... Here is a message\x20
115
150
... with soft line breaks.
120
155
>>> # message' line will be retained in the output.
121
156
>>> print msg['content-type']
122
157
text/plain; format="flowed"; delsp="no"; charset="us-ascii"
123
>>> [line for line in msg.get_payload().splitlines()]
124
['header', 'Here is a message ', 'with soft line breaks.', 'footer']
158
>>> for line in msg.get_payload().splitlines():
159
... print '>{0}<'.format(line)
162
>with soft line breaks.<
127
166
Decorating mixed-charset messages
128
167
=================================
130
When a message has no explicit character set, it is assumed to be us-ascii.
169
When a message has no explicit character set, it is assumed to be ASCII.
131
170
However, if the mailing list's preferred language has a different character
132
171
set, Mailman will still try to concatenate the header and footer, but it will
133
172
convert the text to utf-8 and base-64 encode the message payload.
136
175
# 'ja' = Japanese; charset = 'euc-jp'
137
176
>>> mlist.preferred_language = 'ja'
138
>>> mlist.msg_header = '$description header'
139
>>> mlist.msg_footer = '$description footer'
178
>>> with open(myheader_path, 'w') as fp:
179
... print >> fp, '$description header'
180
>>> with open(myfooter_path, 'w') as fp:
181
... print >> fp, '$description footer'
140
182
>>> mlist.description = '\u65e5\u672c\u8a9e'
142
184
>>> from email.message import Message
154
196
Content-Type: text/plain; charset="utf-8"
155
197
Content-Transfer-Encoding: base64
157
5pel5pys6KqeIGhlYWRlcgpGcmFuw6dhaXNlCuaXpeacrOiqniBmb290ZXI=
199
5pel5pys6KqeIGhlYWRlcgpGcmFuw6dhaXNlCuaXpeacrOiqniBmb290ZXIK
159
201
Sometimes the message even has an unknown character set. In this case,
160
202
Mailman has no choice but to decorate the original message with MIME
163
206
>>> mlist.preferred_language = 'en'
164
>>> mlist.msg_header = 'header'
165
>>> mlist.msg_footer = 'footer'
207
>>> with open(myheader_path, 'w') as fp:
208
... print >> fp, 'header'
209
>>> with open(myfooter_path, 'w') as fp:
210
... print >> fp, 'footer'
166
212
>>> msg = message_from_string("""\
167
213
... From: aperson@example.org
168
214
... Content-Type: text/plain; charset=unknown
211
258
``Content-Disposition`` of ``inline`` so that MUAs can display these headers
212
259
as if they were simply concatenated.
214
>>> mlist.preferred_language = 'en'
215
>>> mlist.msg_header = 'header'
216
>>> mlist.msg_footer = 'footer'
217
261
>>> part_1 = message_from_string("""\
218
262
... From: aperson@example.org