Implemented JSON-RPC apivariant
This commit is contained in:
parent
6a089e0f88
commit
726986c1eb
1
setup.py
1
setup.py
|
@ -11,6 +11,7 @@ from src.version import softwareVersion
|
||||||
|
|
||||||
EXTRAS_REQUIRE = {
|
EXTRAS_REQUIRE = {
|
||||||
'gir': ['pygobject'],
|
'gir': ['pygobject'],
|
||||||
|
'json': ['jsonrpclib'],
|
||||||
'notify2': ['notify2'],
|
'notify2': ['notify2'],
|
||||||
'opencl': ['pyopencl', 'numpy'],
|
'opencl': ['pyopencl', 'numpy'],
|
||||||
'prctl': ['python_prctl'], # Named threads
|
'prctl': ['python_prctl'], # Named threads
|
||||||
|
|
41
src/api.py
41
src/api.py
|
@ -54,6 +54,7 @@ except ImportError:
|
||||||
else:
|
else:
|
||||||
monkey_patch()
|
monkey_patch()
|
||||||
|
|
||||||
|
|
||||||
str_chan = '[chan]'
|
str_chan = '[chan]'
|
||||||
str_broadcast_subscribers = '[Broadcast subscribers]'
|
str_broadcast_subscribers = '[Broadcast subscribers]'
|
||||||
|
|
||||||
|
@ -64,16 +65,6 @@ class APIError(xmlrpclib.Fault):
|
||||||
return "API Error %04i: %s" % (self.faultCode, self.faultString)
|
return "API Error %04i: %s" % (self.faultCode, self.faultString)
|
||||||
|
|
||||||
|
|
||||||
class StoppableXMLRPCServer(SimpleXMLRPCServer):
|
|
||||||
"""A SimpleXMLRPCServer that honours state.shutdown"""
|
|
||||||
allow_reuse_address = True
|
|
||||||
|
|
||||||
def serve_forever(self, poll_interval=None):
|
|
||||||
"""Start the SimpleXMLRPCServer"""
|
|
||||||
while state.shutdown == 0:
|
|
||||||
self.handle_request()
|
|
||||||
|
|
||||||
|
|
||||||
# This thread, of which there is only one, runs the API.
|
# This thread, of which there is only one, runs the API.
|
||||||
class singleAPI(StoppableThread):
|
class singleAPI(StoppableThread):
|
||||||
"""API thread"""
|
"""API thread"""
|
||||||
|
@ -99,17 +90,38 @@ class singleAPI(StoppableThread):
|
||||||
getattr(errno, 'WSAEADDRINUSE')
|
getattr(errno, 'WSAEADDRINUSE')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
errno.WSAEADDRINUSE = errno.EADDRINUSE
|
errno.WSAEADDRINUSE = errno.EADDRINUSE
|
||||||
|
|
||||||
|
RPCServerBase = SimpleXMLRPCServer
|
||||||
|
if BMConfigParser().safeGet(
|
||||||
|
'bitmessagesettings', 'apivariant') == 'json':
|
||||||
|
try:
|
||||||
|
from jsonrpclib.SimpleJSONRPCServer import (
|
||||||
|
SimpleJSONRPCServer as RPCServerBase)
|
||||||
|
except ImportError:
|
||||||
|
logger.warning(
|
||||||
|
'jsonrpclib not available, failing back to XML-RPC')
|
||||||
|
|
||||||
|
# Nested class. FIXME not found a better solution.
|
||||||
|
class StoppableRPCServer(RPCServerBase):
|
||||||
|
"""A SimpleXMLRPCServer that honours state.shutdown"""
|
||||||
|
allow_reuse_address = True
|
||||||
|
|
||||||
|
def serve_forever(self, poll_interval=None):
|
||||||
|
"""Start the RPCServer"""
|
||||||
|
while state.shutdown == 0:
|
||||||
|
self.handle_request()
|
||||||
|
|
||||||
for attempt in range(50):
|
for attempt in range(50):
|
||||||
try:
|
try:
|
||||||
if attempt > 0:
|
if attempt > 0:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
'Failed to start API listener on port %s', port)
|
'Failed to start API listener on port %s', port)
|
||||||
port = random.randint(32767, 65535)
|
port = random.randint(32767, 65535)
|
||||||
se = StoppableXMLRPCServer(
|
se = StoppableRPCServer(
|
||||||
(BMConfigParser().get(
|
(BMConfigParser().get(
|
||||||
'bitmessagesettings', 'apiinterface'),
|
'bitmessagesettings', 'apiinterface'),
|
||||||
port),
|
port),
|
||||||
BMXMLRPCRequestHandler, True, True)
|
BMXMLRPCRequestHandler, True, encoding='UTF-8')
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if e.errno in (errno.EADDRINUSE, errno.WSAEADDRINUSE):
|
if e.errno in (errno.EADDRINUSE, errno.WSAEADDRINUSE):
|
||||||
continue
|
continue
|
||||||
|
@ -120,7 +132,8 @@ class singleAPI(StoppableThread):
|
||||||
'bitmessagesettings', 'apiport', str(port))
|
'bitmessagesettings', 'apiport', str(port))
|
||||||
BMConfigParser().save()
|
BMConfigParser().save()
|
||||||
break
|
break
|
||||||
se.register_instance(BMXMLRPCDispatcher())
|
|
||||||
|
se.register_instance(BMRPCDispatcher())
|
||||||
se.register_introspection_functions()
|
se.register_introspection_functions()
|
||||||
|
|
||||||
apiNotifyPath = BMConfigParser().safeGet(
|
apiNotifyPath = BMConfigParser().safeGet(
|
||||||
|
@ -288,7 +301,7 @@ class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class BMXMLRPCDispatcher(object):
|
class BMRPCDispatcher(object):
|
||||||
"""This class is used to dispatch API commands"""
|
"""This class is used to dispatch API commands"""
|
||||||
__metaclass__ = CommandHandler
|
__metaclass__ = CommandHandler
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user