------------------------------------------------------------
revno: 6747
committer: Barry Warsaw <[email protected]>
branch nick: 3.0
timestamp: Fri 2009-07-10 21:55:26 -0400
message:
  Clean a few more lints.
  
  Add get_mailing_lists() which is used just for the web interface.  Because of
  a bug in lazr.restful, this cannot be a generator.
  
  Similar change in IDomainSet.
  
  Instrument IListManager to be vended through the api.
  
  The REST server must be run in a separate process since SQLite does not like
  objects created in one thread to be used in another thread.  Note that this
  breaks the domain.txt test, but domains really need to be in the database
  anyway.
removed:
  src/mailman/rest/testing/
  src/mailman/rest/testing/__init__.py
  src/mailman/rest/testing/server.py
added:
  src/mailman/rest/docs/lists.txt
modified:
  src/mailman/database/listmanager.py
  src/mailman/docs/listmanager.txt
  src/mailman/interfaces/domain.py
  src/mailman/interfaces/listmanager.py
  src/mailman/interfaces/mailinglist.py
  src/mailman/rest/adapters.py
  src/mailman/rest/configure.zcml
  src/mailman/rest/publication.py
  src/mailman/rest/urls.py
  src/mailman/rest/webservice.py
  src/mailman/testing/layers.py

=== modified file 'src/mailman/database/listmanager.py'
--- src/mailman/database/listmanager.py 2009-01-21 01:54:22 +0000
+++ src/mailman/database/listmanager.py 2009-07-11 01:55:26 +0000
@@ -40,6 +40,7 @@
 
     implements(IListManager)
 
+    # pylint: disable-msg=R0201
     def create(self, fqdn_listname):
         """See `IListManager`."""
         listname, hostname = fqdn_listname.split('@', 1)
@@ -80,3 +81,8 @@
         """See `IListManager`."""
         for mlist in config.db.store.find(MailingList):
             yield '{...@{1}'.format(mlist.list_name, mlist.host_name)
+
+    def get_mailing_lists(self):
+        """See `IListManager`."""
+        # lazr.restful will not allow this to be a generator.
+        return list(self.mailing_lists)

=== modified file 'src/mailman/docs/listmanager.txt'
--- src/mailman/docs/listmanager.txt    2009-01-04 05:22:08 +0000
+++ src/mailman/docs/listmanager.txt    2009-07-11 01:55:26 +0000
@@ -1,5 +1,6 @@
-Using the IListManager interface
-================================
+========================
+The mailing list manager
+========================
 
 The IListManager is how you create, delete, and retrieve mailing list
 objects.  The Mailman system instantiates an IListManager for you based on the
@@ -13,7 +14,7 @@
 
 
 Creating a mailing list
------------------------
+=======================
 
 Creating the list returns the newly created IMailList object.
 
@@ -43,7 +44,7 @@
 
 
 Deleting a mailing list
------------------------
+=======================
 
 Use the list manager to delete a mailing list.
 
@@ -59,7 +60,7 @@
 
 
 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.
@@ -75,7 +76,7 @@
 
 
 Iterating over all mailing lists
---------------------------------
+================================
 
 Once you've created a bunch of mailing lists, you can use the list manager to
 iterate over either the list objects, or the list names.

=== modified file 'src/mailman/interfaces/domain.py'
--- src/mailman/interfaces/domain.py    2009-06-30 01:30:04 +0000
+++ src/mailman/interfaces/domain.py    2009-07-11 01:55:26 +0000
@@ -97,5 +97,9 @@
     export_as_webservice_collection(IDomain)
 
     @collection_default_content()
-    def __iter__():
-        """Iterate over all domains."""
+    def get_domains():
+        """The list of all domains.
+
+        :return: The list of all known domains.
+        :rtype: list of `IDomain`
+        """

=== modified file 'src/mailman/interfaces/listmanager.py'
--- src/mailman/interfaces/listmanager.py       2009-01-17 02:04:21 +0000
+++ src/mailman/interfaces/listmanager.py       2009-07-11 01:55:26 +0000
@@ -26,8 +26,12 @@
     ]
 
 
+from lazr.restful.declarations import (
+    collection_default_content, export_as_webservice_collection)
 from zope.interface import Interface, Attribute
+
 from mailman.interfaces.errors import MailmanError
+from mailman.interfaces.mailinglist import IMailingList
 
 
 
@@ -49,6 +53,8 @@
     `[email protected]`.
     """
 
+    export_as_webservice_collection(IMailingList)
+
     def create(fqdn_listname):
         """Create a mailing list with the given name.
 
@@ -82,3 +88,11 @@
     names = Attribute(
         """An iterator over the fully qualified list names of all mailing
         lists managed by this list manager.""")
+
+    @collection_default_content()
+    def get_mailing_lists():
+        """The list of all mailing lists.
+
+        :return: The list of all known mailing lists.
+        :rtype: list of `IMailingList`
+        """

