[IMP] factorize http request handling

bzr revid: al@openerp.com-20110818183656-qp9zy271jl6wccq9
This commit is contained in:
Antony Lesuisse 2011-08-18 20:36:56 +02:00
parent 79001193ea
commit 5421809120
2 changed files with 51 additions and 74 deletions

View File

@ -87,9 +87,9 @@ def concat_files(file_list):
ftime = os.path.getmtime(fname)
if ftime > files_timestamp:
files_timestamp = ftime
files_content = open(fname).read()
files_content.append(open(fname).read())
files_concat = "".join(files_content)
return files_concat
return (files_concat,files_timestamp)
home_template = textwrap.dedent("""<!DOCTYPE html>
<html style="height: 100%%">
@ -127,17 +127,17 @@ class WebClient(openerpweb.Controller):
def css(self, req, mods='base'):
cherrypy.response.headers['Content-Type'] = 'text/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
return concat
return content
@openerpweb.httprequest
def js(self, req, mods='base'):
cherrypy.response.headers['Content-Type'] = 'application/javascript'
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
return concat
return content
@openerpweb.httprequest
def home(self, req, s_action=None):
@ -157,7 +157,7 @@ class WebClient(openerpweb.Controller):
'css': css
}
return r
@openerpweb.jsonrequest
def translations(self, req, mods, 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})
return {"modules": transs,
"lang_parameters": lang_obj}
class Database(openerpweb.Controller):
_cp_path = "/base/database"
@ -439,18 +438,16 @@ def clean_action(action, session, context=None):
return action
# values come from the server, we can just eval them
if isinstance(action.get('context'), basestring):
action['context'] = eval(
action['context'],
session.evaluation_context(context=context)) or {}
localvars = session.evaluation_context(context=context)
action['context'] = eval( action['context'], localvars ) or {}
if isinstance(action.get('domain'), basestring):
action['domain'] = eval(
action['domain'],
session.evaluation_context(
action.get('context', {}))) or []
localvars = session.evaluation_context( action.get('context', {}))
action['domain'] = eval( action['domain'], localvars ) or []
return fix_view_modes(action)
# I think generate_views,fix_view_modes should go into js ActionManager
def generate_views(action):
"""
While the server generates a sequence called "views" computing dependencies

View File

@ -233,7 +233,25 @@ class OpenERPSession(object):
#----------------------------------------------------------
# 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.
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):
""" Calls the method asked for by the JSON-RPC2 request
:param controller: the instance of the controller which received the request
:type controller: type
:param method: the method which received the request
:type method: callable
:param requestf: a file-like object containing an encoded JSON-RPC2 request
:type requestf: <read() -> bytes>
:param request: an encoded JSON-RPC2 request
:type request: bytes
:param request: a JSON-RPC2 request
:returns: a string-encoded JSON-RPC2 reply
:rtype: bytes
:returns: an utf8 encoded JSON-RPC2 reply
"""
# Read POST content or POST Form Data named "request"
if requestf:
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')}
response = {"jsonrpc": "2.0" }
error = None
try:
print "--> %s.%s %s" % (controller.__class__.__name__, method.__name__, request)
error = None
self.parse(request)
# Read POST content or POST Form Data named "request"
if requestf:
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)
except OpenERPUnboundException:
error = {
@ -357,41 +354,24 @@ def jsonrequest(f):
@functools.wraps(f)
def json_handler(controller):
return JsonRequest().dispatch(controller, f, requestf=cherrypy.request.body)
return json_handler
class HttpRequest(object):
class HttpRequest(CherryPyRequest):
""" Regular GET/POST request
"""
def dispatch(self, controller, f, request, **kw):
self.request = request
self.applicationsession = applicationsession
self.httpsession_id = "cookieid"
self.httpsession = cherrypy.session
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'
def dispatch(self, controller, method, **kw):
self.init(kw)
print "%s --> %s %s.%s %r" % (self.httprequest.method, controller.__class__.__name__, method.__name__, self.httprequest, kw)
r = method(controller, self, **kw)
print "<--", 'size:', len(r)
print
return r
def httprequest(f):
# check cleaner wrapping:
# functools.wraps(f)(lambda x: JsonRequest().dispatch(x, f))
def http_handler(self,*l, **kw):
return HttpRequest().dispatch(self, f, cherrypy.request, **kw)
def http_handler(controller,*l, **kw):
return HttpRequest().dispatch(controller, f, **kw)
http_handler.exposed = 1
return http_handler