← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~thumper/launchpad/webservice-person-adapter into lp:launchpad

 

Tim Penhey has proposed merging lp:~thumper/launchpad/webservice-person-adapter into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~thumper/launchpad/webservice-person-adapter/+merge/46658

Adding a webservice adapter for any person field on any object.

tests:
  TestPersonRenderer

Not much to see here.
-- 
https://code.launchpad.net/~thumper/launchpad/webservice-person-adapter/+merge/46658
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~thumper/launchpad/webservice-person-adapter into lp:launchpad.
=== modified file 'lib/lp/code/browser/sourcepackagerecipe.py'
--- lib/lp/code/browser/sourcepackagerecipe.py	2011-01-14 10:06:08 +0000
+++ lib/lp/code/browser/sourcepackagerecipe.py	2011-01-18 19:09:48 +0000
@@ -53,9 +53,7 @@
     enabled_with_permission,
     LaunchpadView,
     Link,
-    Navigation,
     NavigationMenu,
-    stepthrough,
     structured,
     )
 from canonical.launchpad.webapp.authorization import check_permission
@@ -73,7 +71,9 @@
     LaunchpadFormView,
     render_radio_widget_part,
     )
-from lp.app.browser.tales import format_link
+from lp.app.browser.tales import (
+    format_link,
+    )
 from lp.code.errors import (
     BuildAlreadyPending,
     NoSuchBranch,
@@ -85,9 +85,6 @@
     ISourcePackageRecipeSource,
     MINIMAL_RECIPE_TEXT,
     )
-from lp.code.interfaces.sourcepackagerecipebuild import (
-    ISourcePackageRecipeBuildSource,
-    )
 from lp.registry.interfaces.pocket import PackagePublishingPocket
 from lp.soyuz.model.archive import Archive
 

=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml	2011-01-04 16:08:57 +0000
+++ lib/lp/registry/browser/configure.zcml	2011-01-18 19:09:48 +0000
@@ -2328,4 +2328,6 @@
         rootsite="api"
         attribute_to_parent="owner" />
 
+    <adapter factory="lp.registry.browser.webservice.person_renderer"/>
+
 </configure>

=== added file 'lib/lp/registry/browser/tests/test_webservice.py'
--- lib/lp/registry/browser/tests/test_webservice.py	1970-01-01 00:00:00 +0000
+++ lib/lp/registry/browser/tests/test_webservice.py	2011-01-18 19:09:48 +0000
@@ -0,0 +1,34 @@
+# Copyright 2011 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for lp.registry.browser.webservice."""
+
+__metaclass__ = type
+
+
+from lazr.restful.interfaces import IFieldHTMLRenderer
+from lazr.restful.utils import get_current_web_service_request
+from zope.component import getMultiAdapter
+
+from canonical.testing.layers import DatabaseFunctionalLayer
+from lp.app.browser.tales import format_link
+from lp.registry.interfaces.product import IProduct
+from lp.testing import TestCaseWithFactory
+
+
+class TestPersonRenderer(TestCaseWithFactory):
+
+    layer = DatabaseFunctionalLayer
+
+    def test_person_renderer(self):
+        # A person renderer will result in the same text as a tales
+        # PersonFormatter.
+        eric = self.factory.makePerson(name='eric')
+        # We need something that has an IPersonChoice, a project will do.
+        product = self.factory.makeProduct(owner=eric)
+        field = IProduct['owner']
+        request = get_current_web_service_request()
+        renderer = getMultiAdapter(
+            (product, field, request), IFieldHTMLRenderer)
+        self.assertEqual(
+            '<span>%s</span>' % format_link(eric), renderer(eric))

=== added file 'lib/lp/registry/browser/webservice.py'
--- lib/lp/registry/browser/webservice.py	1970-01-01 00:00:00 +0000
+++ lib/lp/registry/browser/webservice.py	2011-01-18 19:09:48 +0000
@@ -0,0 +1,38 @@
+# Copyright 2011 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Adapters for registry objects for the webservice."""
+
+__metaclass__ = type
+__all__ = []
+
+from lazr.restful.interfaces import (
+    IFieldHTMLRenderer,
+    IWebServiceClientRequest,
+    )
+from zope import component
+from zope.interface import (
+    implementer,
+    Interface,
+    )
+
+from lp.app.browser.tales import PersonFormatterAPI
+from lp.services.fields import IPersonChoice
+
+
+@component.adapter(Interface, IPersonChoice, IWebServiceClientRequest)
+@implementer(IFieldHTMLRenderer)
+def person_renderer(context, field, request):
+    """Render a recipe owner as a link."""
+
+    def render(value):
+        if value is None:
+            return ''
+        else:
+            link = PersonFormatterAPI(value).link(None)
+            # This span is required for now as it is used in the parsing of
+            # the dt list returned by default as the xhtml representation.  To
+            # remove this, you need to fix the javascript parsing in
+            # lp.app.javascript.picker (we think).
+            return '<span>%s</span>' % link
+    return render

=== modified file 'lib/lp/services/fields/__init__.py'
--- lib/lp/services/fields/__init__.py	2010-12-20 17:42:47 +0000
+++ lib/lp/services/fields/__init__.py	2011-01-18 19:09:48 +0000
@@ -22,6 +22,7 @@
     'ILocationField',
     'INoneableTextLine',
     'IPasswordField',
+    'IPersonChoice',
     'IStrippedTextLine',
     'ISummary',
     'ITag',
@@ -817,13 +818,17 @@
     __doc__ = _("A private-membership team is not allowed.")
 
 
+class IPersonChoice(IReferenceChoice):
+    """A marker for people choices."""
+
+
 class PersonChoice(Choice):
     """A person or team.
 
     This is useful as a superclass and provides a clearer error message than
     "Constraint not satisfied".
     """
-    implements(IReferenceChoice)
+    implements(IPersonChoice)
     schema = IObject    # Will be set to IPerson once IPerson is defined.
 
 


Follow ups