------------------------------------------------------------ revno: 6520 committer: Barry Warsaw <[EMAIL PROTECTED]> branch nick: 3.0 timestamp: Mon 2007-07-02 18:45:13 -0400 message: Convert TestFileRecips to a doctest, and update the handler to more modern Python idioms. The recipients are now returned as a set instead of a list, so duplicates are quashed. In MailList.InitTempVars() we need to create the list's data directory when the list is initialized. If the directory already exists, this does nothing. added: Mailman/docs/file-recips.txt modified: Mailman/Handlers/FileRecips.py Mailman/MailList.py Mailman/testing/test_handlers.py
=== added file 'Mailman/docs/file-recips.txt' --- a/Mailman/docs/file-recips.txt 1970-01-01 00:00:00 +0000 +++ b/Mailman/docs/file-recips.txt 2007-07-02 22:45:13 +0000 @@ -0,0 +1,101 @@ +File recipients +=============== + +Mailman can calculate the recipients for a message from a Sendmail-style +include file. This file must be called members.txt and it must live in the +list's data directory. + + >>> from email import message_from_string + >>> from Mailman.Message import Message + >>> from Mailman.Handlers.FileRecips import process + >>> from Mailman.configuration import config + >>> from Mailman.database import flush + >>> mlist = config.list_manager.create('[EMAIL PROTECTED]') + >>> flush() + + +Short circuiting +---------------- + +If the message's metadata already has recipients, this handler immediately +returns. + + >>> msg = message_from_string("""\ + ... From: [EMAIL PROTECTED] + ... + ... A message. + ... """, Message) + >>> msgdata = {'recips': 7} + >>> process(mlist, msg, msgdata) + >>> print msg.as_string() + From: [EMAIL PROTECTED] + <BLANKLINE> + A message. + <BLANKLINE> + >>> msgdata + {'recips': 7} + + +Missing file +------------ + +The include file must live inside the list's data directory, under the name +members.txt. If the file doesn't exist, the list of recipients will be +empty. + + >>> import os + >>> file_path = os.path.join(mlist.full_path, 'members.txt') + >>> open(file_path) + Traceback (most recent call last): + ... + IOError: [Errno ...] + No such file or directory: '.../[EMAIL PROTECTED]/members.txt' + >>> msgdata = {} + >>> process(mlist, msg, msgdata) + >>> sorted(msgdata['recips']) + [] + + +Existing file +------------- + +If the file exists, it contains a list of addresses, one per line. These +addresses are returned as the set of recipients. + + >>> fp = open(file_path, 'w') + >>> try: + ... print >> fp, '[EMAIL PROTECTED]' + ... print >> fp, '[EMAIL PROTECTED]' + ... print >> fp, '[EMAIL PROTECTED]' + ... print >> fp, '[EMAIL PROTECTED]' + ... print >> fp, '[EMAIL PROTECTED]' + ... print >> fp, '[EMAIL PROTECTED]' + ... finally: + ... fp.close() + + >>> msgdata = {} + >>> process(mlist, msg, msgdata) + >>> sorted(msgdata['recips']) + ['[EMAIL PROTECTED]', '[EMAIL PROTECTED]', '[EMAIL PROTECTED]', + '[EMAIL PROTECTED]', '[EMAIL PROTECTED]', '[EMAIL PROTECTED]'] + +However, if the sender of the original message is a member of the list and +their address is in the include file, the sender's address is /not/ included +in the recipients list. + + >>> from Mailman.constants import MemberRole + >>> address_1 = config.user_manager.create_address('[EMAIL PROTECTED]') + >>> address_1.subscribe(mlist, MemberRole.member) + <Member: [EMAIL PROTECTED] on [EMAIL PROTECTED] as MemberRole.member> + >>> flush() + + >>> msg = message_from_string("""\ + ... From: [EMAIL PROTECTED] + ... + ... A message. + ... """, Message) + >>> msgdata = {} + >>> process(mlist, msg, msgdata) + >>> sorted(msgdata['recips']) + ['[EMAIL PROTECTED]', '[EMAIL PROTECTED]', + '[EMAIL PROTECTED]', '[EMAIL PROTECTED]', '[EMAIL PROTECTED]'] === modified file 'Mailman/Handlers/FileRecips.py' --- a/Mailman/Handlers/FileRecips.py 2007-01-19 04:38:06 +0000 +++ b/Mailman/Handlers/FileRecips.py 2007-07-02 22:45:13 +0000 @@ -17,6 +17,8 @@ """Get the normal delivery recipients from a Sendmail style :include: file.""" +from __future__ import with_statement + import os import errno @@ -25,25 +27,20 @@ def process(mlist, msg, msgdata): - if msgdata.has_key('recips'): + if 'recips' in msgdata: return - filename = os.path.join(mlist.fullpath(), 'members.txt') + filename = os.path.join(mlist.full_path, 'members.txt') try: - fp = open(filename) + with open(filename) as fp: + addrs = set(line.strip() for line in fp) except IOError, e: if e.errno <> errno.ENOENT: raise - # If the file didn't exist, just set an empty recipients list - msgdata['recips'] = [] + msgdata['recips'] = set() return - # Read all the lines out of the file, and strip them of the trailing nl - addrs = [line.strip() for line in fp.readlines()] - # If the sender is in that list, remove him + # If the sender is a member of the list, remove them from the file recips. sender = msg.get_sender() - if mlist.isMember(sender): - try: - addrs.remove(mlist.getMemberCPAddress(sender)) - except ValueError: - # Don't worry if the sender isn't in the list - pass + member = mlist.members.get_member(sender) + if member is not None: + addrs.discard(member.address.address) msgdata['recips'] = addrs === modified file 'Mailman/MailList.py' --- a/Mailman/MailList.py 2007-06-09 19:20:32 +0000 +++ b/Mailman/MailList.py 2007-07-02 22:45:13 +0000 @@ -304,8 +304,9 @@ mod = sys.modules[adaptor_module] self._memberadaptor = getattr(mod, adaptor_class)(self) self._make_lock(self.fqdn_listname) - self._full_path = os.path.join(config.LIST_DATA_DIR, - self.fqdn_listname) + # Create the list's data directory. + self._full_path = os.path.join(config.LIST_DATA_DIR, self.fqdn_listname) + Utils.makedirs(self._full_path) # Only one level of mixin inheritance allowed for baseclass in self.__class__.__bases__: if hasattr(baseclass, 'InitTempVars'): === modified file 'Mailman/testing/test_handlers.py' --- a/Mailman/testing/test_handlers.py 2007-06-21 14:23:40 +0000 +++ b/Mailman/testing/test_handlers.py 2007-07-02 22:45:13 +0000 @@ -39,7 +39,6 @@ from Mailman.Handlers import Acknowledge from Mailman.Handlers import AfterDelivery from Mailman.Handlers import Approve -from Mailman.Handlers import FileRecips from Mailman.Handlers import Hold from Mailman.Handlers import MimeDel from Mailman.Handlers import Moderate @@ -135,89 +134,6 @@ -class TestFileRecips(TestBase): - def test_short_circuit(self): - msgdata = {'recips': 1} - rtn = FileRecips.process(self._mlist, None, msgdata) - # Not really a great test, but there's little else to assert - self.assertEqual(rtn, None) - - def test_file_nonexistant(self): - msgdata = {} - FileRecips.process(self._mlist, None, msgdata) - self.assertEqual(msgdata.get('recips'), []) - - def test_file_exists_no_sender(self): - msg = email.message_from_string("""\ -To: [EMAIL PROTECTED] - -""", Message.Message) - msgdata = {} - file = os.path.join(self._mlist.fullpath(), 'members.txt') - addrs = ['[EMAIL PROTECTED]', '[EMAIL PROTECTED]', - '[EMAIL PROTECTED]', '[EMAIL PROTECTED]'] - fp = open(file, 'w') - try: - for addr in addrs: - print >> fp, addr - fp.close() - FileRecips.process(self._mlist, msg, msgdata) - self.assertEqual(msgdata.get('recips'), addrs) - finally: - try: - os.unlink(file) - except OSError, e: - if e.errno <> e.ENOENT: raise - - def test_file_exists_no_member(self): - msg = email.message_from_string("""\ -From: [EMAIL PROTECTED] -To: [EMAIL PROTECTED] - -""", Message.Message) - msgdata = {} - file = os.path.join(self._mlist.fullpath(), 'members.txt') - addrs = ['[EMAIL PROTECTED]', '[EMAIL PROTECTED]', - '[EMAIL PROTECTED]', '[EMAIL PROTECTED]'] - fp = open(file, 'w') - try: - for addr in addrs: - print >> fp, addr - fp.close() - FileRecips.process(self._mlist, msg, msgdata) - self.assertEqual(msgdata.get('recips'), addrs) - finally: - try: - os.unlink(file) - except OSError, e: - if e.errno <> e.ENOENT: raise - - def test_file_exists_is_member(self): - msg = email.message_from_string("""\ -From: [EMAIL PROTECTED] -To: [EMAIL PROTECTED] - -""", Message.Message) - msgdata = {} - file = os.path.join(self._mlist.fullpath(), 'members.txt') - addrs = ['[EMAIL PROTECTED]', '[EMAIL PROTECTED]', - '[EMAIL PROTECTED]', '[EMAIL PROTECTED]'] - fp = open(file, 'w') - try: - for addr in addrs: - print >> fp, addr - self._mlist.addNewMember(addr) - fp.close() - FileRecips.process(self._mlist, msg, msgdata) - self.assertEqual(msgdata.get('recips'), addrs[1:]) - finally: - try: - os.unlink(file) - except OSError, e: - if e.errno <> e.ENOENT: raise - - - class TestHold(TestBase): def setUp(self): TestBase.setUp(self) @@ -1052,7 +968,6 @@ def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestApprove)) - suite.addTest(unittest.makeSuite(TestFileRecips)) suite.addTest(unittest.makeSuite(TestHold)) suite.addTest(unittest.makeSuite(TestMimeDel)) suite.addTest(unittest.makeSuite(TestModerate)) -- (no title) https://code.launchpad.net/~mailman-coders/mailman/3.0 You are receiving this branch notification because you are subscribed to it. To unsubscribe from this branch go to https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins. _______________________________________________ Mailman-checkins mailing list Mailman-checkins@python.org Unsubscribe: http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org