summaryrefslogtreecommitdiff
path: root/mailman/pipeline/docs/avoid-duplicates.txt
blob: 9fd332d1b69d92235e41a17044453c3f804f9a88 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
Avoid duplicates
================

The AvoidDuplicates handler module implements several strategies to try to
reduce the reception of duplicate messages.  It does this by removing certain
recipients from the list of recipients that earlier handler modules
(e.g. CalcRecips) calculates.

    >>> from mailman.configuration import config
    >>> handler = config.handlers['avoid-duplicates']
    >>> mlist = config.db.list_manager.create(u'_xtest@example.com')

Create some members we're going to use.

    >>> from mailman.interfaces import MemberRole
    >>> address_a = config.db.user_manager.create_address(
    ...     u'aperson@example.com')
    >>> address_b = config.db.user_manager.create_address(
    ...     u'bperson@example.com')
    >>> member_a = address_a.subscribe(mlist, MemberRole.member)
    >>> member_b = address_b.subscribe(mlist, MemberRole.member)
    >>> # This is the message metadata dictionary as it would be produced by
    >>> # the CalcRecips handler.
    >>> recips = dict(recips=[u'aperson@example.com', u'bperson@example.com'])


Short circuiting
----------------

The module short-circuits if there are no recipients.

    >>> msg = message_from_string("""\
    ... From: aperson@example.com
    ... Subject: A message of great import
    ...
    ... Something
    ... """)
    >>> msgdata = {}
    >>> handler.process(mlist, msg, msgdata)
    >>> msgdata
    {}
    >>> print msg.as_string()
    From: aperson@example.com
    Subject: A message of great import
    <BLANKLINE>
    Something
    <BLANKLINE>


Suppressing the list copy
-------------------------

Members can elect not to receive a list copy of any message on which they are
explicitly named as a recipient.  This is done by setting their
receive_list_copy preference to False.  However, if they aren't mentioned in
one of the recipient headers (i.e. To, CC, Resent-To, or Resent-CC), then they
will get a list copy.

    >>> member_a.preferences.receive_list_copy = False
    >>> msg = message_from_string("""\
    ... From: Claire Person <cperson@example.com>
    ...
    ... Something of great import.
    ... """)
    >>> msgdata = recips.copy()
    >>> handler.process(mlist, msg, msgdata)
    >>> sorted(msgdata['recips'])
    [u'aperson@example.com', u'bperson@example.com']
    >>> print msg.as_string()
    From: Claire Person <cperson@example.com>
    <BLANKLINE>
    Something of great import.
    <BLANKLINE>

If they're mentioned on the CC line, they won't get a list copy.

    >>> msg = message_from_string("""\
    ... From: Claire Person <cperson@example.com>
    ... CC: aperson@example.com
    ...
    ... Something of great import.
    ... """)
    >>> msgdata = recips.copy()
    >>> handler.process(mlist, msg, msgdata)
    >>> sorted(msgdata['recips'])
    [u'bperson@example.com']
    >>> print msg.as_string()
    From: Claire Person <cperson@example.com>
    CC: aperson@example.com
    <BLANKLINE>
    Something of great import.
    <BLANKLINE>

But if they're mentioned on the CC line and have receive_list_copy set to True
(the default), then they still get a list copy.

    >>> msg = message_from_string("""\
    ... From: Claire Person <cperson@example.com>
    ... CC: bperson@example.com
    ...
    ... Something of great import.
    ... """)
    >>> msgdata = recips.copy()
    >>> handler.process(mlist, msg, msgdata)
    >>> sorted(msgdata['recips'])
    [u'aperson@example.com', u'bperson@example.com']
    >>> print msg.as_string()
    From: Claire Person <cperson@example.com>
    CC: bperson@example.com
    <BLANKLINE>
    Something of great import.
    <BLANKLINE>

Other headers checked for recipients include the To...

    >>> msg = message_from_string("""\
    ... From: Claire Person <cperson@example.com>
    ... To: aperson@example.com
    ...
    ... Something of great import.
    ... """)
    >>> msgdata = recips.copy()
    >>> handler.process(mlist, msg, msgdata)
    >>> sorted(msgdata['recips'])
    [u'bperson@example.com']
    >>> print msg.as_string()
    From: Claire Person <cperson@example.com>
    To: aperson@example.com
    <BLANKLINE>
    Something of great import.
    <BLANKLINE>

...Resent-To...

    >>> msg = message_from_string("""\
    ... From: Claire Person <cperson@example.com>
    ... Resent-To: aperson@example.com
    ...
    ... Something of great import.
    ... """)
    >>> msgdata = recips.copy()
    >>> handler.process(mlist, msg, msgdata)
    >>> sorted(msgdata['recips'])
    [u'bperson@example.com']
    >>> print msg.as_string()
    From: Claire Person <cperson@example.com>
    Resent-To: aperson@example.com
    <BLANKLINE>
    Something of great import.
    <BLANKLINE>

...and Resent-CC headers.

    >>> msg = message_from_string("""\
    ... From: Claire Person <cperson@example.com>
    ... Resent-Cc: aperson@example.com
    ...
    ... Something of great import.
    ... """)
    >>> msgdata = recips.copy()
    >>> handler.process(mlist, msg, msgdata)
    >>> sorted(msgdata['recips'])
    [u'bperson@example.com']
    >>> print msg.as_string()
    From: Claire Person <cperson@example.com>
    Resent-Cc: aperson@example.com
    <BLANKLINE>
    Something of great import.
    <BLANKLINE>