← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~lifeless/launchpad/features into lp:launchpad/devel

 

Robert Collins has proposed merging lp:~lifeless/launchpad/features into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  #634342 need a features 'scope' for page ids
  https://bugs.launchpad.net/bugs/634342


Allow feature rules matching page ids for the scope.
-- 
https://code.launchpad.net/~lifeless/launchpad/features/+merge/35217
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~lifeless/launchpad/features into lp:launchpad/devel.
=== modified file 'lib/canonical/launchpad/webapp/publication.py'
--- lib/canonical/launchpad/webapp/publication.py	2010-08-20 20:31:18 +0000
+++ lib/canonical/launchpad/webapp/publication.py	2010-09-12 04:03:50 +0000
@@ -446,7 +446,7 @@
 
         # The view may be security proxied
         view = removeSecurityProxy(ob)
-        # It's possible that the view is a bounded method.
+        # It's possible that the view is a bound method.
         view = getattr(view, 'im_self', view)
         context = removeSecurityProxy(getattr(view, 'context', None))
         pageid = self.constructPageID(view, context)

=== modified file 'lib/lp/services/features/webapp.py'
--- lib/lp/services/features/webapp.py	2010-09-06 20:25:28 +0000
+++ lib/lp/services/features/webapp.py	2010-09-12 04:03:50 +0000
@@ -10,6 +10,7 @@
 import canonical.config
 from lp.services.features import per_thread
 from lp.services.features.flags import FeatureController
+from lp.services.propertycache import cachedproperty
 
 
 class ScopesFromRequest(object):
@@ -24,14 +25,57 @@
         Currently supports the following scopes:
          - default
          - is_edge/is_lpnet etc (thunks through to the config)
+         - pageid:
+           This scope works on a namespace model: for a page
+           with pageid SomeType:+view#subselector
+           The following page ids scopes will match:
+             - pageid:   (but use 'default' as it is simpler)
+             - pageid:SomeType
+             - pageid:SomeType:+view
+             - pageid:SomeType:+view#subselector
         """
         if scope_name == 'default':
             return True
+        if scope_name.startswith('pageid:'):
+            return self._lookup_pageid(scope_name[len('pageid:'):])
         parts = scope_name.split('.')
         if len(parts) == 2:
             if parts[0] == 'server':
                 return canonical.config.config['launchpad']['is_' + parts[1]]
 
+    def _lookup_pageid(self, pageid_scope):
+        """Lookup a pageid as a scope.
+
+        pageid scopes are written as 'pageid:' + the pageid to match.
+        Page ids are treated as a namespace with : and # delimiters.
+
+        E.g. the scope 'pageid:Foo' will affect pages with pageids:
+        Foo
+        Foo:Bar
+        Foo#quux
+        """
+        scope_segments = self._pageid_to_namespace(pageid_scope)
+        request_segments = self._request_pageid_namespace
+        # In 2.6, this can be replaced with izip_longest
+        for pos, name in enumerate(scope_segments):
+            if pos == len(request_segments):
+                return False
+            if request_segments[pos] != name:
+                return False
+        return True
+
+    def _pageid_to_namespace(self, pageid):
+        """Return a list of namespace elements for pageid."""
+        # Normalise delimiters.
+        pageid = pageid.replace('#', ':')
+        # Create a list to walk, empty namespaces are elided.
+        return [name for name in pageid.split(':') if name]
+
+    @cachedproperty
+    def _request_pageid_namespace(self):
+        return tuple(self._pageid_to_namespace(
+            self._request._orig_env.get('launchpad.pageid', '')))
+
 
 def start_request(event):
     """Register FeatureController."""