2011-01-27, 11:09
daledude Wrote:I cant remember where I found this python module. I believe it was on this forum. It makes accessing xbmc via json more pythonic and a dream. If anyone knows who wrote this I'd like to attribute them in the file!
Code:...
Thanks for that, I've adapted it slightly to use httplib and exposing a single JSONConnection class.
Code:
try:
import simplejson as json
except ImportError:
import json
import base64
import httplib
__all__ = ['JSONConnection', 'JSONRPCError', 'JSONConnectionError', 'JSONUserPassError']
class JSONError(Exception):
pass
class JSONRPCError(JSONError):
def __init__(self, code, message):
JSONError.__init__(self, message)
self.code = code
self.message = message
class JSONConnectionError(JSONError):
def __init__(self, code, message):
JSONError.__init__(self, message)
self.code = code
self.message = message
class JSONUserPassError(JSONError):
pass
class JSONConnection(object):
def __init__(self, host='127.0.0.1', port=8080, username='xbmc', password=''):
self.host = host
self.port = port
self.username = username
self.password = password
self._namespace_cache = {}
def __getattr__(self, namespace):
if namespace in self._namespace_cache:
return self._namespace_cache[namespace]
nsobj = self.Namespace(namespace, self)
self._namespace_cache[namespace] = nsobj
return nsobj
class Namespace(object):
def __init__(self, name, connection):
self.name = name
self.connection = connection
self._id = 1
self._handler_cache = {}
def __getattr__(self, method):
if method in self._handler_cache:
return self._handler_cache[method]
def handler(**kwargs):
data = {'jsonrpc': '2.0',
'id': self._id,
'method': '%s.%s' % (self.name, method)
}
if args:
if len(args) == 1:
data['params'] = args[0]
else:
data['params'] = []
for arg in args:
data['params'].append(arg)
elif kwargs:
data['params'] = {}
for k in kwargs:
data['params'][k] = kwargs[k]
postdata = json.dumps(data, ensure_ascii=False)
postdata = postdata.encode('utf-8')
headers = {'Content-Type': 'application/json-rpc; charset=utf-8'}
if self.connection.password != '':
userpass = base64.encodestring('%s:%s' % \
(self.connection.username, self.connection.password))[:-1]
headers['Authorization'] = 'Basic %s' % userpass
conn = httplib.HTTPConnection(self.connection.host,
self.connection.port)
conn.request('POST', '/jsonrpc', postdata, headers)
data = None
response = conn.getresponse()
if response.status == httplib.OK:
data = response.read()
conn.close()
if response.status != httplib.OK:
if response.status == httplib.UNAUTHORIZED:
raise JSONUserPassError()
else:
raise JSONConnectionError(response.status,
'Connection Error: %s' % httplib.responses[response.status])
conn.close()
self._id += 1
if data is not None:
response = json.loads(data)
if 'error' in response:
raise JSONRPCError(json['error']['code'],
json['error']['message'])
return response['result']
else:
return None
handler.method = method
self._handler_cache[method] = handler
return handler
if __name__ == '__main__':
conn = JSONConnection()
data = conn.JSONRPC.Introspect()
print(json.dumps(data, sort_keys=True, indent=4))
Edit: Added code to send positional args. XBMC expects a single position arg to be sent as is which may not be valid JSON-RPC 2.0