1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
Archives
========
Updating the archives with posted messages is handled by a separate queue,
which allows for better memory management and prevents blocking the main
delivery processes while messages are archived. This also allows external
archivers to work in a separate process from the main Mailman delivery
processes.
>>> from mailman.app.lifecycle import create_list
>>> handler = config.handlers['to-archive']
>>> mlist = create_list(u'_xtest@example.com')
>>> switchboard = config.switchboards['archive']
A helper function.
>>> def clear():
... for filebase in switchboard.files:
... msg, msgdata = switchboard.dequeue(filebase)
... switchboard.finish(filebase)
The purpose of the ToArchive handler is to make a simple decision as to
whether the message should get archived and if so, to drop the message in the
archiving queue. Really the most important things are to determine when a
message should /not/ get archived.
For example, no digests should ever get archived.
>>> mlist.archive = True
>>> msg = message_from_string("""\
... Subject: A sample message
...
... A message of great import.
... """)
>>> handler.process(mlist, msg, dict(isdigest=True))
>>> switchboard.files
[]
If the mailing list is not configured to archive, then even regular deliveries
won't be archived.
>>> mlist.archive = False
>>> handler.process(mlist, msg, {})
>>> switchboard.files
[]
There are two de-facto standards for a message to indicate that it does not
want to be archived. We've seen both in the wild so both are supported. The
X-No-Archive: header can be used to indicate that the message should not be
archived. Confusingly, this header's value is actually ignored.
>>> mlist.archive = True
>>> msg = message_from_string("""\
... Subject: A sample message
... X-No-Archive: YES
...
... A message of great import.
... """)
>>> handler.process(mlist, msg, dict(isdigest=True))
>>> switchboard.files
[]
Even a 'no' value will stop the archiving of the message.
>>> msg = message_from_string("""\
... Subject: A sample message
... X-No-Archive: No
...
... A message of great import.
... """)
>>> handler.process(mlist, msg, dict(isdigest=True))
>>> switchboard.files
[]
Another header that's been observed is the X-Archive: header. Here, the
header's case folded value must be 'no' in order to prevent archiving.
>>> msg = message_from_string("""\
... Subject: A sample message
... X-Archive: No
...
... A message of great import.
... """)
>>> handler.process(mlist, msg, dict(isdigest=True))
>>> switchboard.files
[]
But if the value is 'yes', then the message will be archived.
>>> msg = message_from_string("""\
... Subject: A sample message
... X-Archive: Yes
...
... A message of great import.
... """)
>>> handler.process(mlist, msg, {})
>>> len(switchboard.files)
1
>>> filebase = switchboard.files[0]
>>> qmsg, qdata = switchboard.dequeue(filebase)
>>> switchboard.finish(filebase)
>>> print qmsg.as_string()
Subject: A sample message
X-Archive: Yes
<BLANKLINE>
A message of great import.
<BLANKLINE>
>>> dump_msgdata(qdata)
_parsemsg: False
version : 3
Without either archiving header, and all other things being the same, the
message will get archived.
>>> msg = message_from_string("""\
... Subject: A sample message
...
... A message of great import.
... """)
>>> handler.process(mlist, msg, {})
>>> len(switchboard.files)
1
>>> filebase = switchboard.files[0]
>>> qmsg, qdata = switchboard.dequeue(filebase)
>>> switchboard.finish(filebase)
>>> print qmsg.as_string()
Subject: A sample message
<BLANKLINE>
A message of great import.
<BLANKLINE>
>>> dump_msgdata(qdata)
_parsemsg: False
version : 3
|