summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/interfaces/rest.py44
-rw-r--r--src/mailman/model/listmanager.py3
-rw-r--r--src/mailman/queue/rest.py2
-rw-r--r--src/mailman/rest/adapters.py14
-rw-r--r--src/mailman/rest/webservice.py86
-rw-r--r--src/mailman/rest/wsgiapp.py87
6 files changed, 96 insertions, 140 deletions
diff --git a/src/mailman/interfaces/rest.py b/src/mailman/interfaces/rest.py
deleted file mode 100644
index 9ec7914ad..000000000
--- a/src/mailman/interfaces/rest.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2009-2010 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Interfaces for the RESTful admin server."""
-
-from __future__ import absolute_import, unicode_literals
-
-__metaclass__ = type
-__all__ = [
- 'APIValueError',
- 'IResolvePathNames',
- ]
-
-
-from zope.interface import Interface
-
-from mailman.core.errors import MailmanError
-
-
-
-class APIValueError(MailmanError, ValueError):
- """A `ValueError` from the REST API."""
-
-
-
-class IResolvePathNames(Interface):
- """A marker interface objects that implement simple traversal."""
-
- def get(name):
- """Traverse to a contained object."""
diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py
index cc3226b80..3d0448e8e 100644
--- a/src/mailman/model/listmanager.py
+++ b/src/mailman/model/listmanager.py
@@ -32,7 +32,6 @@ from zope.interface import implements
from mailman.config import config
from mailman.interfaces.address import InvalidEmailAddressError
from mailman.interfaces.listmanager import IListManager, ListAlreadyExistsError
-from mailman.interfaces.rest import IResolvePathNames
from mailman.model.mailinglist import MailingList
@@ -40,7 +39,7 @@ from mailman.model.mailinglist import MailingList
class ListManager:
"""An implementation of the `IListManager` interface."""
- implements(IListManager, IResolvePathNames)
+ implements(IListManager)
# pylint: disable-msg=R0201
def create(self, fqdn_listname):
diff --git a/src/mailman/queue/rest.py b/src/mailman/queue/rest.py
index a14f0b081..a7c9727e2 100644
--- a/src/mailman/queue/rest.py
+++ b/src/mailman/queue/rest.py
@@ -32,7 +32,7 @@ import signal
import logging
from mailman.queue import Runner
-from mailman.rest.webservice import make_server
+from mailman.rest.wsgiapp import make_server
log = logging.getLogger('mailman.http')
diff --git a/src/mailman/rest/adapters.py b/src/mailman/rest/adapters.py
index 2ae5d497e..6acfe3866 100644
--- a/src/mailman/rest/adapters.py
+++ b/src/mailman/rest/adapters.py
@@ -36,7 +36,6 @@ from mailman.interfaces.address import InvalidEmailAddressError
from mailman.interfaces.listmanager import IListManager, NoSuchListError
from mailman.interfaces.member import DeliveryMode
from mailman.interfaces.membership import ISubscriptionService
-from mailman.interfaces.rest import APIValueError
@@ -77,15 +76,10 @@ class SubscriptionService:
mlist = getUtility(IListManager).get(fqdn_listname)
if mlist is None:
raise NoSuchListError(fqdn_listname)
- # Convert from string to enum. Turn Python's ValueErrors into one
- # suitable for the REST API.
- try:
- mode = (DeliveryMode.regular
- if delivery_mode is None
- else DeliveryMode(delivery_mode))
- except ValueError:
- raise APIValueError(
- 'Invalid delivery_mode: {0}'.format(delivery_mode))
+ # Convert from string to enum.
+ mode = (DeliveryMode.regular
+ if delivery_mode is None
+ else DeliveryMode(delivery_mode))
if real_name is None:
real_name, at, domain = address.partition('@')
if len(at) == 0:
diff --git a/src/mailman/rest/webservice.py b/src/mailman/rest/webservice.py
index d7f7d231e..9db29f133 100644
--- a/src/mailman/rest/webservice.py
+++ b/src/mailman/rest/webservice.py
@@ -21,9 +21,7 @@ from __future__ import absolute_import, unicode_literals
__metaclass__ = type
__all__ = [
- 'AdminWebServiceApplication',
- 'AdminWebServiceRequest',
- 'make_server',
+ 'Root',
]
@@ -31,10 +29,8 @@ import json
import hashlib
import logging
-from restish.app import RestishApp
from restish import http, resource
-from wsgiref.simple_server import (
- make_server as wsgi_server, WSGIRequestHandler)
+from wsgiref.simple_server import make_server as wsgi_server
from zope.component import getUtility
from zope.interface import implements
@@ -51,8 +47,6 @@ from mailman.interfaces.mailinglist import IMailingList
from mailman.interfaces.member import (
AlreadySubscribedError, IMember, MemberRole)
from mailman.interfaces.membership import ISubscriptionService
-from mailman.interfaces.rest import APIValueError, IResolvePathNames
-#from mailman.rest.publication import AdminWebServicePublication
COMMASPACE = ', '
@@ -370,7 +364,7 @@ class AllMembers(_MemberBase):
return http.bad_request([], b'No such list')
except InvalidEmailAddressError:
return http.bad_request([], b'Invalid email address')
- except APIValueError as error:
+ except ValueError as error:
return http.bad_request([], str(error))
# wsgiref wants headers to be bytes, not unicodes.
location = b'http://localhost:8001/3.0/lists/{0}/member/{1}'.format(
@@ -399,77 +393,3 @@ class AllMembers(_MemberBase):
member_data = self._format_member(member)
entries.append(member_data)
return http.ok([], json.dumps(response))
-
-
-
-
-## class AdminWebServiceRootResource(RootResource):
-## """The lazr.restful non-versioned root resource."""
-
-## implements(IResolvePathNames)
-
-## # XXX 2010-02-16 barry lazr.restful really wants this class to exist and
-## # be a subclass of RootResource. Our own traversal really wants this to
-## # implement IResolvePathNames. RootResource says to override
-## # _build_top_level_objects() to return the top-level objects, but that
-## # appears to never be called by lazr.restful, so you've got me. I don't
-## # understand this, which sucks, so just ensure that it doesn't do anything
-## # useful so if/when I do understand this, I can resolve the conflict
-## # between the way lazr.restful wants us to do things and the way our
-## # traversal wants to do things.
-## def _build_top_level_objects(self):
-## """See `RootResource`."""
-## raise NotImplementedError('Magic suddenly got invoked')
-
-## def get(self, name):
-## """See `IResolvePathNames`."""
-## top_names = dict(
-## domains=getUtility(IDomainCollection),
-## lists=getUtility(IListManager),
-## members=getUtility(ISubscriptionService),
-## system=system,
-## )
-## return top_names.get(name)
-
-
-## class AdminWebServiceApplication(WSGIApplication):
-## """A WSGI application for the admin REST interface."""
-
-## # The only thing we need to override is the publication class.
-## publication_class = AdminWebServicePublication
-
-
-class AdminWebServiceWSGIRequestHandler(WSGIRequestHandler):
- """Handler class which just logs output to the right place."""
-
- def log_message(self, format, *args):
- """See `BaseHTTPRequestHandler`."""
- log.info('%s - - %s', self.address_string(), format % args)
-
-
-class AdminWebServiceApplication(RestishApp):
- """Interpose in the restish request processor."""
-
- def __call__(self, environ, start_response):
- """See `RestishApp`."""
- try:
- response = super(AdminWebServiceApplication, self).__call__(
- environ, start_response)
- except:
- config.db.abort()
- raise
- else:
- config.db.commit()
- return response
-
-
-
-def make_server():
- """Create the WSGI admin REST server."""
- app = AdminWebServiceApplication(Root())
- host = config.webservice.hostname
- port = int(config.webservice.port)
- server = wsgi_server(
- host, port, app,
- handler_class=AdminWebServiceWSGIRequestHandler)
- return server
diff --git a/src/mailman/rest/wsgiapp.py b/src/mailman/rest/wsgiapp.py
new file mode 100644
index 000000000..cfb8cba50
--- /dev/null
+++ b/src/mailman/rest/wsgiapp.py
@@ -0,0 +1,87 @@
+# Copyright (C) 2010 by the Free Software Foundation, Inc.
+#
+# This file is part of GNU Mailman.
+#
+# GNU Mailman is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
+
+"""Basic WSGI Application object for REST server."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ 'make_application',
+ 'make_server',
+ ]
+
+
+import logging
+
+from restish.app import RestishApp
+from wsgiref.simple_server import WSGIRequestHandler
+from wsgiref.simple_server import make_server as wsgi_server
+
+from mailman.config import config
+from mailman.rest.webservice import Root
+
+
+log = logging.getLogger('mailman.http')
+
+
+
+class AdminWebServiceWSGIRequestHandler(WSGIRequestHandler):
+ """Handler class which just logs output to the right place."""
+
+ def log_message(self, format, *args):
+ """See `BaseHTTPRequestHandler`."""
+ log.info('%s - - %s', self.address_string(), format % args)
+
+
+class AdminWebServiceApplication(RestishApp):
+ """Connect the restish WSGI application to Mailman's database."""
+
+ def __call__(self, environ, start_response):
+ """See `RestishApp`."""
+ try:
+ response = super(AdminWebServiceApplication, self).__call__(
+ environ, start_response)
+ except:
+ config.db.abort()
+ raise
+ else:
+ config.db.commit()
+ return response
+
+
+
+def make_application():
+ """Create the WSGI application.
+
+ Use this if you want to integrate Mailman's REST server with your own WSGI
+ server.
+ """
+ return AdminWebServiceApplication(Root())
+
+
+def make_server():
+ """Create the Mailman REST server.
+
+ Use this if you just want to run Mailman's wsgiref-based REST server.
+ """
+ host = config.webservice.hostname
+ port = int(config.webservice.port)
+ server = wsgi_server(
+ host, port, make_application(),
+ handler_class=AdminWebServiceWSGIRequestHandler)
+ return server