Commit 78b9ea39 authored by Barry Warsaw's avatar Barry Warsaw

* `IMailTransportAgentAliases` now explicitly accepts duck-typed arguments.

- Also, rewrite the Postfix alias generator to use the faster, duck-typed API.
parent 1655fcc1
......@@ -24,9 +24,10 @@ Architecture
Interfaces
----------
* Add property `IUserManager.members` to return all `IMembers` in the system.
* Add property `IListmanager.name_compoments` which returns 2-tuples for
* Add property `IListmanager.name_components` which returns 2-tuples for
every mailing list as (list_name, mail_host).
* Remove previously deprecated `IListManager.get_mailing_lists()`.
* `IMailTransportAgentAliases` now explicitly accepts duck-typed arguments.
Commands
--------
......
......@@ -50,6 +50,13 @@ class IMailTransportAgentAliases(Interface):
This method is a generator. The posting address will be returned
first, followed by the rest of the aliases in alphabetical order.
:param mlist: The mailing list.
:type mlist: An `IMailingList` or an object with `list_name`,
`mail_host`, and `posting_address` attributes.
:return: The set of fully qualified common aliases for the mailing
list.
:rtype: string
"""
def destinations(mlist):
......@@ -57,6 +64,13 @@ class IMailTransportAgentAliases(Interface):
This method is a generator. The posting address will be returned
first, followed by the rest of the aliases in alphabetical order.
:param mlist: The mailing list.
:type mlist: An `IMailingList` or an object with a `list_name`
attribute.
:return: The set of short (i.e. without the @dom.ain part) common
aliases for the mailing list.
:rtype: string
"""
......
......@@ -44,6 +44,16 @@ log = logging.getLogger('mailman.error')
ALIASTMPL = '{0:{2}}lmtp:[{1.mta.lmtp_host}]:{1.mta.lmtp_port}'
class _FakeList:
"""Duck-typed list for the `IMailTransportAgentAliases` interface."""
def __init__(self, list_name, mail_host):
self.list_name = list_name
self.mail_host = mail_host
self.posting_address = '{0}@{1}'.format(list_name, mail_host)
class LMTP:
"""Connect Mailman to Postfix via LMTP."""
......@@ -102,8 +112,10 @@ class LMTP:
"""Do the actual file writes for list creation."""
# Sort all existing mailing list names first by domain, then by local
# part. For postfix we need a dummy entry for the domain.
list_manager = getUtility(IListManager)
by_domain = {}
for mlist in getUtility(IListManager).mailing_lists:
for list_name, mail_host in list_manager.name_components:
mlist = _FakeList(list_name, mail_host)
by_domain.setdefault(mlist.mail_host, []).append(mlist)
print >> fp, """\
# AUTOMATICALLY GENERATED BY MAILMAN ON {0}
......
......@@ -81,6 +81,46 @@ class TestAliases(unittest.TestCase):
'test-unsubscribe',
])
def test_duck_typed_aliases(self):
# Test the .aliases() method with duck typed arguments.
class Duck:
def __init__(self, list_name, mail_host):
self.list_name = list_name
self.mail_host = mail_host
self.posting_address = '{0}@{1}'.format(list_name, mail_host)
duck_list = Duck('sample', 'example.net')
aliases = list(self.utility.aliases(duck_list))
self.assertEqual(aliases, [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
])
def test_duck_typed_destinations(self):
# Test the .destinations() method with duck typed arguments.
class Duck:
def __init__(self, list_name):
self.list_name = list_name
duck_list = Duck('sample')
destinations = list(self.utility.destinations(duck_list))
self.assertEqual(destinations, [
'sample',
'sample-bounces',
'sample-confirm',
'sample-join',
'sample-leave',
'sample-owner',
'sample-request',
'sample-subscribe',
'sample-unsubscribe',
])
class TestPostfix(unittest.TestCase):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment