Avoid duplicates

This handler implements several strategies to reduce the reception of duplicate messages. It does this by removing certain recipients from the list of recipients calculated earlier.

>>> mlist = create_list('[email protected]')

Create some members we’re going to use.

>>> from mailman.interfaces.usermanager import IUserManager
>>> from zope.component import getUtility
>>> user_manager = getUtility(IUserManager)

>>> address_a = user_manager.create_address('[email protected]')
>>> address_b = user_manager.create_address('[email protected]')

>>> from mailman.interfaces.member import MemberRole
>>> member_a = mlist.subscribe(address_a, MemberRole.member)
>>> member_b = mlist.subscribe(address_b, MemberRole.member)
>>> # This is the message metadata dictionary as it would be produced by
>>> # the CalcRecips handler.
>>> recips = dict(
...     recipients=['[email protected]', '[email protected]'])

Short circuiting

The module short-circuits if there are no recipients.

>>> msg = message_from_string("""\
... From: [email protected]
... Subject: A message of great import
...
... Something
... """)
>>> msgdata = {}

>>> handler = config.handlers['avoid-duplicates']
>>> handler.process(mlist, msg, msgdata)
>>> msgdata
{}
>>> print(msg.as_string())
From: [email protected]
Subject: A message of great import

Something

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 <[email protected]>
...
... Something of great import.
... """)
>>> msgdata = recips.copy()
>>> handler.process(mlist, msg, msgdata)
>>> sorted(msgdata['recipients'])
['[email protected]', '[email protected]']
>>> print(msg.as_string())
From: Claire Person <[email protected]>
<BLANKLINE>
Something of great import.
<BLANKLINE>

If they’re mentioned on the CC line, they won’t get a list copy and will be removed from the CC.

>>> msg = message_from_string("""\
... From: Claire Person <[email protected]>
... CC: [email protected]
...
... Something of great import.
... """)
>>> msgdata = recips.copy()
>>> handler.process(mlist, msg, msgdata)
>>> sorted(msgdata['recipients'])
['[email protected]']
>>> print(msg.as_string())
From: Claire Person <[email protected]>
<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 <[email protected]>
... CC: [email protected]
...
... Something of great import.
... """)
>>> msgdata = recips.copy()
>>> handler.process(mlist, msg, msgdata)
>>> sorted(msgdata['recipients'])
['[email protected]', '[email protected]']
>>> print(msg.as_string())
From: Claire Person <[email protected]>
CC: [email protected]
<BLANKLINE>
Something of great import.
<BLANKLINE>

Other headers checked for recipients include the To

>>> msg = message_from_string("""\
... From: Claire Person <[email protected]>
... To: [email protected]
...
... Something of great import.
... """)
>>> msgdata = recips.copy()
>>> handler.process(mlist, msg, msgdata)
>>> sorted(msgdata['recipients'])
['[email protected]']
>>> print(msg.as_string())
From: Claire Person <[email protected]>
To: [email protected]
<BLANKLINE>
Something of great import.
<BLANKLINE>

Resent-To

>>> msg = message_from_string("""\
... From: Claire Person <[email protected]>
... Resent-To: [email protected]
...
... Something of great import.
... """)
>>> msgdata = recips.copy()
>>> handler.process(mlist, msg, msgdata)
>>> sorted(msgdata['recipients'])
['[email protected]']
>>> print(msg.as_string())
From: Claire Person <[email protected]>
Resent-To: [email protected]
<BLANKLINE>
Something of great import.
<BLANKLINE>

…and Resent-CC headers.

>>> msg = message_from_string("""\
... From: Claire Person <[email protected]>
... Resent-Cc: [email protected]
...
... Something of great import.
... """)
>>> msgdata = recips.copy()
>>> handler.process(mlist, msg, msgdata)
>>> sorted(msgdata['recipients'])
['[email protected]']
>>> print(msg.as_string())
From: Claire Person <[email protected]>
Resent-Cc: [email protected]
<BLANKLINE>
Something of great import.
<BLANKLINE>