aboutsummaryrefslogtreecommitdiffstats
path: root/Mailman/Handlers
diff options
context:
space:
mode:
Diffstat (limited to 'Mailman/Handlers')
-rw-r--r--Mailman/Handlers/CalcRecips.py76
1 files changed, 75 insertions, 1 deletions
diff --git a/Mailman/Handlers/CalcRecips.py b/Mailman/Handlers/CalcRecips.py
index 75a8a457..66c16f86 100644
--- a/Mailman/Handlers/CalcRecips.py
+++ b/Mailman/Handlers/CalcRecips.py
@@ -23,13 +23,22 @@ on the `recips' attribute of the message. This attribute is used by the
SendmailDeliver and BulkDeliver modules.
"""
+import email.Utils
from Mailman import mm_cfg
from Mailman import Utils
from Mailman import Message
from Mailman import Errors
from Mailman.MemberAdaptor import ENABLED
+from Mailman.MailList import MailList
from Mailman.i18n import _
from Mailman.Logging.Syslog import syslog
+from Mailman.Errors import MMUnknownListError
+
+# Use set for sibling list recipient calculation
+try:
+ set
+except NameError: # Python2.3
+ from sets import Set as set
@@ -86,6 +95,9 @@ delivery. The original message as received by Mailman is attached.
pass
# Handle topic classifications
do_topic_filters(mlist, msg, msgdata, recips)
+ # Regular delivery exclude/include (if in/not_in To: or Cc:) lists
+ recips = do_exclude(mlist, msg, msgdata, recips)
+ recips = do_include(mlist, msg, msgdata, recips)
# Bookkeeping
msgdata['recips'] = recips
@@ -135,4 +147,66 @@ def do_topic_filters(mlist, msg, msgdata, recips):
# Prune out the non-receiving users
for user in zaprecips:
recips.remove(user)
-
+
+
+def do_exclude(mlist, msg, msgdata, recips):
+ # regular_exclude_lists are the other mailing lists on this mailman
+ # installation whose members are excluded from the regular (non-digest)
+ # delivery of this list if those list addresses appear in To: or Cc:
+ # headers.
+ if not mlist.regular_exclude_lists:
+ return recips
+ recips = set(recips)
+ destinations = email.Utils.getaddresses(msg.get_all('to', []) +
+ msg.get_all('cc', []))
+ destinations = [y for x,y in destinations]
+ for listname in mlist.regular_exclude_lists:
+ if listname not in destinations:
+ continue
+ listlhs, hostname = listname.split('@')
+ try:
+ slist = MailList(listlhs, lock=False)
+ except MMUnknownListError:
+ syslog('error', 'Exclude list %s not found.', listname)
+ continue
+ if not mm_cfg.ALLOW_CROSS_DOMAIN_SIBLING \
+ and slist.host_name != hostname:
+ syslog('error', 'Exclude list %s is not in the same domain.',
+ listname)
+ continue
+ srecips = set([slist.getMemberCPAddress(m)
+ for m in slist.getRegularMemberKeys()
+ if slist.getDeliveryStatus(m) == ENABLED])
+ recips -= srecips
+ return list(recips)
+
+
+def do_include(mlist, msg, msgdata, recips):
+ # regular_include_lists are the other mailing lists on this mailman
+ # installation whose members are included in the regular (non-digest)
+ # delivery if those list addresses don't appear in To: or Cc: headers.
+ if not mlist.regular_include_lists:
+ return recips
+ recips = set(recips)
+ destinations = email.Utils.getaddresses(msg.get_all('to', []) +
+ msg.get_all('cc', []))
+ destinations = [y for x,y in destinations]
+ for listname in mlist.regular_include_lists:
+ if listname in destinations:
+ continue
+ listlhs, hostname = listname.split('@')
+ try:
+ slist = MailList(listlhs, lock=False)
+ except MMUnknownListError:
+ syslog('error', 'Include list %s not found.', listname)
+ continue
+ if not mm_cfg.ALLOW_CROSS_DOMAIN_SIBLING \
+ and slist.host_name != hostname:
+ syslog('error', 'Include list %s is not in the same domain.',
+ listname)
+ continue
+ srecips = set([slist.getMemberCPAddress(m)
+ for m in slist.getRegularMemberKeys()
+ if slist.getDeliveryStatus(m) == ENABLED])
+ recips |= srecips
+ return list(recips)