andrej@1881: from __future__ import absolute_import
laurent@371: import sys
andrej@1832: import gluon.contrib.simplejson as simplejson
laurent@371: 
andrej@1736: 
andrej@1851: class JSONRPCServiceBase(object):
laurent@371: 
laurent@371:     def __init__(self):
andrej@1742:         self.methods = {}
laurent@371: 
laurent@371:     def response(self, id, result):
andrej@1740:         return simplejson.dumps({'version': '1.1', 'id': id,
andrej@1740:                                  'result': result, 'error': None})
andrej@1751: 
laurent@371:     def error(self, id, code, message):
andrej@1773:         return simplejson.dumps({
andrej@1773:             'id': id,
andrej@1773:             'version': '1.1',
andrej@1773:             'error': {'name': 'JSONRPCError',
andrej@1773:                       'code': code,
andrej@1773:                       'message': message}
andrej@1773:         })
laurent@371: 
laurent@371:     def add_method(self, name, method):
laurent@371:         self.methods[name] = method
laurent@371: 
laurent@371:     def process(self, data):
laurent@371:         data = simplejson.loads(data)
laurent@371:         id, method, params = data["id"], data["method"], data["params"]
laurent@371:         if method in self.methods:
laurent@371:             try:
andrej@1742:                 result = self.methods[method](*params)
laurent@371:                 return self.response(id, result)
andrej@1866:             except Exception:
andrej@1866:                 etype, eval, _etb = sys.exc_info()
andrej@1866:                 return self.error(id, 100, 'Exception %s: %s' % (etype, eval))
laurent@371:             except BaseException:
andrej@1847:                 etype, eval, _etb = sys.exc_info()
andrej@1742:                 return self.error(id, 100, '%s: %s' % (etype.__name__, eval))
laurent@371:         else:
laurent@371:             return self.error(id, 100, 'method "%s" does not exist' % method)
laurent@371: 
laurent@371:     def listmethods(self):
andrej@1730:         return self.methods.keys()