diff options
Diffstat (limited to 'Mailman/Handlers/CalcRecips.py')
-rw-r--r-- | Mailman/Handlers/CalcRecips.py | 76 |
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) |