=== modified file 'src/mailman/interfaces/mailinglist.py'
--- src/mailman/interfaces/mailinglist.py       2009-03-03 15:15:42 +0000
+++ src/mailman/interfaces/mailinglist.py       2009-07-11 01:55:26 +0000
@@ -30,8 +30,13 @@
     ]
 
 
+from lazr.restful.declarations import (
+    export_as_webservice_entry, exported)
 from munepy import Enum
 from zope.interface import Interface, Attribute
+from zope.schema import TextLine
+
+from mailman.i18n import _
 
 
 
@@ -66,31 +71,39 @@
 class IMailingList(Interface):
     """A mailing list."""
 
+    export_as_webservice_entry()
+
     # List identity
 
-    list_name = Attribute(
-        """The read-only short name of the mailing list.  Note that where a
+    list_name = exported(TextLine(
+        title=_("The mailing list's short name"),
+        description=_("""\
+        The read-only short name of the mailing list.  Note that where a
         Mailman installation supports multiple domains, this short name may
         not be unique.  Use the fqdn_listname attribute for a guaranteed
         unique id for the mailing list.  This short name is always the local
         part of the posting email address.  For example, if messages are
         posted to [email protected], then the list_name is 'mylist'.
-        """)
+        """)))
 
-    host_name = Attribute(
-        """The read-only domain name 'hosting' this mailing list.  This is
-        always the domain name part of the posting email address, and it may
-        bear no relationship to the web url used to access this mailing list.
-        For example, if messages are posted to [email protected], then the
+    host_name = exported(TextLine(
+        title=_("The mailing list's host name"),
+        description=_("""\
+        The read-only domain name 'hosting' this mailing list.  This is always
+        the domain name part of the posting email address, and it may bear no
+        relationship to the web url used to access this mailing list.  For
+        example, if messages are posted to [email protected], then the
         host_name is 'example.com'.
-        """)
+        """)))
 
