[FIX] bunch of broken stuff over http requests in new routing thing

* make ModelConverter use its regex for data extraction so
  replacements can just fixup the request and don't have to mess with
  _uid

* replace routing_map property by method, for unknown reasons the
  property does not work at least overridden (it's not found) and I
  don't care enough to wonder why

* arguments result from MapAdapter.match() is a mapping, not a
  sequence. Iterate through values()/itervalues() otherwise we'll
  never get a browse_record to do the uid substitution on, only
  strings (params names)

* inject arguments from URL map/match into the function before
  executing it, this was apparently lost during the transition

* reintroduce get_db_router for third-party code needing to generate
  URLs

bzr revid: xmo@openerp.com-20131115124819-bp4gjpfdlda2qyf5
This commit is contained in:
Xavier Morel 2013-11-15 13:48:19 +01:00
parent 321d4681e1
commit 0ece469392
2 changed files with 17 additions and 9 deletions

View File

@ -2,6 +2,7 @@
# ir_http modular http routing
#----------------------------------------------------------
import logging
import re
import werkzeug.exceptions
import werkzeug.routing
@ -22,14 +23,12 @@ class ModelConverter(werkzeug.routing.BaseConverter):
def __init__(self, url_map, model=False):
super(ModelConverter, self).__init__(url_map)
self.model = model
# TODO add support for slug in the form [A-Za-z0-9-] bla-bla-89 -> id 89
self.regex = '([0-9]+)'
def to_python(self, value):
# TODO:
# - raise routing.ValidationError() if no browse record can be createdm
# - support slug
return request.registry[self.model].browse(request.cr, _uid, int(value), context=request.context)
m = re.match(self.regex, value)
return request.registry[self.model].browse(
request.cr, _uid, int(m.group(1)), context=request.context)
def to_url(self, value):
return value.id
@ -60,7 +59,7 @@ class ir_http(osv.AbstractModel):
return {'model': ModelConverter, 'models': ModelsConverter}
def _find_handler(self):
return self.routing_map.bind_to_environ(request.httprequest.environ).match()
return self.routing_map().bind_to_environ(request.httprequest.environ).match()
def _auth_method_user(self):
request.uid = request.session.uid
@ -113,7 +112,7 @@ class ir_http(osv.AbstractModel):
return self._handle_403(e)
# post process arg to set uid on browse records
for arg in arguments:
for arg in arguments.itervalues():
if isinstance(arg, orm.browse_record) and arg._uid is _uid:
arg._uid = request.uid
@ -130,7 +129,6 @@ class ir_http(osv.AbstractModel):
return result
@property
def routing_map(self):
if not hasattr(self, '_routing_map'):
_logger.info("Generating routing map")

View File

@ -100,6 +100,7 @@ class WebRequest(object):
self.disable_db = False
self.uid = None
self.func = None
self.func_arguments = {}
self.auth_method = None
self._cr_cm = None
self._cr = None
@ -143,7 +144,8 @@ class WebRequest(object):
def set_handler(self, func, arguments, auth):
# is this needed ?
arguments = dict([(k, v) for k, v in arguments.items() if not k.startswith("_ignored_")])
arguments = dict((k, v) for k, v in arguments.iteritems()
if not k.startswith("_ignored_"))
self.func = func
self.func_request_type = func.exposed
@ -167,6 +169,9 @@ class WebRequest(object):
if self.func_request_type != self._request_type:
raise Exception("%s, %s: Function declared as capable of handling request of type '%s' but called with a request of type '%s'" \
% (self.func, self.httprequest.path, self.func_request_type, self._request_type))
kwargs.update(self.func_arguments)
# Backward for 7.0
if getattr(self.func, '_first_arg_is_req', False):
args = (request,) + args
@ -987,6 +992,11 @@ class Root(object):
except werkzeug.exceptions.HTTPException, e:
return e(environ, start_response)
def get_db_router(self, db):
if not db:
return self.nodb_routing_map
return request.registry['ir.http'].routing_map()
def db_list(force=False, httprequest=None):
httprequest = httprequest or request.httprequest
dbs = openerp.netsvc.dispatch_rpc("db", "list", [force])