/usr/share/pyshared/scrapy/utils/jsonrpc.py is in python-scrapy 0.14.4-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | """
This module implements the JSON-RPC 2.0 protocol, as defined in:
http://groups.google.com/group/json-rpc/web/json-rpc-2-0
"""
import urllib
import traceback
from scrapy.utils.py26 import json
from scrapy.utils.serialize import ScrapyJSONDecoder
# JSON-RPC 2.0 errors, as defined in:
class jsonrpc_errors:
PARSE_ERROR = -32700
INVALID_REQUEST = -32600
METHOD_NOT_FOUND = -32601
INVALID_PARAMS = -32602
INTERNAL_ERROR = -32603
class JsonRpcError(Exception):
def __init__(self, code, message, data=None):
super(JsonRpcError, self).__init__()
self.code = code
self.message = message
self.data = data
def __str__(self):
return "JSON-RPC error (code %d): %s" % (self.code, self.message)
def jsonrpc_client_call(url, method, *args, **kwargs):
"""Execute a JSON-RPC call on the given url"""
_urllib = kwargs.pop('_urllib', urllib)
if args and kwargs:
raise ValueError("Pass *args or **kwargs but not both to jsonrpc_client_call")
req = {'jsonrpc': '2.0', 'method': method, 'params': args or kwargs, 'id': 1}
res = json.loads(_urllib.urlopen(url, json.dumps(req)).read())
if 'result' in res:
return res['result']
elif 'error' in res:
er = res['error']
raise JsonRpcError(er['code'], er['message'], er['data'])
else:
msg = "JSON-RPC response must contain 'result' or 'error': %s" % res
raise ValueError(msg)
def jsonrpc_server_call(target, jsonrpc_request, json_decoder=None):
"""Execute the given JSON-RPC request (as JSON-encoded string) on the given
target object and return the JSON-RPC response, as a dict
"""
if json_decoder is None:
json_decoder = ScrapyJSONDecoder()
try:
req = json_decoder.decode(jsonrpc_request)
except Exception, e:
return jsonrpc_error(None, jsonrpc_errors.PARSE_ERROR, 'Parse error', \
traceback.format_exc())
try:
id, methname = req['id'], req['method']
except KeyError:
return jsonrpc_error(None, jsonrpc_errors.INVALID_REQUEST, 'Invalid Request')
try:
method = getattr(target, methname)
except AttributeError:
return jsonrpc_error(id, jsonrpc_errors.METHOD_NOT_FOUND, 'Method not found')
params = req.get('params', [])
a, kw = ([], params) if isinstance(params, dict) else (params, {})
kw = dict([(str(k), v) for k, v in kw.items()]) # convert kw keys to str
try:
return jsonrpc_result(id, method(*a, **kw))
except Exception, e:
return jsonrpc_error(id, jsonrpc_errors.INTERNAL_ERROR, str(e), \
traceback.format_exc())
def jsonrpc_error(id, code, message, data=None):
"""Create JSON-RPC error response"""
return {
'jsonrpc': '2.0',
'error': {
'code': code,
'message': message,
'data': data,
},
'id': id,
}
def jsonrpc_result(id, result):
"""Create JSON-RPC result response"""
return {
'jsonrpc': '2.0',
'result': result,
'id': id,
}
|