-    fqdn_listname = Attribute(
-        """The read-only fully qualified name of the mailing list.  This is
-        the guaranteed unique id for the mailing list, and it is always the
+    fqdn_listname = exported(TextLine(
+        title=_("The mailing list's filly qualified name"),
+        description=_("""\
+        The read-only fully qualified name of the mailing list.  This is the
+        guaranteed unique id for the mailing list, and it is always the
         address to which messages are posted, e.g. [email protected].  It is
         always comprised of the list_name + '@' + host_name.
-        """)
+        """)))
 
     real_name = Attribute(
         """The short human-readable descriptive name for the mailing list.  By

=== modified file 'src/mailman/rest/adapters.py'
--- src/mailman/rest/adapters.py        2009-06-30 03:31:51 +0000
+++ src/mailman/rest/adapters.py        2009-07-11 01:55:26 +0000
@@ -43,8 +43,9 @@
     def __init__(self, config):
         self._config = config
 
-    def __iter__(self):
+    def get_domains(self):
         """See `IDomainSet`."""
+        # lazr.restful will not allow this to be a generator.
         domains = self._config.domains
         return [domains[domain] for domain in sorted(domains)]
 

=== modified file 'src/mailman/rest/configure.zcml'
--- src/mailman/rest/configure.zcml     2009-06-30 03:15:11 +0000
+++ src/mailman/rest/configure.zcml     2009-07-11 01:55:26 +0000
@@ -8,8 +8,9 @@
   <include package="lazr.restful" file="meta.zcml"/>
   <include package="lazr.restful" file="configure.zcml"/>
 
+  <webservice:register module="mailman.interfaces.domain" />
+  <webservice:register module="mailman.interfaces.listmanager" />
   <webservice:register module="mailman.interfaces.system" />
-  <webservice:register module="mailman.interfaces.domain" />
 
   <adapter
     for="mailman.config.config.IConfiguration"

=== added file 'src/mailman/rest/docs/lists.txt'
--- src/mailman/rest/docs/lists.txt     1970-01-01 00:00:00 +0000
+++ src/mailman/rest/docs/lists.txt     2009-07-11 01:55:26 +0000
@@ -0,0 +1,12 @@
+=============
+Mailing lists
+=============
+
+The REST API can be queried for the set of known mailing lists.  There is a
+top level collection that can return all the mailing lists.  There aren't any
+yet though.
+
+    >>> dump_json('http://localhost:8001/3.0/lists')
+    resource_type_link: https://localhost:8001/3.0/#mailing_lists
+    start: None
+    total_size: 0

=== modified file 'src/mailman/rest/publication.py'
--- src/mailman/rest/publication.py     2009-06-30 03:15:11 +0000
+++ src/mailman/rest/publication.py     2009-07-11 01:55:26 +0000
@@ -41,6 +41,7 @@
 
 class Publication:
     """Very simple implementation of `IPublication`."""
+
     implements(IPublication)
 
     def __init__(self, application):
@@ -94,6 +95,7 @@
 
     def endRequest(self, request, ob):
         """Ends the interaction."""
+        config.db.commit()
         endInteraction()
 
 

=== removed directory 'src/mailman/rest/testing'
=== removed file 'src/mailman/rest/testing/__init__.py'
=== removed file 'src/mailman/rest/testing/server.py'
--- src/mailman/rest/testing/server.py  2009-06-30 01:46:20 +0000
+++ src/mailman/rest/testing/server.py  1970-01-01 00:00:00 +0000
@@ -1,63 +0,0 @@
-# Copyright (C) 2009 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/>.
-
-"""A testable REST server."""
-
-from __future__ import absolute_import, unicode_literals
-
-__metaclass__ = type
-__all__ = [
-    'TestableServer',
-    ]
-
-
-import logging
-import threading
-
-from urllib2 import urlopen
-
-from mailman.rest.webservice import make_server
-
-
-log = logging.getLogger('mailman.http')
-
-
-
-class TestableServer:
-    """A REST server which polls for the stop action."""
-
-    def __init__(self):
-        self.server = make_server()
-        self.event = threading.Event()
-        self.thread = threading.Thread(target=self.loop)
-        self.thread.daemon = True
-        
-    def start(self):
-        """Start the server."""
-        self.thread.start()
-
-    def stop(self):
-        """Stop the server by firing the event."""
-        self.event.set()
-        # Fire off one more request so the handle_request() will exit.
-        fp = urlopen('http://localhost:8001/3.0/system')
-        fp.close()
-        self.thread.join()
-
-    def loop(self):
-        while not self.event.is_set():
-            self.server.handle_request()

=== modified file 'src/mailman/rest/urls.py'
--- src/mailman/rest/urls.py    2009-06-30 03:15:11 +0000
+++ src/mailman/rest/urls.py    2009-07-11 01:55:26 +0000
@@ -26,6 +26,8 @@
     ]
 
 
+import logging
+
 from zope.component import adapts
 from zope.interface import implements, Interface
 from zope.traversing.browser.interfaces import IAbsoluteURL
@@ -35,6 +37,8 @@
 from mailman.rest.configuration import AdminWebServiceConfiguration
 from mailman.rest.webservice import AdminWebServiceApplication
 
+log = logging.getLogger('mailman.http')
+
 
 
 class BasicURLMapper:
@@ -72,11 +76,13 @@
         :rtype: string
         :raises KeyError: if no path component can be found.
         """
+        log.debug('generic url mapper lookup: %s', ob)
         # Special cases.
         if isinstance(ob, AdminWebServiceApplication):
             return ''
         urls = {
             system: 'system',
+            #config.db.list_manager: 'lists',
             }
         return urls[ob]
 

=== modified file 'src/mailman/rest/webservice.py'
--- src/mailman/rest/webservice.py      2009-06-30 01:30:04 +0000
+++ src/mailman/rest/webservice.py      2009-07-11 01:55:26 +0000
@@ -49,6 +49,7 @@
 
 
 
+# pylint: disable-msg: W0232
 class AdminWebServiceRequest(WebServiceRequestTraversal, BrowserRequest):
     """A request for the admin REST interface."""
 
@@ -81,9 +82,11 @@
 
     def get(self, name):
         """Maps root names to resources."""
+        log.debug('Getting top level name: %s', name)
         top_level = dict(
             system=system,
             domains=IDomainSet(config),
+            lists=config.db.list_manager,
             )
         return top_level.get(name)
 

=== modified file 'src/mailman/testing/layers.py'
--- src/mailman/testing/layers.py       2009-05-27 15:44:10 +0000
+++ src/mailman/testing/layers.py       2009-07-11 01:55:26 +0000
@@ -32,20 +32,23 @@
 import sys
 import shutil
 import logging
+import datetime
 import tempfile
 
 from pkg_resources import resource_string
 from textwrap import dedent
+from urllib2 import urlopen, URLError
 
 from mailman.config import config
 from mailman.core import initialize
 from mailman.core.logging import get_handler
 from mailman.i18n import _
-from mailman.testing.helpers import SMTPServer
+from mailman.testing.helpers import SMTPServer, TestableMaster
 from mailman.utilities.datetime import factory
 from mailman.utilities.string import expand
 
 
+TEST_TIMEOUT = datetime.timedelta(seconds=5)
 NL = '\n'
 
 
@@ -230,12 +233,25 @@
 
     server = None
 
+    @staticmethod
+    def _wait_for_rest_server():
+        until = datetime.datetime.now() + TEST_TIMEOUT
+        while datetime.datetime.now() < until:
+            try:
+                fp = urlopen('http://localhost:8001/3.0/system')
+            except URLError:
+                pass
+            else:
+                fp.close()
+                break
+        else:
+            raise RuntimeError('REST server did not start up')
+
     @classmethod
     def setUp(cls):
         assert cls.server is None, 'Layer already set up'
-        from mailman.rest.testing.server import TestableServer
-        cls.server = TestableServer()
-        cls.server.start()
+        cls.server = TestableMaster(cls._wait_for_rest_server)
+        cls.server.start('rest')
 
     @classmethod
     def tearDown(cls):



--
lp:mailman
https://code.launchpad.net/~mailman-coders/mailman/3.0

Your team Mailman Checkins is subscribed to branch lp:mailman.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+edit-subscription.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to