Introduce dynamic scope_path regexps
authorSverre Rabbelier <srabbelier@gmail.com>
Sat, 06 Dec 2008 14:23:53 +0000
changeset 679 77a286ff6667
parent 678 b982d9175605
child 680 7f047b2a2d3a
Introduce dynamic scope_path regexps Instead of relying on scope_path's being "one slash deep", we should instead allow for either: 1. scope_paths that have a pre-defined depth 2. scope_paths that can be arbitrarily deep We achieve 1 by setting an entities scope_logic to another logic module. We then recursively call getScopeDepth until we get to the topmost entity (that is, an unscoped entity). A little different is the solution to 2, since some entities can have an arbitrarily deep scope (such as Documents), we need to have some way of signaling this to getScopePattern. A clean solution is to return None, rather than a number. If None is returned, the SCOPE_PATH_ARG_PATTERN is returned as regexp instead, which will match an arbitrarily deeply nested scope. The solution for 2 requires that we return None somewhere in the scope_logic chain, the most straight forward method to do so is to override getScopeDepth anywhere such a scope is needed and make it return None. A more elegant solution however, is to set the scope_logic to that module in all entities that require it. Patch by: Sverre Rabbelier
app/soc/logic/models/base.py
app/soc/views/helper/params.py
--- a/app/soc/logic/models/base.py	Sat Dec 06 14:23:25 2008 +0000
+++ b/app/soc/logic/models/base.py	Sat Dec 06 14:23:53 2008 +0000
@@ -77,6 +77,18 @@
 
     return self._scope_logic
 
+  def getScopeDepth(self):
+    """Returns the scope depth for this entity
+
+    Returns None if any of the parent scopes return None
+    """
+
+    if not self._scope_logic:
+      return 0
+
+    depth = self._scope_logic.logic.getScopeDepth()
+    return None if (depth is None) else (depth + 1)
+
   def _updateField(self, model, name, value):
     """Hook called when a field is updated.
 
--- a/app/soc/views/helper/params.py	Sat Dec 06 14:23:25 2008 +0000
+++ b/app/soc/views/helper/params.py	Sat Dec 06 14:23:53 2008 +0000
@@ -245,8 +245,24 @@
   patterns = params['key_fields_prefix']
 
   for name in names:
-    pattern = r'(?P<%s>%s)' % (name, linkable.LINK_ID_PATTERN_CORE)
+    if name == 'scope_path':
+      pattern = getScopePattern(params)
+    else:
+      pattern = r'(?P<%s>%s)' % (name, linkable.LINK_ID_PATTERN_CORE)
     patterns.append(pattern)
 
   result = '/'.join(patterns)
   return result
+
+def getScopePattern(params):
+  """Returns the Scope pattern for this entity
+  """
+
+  logic = params['logic']
+  depth = logic.getScopeDepth()
+  if depth is None:
+    return linkable.SCOPE_PATH_ARG_PATTERN
+
+  regexps = [linkable.LINK_ID_PATTERN_CORE for i in range(depth)]
+  regexp = '/'.join(regexps)
+  return r'(?P<scope_path>%s)' % regexp