""" Requires the jsolait Javascript library: http://jsolait.net/ Typically unpack this library into web/jsolait """ from Component import Component, ServletComponent from json import jsonToObj, objToJson from paste import httpexceptions from cStringIO import StringIO import traceback from paste import wsgilib class JSONServletComponent(ServletComponent): _servletMethods = ['jsonaction', 'jsonjs'] def __init__(self, jsolaitURL='jsolait', libURL='', baseConfig=None, jsonMethods=()): self.baseConfig = baseConfig self.jsolaitURL = jsolaitURL self.libURL = libURL self._declaredJsonMethods = list(jsonMethods) def actions(self): return ['jsonaction'] def jsonMethods(self): all_methods = self._declaredJsonMethods[:] all_methods.extend(self.optionalMethod('jsonMethods', [])) return all_methods def jsonaction(self): request_body = self.servlet().request().rawInput().read() req_data = jsonToObj(request_body) req_id = req_data['id'] try: method_name = req_data['method'] if method_name not in self.jsonMethods(): raise HTTPForbidden( "The method %s is not public" % method_name) method = getattr(self.servlet(), method_name) result = method(*req_data['params']) json_res = {'id': req_id, 'result': result, 'error': None} json_res = objToJson(json_res) except Exception, e: if isinstance(e, httpexceptions.HTTPException): raise out = StringIO() # @@: I should also report this error traceback.print_exc(file=out) json_res = {'id': req_id, 'result': None, 'error': out.getvalue()} json_res = objToJson(json_res) self.servlet().response().write(json_res) self.servlet().setView(None) def jsonjs(self): env = self.servlet().request().environ() jsolaitURL = self.jsolaitURL lib = self.libURL here = wsgilib.construct_url(env, False) here += '?_action_=jsonaction'; if self.baseConfig: app_base = env['%s.base_url' % self.baseConfig] if not jsolaitURL.startswith('/'): jsolaitURL = app_base + '/' + jsolaitURL if not lib.startswith('/'): lib = app_base + '/' + lib text = (r''' ''' % {'jsolaitURL': jsolaitURL, 'lib': lib, 'here': here, 'methods': self.jsonMethods()}) return text class JSONComponent(Component): _componentClass = JSONServletComponent