[IMP] factorize http request handling
bzr revid: al@openerp.com-20110818183656-qp9zy271jl6wccq9
This commit is contained in:
parent
79001193ea
commit
5421809120
|
@ -87,9 +87,9 @@ def concat_files(file_list):
|
||||||
ftime = os.path.getmtime(fname)
|
ftime = os.path.getmtime(fname)
|
||||||
if ftime > files_timestamp:
|
if ftime > files_timestamp:
|
||||||
files_timestamp = ftime
|
files_timestamp = ftime
|
||||||
files_content = open(fname).read()
|
files_content.append(open(fname).read())
|
||||||
files_concat = "".join(files_content)
|
files_concat = "".join(files_content)
|
||||||
return files_concat
|
return (files_concat,files_timestamp)
|
||||||
|
|
||||||
home_template = textwrap.dedent("""<!DOCTYPE html>
|
home_template = textwrap.dedent("""<!DOCTYPE html>
|
||||||
<html style="height: 100%%">
|
<html style="height: 100%%">
|
||||||
|
@ -127,17 +127,17 @@ class WebClient(openerpweb.Controller):
|
||||||
def css(self, req, mods='base'):
|
def css(self, req, mods='base'):
|
||||||
cherrypy.response.headers['Content-Type'] = 'text/css'
|
cherrypy.response.headers['Content-Type'] = 'text/css'
|
||||||
files = manifest_glob(mods.split(','), 'css')
|
files = manifest_glob(mods.split(','), 'css')
|
||||||
concat = concat_files(files)[0]
|
content,timestamp = concat_files(files)
|
||||||
# TODO request set the Date of last modif and Etag
|
# TODO request set the Date of last modif and Etag
|
||||||
return concat
|
return content
|
||||||
|
|
||||||
@openerpweb.httprequest
|
@openerpweb.httprequest
|
||||||
def js(self, req, mods='base'):
|
def js(self, req, mods='base'):
|
||||||
cherrypy.response.headers['Content-Type'] = 'application/javascript'
|
cherrypy.response.headers['Content-Type'] = 'application/javascript'
|
||||||
files = manifest_glob(mods.split(','), 'js')
|
files = manifest_glob(mods.split(','), 'js')
|
||||||
concat = concat_files(files)[0]
|
content,timestamp = concat_files(files)
|
||||||
# TODO request set the Date of last modif and Etag
|
# TODO request set the Date of last modif and Etag
|
||||||
return concat
|
return content
|
||||||
|
|
||||||
@openerpweb.httprequest
|
@openerpweb.httprequest
|
||||||
def home(self, req, s_action=None):
|
def home(self, req, s_action=None):
|
||||||
|
@ -157,7 +157,7 @@ class WebClient(openerpweb.Controller):
|
||||||
'css': css
|
'css': css
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def translations(self, req, mods, lang):
|
def translations(self, req, mods, lang):
|
||||||
lang_model = req.session.model('res.lang')
|
lang_model = req.session.model('res.lang')
|
||||||
|
@ -193,7 +193,6 @@ class WebClient(openerpweb.Controller):
|
||||||
transl["messages"].append({'id': x.id, 'string': x.string})
|
transl["messages"].append({'id': x.id, 'string': x.string})
|
||||||
return {"modules": transs,
|
return {"modules": transs,
|
||||||
"lang_parameters": lang_obj}
|
"lang_parameters": lang_obj}
|
||||||
|
|
||||||
|
|
||||||
class Database(openerpweb.Controller):
|
class Database(openerpweb.Controller):
|
||||||
_cp_path = "/base/database"
|
_cp_path = "/base/database"
|
||||||
|
@ -439,18 +438,16 @@ def clean_action(action, session, context=None):
|
||||||
return action
|
return action
|
||||||
# values come from the server, we can just eval them
|
# values come from the server, we can just eval them
|
||||||
if isinstance(action.get('context'), basestring):
|
if isinstance(action.get('context'), basestring):
|
||||||
action['context'] = eval(
|
localvars = session.evaluation_context(context=context)
|
||||||
action['context'],
|
action['context'] = eval( action['context'], localvars ) or {}
|
||||||
session.evaluation_context(context=context)) or {}
|
|
||||||
|
|
||||||
if isinstance(action.get('domain'), basestring):
|
if isinstance(action.get('domain'), basestring):
|
||||||
action['domain'] = eval(
|
localvars = session.evaluation_context( action.get('context', {}))
|
||||||
action['domain'],
|
action['domain'] = eval( action['domain'], localvars ) or []
|
||||||
session.evaluation_context(
|
|
||||||
action.get('context', {}))) or []
|
|
||||||
|
|
||||||
return fix_view_modes(action)
|
return fix_view_modes(action)
|
||||||
|
|
||||||
|
# I think generate_views,fix_view_modes should go into js ActionManager
|
||||||
def generate_views(action):
|
def generate_views(action):
|
||||||
"""
|
"""
|
||||||
While the server generates a sequence called "views" computing dependencies
|
While the server generates a sequence called "views" computing dependencies
|
||||||
|
|
|
@ -233,7 +233,25 @@ class OpenERPSession(object):
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
# OpenERP Web RequestHandler
|
# OpenERP Web RequestHandler
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
class JsonRequest(object):
|
class CherryPyRequest(object):
|
||||||
|
""" CherryPy request handling
|
||||||
|
"""
|
||||||
|
def init(self,params):
|
||||||
|
self.params = params
|
||||||
|
# Move cherrypy thread local objects to attributes
|
||||||
|
self.applicationsession = applicationsession
|
||||||
|
self.httprequest = cherrypy.request
|
||||||
|
self.httpresponse = cherrypy.response
|
||||||
|
self.httpsession = cherrypy.session
|
||||||
|
self.httpsession_id = "cookieid"
|
||||||
|
# OpenERP session setup
|
||||||
|
self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex
|
||||||
|
host = cherrypy.config['openerp.server.host']
|
||||||
|
port = cherrypy.config['openerp.server.port']
|
||||||
|
self.session = self.httpsession.setdefault(self.session_id, OpenERPSession(host, port))
|
||||||
|
self.context = self.params.pop('context', None)
|
||||||
|
|
||||||
|
class JsonRequest(CherryPyRequest):
|
||||||
""" JSON-RPC2 over HTTP.
|
""" JSON-RPC2 over HTTP.
|
||||||
|
|
||||||
Sucessful request::
|
Sucessful request::
|
||||||
|
@ -267,48 +285,27 @@ class JsonRequest(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def parse(self, request):
|
|
||||||
self.request = request
|
|
||||||
self.params = request.get("params", {})
|
|
||||||
self.applicationsession = applicationsession
|
|
||||||
self.httprequest = cherrypy.request
|
|
||||||
self.httpresponse = cherrypy.response
|
|
||||||
self.httpsession = cherrypy.session
|
|
||||||
self.httpsession_id = "cookieid"
|
|
||||||
self.httpsession = cherrypy.session
|
|
||||||
self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex
|
|
||||||
host = cherrypy.config['openerp.server.host']
|
|
||||||
port = cherrypy.config['openerp.server.port']
|
|
||||||
self.session = self.httpsession.setdefault(self.session_id, OpenERPSession(host, port))
|
|
||||||
self.context = self.params.pop('context', None)
|
|
||||||
return self.params
|
|
||||||
|
|
||||||
def dispatch(self, controller, method, requestf=None, request=None):
|
def dispatch(self, controller, method, requestf=None, request=None):
|
||||||
""" Calls the method asked for by the JSON-RPC2 request
|
""" Calls the method asked for by the JSON-RPC2 request
|
||||||
|
|
||||||
:param controller: the instance of the controller which received the request
|
:param controller: the instance of the controller which received the request
|
||||||
:type controller: type
|
|
||||||
:param method: the method which received the request
|
:param method: the method which received the request
|
||||||
:type method: callable
|
|
||||||
:param requestf: a file-like object containing an encoded JSON-RPC2 request
|
:param requestf: a file-like object containing an encoded JSON-RPC2 request
|
||||||
:type requestf: <read() -> bytes>
|
:param request: a JSON-RPC2 request
|
||||||
:param request: an encoded JSON-RPC2 request
|
|
||||||
:type request: bytes
|
|
||||||
|
|
||||||
:returns: a string-encoded JSON-RPC2 reply
|
:returns: an utf8 encoded JSON-RPC2 reply
|
||||||
:rtype: bytes
|
|
||||||
"""
|
"""
|
||||||
# Read POST content or POST Form Data named "request"
|
response = {"jsonrpc": "2.0" }
|
||||||
if requestf:
|
error = None
|
||||||
request = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder)
|
|
||||||
else:
|
|
||||||
request = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
|
|
||||||
|
|
||||||
response = {"jsonrpc": "2.0", "id": request.get('id')}
|
|
||||||
try:
|
try:
|
||||||
print "--> %s.%s %s" % (controller.__class__.__name__, method.__name__, request)
|
# Read POST content or POST Form Data named "request"
|
||||||
error = None
|
if requestf:
|
||||||
self.parse(request)
|
self.jsonrequest = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder)
|
||||||
|
else:
|
||||||
|
self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
|
||||||
|
print "--> %s.%s %s" % (controller.__class__.__name__, method.__name__, self.jsonrequest)
|
||||||
|
self.init(self.jsonrequest.get("params", {}))
|
||||||
|
response['id'] = self.jsonrequest.get('id')
|
||||||
response["result"] = method(controller, self, **self.params)
|
response["result"] = method(controller, self, **self.params)
|
||||||
except OpenERPUnboundException:
|
except OpenERPUnboundException:
|
||||||
error = {
|
error = {
|
||||||
|
@ -357,41 +354,24 @@ def jsonrequest(f):
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
def json_handler(controller):
|
def json_handler(controller):
|
||||||
return JsonRequest().dispatch(controller, f, requestf=cherrypy.request.body)
|
return JsonRequest().dispatch(controller, f, requestf=cherrypy.request.body)
|
||||||
|
|
||||||
return json_handler
|
return json_handler
|
||||||
|
|
||||||
class HttpRequest(object):
|
class HttpRequest(CherryPyRequest):
|
||||||
""" Regular GET/POST request
|
""" Regular GET/POST request
|
||||||
"""
|
"""
|
||||||
def dispatch(self, controller, f, request, **kw):
|
def dispatch(self, controller, method, **kw):
|
||||||
self.request = request
|
self.init(kw)
|
||||||
self.applicationsession = applicationsession
|
print "%s --> %s %s.%s %r" % (self.httprequest.method, controller.__class__.__name__, method.__name__, self.httprequest, kw)
|
||||||
self.httpsession_id = "cookieid"
|
r = method(controller, self, **kw)
|
||||||
self.httpsession = cherrypy.session
|
print "<--", 'size:', len(r)
|
||||||
self.context = kw.get('context', {})
|
|
||||||
host = cherrypy.config['openerp.server.host']
|
|
||||||
port = cherrypy.config['openerp.server.port']
|
|
||||||
self.session_id = kw.pop('session_id', None)
|
|
||||||
self.session = self.httpsession.setdefault(self.session_id, OpenERPSession(host, port))
|
|
||||||
self.result = ""
|
|
||||||
if request.method == 'GET':
|
|
||||||
print "GET --> %s.%s %s %r" % (controller.__class__.__name__, f.__name__, request, kw)
|
|
||||||
else:
|
|
||||||
akw = dict([(key, kw[key] if isinstance(kw[key], basestring) else type(kw[key])) for key in kw.keys()])
|
|
||||||
print "POST --> %s.%s %s %r" % (controller.__class__.__name__, f.__name__, request, akw)
|
|
||||||
r = f(controller, self, **kw)
|
|
||||||
if isinstance(r, str):
|
|
||||||
print "<--", len(r), 'bytes'
|
|
||||||
else:
|
|
||||||
print "<--", len(r), 'characters'
|
|
||||||
print
|
print
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def httprequest(f):
|
def httprequest(f):
|
||||||
# check cleaner wrapping:
|
# check cleaner wrapping:
|
||||||
# functools.wraps(f)(lambda x: JsonRequest().dispatch(x, f))
|
# functools.wraps(f)(lambda x: JsonRequest().dispatch(x, f))
|
||||||
def http_handler(self,*l, **kw):
|
def http_handler(controller,*l, **kw):
|
||||||
return HttpRequest().dispatch(self, f, cherrypy.request, **kw)
|
return HttpRequest().dispatch(controller, f, **kw)
|
||||||
http_handler.exposed = 1
|
http_handler.exposed = 1
|
||||||
return http_handler
|
return http_handler
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue