7199
by Barry Warsaw
Bump copyright years. |
1 |
# Copyright (C) 1998-2013 by the Free Software Foundation, Inc.
|
1713
by bwarsaw
New pipeline delivery module |
2 |
#
|
6643
by Barry Warsaw
Upgrade to GPLv3. |
3 |
# This file is part of GNU Mailman.
|
4 |
#
|
|
5 |
# GNU Mailman is free software: you can redistribute it and/or modify it under
|
|
6 |
# the terms of the GNU General Public License as published by the Free
|
|
7 |
# Software Foundation, either version 3 of the License, or (at your option)
|
|
8 |
# any later version.
|
|
9 |
#
|
|
10 |
# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
|
|
11 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
12 |
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
13 |
# more details.
|
|
14 |
#
|
|
15 |
# You should have received a copy of the GNU General Public License along with
|
|
16 |
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
|
|
1713
by bwarsaw
New pipeline delivery module |
17 |
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
18 |
"""Cook a message's headers."""
|
1713
by bwarsaw
New pipeline delivery module |
19 |
|
7152
by Barry Warsaw
General code cleanup. |
20 |
from __future__ import absolute_import, print_function, unicode_literals |
6671
by Barry Warsaw
Several important cleanups. |
21 |
|
6592
by Barry Warsaw
Reorganize the Handler architecture to a pipeline architecture with plugins. |
22 |
__metaclass__ = type |
6643.2.5
by Barry Warsaw
Move core Mailman modules to the new mailman.core package. Functionality |
23 |
__all__ = [ |
24 |
'CookHeaders', |
|
25 |
]
|
|
6592
by Barry Warsaw
Reorganize the Handler architecture to a pipeline architecture with plugins. |
26 |
|
27 |
||
1713
by bwarsaw
New pipeline delivery module |
28 |
import re |
2736
by bwarsaw
Conversion to mimelib. |
29 |
|
6643.2.5
by Barry Warsaw
Move core Mailman modules to the new mailman.core package. Functionality |
30 |
from email.errors import HeaderParseError |
31 |
from email.header import Header, decode_header, make_header |
|
32 |
from email.utils import parseaddr, formataddr, getaddresses |
|
7152
by Barry Warsaw
General code cleanup. |
33 |
from zope.interface import implementer |
3918
by bwarsaw
process(): Reworked Reply-To: munging so list owners can establish |
34 |
|
6810.1.1
by Barry Warsaw
Factor out most of the i18n subsystem and convert to using the flufl.i18n |
35 |
from mailman.core.i18n import _ |
6661
by Barry Warsaw
Remove the mailman.interface magic. Use the more specific interface imports. |
36 |
from mailman.interfaces.handler import IHandler |
37 |
from mailman.interfaces.mailinglist import Personalization, ReplyToMunging |
|
6625
by Barry Warsaw
mailman.Version -> mailman.version |
38 |
from mailman.version import VERSION |
6618
by Barry Warsaw
More fixes to get the basic end-to-end delivery mechanisms working. |
39 |
|
1713
by bwarsaw
New pipeline delivery module |
40 |
|
3918
by bwarsaw
process(): Reworked Reply-To: munging so list owners can establish |
41 |
COMMASPACE = ', ' |
4765
by bwarsaw
process(), prefix_subject(): Ben Gertzfield's patch (refactored by |
42 |
MAXLINELEN = 78 |
2689
by bwarsaw
process(): Get rid of the string module in favor of string methods. |
43 |
|
6158
by tkikuchi
back porting from 2.1.6 |
44 |
nonascii = re.compile('[^\s!-~]') |
45 |
||
6334
by bwarsaw
Remove most uses of the types module, in favor of isinstance checks against |
46 |
|
47 |
||
6158
by tkikuchi
back porting from 2.1.6 |
48 |
def uheader(mlist, s, header_name=None, continuation_ws='\t', maxlinelen=None): |
6859
by Barry Warsaw
Pick lint. Down to 4137 lines of warnings. |
49 |
"""Get the charset to encode the string in.
|
50 |
||
51 |
Then search if there is any non-ascii character is in the string. If
|
|
52 |
there is and the charset is us-ascii then we use iso-8859-1 instead. If
|
|
53 |
the string is ascii only we use 'us-ascii' if another charset is
|
|
54 |
specified.
|
|
55 |
"""
|
|
6686
by Barry Warsaw
Much clean up of the language code, though more can be done. Factor out the |
56 |
charset = mlist.preferred_language.charset |
6158
by tkikuchi
back porting from 2.1.6 |
57 |
if nonascii.search(s): |
58 |
# use list charset but ...
|
|
59 |
if charset == 'us-ascii': |
|
60 |
charset = 'iso-8859-1' |
|
61 |
else: |
|
62 |
# there is no nonascii so ...
|
|
63 |
charset = 'us-ascii' |
|
64 |
return Header(s, charset, maxlinelen, header_name, continuation_ws) |
|
5484
by bwarsaw
process(): Patch #625482 by Tokio Kikuchi to properly MIME encode the |
65 |
|
5240
by bwarsaw
Better support for "funny" characters in subject prefixes. |
66 |
|
67 |
||
2121
by bwarsaw
Many changes to make message delivery more robust in the face of |
68 |
def process(mlist, msg, msgdata): |
6859
by Barry Warsaw
Pick lint. Down to 4137 lines of warnings. |
69 |
"""Process the headers of the message."""
|
2479
by bwarsaw
process(): To finally break -admin autoreply loops, we need to add the |
70 |
# Set the "X-Ack: no" header if noack flag is set.
|
71 |
if msgdata.get('noack'): |
|
2736
by bwarsaw
Conversion to mimelib. |
72 |
del msg['x-ack'] |
2479
by bwarsaw
process(): To finally break -admin autoreply loops, we need to add the |
73 |
msg['X-Ack'] = 'no' |
1808
by bwarsaw
First, because this module is going to modify the Sender: field for |
74 |
# Because we're going to modify various important headers in the email
|
2121
by bwarsaw
Many changes to make message delivery more robust in the face of |
75 |
# message, we want to save some of the information in the msgdata
|
76 |
# dictionary for later. Specifically, the sender header will get waxed,
|
|
77 |
# but we need it for the Acknowledge module later.
|
|
6682
by Barry Warsaw
Move mailman.Message to mailman.email.Message. Rename Message.get_sender() to |
78 |
msgdata['original_sender'] = msg.sender |
2736
by bwarsaw
Conversion to mimelib. |
79 |
# VirginRunner sets _fasttrack for internally crafted messages.
|
80 |
fasttrack = msgdata.get('_fasttrack') |
|
2121
by bwarsaw
Many changes to make message delivery more robust in the face of |
81 |
if not msgdata.get('isdigest') and not fasttrack: |
6158
by tkikuchi
back porting from 2.1.6 |
82 |
try: |
83 |
prefix_subject(mlist, msg, msgdata) |
|
84 |
except (UnicodeError, ValueError): |
|
85 |
# TK: Sometimes subject header is not MIME encoded for 8bit
|
|
86 |
# simply abort prefixing.
|
|
87 |
pass
|
|
1713
by bwarsaw
New pipeline delivery module |
88 |
# Add Precedence: and other useful headers. None of these are standard
|
89 |
# and finding information on some of them are fairly difficult. Some are
|
|
90 |
# just common practice, and we'll add more here as they become necessary.
|
|
2736
by bwarsaw
Conversion to mimelib. |
91 |
# Good places to look are:
|
1713
by bwarsaw
New pipeline delivery module |
92 |
#
|
93 |
# http://www.dsv.su.se/~jpalme/ietf/jp-ietf-home.html
|
|
2736
by bwarsaw
Conversion to mimelib. |
94 |
# http://www.faqs.org/rfcs/rfc2076.html
|
1713
by bwarsaw
New pipeline delivery module |
95 |
#
|
2736
by bwarsaw
Conversion to mimelib. |
96 |
# None of these headers are added if they already exist. BAW: some
|
97 |
# consider the advertising of this a security breach. I.e. if there are
|
|
98 |
# known exploits in a particular version of Mailman and we know a site is
|
|
99 |
# using such an old version, they may be vulnerable. It's too easy to
|
|
100 |
# edit the code to add a configuration variable to handle this.
|
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
101 |
if 'x-mailman-version' not in msg: |
6625
by Barry Warsaw
mailman.Version -> mailman.version |
102 |
msg['X-Mailman-Version'] = VERSION |
4927
by bwarsaw
process(): Use Precedence: list instead of bulk for mail list exploded |
103 |
# We set "Precedence: list" because this is the recommendation from the
|
104 |
# sendmail docs, the most authoritative source of this header's semantics.
|
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
105 |
if 'precedence' not in msg: |
4927
by bwarsaw
process(): Use Precedence: list instead of bulk for mail list exploded |
106 |
msg['Precedence'] = 'list' |
1987
by bwarsaw
process(): 'fastrack' => 'fasttrack'. Elaborate the Reply-To: munging |
107 |
# Reply-To: munging. Do not do this if the message is "fast tracked",
|
2736
by bwarsaw
Conversion to mimelib. |
108 |
# meaning it is internally crafted and delivered to a specific user. BAW:
|
109 |
# Yuck, I really hate this feature but I've caved under the sheer pressure
|
|
3918
by bwarsaw
process(): Reworked Reply-To: munging so list owners can establish |
110 |
# of the (very vocal) folks want it. OTOH, RFC 2822 allows Reply-To: to
|
111 |
# be a list of addresses, so instead of replacing the original, simply
|
|
112 |
# augment it. RFC 2822 allows max one Reply-To: header so collapse them
|
|
113 |
# if we're adding a value, otherwise don't touch it. (Should we collapse
|
|
114 |
# in all cases?)
|
|
2631
by bwarsaw
process(): "Fix" the Reply-To: header munging algorithm. If munging |
115 |
if not fasttrack: |
5317
by bwarsaw
process(): Two important fixes. First, when adding Cc headers to |
116 |
# A convenience function, requires nested scopes. pair is (name, addr)
|
117 |
new = [] |
|
5009
by bwarsaw
process(): Implement a suggestion by David W. Tamkin on list-managers |
118 |
d = {} |
5317
by bwarsaw
process(): Two important fixes. First, when adding Cc headers to |
119 |
def add(pair): |
120 |
lcaddr = pair[1].lower() |
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
121 |
if lcaddr in d: |
5009
by bwarsaw
process(): Implement a suggestion by David W. Tamkin on list-managers |
122 |
return
|
5317
by bwarsaw
process(): Two important fixes. First, when adding Cc headers to |
123 |
d[lcaddr] = pair |
124 |
new.append(pair) |
|
5009
by bwarsaw
process(): Implement a suggestion by David W. Tamkin on list-managers |
125 |
# List admin wants an explicit Reply-To: added
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
126 |
if mlist.reply_goes_to_list == ReplyToMunging.explicit_header: |
5312
by bwarsaw
process(): If the list is personalized, and the list's posting address |
127 |
add(parseaddr(mlist.reply_to_address)) |
3918
by bwarsaw
process(): Reworked Reply-To: munging so list owners can establish |
128 |
# If we're not first stripping existing Reply-To: then we need to add
|
129 |
# the original Reply-To:'s to the list we're building up. In both
|
|
130 |
# cases we'll zap the existing field because RFC 2822 says max one is
|
|
131 |
# allowed.
|
|
132 |
if not mlist.first_strip_reply_to: |
|
133 |
orig = msg.get_all('reply-to', []) |
|
5312
by bwarsaw
process(): If the list is personalized, and the list's posting address |
134 |
for pair in getaddresses(orig): |
5009
by bwarsaw
process(): Implement a suggestion by David W. Tamkin on list-managers |
135 |
add(pair) |
136 |
# Set Reply-To: header to point back to this list. Add this last
|
|
137 |
# because some folks think that some MUAs make it easier to delete
|
|
138 |
# addresses from the right than from the left.
|
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
139 |
if mlist.reply_goes_to_list == ReplyToMunging.point_to_list: |
6158
by tkikuchi
back porting from 2.1.6 |
140 |
i18ndesc = uheader(mlist, mlist.description, 'Reply-To') |
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
141 |
add((str(i18ndesc), mlist.posting_address)) |
3918
by bwarsaw
process(): Reworked Reply-To: munging so list owners can establish |
142 |
del msg['reply-to'] |
5009
by bwarsaw
process(): Implement a suggestion by David W. Tamkin on list-managers |
143 |
# Don't put Reply-To: back if there's nothing to add!
|
5317
by bwarsaw
process(): Two important fixes. First, when adding Cc headers to |
144 |
if new: |
5009
by bwarsaw
process(): Implement a suggestion by David W. Tamkin on list-managers |
145 |
# Preserve order
|
3918
by bwarsaw
process(): Reworked Reply-To: munging so list owners can establish |
146 |
msg['Reply-To'] = COMMASPACE.join( |
5317
by bwarsaw
process(): Two important fixes. First, when adding Cc headers to |
147 |
[formataddr(pair) for pair in new]) |
148 |
# The To field normally contains the list posting address. However
|
|
5449
by bwarsaw
process(): Re-enable the Cc header hacking, but only if personalize == |
149 |
# when messages are fully personalized, that header will get
|
150 |
# overwritten with the address of the recipient. We need to get the
|
|
151 |
# posting address in one of the recipient headers or they won't be
|
|
152 |
# able to reply back to the list. It's possible the posting address
|
|
153 |
# was munged into the Reply-To header, but if not, we'll add it to a
|
|
154 |
# Cc header. BAW: should we force it into a Reply-To header in the
|
|
155 |
# above code?
|
|
6158
by tkikuchi
back porting from 2.1.6 |
156 |
# Also skip Cc if this is an anonymous list as list posting address
|
157 |
# is already in From and Reply-To in this case.
|
|
7215
by Barry Warsaw
* `bin/runner` command has been simplified and its command line options |
158 |
if (mlist.personalize is Personalization.full and |
159 |
mlist.reply_goes_to_list is not ReplyToMunging.point_to_list and |
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
160 |
not mlist.anonymous_list): |
5449
by bwarsaw
process(): Re-enable the Cc header hacking, but only if personalize == |
161 |
# Watch out for existing Cc headers, merge, and remove dups. Note
|
162 |
# that RFC 2822 says only zero or one Cc header is allowed.
|
|
163 |
new = [] |
|
164 |
d = {} |
|
165 |
for pair in getaddresses(msg.get_all('cc', [])): |
|
166 |
add(pair) |
|
6158
by tkikuchi
back porting from 2.1.6 |
167 |
i18ndesc = uheader(mlist, mlist.description, 'Cc') |
6567
by Barry Warsaw
Remove the action.py module, move this to Mailman/interfaces/__init__.py. |
168 |
add((str(i18ndesc), mlist.posting_address)) |
5449
by bwarsaw
process(): Re-enable the Cc header hacking, but only if personalize == |
169 |
del msg['Cc'] |
170 |
msg['Cc'] = COMMASPACE.join([formataddr(pair) for pair in new]) |
|
4765
by bwarsaw
process(), prefix_subject(): Ben Gertzfield's patch (refactored by |
171 |
|
172 |
||
173 |
||
5039
by bwarsaw
Allow postings gatewayed to Usenet to inhibit the Subject: field |
174 |
def prefix_subject(mlist, msg, msgdata): |
6859
by Barry Warsaw
Pick lint. Down to 4137 lines of warnings. |
175 |
"""Maybe add a subject prefix.
|
7066
by Barry Warsaw
* Stop adding the X-BeenThere header. |
176 |
|
6859
by Barry Warsaw
Pick lint. Down to 4137 lines of warnings. |
177 |
Add the subject prefix unless the message is a digest or is being fast
|
178 |
tracked (e.g. internally crafted, delivered to a single user such as the
|
|
179 |
list admin).
|
|
180 |
"""
|
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
181 |
if not mlist.subject_prefix.strip(): |
6158
by tkikuchi
back porting from 2.1.6 |
182 |
return
|
6504.1.12
by Barry Warsaw
Convert the CookHeaders tests in test_handlers to using doctests, split up |
183 |
prefix = mlist.subject_prefix |
5737
by bwarsaw
prefix_subject(): Supply default argument '' to the get of the subject |
184 |
subject = msg.get('subject', '') |
5723
by bwarsaw
Some fixes to retain the continuation whitespace on Subject: lines |
185 |
# Try to figure out what the continuation_ws is for the header
|
5750
by bwarsaw
prefix_subject(): If the subject is a Header instead of a string, |
186 |
if isinstance(subject, Header): |
187 |
lines = str(subject).splitlines() |
|
188 |
else: |
|
189 |
lines = subject.splitlines() |
|
5723
by bwarsaw
Some fixes to retain the continuation whitespace on Subject: lines |
190 |
ws = '\t' |
191 |
if len(lines) > 1 and lines[1] and lines[1][0] in ' \t': |
|
192 |
ws = lines[1][0] |
|
7139.1.1
by Barry Warsaw
* The `news` runner and queue has been renamed to the more accurate `nntp`. |
193 |
msgdata['original_subject'] = subject |
6257
by bwarsaw
Port cleaning changes forward from 2.1-maint branch. |
194 |
# The subject may be multilingual but we take the first charset as major
|
195 |
# one and try to decode. If it is decodable, returned subject is in one
|
|
196 |
# line and cset is properly set. If fail, subject is mime-encoded and
|
|
197 |
# cset is set as us-ascii. See detail for ch_oneline() (CookHeaders one
|
|
198 |
# line function).
|
|
6158
by tkikuchi
back porting from 2.1.6 |
199 |
subject, cset = ch_oneline(subject) |
6257
by bwarsaw
Port cleaning changes forward from 2.1-maint branch. |
200 |
# TK: Python interpreter has evolved to be strict on ascii charset code
|
201 |
# range. It is safe to use unicode string when manupilating header
|
|
202 |
# contents with re module. It would be best to return unicode in
|
|
203 |
# ch_oneline() but here is temporary solution.
|
|
6251
by tkikuchi
Python interpreter has evolved to be strict on ascii charset range. |
204 |
subject = unicode(subject, cset) |
6158
by tkikuchi
back porting from 2.1.6 |
205 |
# If the subject_prefix contains '%d', it is replaced with the
|
206 |
# mailing list sequential number. Sequential number format allows
|
|
207 |
# '%d' or '%05d' like pattern.
|
|
208 |
prefix_pattern = re.escape(prefix) |
|
209 |
# unescape '%' :-<
|
|
210 |
prefix_pattern = '%'.join(prefix_pattern.split(r'\%')) |
|
211 |
p = re.compile('%\d*d') |
|
212 |
if p.search(prefix, 1): |
|
213 |
# prefix have number, so we should search prefix w/number in subject.
|
|
214 |
# Also, force new style.
|
|
215 |
prefix_pattern = p.sub(r'\s*\d+\s*', prefix_pattern) |
|
216 |
subject = re.sub(prefix_pattern, '', subject) |
|
6203
by tkikuchi
Finnish dialect of "Re:". |
217 |
rematch = re.match('((RE|AW|SV|VS)(\[\d+\])?:\s*)+', subject, re.I) |
6158
by tkikuchi
back porting from 2.1.6 |
218 |
if rematch: |
219 |
subject = subject[rematch.end():] |
|
220 |
recolon = 'Re:' |
|
221 |
else: |
|
222 |
recolon = '' |
|
223 |
# At this point, subject may become null if someone post mail with
|
|
224 |
# subject: [subject prefix]
|
|
225 |
if subject.strip() == '': |
|
5779
by bwarsaw
prefix_subject(): Capture the no-subject header before we decode it. |
226 |
subject = _('(no subject)') |
6686
by Barry Warsaw
Much clean up of the language code, though more can be done. Factor out the |
227 |
cset = mlist.preferred_language.charset |
6158
by tkikuchi
back porting from 2.1.6 |
228 |
# and substitute %d in prefix with post_id
|
229 |
try: |
|
230 |
prefix = prefix % mlist.post_id |
|
231 |
except TypeError: |
|
232 |
pass
|
|
233 |
# Get the header as a Header instance, with proper unicode conversion
|
|
6484
by tkikuchi
CookHeaders.py: |
234 |
if not recolon: |
235 |
h = uheader(mlist, prefix, 'Subject', continuation_ws=ws) |
|
6158
by tkikuchi
back porting from 2.1.6 |
236 |
else: |
237 |
h = uheader(mlist, prefix, 'Subject', continuation_ws=ws) |
|
238 |
h.append(recolon) |
|
6257
by bwarsaw
Port cleaning changes forward from 2.1-maint branch. |
239 |
# TK: Subject is concatenated and unicode string.
|
6251
by tkikuchi
Python interpreter has evolved to be strict on ascii charset range. |
240 |
subject = subject.encode(cset, 'replace') |
6158
by tkikuchi
back porting from 2.1.6 |
241 |
h.append(subject, cset) |
5240
by bwarsaw
Better support for "funny" characters in subject prefixes. |
242 |
del msg['subject'] |
243 |
msg['Subject'] = h |
|
6158
by tkikuchi
back porting from 2.1.6 |
244 |
ss = uheader(mlist, recolon, 'Subject', continuation_ws=ws) |
245 |
ss.append(subject, cset) |
|
246 |
msgdata['stripped_subject'] = ss |
|
247 |
||
6257
by bwarsaw
Port cleaning changes forward from 2.1-maint branch. |
248 |
|
6158
by tkikuchi
back porting from 2.1.6 |
249 |
|
6297
by tkikuchi
ch_oneline(): Input string variable is overwritten. Also use 'utf-8' |
250 |
def ch_oneline(headerstr): |
6686
by Barry Warsaw
Much clean up of the language code, though more can be done. Factor out the |
251 |
# Decode header string in one line and convert into single charset.
|
252 |
# Return (string, cset) tuple as check for failure.
|
|
6158
by tkikuchi
back porting from 2.1.6 |
253 |
try: |
6297
by tkikuchi
ch_oneline(): Input string variable is overwritten. Also use 'utf-8' |
254 |
d = decode_header(headerstr) |
255 |
# At this point, we should rstrip() every string because some
|
|
6158
by tkikuchi
back porting from 2.1.6 |
256 |
# MUA deliberately add trailing spaces when composing return
|
257 |
# message.
|
|
6664
by Barry Warsaw
Picking some (py)lint. |
258 |
d = [(s.rstrip(), c) for (s, c) in d] |
6297
by tkikuchi
ch_oneline(): Input string variable is overwritten. Also use 'utf-8' |
259 |
# Find all charsets in the original header. We use 'utf-8' rather
|
260 |
# than using the first charset (in mailman 2.1.x) if multiple
|
|
261 |
# charsets are used.
|
|
262 |
csets = [] |
|
6664
by Barry Warsaw
Picking some (py)lint. |
263 |
for (s, c) in d: |
6297
by tkikuchi
ch_oneline(): Input string variable is overwritten. Also use 'utf-8' |
264 |
if c and c not in csets: |
265 |
csets.append(c) |
|
266 |
if len(csets) == 0: |
|
267 |
cset = 'us-ascii' |
|
268 |
elif len(csets) == 1: |
|
269 |
cset = csets[0] |
|
270 |
else: |
|
271 |
cset = 'utf-8' |
|
6158
by tkikuchi
back porting from 2.1.6 |
272 |
h = make_header(d) |
6297
by tkikuchi
ch_oneline(): Input string variable is overwritten. Also use 'utf-8' |
273 |
ustr = unicode(h) |
6671
by Barry Warsaw
Several important cleanups. |
274 |
oneline = ''.join(ustr.splitlines()) |
6158
by tkikuchi
back porting from 2.1.6 |
275 |
return oneline.encode(cset, 'replace'), cset |
276 |
except (LookupError, UnicodeError, ValueError, HeaderParseError): |
|
277 |
# possibly charset problem. return with undecoded string in one line.
|
|
6297
by tkikuchi
ch_oneline(): Input string variable is overwritten. Also use 'utf-8' |
278 |
return ''.join(headerstr.splitlines()), 'us-ascii' |
6592
by Barry Warsaw
Reorganize the Handler architecture to a pipeline architecture with plugins. |
279 |
|
280 |
||
281 |
||
7152
by Barry Warsaw
General code cleanup. |
282 |
@implementer(IHandler) |
6592
by Barry Warsaw
Reorganize the Handler architecture to a pipeline architecture with plugins. |
283 |
class CookHeaders: |
284 |
"""Modify message headers."""
|
|
285 |
||
286 |
name = 'cook-headers' |
|
287 |
description = _('Modify message headers.') |
|
288 |
||
289 |
def process(self, mlist, msg, msgdata): |
|
290 |
"""See `IHandler`."""
|
|
291 |
process(mlist, msg, msgdata) |