summaryrefslogtreecommitdiff
path: root/src/mailman/handlers/docs/archives.rst
blob: b6d06ed99e910ba101689ad6dd59ec9bbae17471 (plain)
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
134
========
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.

    >>> handler = config.handlers['to-archive']
    >>> mlist = create_list('_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 this 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.

    >>> from mailman.interfaces.archiver import ArchivePolicy
    >>> mlist.archive_policy = ArchivePolicy.public
    >>> 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_policy = ArchivePolicy.never
    >>> 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_policy = ArchivePolicy.public
    >>> 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