diff options
| -rw-r--r-- | src/mailman/mta/bulk.py | 27 | ||||
| -rw-r--r-- | src/mailman/mta/docs/bulk.txt | 70 |
2 files changed, 89 insertions, 8 deletions
diff --git a/src/mailman/mta/bulk.py b/src/mailman/mta/bulk.py index 5c6d8257f..2b400e8b5 100644 --- a/src/mailman/mta/bulk.py +++ b/src/mailman/mta/bulk.py @@ -29,7 +29,9 @@ from itertools import chain from zope.interface import implements +from mailman.config import config from mailman.interfaces.mta import IMailTransportAgentDelivery +from mailman.mta.connection import Connection # A mapping of top-level domains to bucket numbers. The zeroth bucket is @@ -51,18 +53,20 @@ class BulkDelivery: implements(IMailTransportAgentDelivery) - def __init__(self, max_recipients): + def __init__(self, max_recipients=None): """Create a bulk deliverer. :param max_recipients: The maximum number of recipients per delivery - chunk. Zero or less means to group all recipients into one - chunk. + chunk. None, zero or less means to group all recipients into one + big chunk. :type max_recipients: integer """ - self._max_recipients = max_recipients - - def deliver(self, mlist, msg, msgdata): - """See `IMailTransportAgentDelivery`.""" + self._max_recipients = (max_recipients + if max_recipients is not None + else 0) + self._connection = Connection( + config.mta.smtp_host, int(config.mta.smtp_port), + self._max_recipients) def chunkify(self, recipients): """Split a set of recipients into chunks. @@ -105,3 +109,12 @@ class BulkDelivery: # Be sure to include the last chunk, but only if it's non-empty. if len(chunk) > 0: yield chunk + + def deliver(self, mlist, msg, msgdata): + """See `IMailTransportAgentDelivery`.""" + recipients = msgdata.get('recipients') + if recipients is None: + return + for recipients in self.chunkify(msgdata['recipients']): + self._connection.sendmail( + 'foo@example.com', recipients, msg.as_string()) diff --git a/src/mailman/mta/docs/bulk.txt b/src/mailman/mta/docs/bulk.txt index 0943b276f..42c9e386a 100644 --- a/src/mailman/mta/docs/bulk.txt +++ b/src/mailman/mta/docs/bulk.txt @@ -18,7 +18,7 @@ The standard bulk deliverer takes as an argument the maximum number of recipients per session. The default is to deliver the message in one chunk, containing all recipients. - >>> bulk = BulkDelivery(0) + >>> bulk = BulkDelivery() Delivery strategies must implement the proper interface. @@ -134,3 +134,71 @@ The final chunk will contain the outliers, .xx (1) and .zz (2). ... print address paco@example.xx quaq@example.zz + + +Bulk delivery +============= + +The set of recipients for bulk delivery comes from the message metadata. If +there are no calculated recipients, nothing gets sent. + + >>> smtpd.clear() + >>> mlist = create_list('test@example.com') + >>> msg = message_from_string("""\ + ... From: aperson@example.org + ... To: test@example.com + ... Subject: test one + ... Message-ID: <aardvark> + ... + ... This is a test. + ... """) + + >>> bulk = BulkDelivery() + >>> bulk.deliver(mlist, msg, {}) + >>> len(list(smtpd.messages)) + 0 + +With bulk delivery and no maximum number of recipients, there will be just one +message sent, with all the recipients packed into the envelope recipients +(i.e. RCTP TO). + + >>> recipients = set('person_{0:02d}'.format(i) for i in range(100)) + >>> msgdata = dict(recipients=recipients) + >>> bulk.deliver(mlist, msg, msgdata) + >>> messages = list(smtpd.messages) + >>> len(messages) + 1 + >>> print messages[0].as_string() + From: aperson@example.org + To: test@example.com + Subject: test one + Message-ID: <aardvark> + X-Peer: ... + X-MailFrom: ... + X-RcptTo: person_... + person_... + ... + <BLANKLINE> + This is a test. + +The X-RcptTo header contains the set of recipients, in random order. + + >>> len(messages[0]['x-rcptto'].split(',')) + 100 + +When the maximum number of recipients is set to 20, 5 messages will be sent, +each with 20 addresses in the RCPT TO header. + + >>> bulk = BulkDelivery(20) + >>> bulk.deliver(mlist, msg, msgdata) + >>> messages = list(smtpd.messages) + >>> len(messages) + 5 + >>> for message in messages: + ... x_rcptto = message['x-rcptto'] + ... print 'Number of recipients:', len(x_rcptto.split(',')) + Number of recipients: 20 + Number of recipients: 20 + Number of recipients: 20 + Number of recipients: 20 + Number of recipients: 20 |
