62
62
# "X-List-Administrivia: yes" header. For all others (i.e. those coming
63
63
# from list posts), we add a bunch of other RFC 2369 headers.
64
64
requestaddr = mlist.request_address
65
subfieldfmt = '<{0}>, <mailto:{1}>'
65
subfieldfmt = '<{}>, <mailto:{}>'
66
66
listinfo = mlist.script_url('listinfo')
68
68
# XXX reduced_list_headers used to suppress List-Help, List-Subject, and
69
69
# List-Unsubscribe from UserNotification. That doesn't seem to make sense
70
70
# any more, so always add those three headers (others will still be
73
'List-Help' : '<mailto:{0}?subject=help>'.format(requestaddr),
74
'List-Unsubscribe': subfieldfmt.format(listinfo, mlist.leave_address),
75
'List-Subscribe' : subfieldfmt.format(listinfo, mlist.join_address),
73
('List-Help', '<mailto:{}?subject=help>'.format(requestaddr)),
75
subfieldfmt.format(listinfo, mlist.leave_address)),
76
('List-Subscribe', subfieldfmt.format(listinfo, mlist.join_address)),
77
78
if not msgdata.get('reduced_list_headers'):
78
79
# List-Post: is controlled by a separate attribute, which is somewhat
79
80
# misnamed. RFC 2369 requires a value of NO if posting is not
80
81
# allowed, i.e. for an announce-only list.
81
list_post = ('<mailto:{0}>'.format(mlist.posting_address)
82
list_post = ('<mailto:{}>'.format(mlist.posting_address)
82
83
if mlist.allow_list_posts
84
headers['List-Post'] = list_post
85
headers.append(('List-Post', list_post))
85
86
# Add RFC 2369 and 5064 archiving headers, if archiving is enabled.
86
87
if mlist.archive_policy is not ArchivePolicy.never:
87
88
archiver_set = IListArchiverSet(mlist)
88
89
for archiver in archiver_set.archivers:
89
90
if not archiver.is_enabled:
91
headers['List-Archive'] = '<{0}>'.format(
92
archiver_url = '<{}>'.format(
92
93
archiver.system_archiver.list_url(mlist))
94
headers.append(('List-Archive', archiver_url))
93
95
permalink = archiver.system_archiver.permalink(mlist, msg)
94
96
if permalink is not None:
95
headers['Archived-At'] = permalink
97
headers.append(('Archived-At', permalink))
96
98
# XXX RFC 2369 also defines a List-Owner header which we are not currently
97
99
# supporting, but should.
98
for h, v in headers.items():
99
# First we delete any pre-existing headers because the RFC permits
100
# only one copy of each, and we want to be sure it's ours.
101
# Some headers will appear more than once in the new set, e.g. the
102
# List-Archive and Archived-At headers. We want to delete any RFC 2369
103
# headers from the original message, but make sure to preserve all of the
104
# new headers we're adding. Go through the list of new headers twice,
105
# first removing any old ones, then adding all the new ones.
108
for h, v in sorted(headers):
102
109
# Wrap these lines if they are too long. 78 character width probably
103
110
# shouldn't be hardcoded, but is at least text-MUA friendly. The
104
111
# adding of 2 is for the colon-space separator.