diff options
| author | Barry Warsaw | 2017-06-24 21:57:16 +0000 |
|---|---|---|
| committer | Barry Warsaw | 2017-06-24 21:57:16 +0000 |
| commit | e8b134b8f34a8226dd512ecc96a6c908d712663b (patch) | |
| tree | 9057e4acfb9b4db2c75542d13b41b8938ef99451 | |
| parent | 6a148f762d5ee4fd91505eb0aa165b759899019f (diff) | |
| download | mailman-e8b134b8f34a8226dd512ecc96a6c908d712663b.tar.gz mailman-e8b134b8f34a8226dd512ecc96a6c908d712663b.tar.zst mailman-e8b134b8f34a8226dd512ecc96a6c908d712663b.zip | |
| -rw-r--r-- | src/mailman/docs/NEWS.rst | 7 | ||||
| -rw-r--r-- | src/mailman/interfaces/listmanager.py | 30 | ||||
| -rw-r--r-- | src/mailman/model/docs/listmanager.rst | 66 | ||||
| -rw-r--r-- | src/mailman/model/listmanager.py | 15 | ||||
| -rw-r--r-- | src/mailman/model/mailinglist.py | 4 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_listmanager.py | 18 |
6 files changed, 97 insertions, 43 deletions
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index df8032284..654cf4edc 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -17,6 +17,13 @@ Bugs * A missing html_to_plain_text_command is now properly detected and logged. (closes #345) +Interfaces +---------- + * Broaden the semantics for ``IListManager.get()``. This API now accepts + both ``List-ID``s and fully qualified list names, since that's the most + common use case. There's now a separate ``.get_by_fqdn()`` which only + accepts the latter and mirrors the already existing ``.get_by_list_id()``. + 3.1.0 -- "Between The Wheels" ============================= diff --git a/src/mailman/interfaces/listmanager.py b/src/mailman/interfaces/listmanager.py index 3f52d6f0e..dcd4ba152 100644 --- a/src/mailman/interfaces/listmanager.py +++ b/src/mailman/interfaces/listmanager.py @@ -94,22 +94,36 @@ class IListManager(Interface): :raise `ListAlreadyExistsError` if the named list already exists. """ - def get(fqdn_listname): + def get(list_spec): + """Return the mailing list with the given specification, if it exists. + + :param list_spec: Either the fully qualified name of the mailing list, + or its List-ID. If list_spec has an `@` in it, it's considered an + FQDN listname, otherwise it's considered a List-ID. + :type list_spec: str + :return: the matching mailing list or None if no matching list is + found. + :rtype: IMailingList + """ + + def get_by_fqdn(fqdn_listname): """Return the mailing list with the given name, if it exists. :param fqdn_listname: The fully qualified name of the mailing list. - :type fqdn_listname: Unicode. - :return: the matching `IMailingList` or None if the named list does - not exist. + :type fqdn_listname: str + :return: the matching mailing list or None if no matching list is + found. + :rtype: IMailingList """ def get_by_list_id(list_id): """Return the mailing list with the given list id, if it exists. - :param fqdn_listname: The fully qualified name of the mailing list. - :type fqdn_listname: Unicode. - :return: the matching `IMailingList` or None if the named list does - not exist. + :param list_id: The List-ID + :type list_id: str + :return: the matching mailing list or None if no matching list is + found. + :rtype: IMailingList """ def delete(mlist): diff --git a/src/mailman/model/docs/listmanager.rst b/src/mailman/model/docs/listmanager.rst index 8ff6ad3b0..234394ac6 100644 --- a/src/mailman/model/docs/listmanager.rst +++ b/src/mailman/model/docs/listmanager.rst @@ -16,7 +16,7 @@ Creating a mailing list Creating the list returns the newly created IMailList object. >>> from mailman.interfaces.mailinglist import IMailingList - >>> mlist = list_manager.create('test@example.com') + >>> mlist = list_manager.create('ant@example.com') >>> IMailingList.providedBy(mlist) True @@ -26,13 +26,13 @@ mailing list moves to a different host, so it is what uniquely distinguishes the mailing list to the system. >>> print(mlist.list_name) - test + ant >>> print(mlist.mail_host) example.com >>> print(mlist.fqdn_listname) - test@example.com + ant@example.com >>> print(mlist.list_id) - test.example.com + ant.example.com Deleting a mailing list @@ -46,9 +46,9 @@ Use the list manager to delete a mailing list. After deleting the list, you can create it again. - >>> mlist = list_manager.create('test@example.com') + >>> mlist = list_manager.create('ant@example.com') >>> print(mlist.fqdn_listname) - test@example.com + ant@example.com Retrieving a mailing list @@ -57,21 +57,29 @@ Retrieving a mailing list When a mailing list exists, you can ask the list manager for it and you will always get the same object back. - >>> mlist_2 = list_manager.get('test@example.com') - >>> mlist_2 is mlist - True + >>> list_manager.get('ant@example.com') + <mailing list "ant@example.com" at ...> -You can also get a mailing list by it's list id. +The ``.get()`` method is ambidextrous, so it also accepts ``List-ID``s. - >>> mlist_2 = list_manager.get_by_list_id('test.example.com') - >>> mlist_2 is mlist - True + >>> list_manager.get('ant.example.com') + <mailing list "ant@example.com" at ...> + +You can get a mailing list specifically by its ``List-ID``. + + >>> list_manager.get_by_list_id('ant.example.com') + <mailing list "ant@example.com" at ...> + +And you can get a mailing list specifically by its fully-qualified list name. + + >>> list_manager.get_by_fqdn('ant@example.com') + <mailing list "ant@example.com" at ...> If you try to get a list that doesn't existing yet, you get ``None``. - >>> print(list_manager.get('test_2@example.com')) + >>> print(list_manager.get('bee@example.com')) None - >>> print(list_manager.get_by_list_id('test_2.example.com')) + >>> print(list_manager.get_by_list_id('bee.example.com')) None You also get ``None`` if the list name is invalid. @@ -88,33 +96,33 @@ iterate over the mailing list objects, the list posting addresses, or the list address components. :: - >>> mlist_3 = list_manager.create('test_3@example.com') - >>> mlist_4 = list_manager.create('test_4@example.com') + >>> mlist_3 = list_manager.create('cat@example.com') + >>> mlist_4 = list_manager.create('dog@example.com') >>> for name in sorted(list_manager.names): ... print(name) - test@example.com - test_3@example.com - test_4@example.com + ant@example.com + cat@example.com + dog@example.com >>> for list_id in sorted(list_manager.list_ids): ... print(list_id) - test.example.com - test_3.example.com - test_4.example.com + ant.example.com + cat.example.com + dog.example.com >>> for fqdn_listname in sorted(m.fqdn_listname ... for m in list_manager.mailing_lists): ... print(fqdn_listname) - test@example.com - test_3@example.com - test_4@example.com + ant@example.com + cat@example.com + dog@example.com >>> for list_name, mail_host in sorted(list_manager.name_components): ... print(list_name, '@', mail_host) - test @ example.com - test_3 @ example.com - test_4 @ example.com + ant @ example.com + cat @ example.com + dog @ example.com .. _`RFC 2369`: http://www.faqs.org/rfcs/rfc2369.html diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py index 885e5c284..e20598f81 100644 --- a/src/mailman/model/listmanager.py +++ b/src/mailman/model/listmanager.py @@ -59,11 +59,11 @@ class ListManager: return mlist @dbconnection - def get(self, store, fqdn_listname): + def get(self, store, list_spec): """See `IListManager`.""" - listname, at, hostname = fqdn_listname.partition('@') - list_id = '{}.{}'.format(listname, hostname) - return store.query(MailingList).filter_by(_list_id=list_id).first() + return (self.get_by_fqdn(list_spec) + if '@' in list_spec + else self.get_by_list_id(list_spec)) @dbconnection def get_by_list_id(self, store, list_id): @@ -71,6 +71,13 @@ class ListManager: return store.query(MailingList).filter_by(_list_id=list_id).first() @dbconnection + def get_by_fqdn(self, store, fqdn_listname): + """See `IListManager`.""" + listname, at, hostname = fqdn_listname.partition('@') + list_id = '{}.{}'.format(listname, hostname) + return store.query(MailingList).filter_by(_list_id=list_id).first() + + @dbconnection def delete(self, store, mlist): """See `IListManager`.""" fqdn_listname = mlist.fqdn_listname diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py index 64d1fe1db..2e50575d5 100644 --- a/src/mailman/model/mailinglist.py +++ b/src/mailman/model/mailinglist.py @@ -225,13 +225,13 @@ class MailingList(Model): listen(cls, 'load', cls._post_load) def __repr__(self): - return '<mailing list "{0}" at {1:#x}>'.format( + return '<mailing list "{}" at {:#x}>'.format( self.fqdn_listname, id(self)) @property def fqdn_listname(self): """See `IMailingList`.""" - return '{0}@{1}'.format(self.list_name, self.mail_host) + return '{}@{}'.format(self.list_name, self.mail_host) @property def list_id(self): diff --git a/src/mailman/model/tests/test_listmanager.py b/src/mailman/model/tests/test_listmanager.py index da65f88ce..da8c4f76f 100644 --- a/src/mailman/model/tests/test_listmanager.py +++ b/src/mailman/model/tests/test_listmanager.py @@ -135,6 +135,24 @@ class TestListManager(unittest.TestCase): self.assertEqual(len(result), 1) self.assertEqual(result[0], cat) + def test_find_by_list_spec(self): + ant = create_list('ant@example.com') + list_manager = getUtility(IListManager) + self.assertEqual(list_manager.get('ant@example.com'), ant) + self.assertEqual(list_manager.get('ant.example.com'), ant) + + def test_find_by_list_id(self): + ant = create_list('ant@example.com') + list_manager = getUtility(IListManager) + self.assertEqual(list_manager.get_by_list_id('ant.example.com'), ant) + self.assertIsNone(list_manager.get_by_list_id('ant@example.com')) + + def test_find_by_fqdn(self): + ant = create_list('ant@example.com') + list_manager = getUtility(IListManager) + self.assertEqual(list_manager.get_by_fqdn('ant@example.com'), ant) + self.assertIsNone(list_manager.get_by_fqdn('ant.example.com')) + class TestListLifecycleEvents(unittest.TestCase): layer = ConfigLayer |
