[CHG] Allow @http.route() to use additional parameters and inherits them properly
authorFabien Meghazi <fme@openerp.com>
Mon, 20 Jan 2014 15:36:14 +0000 (16:36 +0100)
committerFabien Meghazi <fme@openerp.com>
Mon, 20 Jan 2014 15:36:14 +0000 (16:36 +0100)
bzr revid: fme@openerp.com-20140120153614-t8l7tfit686ehfn0

openerp/addons/base/ir/ir_http.py
openerp/http.py

index 089d962..7d0c4be 100644 (file)
@@ -99,7 +99,7 @@ class ir_http(osv.AbstractModel):
 
         # check authentication level
         try:
-            auth_method = self._authenticate(getattr(func, "auth", None))
+            auth_method = self._authenticate(func.routing["auth"])
         except Exception:
             # force a Forbidden exception with the original traceback
             return self._handle_exception(
index 92d9349..03c8c99 100644 (file)
@@ -168,7 +168,7 @@ class WebRequest(object):
                          if not k.startswith("_ignored_"))
 
         self.func = func
-        self.func_request_type = func.exposed
+        self.func_request_type = func.routing['type']
         self.func_arguments = arguments
         self.auth_method = auth
 
@@ -207,7 +207,7 @@ class WebRequest(object):
         warnings.warn('please use request.registry and request.cr directly', DeprecationWarning)
         yield (self.registry, self.cr)
 
-def route(route, type="http", auth="user", methods=None):
+def route(route=None, **kw):
     """
     Decorator marking the decorated method as being a handler for requests. The method must be part of a subclass
     of ``Controller``.
@@ -226,16 +226,16 @@ def route(route, type="http", auth="user", methods=None):
         configuration indicating the current database nor the current user.
     :param methods: A sequence of http methods this route applies to. If not specified, all methods are allowed.
     """
-    assert type in ["http", "json"]
+    routing = kw.copy()
+    assert not 'type' in routing or routing['type'] in ("http", "json")
     def decorator(f):
-        if isinstance(route, list):
-            f.routes = route
-        else:
-            f.routes = [route]
-        f.methods = methods
-        f.exposed = type
-        if getattr(f, "auth", None) is None:
-            f.auth = auth
+        if route:
+            if isinstance(route, list):
+                routes = route
+            else:
+                routes = [route]
+            routing['routes'] = routes
+        f.routing = routing
         return f
     return decorator
 
@@ -388,11 +388,10 @@ def jsonrequest(f):
 
         Use the ``route()`` decorator instead.
     """
-    f.combine = True
     base = f.__name__.lstrip('/')
     if f.__name__ == "index":
         base = ""
-    return route([base, base + "/<path:_ignored_path>"], type="json", auth="user")(f)
+    return route([base, base + "/<path:_ignored_path>"], type="json", auth="user", combine=True)(f)
 
 class HttpRequest(WebRequest):
     """ Regular GET/POST request
@@ -444,11 +443,10 @@ def httprequest(f):
 
         Use the ``route()`` decorator instead.
     """
-    f.combine = True
     base = f.__name__.lstrip('/')
     if f.__name__ == "index":
         base = ""
-    return route([base, base + "/<path:_ignored_path>"], type="http", auth="user")(f)
+    return route([base, base + "/<path:_ignored_path>"], type="http", auth="user", combine=True)(f)
 
 #----------------------------------------------------------
 # Controller and route registration
@@ -501,13 +499,22 @@ def routing_map(modules, nodb_only, converters=None):
             o = cls()
             members = inspect.getmembers(o)
             for mk, mv in members:
-                if inspect.ismethod(mv) and getattr(mv, 'exposed', False) and (not nodb_only or nodb_only == (mv.auth == "none")):
-                    for url in mv.routes:
-                        if getattr(mv, "combine", False):
-                            url = o._cp_path.rstrip('/') + '/' + url.lstrip('/')
-                            if url.endswith("/") and len(url) > 1:
-                                url = url[: -1]
-                        routing_map.add(werkzeug.routing.Rule(url, endpoint=mv, methods=mv.methods))
+                if inspect.ismethod(mv) and hasattr(mv, 'routing'):
+                    routing = dict(type='http', auth='user', methods=None)
+                    for claz in reversed(mv.im_class.mro()):
+                        fn = getattr(claz, mv.func_name, None)
+                        if fn and hasattr(fn, 'routing'):
+                            routing.update(fn.routing)
+                    mv.routing.update(routing)
+                    assert 'routes' in mv.routing
+                    if not nodb_only or nodb_only == (mv.routing['auth'] == "none"):
+                        for url in mv.routing['routes']:
+                            if mv.routing.get("combine", False):
+                                # deprecated
+                                url = o._cp_path.rstrip('/') + '/' + url.lstrip('/')
+                                if url.endswith("/") and len(url) > 1:
+                                    url = url[: -1]
+                            routing_map.add(werkzeug.routing.Rule(url, endpoint=mv, methods=mv.routing['methods']))
     return routing_map
 
 #----------------------------------------------------------