summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Lesuisse <al@openerp.com>2011-03-17 16:47:46 +0100
committerAntony Lesuisse <al@openerp.com>2011-03-17 16:47:46 +0100
commitd51d885c77fa2a9eb53c879ca080b78ab35ebf7b (patch)
tree496df7a4d08217565929d20310c2c7379a2575d0
parente14677f2552b32836e183f1387026fac8b36f1bd (diff)
parent6e9014a8794ca23e457bf69642e695cbe5ae337c (diff)
[MERGE] xmo compliant json-rpc2
bzr revid: al@openerp.com-20110317154746-7mbwuqt9gk940mra
-rw-r--r--addons/base/static/openerp/js/base_chrome.js25
-rw-r--r--openerpweb/openerpweb.py120
2 files changed, 85 insertions, 60 deletions
diff --git a/addons/base/static/openerp/js/base_chrome.js b/addons/base/static/openerp/js/base_chrome.js
index 53256f7d260..dedab94eeab 100644
--- a/addons/base/static/openerp/js/base_chrome.js
+++ b/addons/base/static/openerp/js/base_chrome.js
@@ -143,27 +143,28 @@ openerp.base.Session = openerp.base.BasicController.extend({
// Construct a JSON-RPC2 request, method is currently unused
params.session_id = this.session_id;
params.context = typeof(params.context) != "undefined" ? params.context : this.context;
- var request = { jsonrpc: "2.0", method: "call", params: params, "id":null };
-
- // This is a violation of the JSON-RPC2 over HTTP protocol
- // specification but i don't know how to parse the raw POST content from
- // cherrypy so i use a POST form with one variable named request
- var post = { request: JSON.stringify(request) };
// Use a default error handler unless defined
error_callback = typeof(error_callback) != "undefined" ? error_callback : this.on_rpc_error;
// Call using the rpc_mode
- this.rpc_ajax(url, post, success_callback, error_callback);
- },
- rpc_ajax: function(url, post, success_callback, error_callback) {
+ this.rpc_ajax(url, {
+ jsonrpc: "2.0",
+ method: "call",
+ params: params,
+ id:null
+ }, success_callback, error_callback);
+ },
+ rpc_ajax: function(url, payload, success_callback, error_callback) {
var self = this;
this.on_rpc_request();
$.ajax({
type: "POST",
url: url,
dataType: 'json',
- data: post,
+ contentType: 'application/json',
+ data: JSON.stringify(payload),
+ processData: false,
success: function(response, textStatus, jqXHR) {
self.on_rpc_response();
if (response.error) {
@@ -182,7 +183,7 @@ openerp.base.Session = openerp.base.BasicController.extend({
error: function(jqXHR, textStatus, errorThrown) {
self.on_rpc_response();
var error = {
- code: 1,
+ code: -32098,
message: "XmlHttpRequestError " + errorThrown,
data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
};
@@ -196,7 +197,7 @@ openerp.base.Session = openerp.base.BasicController.extend({
},
on_rpc_error: function(error) {
// TODO this should use the $element with focus and button is displaying OPW etc...
- this.on_log(error, error.message, error.data.type, error.data.debug);
+ this.on_log(error.message, error.data);
},
on_session_invalid: function(contination) {
},
diff --git a/openerpweb/openerpweb.py b/openerpweb/openerpweb.py
index 4a795cce903..3d0db1cea14 100644
--- a/openerpweb/openerpweb.py
+++ b/openerpweb/openerpweb.py
@@ -1,7 +1,9 @@
#!/usr/bin/python
+import functools
import optparse, os, re, sys, traceback, xmlrpclib
+import cherrypy
import cherrypy.lib.static
import simplejson
@@ -79,60 +81,81 @@ class JsonRequest(object):
<-- {"jsonrpc": "2.0", "error": {"code": 1, "message": "End user error message.", "data": {"code": "codestring", "debug": "traceback" } }, "id": null}
"""
- def __init__(self):
- # result may be filled, it's content will be updated by the return
- # value of the dispatched function if it's a dict
- self.result = {}
- self.error_type = ""
- self.error_message = ""
- self.error_debug = ""
def parse(self, request):
- self.cherrypy_request = None
- self.cherrypy_session = None
- d = simplejson.loads(request)
- self.params = d.get("params",{})
+ self.params = request.get("params",{})
self.session_id = self.params.pop("session_id", None) or "random.random"
self.session = session_store.setdefault(self.session_id, OpenERPSession())
- self.context = self.params.pop("context", {})
-
- def dispatch(self, controller, f, request):
+ 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
+
+ :returns: a string-encoded JSON-RPC2 reply
+ :rtype: bytes
+ '''
+ if requestf:
+ request = simplejson.load(requestf)
+ else:
+ request = simplejson.loads(request)
try:
- print "--> %s.%s %s"%(controller.__class__.__name__,f.__name__,request)
- self.parse(request)
- r=f(controller, self, **self.params)
- if isinstance(r, dict):
- self.result.update(r)
- except OpenERPUnboundException,e:
- self.error_type = "session_invalid"
- self.error_message = "OpenERP Session Invalid"
- self.error_debug = traceback.format_exc()
+ print "--> %s.%s %s"%(controller.__class__.__name__,method.__name__,request)
+ error = None
+ result = method(controller, self, **self.parse(request))
+ except OpenERPUnboundException:
+ error = {
+ 'code': 100,
+ 'message': "OpenERP Session Invalid",
+ 'data': {
+ 'type': 'session_invalid',
+ 'debug': traceback.format_exc()
+ }
+ }
except xmlrpclib.Fault, e:
- tb = "".join(traceback.format_exception("", None, sys.exc_traceback))
- self.error_type = "server_exception"
- self.error_message = "OpenERP Server Error: %s"%e.faultCode
- self.error_debug = "Client %s\nServer %s"%(tb,e.faultString)
- except Exception,e:
- self.error_type = "client_exception"
- self.error_message = "OpenERP WebClient Error: %r"%e
- self.error_debug = "Client %s"%traceback.format_exc()
- r = {"jsonrpc": "2.0", "id": None}
- if self.error_type:
- r["error"] = {"code": 1, "message": self.error_message, "data": { "type":self.error_type, "debug": self.error_debug } }
+ error = {
+ 'code': 200,
+ 'message': "OpenERP Server Error",
+ 'data': {
+ 'type': 'server_exception',
+ 'fault_code': e.faultCode,
+ 'debug': "Client %s\nServer %s" % ("".join(traceback.format_exception("", None, sys.exc_traceback)), e.faultString)
+ }
+ }
+ except Exception:
+ error = {
+ 'code': 300,
+ 'message': "OpenERP WebClient Error",
+ 'data': {
+ 'type': 'client_exception',
+ 'debug': "Client %s" % traceback.format_exc()
+ }
+ }
+ response = {"jsonrpc": "2.0", "id": request.get('id')}
+ if error:
+ response["error"] = error
else:
- r["result"] = self.result
- print "<--",r
+ response["result"] = result
+
+ print "<--", response
print
- #import pprint
- #pprint.pprint(r)
- return simplejson.dumps(r)
+ return simplejson.dumps(response)
def jsonrequest(f):
- # check cleaner wrapping:
- # functools.wraps(f)(lambda x: JsonRequest().dispatch(x, f))
- l=lambda self, request: JsonRequest().dispatch(self, f, request)
- l.exposed=1
- return l
+ @cherrypy.expose
+ @functools.wraps(f)
+ def json_handler(self):
+ return JsonRequest().dispatch(self, f, requestf=cherrypy.request.body)
+ return json_handler
class HttpRequest(object):
""" Regular GET/POST request
@@ -234,8 +257,9 @@ def main(argv):
#'server.thread_pool' = 10,
'tools.sessions.on': True,
}
- cherrypy.config.update(config)
- cherrypy_root = Root()
- cherrypy.quickstart(cherrypy_root,'',{'/':{}})
+ cherrypy.tree.mount(Root())
-# vim:
+ cherrypy.config.update(config)
+ cherrypy.server.subscribe()
+ cherrypy.engine.start()
+ cherrypy.engine.block()