summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/interfaces/domain.py2
-rw-r--r--src/mailman/model/docs/domains.rst23
-rw-r--r--src/mailman/model/domain.py9
-rw-r--r--src/mailman/model/listmanager.py1
-rw-r--r--src/mailman/rest/docs/domains.rst43
-rw-r--r--src/mailman/rest/docs/lists.rst19
-rw-r--r--src/mailman/rest/domains.py12
-rw-r--r--src/mailman/rest/lists.py20
-rw-r--r--src/mailman/rest/root.py5
9 files changed, 131 insertions, 3 deletions
diff --git a/src/mailman/interfaces/domain.py b/src/mailman/interfaces/domain.py
index 0e0ea72ae..baf8dafcb 100644
--- a/src/mailman/interfaces/domain.py
+++ b/src/mailman/interfaces/domain.py
@@ -64,6 +64,8 @@ class IDomain(Interface):
The contact address for the human at this domain.
E.g. postmaster@example.com""")
+ mailing_lists = Attribute("""All mailing lists for this domain.""");
+
def confirm_url(token=''):
"""The url used for various forms of confirmation.
diff --git a/src/mailman/model/docs/domains.rst b/src/mailman/model/docs/domains.rst
index 4fa39aa2f..924ab7301 100644
--- a/src/mailman/model/docs/domains.rst
+++ b/src/mailman/model/docs/domains.rst
@@ -71,6 +71,29 @@ Domains can have explicit descriptions and contact addresses.
base_url: http://lists.example.net,
contact_address: postmaster@example.com>
+Domains can list all associated mailing lists with the mailing_lists
+property.
+::
+
+ >>> def show_lists(domain):
+ ... mlists = list(domain.mailing_lists)
+ ... for mlist in mlists:
+ ... print mlist
+ ... if len(mlists) == 0:
+ ... print "no lists"
+
+ >>> net_domain = manager['example.net']
+ >>> com_domain = manager['example.com']
+ >>> show_lists(net_domain)
+ no lists
+ >>> create_list('test@example.net')
+ <mailing list "test@example.net" at ...>
+ >>> transaction.commit()
+ >>> show_lists(net_domain)
+ <mailing list "test@example.net" at ...>
+ >>> show_lists(com_domain)
+ no lists
+
In the global domain manager, domains are indexed by their email host name.
::
diff --git a/src/mailman/model/domain.py b/src/mailman/model/domain.py
index ad3e84fc7..2c0d35082 100644
--- a/src/mailman/model/domain.py
+++ b/src/mailman/model/domain.py
@@ -33,6 +33,7 @@ from mailman.config import config
from mailman.database.model import Model
from mailman.interfaces.domain import (
BadDomainSpecificationError, IDomain, IDomainManager)
+from mailman.model.mailinglist import MailingList
@@ -85,6 +86,14 @@ class Domain(Model):
"""See `IDomain`."""
return urlparse(self.base_url).scheme
+ @property
+ def mailing_lists(self):
+ """See `IDomain`."""
+ mlist_iter = config.db.store.find(MailingList,
+ MailingList.mail_host == self.email_host)
+ for mlist in mlist_iter:
+ yield mlist
+
def confirm_url(self, token=''):
"""See `IDomain`."""
return urljoin(self.base_url, 'confirm/' + token)
diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py
index 16185e670..fbbb85c06 100644
--- a/src/mailman/model/listmanager.py
+++ b/src/mailman/model/listmanager.py
@@ -102,3 +102,4 @@ class ListManager:
"""See `IListManager`."""
# lazr.restful will not allow this to be a generator.
return list(self.mailing_lists)
+
diff --git a/src/mailman/rest/docs/domains.rst b/src/mailman/rest/docs/domains.rst
index 15638c38d..9a2708ac9 100644
--- a/src/mailman/rest/docs/domains.rst
+++ b/src/mailman/rest/docs/domains.rst
@@ -117,6 +117,49 @@ But we get a 404 for a non-existent domain.
...
HTTPError: HTTP Error 404: 404 Not Found
+You can also list mailing lists for a given domain by appending
+`/lists` to the URL.
+
+ >>> dump_json('http://localhost:9001/3.0/domains/example.com/lists')
+ http_etag: "..."
+ start: 0
+ total_size: 0
+
+ >>> dump_json('http://localhost:9001/3.0/lists', {
+ ... 'fqdn_listname': 'test-domains@example.com',
+ ... })
+ content-length: 0
+ date: ...
+ location: http://localhost:9001/3.0/lists/test-domains@example.com
+ ...
+
+ >>> dump_json('http://localhost:9001/3.0/domains/example.com/lists')
+ entry 0:
+ fqdn_listname: test-domains@example.com
+ http_etag: "..."
+ ...
+ self_link: http://localhost:9001/3.0/lists/test-domains@example.com
+ http_etag: "..."
+ start: 0
+ total_size: 1
+
+ >>> dump_json('http://localhost:9001/3.0/domains/lists.example.net/lists')
+ http_etag: "..."
+ start: 0
+ total_size: 0
+
+Here are some poorly-formed URL's for testing purposes:
+
+ >>> dump_json('http://localhost:9001/3.0/domains/example.com/lists/wrong')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 400: 400 Bad Request
+
+ >>> dump_json('http://localhost:9001/3.0/domains/example.com/wrong')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 404: 404 Not Found
+
Creating new domains
====================
diff --git a/src/mailman/rest/docs/lists.rst b/src/mailman/rest/docs/lists.rst
index fd96507c3..f16daf00d 100644
--- a/src/mailman/rest/docs/lists.rst
+++ b/src/mailman/rest/docs/lists.rst
@@ -30,6 +30,25 @@ Create a mailing list in a domain and it's accessible via the API.
start: 0
total_size: 1
+You can also query for lists from a particular domain.
+::
+
+ >>> dump_json('http://localhost:9001/3.0/domains/example.com/lists')
+ entry 0:
+ fqdn_listname: test-one@example.com
+ http_etag: "..."
+ list_name: test-one
+ mail_host: example.com
+ real_name: Test-one
+ self_link: http://localhost:9001/3.0/lists/test-one@example.com
+ http_etag: "..."
+ start: 0
+ total_size: 1
+
+ >>> dump_json('http://localhost:9001/3.0/domains/no.example.org/lists')
+ Traceback (most recent call last):
+ ...
+ HTTPError: HTTP Error 404: 404 Not Found
Creating lists via the API
==========================
diff --git a/src/mailman/rest/domains.py b/src/mailman/rest/domains.py
index d42497157..ca477888c 100644
--- a/src/mailman/rest/domains.py
+++ b/src/mailman/rest/domains.py
@@ -32,6 +32,7 @@ from zope.component import getUtility
from mailman.interfaces.domain import (
BadDomainSpecificationError, IDomainManager)
from mailman.rest.helpers import CollectionMixin, etag, no_content, path_to
+from mailman.rest.lists import ListsForDomain
from mailman.rest.validator import Validator
@@ -79,6 +80,17 @@ class ADomain(_DomainBase):
return http.not_found()
return no_content()
+ @resource.child()
+ def lists(self, request, segments):
+ """/<api>/domains/<domain>/lists"""
+ if len(segments) == 0:
+ domain = getUtility(IDomainManager).get(self._domain)
+ if domain is None:
+ return http.not_found()
+ return ListsForDomain(domain)
+ else:
+ return http.bad_request()
+
class AllDomains(_DomainBase):
"""The domains."""
diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py
index 2c2f58da1..91a2d7ded 100644
--- a/src/mailman/rest/lists.py
+++ b/src/mailman/rest/lists.py
@@ -24,6 +24,7 @@ __all__ = [
'AList',
'AllLists',
'ListConfiguration',
+ 'ListsForDomain',
]
@@ -207,4 +208,21 @@ class MembersOfList(MemberCollection):
roster = self._mlist.get_roster(self._role)
address_of_member = attrgetter('address.email')
return list(sorted(roster.members, key=address_of_member))
-
+
+
+class ListsForDomain(_ListBase):
+ """The mailing lists for a particular domain."""
+
+ def __init__(self, domain):
+ self._domain = domain
+
+ @resource.GET()
+ def collection(self, request):
+ """/<api>/domains/<domain>/lists"""
+ resource = self._make_collection(request)
+ return http.ok([], etag(resource))
+
+ def _get_collection(self, request):
+ """See `CollectionMixin`."""
+ return list(self._domain.mailing_lists)
+
diff --git a/src/mailman/rest/root.py b/src/mailman/rest/root.py
index cd4c8ceef..e4e1433f2 100644
--- a/src/mailman/rest/root.py
+++ b/src/mailman/rest/root.py
@@ -98,8 +98,9 @@ class TopLevel(resource.Resource):
"""
if len(segments) == 0:
return AllDomains()
- elif len(segments) == 1:
- return ADomain(segments[0]), []
+ elif len(segments) >= 1:
+ domain = segments.pop(0)
+ return ADomain(domain), segments
else:
return http.bad_request()