summaryrefslogtreecommitdiffstats
path: root/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib
diff options
context:
space:
mode:
Diffstat (limited to 'external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib')
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/SimpleJSONRPCServer.py602
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/__init__.py34
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/config.py141
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/history.py95
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonclass.py295
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonrpc.py1192
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/threadpool.py490
-rw-r--r--external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/utils.py122
8 files changed, 0 insertions, 2971 deletions
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/SimpleJSONRPCServer.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/SimpleJSONRPCServer.py
deleted file mode 100644
index e9fe4e68..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/SimpleJSONRPCServer.py
+++ /dev/null
@@ -1,602 +0,0 @@
-#!/usr/bin/python
-# -- Content-Encoding: UTF-8 --
-"""
-Defines a request dispatcher, a HTTP request handler, a HTTP server and a
-CGI request handler.
-
-:authors: Josh Marshall, Thomas Calmant
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Module version
-__version_info__ = (0, 2, 5)
-__version__ = ".".join(str(x) for x in __version_info__)
-
-# Documentation strings format
-__docformat__ = "restructuredtext en"
-
-# ------------------------------------------------------------------------------
-# Local modules
-from jsonrpclib import Fault
-import jsonrpclib.config
-import jsonrpclib.utils as utils
-import jsonrpclib.threadpool
-
-# Standard library
-import logging
-import socket
-import sys
-import traceback
-
-# Prepare the logger
-_logger = logging.getLogger(__name__)
-
-try:
- # Python 3
- # pylint: disable=F0401,E0611
- import xmlrpc.server as xmlrpcserver
- import socketserver
-except (ImportError, AttributeError):
- # Python 2 or IronPython
- # pylint: disable=F0401,E0611
- import SimpleXMLRPCServer as xmlrpcserver
- import SocketServer as socketserver
-
-try:
- # Windows
- import fcntl
-except ImportError:
- # Other systems
- # pylint: disable=C0103
- fcntl = None
-
-# ------------------------------------------------------------------------------
-
-
-def get_version(request):
- """
- Computes the JSON-RPC version
-
- :param request: A request dictionary
- :return: The JSON-RPC version or None
- """
- if 'jsonrpc' in request:
- return 2.0
- elif 'id' in request:
- return 1.0
-
- return None
-
-
-def validate_request(request, json_config):
- """
- Validates the format of a request dictionary
-
- :param request: A request dictionary
- :param json_config: A JSONRPClib Config instance
- :return: True if the dictionary is valid, else a Fault object
- """
- if not isinstance(request, utils.DictType):
- # Invalid request type
- fault = Fault(-32600, 'Request must be a dict, not {0}'
- .format(type(request).__name__),
- config=json_config)
- _logger.warning("Invalid request content: %s", fault)
- return fault
-
- # Get the request ID
- rpcid = request.get('id', None)
-
- # Check request version
- version = get_version(request)
- if not version:
- fault = Fault(-32600, 'Request {0} invalid.'.format(request),
- rpcid=rpcid, config=json_config)
- _logger.warning("No version in request: %s", fault)
- return fault
-
- # Default parameters: empty list
- request.setdefault('params', [])
-
- # Check parameters
- method = request.get('method', None)
- params = request.get('params')
- param_types = (utils.ListType, utils.DictType, utils.TupleType)
-
- if not method or not isinstance(method, utils.string_types) or \
- not isinstance(params, param_types):
- # Invalid type of method name or parameters
- fault = Fault(-32600, 'Invalid request parameters or method.',
- rpcid=rpcid, config=json_config)
- _logger.warning("Invalid request content: %s", fault)
- return fault
-
- # Valid request
- return True
-
-# ------------------------------------------------------------------------------
-
-
-class NoMulticallResult(Exception):
- """
- No result in multicall
- """
- pass
-
-
-class SimpleJSONRPCDispatcher(xmlrpcserver.SimpleXMLRPCDispatcher, object):
- """
- Mix-in class that dispatches JSON-RPC requests.
-
- This class is used to register JSON-RPC method handlers
- and then to dispatch them. This class doesn't need to be
- instanced directly when used by SimpleJSONRPCServer.
- """
- def __init__(self, encoding=None, config=jsonrpclib.config.DEFAULT):
- """
- Sets up the dispatcher with the given encoding.
- None values are allowed.
- """
- xmlrpcserver.SimpleXMLRPCDispatcher.__init__(
- self, allow_none=True, encoding=encoding or "UTF-8")
- self.json_config = config
-
- # Notification thread pool
- self.__notification_pool = None
-
- def set_notification_pool(self, thread_pool):
- """
- Sets the thread pool to use to handle notifications
- """
- self.__notification_pool = thread_pool
-
- def _unmarshaled_dispatch(self, request, dispatch_method=None):
- """
- Loads the request dictionary (unmarshaled), calls the method(s)
- accordingly and returns a JSON-RPC dictionary (not marshaled)
-
- :param request: JSON-RPC request dictionary (or list of)
- :param dispatch_method: Custom dispatch method (for method resolution)
- :return: A JSON-RPC dictionary (or an array of) or None if the request
- was a notification
- :raise NoMulticallResult: No result in batch
- """
- if not request:
- # Invalid request dictionary
- fault = Fault(-32600, 'Request invalid -- no request data.',
- config=self.json_config)
- _logger.warning("Invalid request: %s", fault)
- return fault.dump()
-
- if isinstance(request, utils.ListType):
- # This SHOULD be a batch, by spec
- responses = []
- for req_entry in request:
- # Validate the request
- result = validate_request(req_entry, self.json_config)
- if isinstance(result, Fault):
- responses.append(result.dump())
- continue
-
- # Call the method
- resp_entry = self._marshaled_single_dispatch(req_entry,
- dispatch_method)
-
- # Store its result
- if isinstance(resp_entry, Fault):
- # pylint: disable=E1103
- responses.append(resp_entry.dump())
- elif resp_entry is not None:
- responses.append(resp_entry)
-
- if not responses:
- # No non-None result
- _logger.error("No result in Multicall")
- raise NoMulticallResult("No result")
-
- return responses
-
- else:
- # Single call
- result = validate_request(request, self.json_config)
- if isinstance(result, Fault):
- return result.dump()
-
- # Call the method
- response = self._marshaled_single_dispatch(request,
- dispatch_method)
- if isinstance(response, Fault):
- # pylint: disable=E1103
- return response.dump()
-
- return response
-
- def _marshaled_dispatch(self, data, dispatch_method=None, path=None):
- """
- Parses the request data (marshaled), calls method(s) and returns a
- JSON string (marshaled)
-
- :param data: A JSON request string
- :param dispatch_method: Custom dispatch method (for method resolution)
- :param path: Unused parameter, to keep compatibility with xmlrpclib
- :return: A JSON-RPC response string (marshaled)
- """
- # Parse the request
- try:
- request = jsonrpclib.loads(data, self.json_config)
- except Exception as ex:
- # Parsing/loading error
- fault = Fault(-32700, 'Request {0} invalid. ({1}:{2})'
- .format(data, type(ex).__name__, ex),
- config=self.json_config)
- _logger.warning("Error parsing request: %s", fault)
- return fault.response()
-
- # Get the response dictionary
- try:
- response = self._unmarshaled_dispatch(request, dispatch_method)
- if response is not None:
- # Compute the string representation of the dictionary/list
- return jsonrpclib.jdumps(response, self.encoding)
- else:
- # No result (notification)
- return ''
- except NoMulticallResult:
- # Return an empty string (jsonrpclib internal behaviour)
- return ''
-
- def _marshaled_single_dispatch(self, request, dispatch_method=None):
- """
- Dispatches a single method call
-
- :param request: A validated request dictionary
- :param dispatch_method: Custom dispatch method (for method resolution)
- :return: A JSON-RPC response dictionary, or None if it was a
- notification request
- """
- method = request.get('method')
- params = request.get('params')
-
- # Prepare a request-specific configuration
- if 'jsonrpc' not in request and self.json_config.version >= 2:
- # JSON-RPC 1.0 request on a JSON-RPC 2.0
- # => compatibility needed
- config = self.json_config.copy()
- config.version = 1.0
- else:
- # Keep server configuration as is
- config = self.json_config
-
- # Test if this is a notification request
- is_notification = 'id' not in request or request['id'] in (None, '')
- if is_notification and self.__notification_pool is not None:
- # Use the thread pool for notifications
- if dispatch_method is not None:
- self.__notification_pool.enqueue(dispatch_method,
- method, params)
- else:
- self.__notification_pool.enqueue(self._dispatch,
- method, params, config)
-
- # Return immediately
- return None
- else:
- # Synchronous call
- try:
- # Call the method
- if dispatch_method is not None:
- response = dispatch_method(method, params)
- else:
- response = self._dispatch(method, params, config)
- except Exception as ex:
- # Return a fault
- fault = Fault(-32603, '{0}:{1}'.format(type(ex).__name__, ex),
- config=config)
- _logger.error("Error calling method %s: %s", method, fault)
- return fault.dump()
-
- if is_notification:
- # It's a notification, no result needed
- # Do not use 'not id' as it might be the integer 0
- return None
-
- # Prepare a JSON-RPC dictionary
- try:
- return jsonrpclib.dump(response, rpcid=request['id'],
- is_response=True, config=config)
- except Exception as ex:
- # JSON conversion exception
- fault = Fault(-32603, '{0}:{1}'.format(type(ex).__name__, ex),
- config=config)
- _logger.error("Error preparing JSON-RPC result: %s", fault)
- return fault.dump()
-
- def _dispatch(self, method, params, config=None):
- """
- Default method resolver and caller
-
- :param method: Name of the method to call
- :param params: List of arguments to give to the method
- :param config: Request-specific configuration
- :return: The result of the method
- """
- config = config or self.json_config
-
- func = None
- try:
- # Look into registered methods
- func = self.funcs[method]
- except KeyError:
- if self.instance is not None:
- # Try with the registered instance
- try:
- # Instance has a custom dispatcher
- return getattr(self.instance, '_dispatch')(method, params)
- except AttributeError:
- # Resolve the method name in the instance
- try:
- func = xmlrpcserver.resolve_dotted_attribute(
- self.instance, method, True)
- except AttributeError:
- # Unknown method
- pass
-
- if func is not None:
- try:
- # Call the method
- if isinstance(params, utils.ListType):
- return func(*params)
- else:
- return func(**params)
- except TypeError as ex:
- # Maybe the parameters are wrong
- fault = Fault(-32602, 'Invalid parameters: {0}'.format(ex),
- config=config)
- _logger.warning("Invalid call parameters: %s", fault)
- return fault
- except:
- # Method exception
- err_lines = traceback.format_exc().splitlines()
- trace_string = '{0} | {1}'.format(err_lines[-3], err_lines[-1])
- fault = Fault(-32603, 'Server error: {0}'.format(trace_string),
- config=config)
- _logger.exception("Server-side exception: %s", fault)
- return fault
- else:
- # Unknown method
- fault = Fault(-32601, 'Method {0} not supported.'.format(method),
- config=config)
- _logger.warning("Unknown method: %s", fault)
- return fault
-
-# ------------------------------------------------------------------------------
-
-
-class SimpleJSONRPCRequestHandler(xmlrpcserver.SimpleXMLRPCRequestHandler):
- """
- HTTP request handler.
-
- The server that receives the requests must have a json_config member,
- containing a JSONRPClib Config instance
- """
- def do_POST(self):
- """
- Handles POST requests
- """
- if not self.is_rpc_path_valid():
- self.report_404()
- return
-
- # Retrieve the configuration
- config = getattr(self.server, 'json_config', jsonrpclib.config.DEFAULT)
-
- try:
- # Read the request body
- max_chunk_size = 10 * 1024 * 1024
- size_remaining = int(self.headers["content-length"])
- chunks = []
- while size_remaining:
- chunk_size = min(size_remaining, max_chunk_size)
- raw_chunk = self.rfile.read(chunk_size)
- if not raw_chunk:
- break
- chunks.append(utils.from_bytes(raw_chunk))
- size_remaining -= len(chunks[-1])
- data = ''.join(chunks)
-
- try:
- # Decode content
- data = self.decode_request_content(data)
- if data is None:
- # Unknown encoding, response has been sent
- return
- except AttributeError:
- # Available since Python 2.7
- pass
-
- # Execute the method
- response = self.server._marshaled_dispatch(
- data, getattr(self, '_dispatch', None), self.path)
-
- # No exception: send a 200 OK
- self.send_response(200)
- except:
- # Exception: send 500 Server Error
- self.send_response(500)
- err_lines = traceback.format_exc().splitlines()
- trace_string = '{0} | {1}'.format(err_lines[-3], err_lines[-1])
- fault = jsonrpclib.Fault(-32603, 'Server error: {0}'
- .format(trace_string), config=config)
- _logger.exception("Server-side error: %s", fault)
- response = fault.response()
-
- if response is None:
- # Avoid to send None
- response = ''
-
- # Convert the response to the valid string format
- response = utils.to_bytes(response)
-
- # Send it
- self.send_header("Content-type", config.content_type)
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- if response:
- self.wfile.write(response)
-
-# ------------------------------------------------------------------------------
-
-
-class SimpleJSONRPCServer(socketserver.TCPServer, SimpleJSONRPCDispatcher):
- """
- JSON-RPC server (and dispatcher)
- """
- # This simplifies server restart after error
- allow_reuse_address = True
-
- # pylint: disable=C0103
- def __init__(self, addr, requestHandler=SimpleJSONRPCRequestHandler,
- logRequests=True, encoding=None, bind_and_activate=True,
- address_family=socket.AF_INET,
- config=jsonrpclib.config.DEFAULT):
- """
- Sets up the server and the dispatcher
-
- :param addr: The server listening address
- :param requestHandler: Custom request handler
- :param logRequests: Flag to(de)activate requests logging
- :param encoding: The dispatcher request encoding
- :param bind_and_activate: If True, starts the server immediately
- :param address_family: The server listening address family
- :param config: A JSONRPClib Config instance
- """
- # Set up the dispatcher fields
- SimpleJSONRPCDispatcher.__init__(self, encoding, config)
-
- # Prepare the server configuration
- # logRequests is used by SimpleXMLRPCRequestHandler
- self.logRequests = logRequests
- self.address_family = address_family
- self.json_config = config
-
- # Work on the request handler
- class RequestHandlerWrapper(requestHandler, object):
- """
- Wraps the request handle to have access to the configuration
- """
- def __init__(self, *args, **kwargs):
- """
- Constructs the wrapper after having stored the configuration
- """
- self.config = config
- super(RequestHandlerWrapper, self).__init__(*args, **kwargs)
-
- # Set up the server
- socketserver.TCPServer.__init__(self, addr, requestHandler,
- bind_and_activate)
-
- # Windows-specific
- if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
- flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
- flags |= fcntl.FD_CLOEXEC
- fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
-
-# ------------------------------------------------------------------------------
-
-
-class PooledJSONRPCServer(SimpleJSONRPCServer, socketserver.ThreadingMixIn):
- """
- JSON-RPC server based on a thread pool
- """
- def __init__(self, addr, requestHandler=SimpleJSONRPCRequestHandler,
- logRequests=True, encoding=None, bind_and_activate=True,
- address_family=socket.AF_INET,
- config=jsonrpclib.config.DEFAULT, thread_pool=None):
- """
- Sets up the server and the dispatcher
-
- :param addr: The server listening address
- :param requestHandler: Custom request handler
- :param logRequests: Flag to(de)activate requests logging
- :param encoding: The dispatcher request encoding
- :param bind_and_activate: If True, starts the server immediately
- :param address_family: The server listening address family
- :param config: A JSONRPClib Config instance
- :param thread_pool: A ThreadPool object. The pool must be started.
- """
- # Normalize the thread pool
- if thread_pool is None:
- # Start a thread pool with 30 threads max, 0 thread min
- thread_pool = jsonrpclib.threadpool.ThreadPool(
- 30, 0, logname="PooledJSONRPCServer")
- thread_pool.start()
-
- # Store the thread pool
- self.__request_pool = thread_pool
-
- # Prepare the server
- SimpleJSONRPCServer.__init__(self, addr, requestHandler, logRequests,
- encoding, bind_and_activate,
- address_family, config)
-
- def process_request(self, request, client_address):
- """
- Handle a client request: queue it in the thread pool
- """
- self.__request_pool.enqueue(self.process_request_thread,
- request, client_address)
-
- def server_close(self):
- """
- Clean up the server
- """
- SimpleJSONRPCServer.server_close(self)
- self.__request_pool.stop()
-
-# ------------------------------------------------------------------------------
-
-
-class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher):
- """
- JSON-RPC CGI handler (and dispatcher)
- """
- def __init__(self, encoding=None, config=jsonrpclib.config.DEFAULT):
- """
- Sets up the dispatcher
-
- :param encoding: Dispatcher encoding
- :param config: A JSONRPClib Config instance
- """
- SimpleJSONRPCDispatcher.__init__(self, encoding, config)
-
- def handle_jsonrpc(self, request_text):
- """
- Handle a JSON-RPC request
- """
- response = self._marshaled_dispatch(request_text)
- sys.stdout.write('Content-Type: {0}\r\n'
- .format(self.json_config.content_type))
- sys.stdout.write('Content-Length: {0:d}\r\n'.format(len(response)))
- sys.stdout.write('\r\n')
- sys.stdout.write(response)
-
- # XML-RPC alias
- handle_xmlrpc = handle_jsonrpc
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/__init__.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/__init__.py
deleted file mode 100644
index a92774ab..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/__init__.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-# -- Content-Encoding: UTF-8 --
-"""
-Aliases to ease access to jsonrpclib classes
-
-:authors: Josh Marshall, Thomas Calmant
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Easy access to utility methods and classes
-from jsonrpclib.jsonrpc import Server, ServerProxy
-from jsonrpclib.jsonrpc import MultiCall, Fault, ProtocolError, AppError
-from jsonrpclib.jsonrpc import loads, dumps, load, dump
-from jsonrpclib.jsonrpc import jloads, jdumps
-import jsonrpclib.history as history
-import jsonrpclib.utils as utils
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/config.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/config.py
deleted file mode 100644
index 77838d4e..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/config.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/python
-# -- Content-Encoding: UTF-8 --
-"""
-The configuration module.
-
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Module version
-__version_info__ = (0, 2, 5)
-__version__ = ".".join(str(x) for x in __version_info__)
-
-# Documentation strings format
-__docformat__ = "restructuredtext en"
-
-# ------------------------------------------------------------------------------
-
-import sys
-
-# ------------------------------------------------------------------------------
-
-
-class LocalClasses(dict):
- """
- Associates local classes with their names (used in the jsonclass module)
- """
- def add(self, cls, name=None):
- """
- Stores a local class
-
- :param cls: A class
- :param name: Custom name used in the __jsonclass__ attribute
- """
- if not name:
- name = cls.__name__
- self[name] = cls
-
-# ------------------------------------------------------------------------------
-
-
-class Config(object):
- """
- This is pretty much used exclusively for the 'jsonclass'
- functionality... set use_jsonclass to False to turn it off.
- You can change serialize_method and ignore_attribute, or use
- the local_classes.add(class) to include "local" classes.
- """
- def __init__(self, version=2.0, content_type="application/json-rpc",
- user_agent=None, use_jsonclass=True,
- serialize_method='_serialize',
- ignore_attribute='_ignore',
- serialize_handlers=None):
- """
- Sets up a configuration of JSONRPClib
-
- :param version: JSON-RPC specification version
- :param content_type: HTTP content type header value
- :param user_agent: The HTTP request user agent
- :param use_jsonclass: Allow bean marshalling
- :param serialize_method: A string that references the method on a
- custom class object which is responsible for
- returning a tuple of the arguments and a dict
- of attributes.
- :param ignore_attribute: A string that references the attribute on a
- custom class object which holds strings and/or
- references of the attributes the class
- translator should ignore.
- :param serialize_handlers: A dictionary of dump handler functions by
- type for additional type support and for
- overriding dump of built-in types in utils
- """
- # JSON-RPC specification
- self.version = version
-
- # Change to False to keep __jsonclass__ entries raw.
- self.use_jsonclass = use_jsonclass
-
- # it SHOULD be 'application/json-rpc'
- # but MAY be 'application/json' or 'application/jsonrequest'
- self.content_type = content_type
-
- # Default user agent
- if user_agent is None:
- user_agent = 'jsonrpclib/{0} (Python {1})'.format(
- __version__, '.'.join(str(ver)
- for ver in sys.version_info[0:3]))
- self.user_agent = user_agent
-
- # The list of classes to use for jsonclass translation.
- self.classes = LocalClasses()
-
- # The serialize_method should be a string that references the
- # method on a custom class object which is responsible for
- # returning a tuple of the constructor arguments and a dict of
- # attributes.
- self.serialize_method = serialize_method
-
- # The ignore attribute should be a string that references the
- # attribute on a custom class object which holds strings and / or
- # references of the attributes the class translator should ignore.
- self.ignore_attribute = ignore_attribute
-
- # The list of serialize handler functions for jsonclass dump.
- # Used for handling additional types and overriding built-in types.
- # Functions are expected to have the same parameters as jsonclass dump
- # (possibility to call standard jsonclass dump function within).
- self.serialize_handlers = serialize_handlers or {}
-
- def copy(self):
- """
- Returns a shallow copy of this configuration bean
-
- :return: A shallow copy of this configuration
- """
- new_config = Config(self.version, self.content_type, self.user_agent,
- self.use_jsonclass, self.serialize_method,
- self.ignore_attribute, None)
- new_config.classes = self.classes.copy()
- new_config.serialize_handlers = self.serialize_handlers.copy()
- return new_config
-
-# Default configuration
-DEFAULT = Config()
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/history.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/history.py
deleted file mode 100644
index 288d9539..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/history.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/python
-# -- Content-Encoding: UTF-8 --
-"""
-The history module.
-
-:authors: Josh Marshall, Thomas Calmant
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Module version
-__version_info__ = (0, 2, 5)
-__version__ = ".".join(str(x) for x in __version_info__)
-
-# Documentation strings format
-__docformat__ = "restructuredtext en"
-
-# ------------------------------------------------------------------------------
-
-
-class History(object):
- """
- This holds all the response and request objects for a
- session. A server using this should call "clear" after
- each request cycle in order to keep it from clogging
- memory.
- """
- def __init__(self):
- """
- Sets up members
- """
- self.requests = []
- self.responses = []
-
- def add_response(self, response_obj):
- """
- Adds a response to the history
-
- :param response_obj: Response content
- """
- self.responses.append(response_obj)
-
- def add_request(self, request_obj):
- """
- Adds a request to the history
-
- :param request_obj: A request object
- """
- self.requests.append(request_obj)
-
- @property
- def request(self):
- """
- Returns the latest stored request or None
- """
- try:
- return self.requests[-1]
-
- except IndexError:
- return None
-
- @property
- def response(self):
- """
- Returns the latest stored response or None
- """
- try:
- return self.responses[-1]
-
- except IndexError:
- return None
-
- def clear(self):
- """
- Clears the history lists
- """
- del self.requests[:]
- del self.responses[:]
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonclass.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonclass.py
deleted file mode 100644
index 6bcbeab7..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonclass.py
+++ /dev/null
@@ -1,295 +0,0 @@
-#!/usr/bin/python
-# -- Content-Encoding: UTF-8 --
-"""
-The serialization module
-
-:authors: Josh Marshall, Thomas Calmant
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Module version
-__version_info__ = (0, 2, 5)
-__version__ = ".".join(str(x) for x in __version_info__)
-
-# Documentation strings format
-__docformat__ = "restructuredtext en"
-
-# ------------------------------------------------------------------------------
-
-# Local package
-import jsonrpclib.config
-import jsonrpclib.utils as utils
-
-# Standard library
-import inspect
-import re
-
-# ------------------------------------------------------------------------------
-
-# Supported transmitted code
-SUPPORTED_TYPES = (utils.DictType,) + utils.iterable_types \
- + utils.primitive_types
-
-# Regex of invalid module characters
-INVALID_MODULE_CHARS = r'[^a-zA-Z0-9\_\.]'
-
-# ------------------------------------------------------------------------------
-
-
-class TranslationError(Exception):
- """
- Unmarshaling exception
- """
- pass
-
-
-def _slots_finder(clazz, fields_set):
- """
- Recursively visits the class hierarchy to find all slots
-
- :param clazz: Class to analyze
- :param fields_set: Set where to store __slots___ content
- """
- # ... class level
- try:
- fields_set.update(clazz.__slots__)
- except AttributeError:
- pass
-
- # ... parent classes level
- for base_class in clazz.__bases__:
- _slots_finder(base_class, fields_set)
-
-
-def _find_fields(obj):
- """
- Returns the names of the fields of the given object
-
- :param obj: An object to analyze
- :return: A set of field names
- """
- # Find fields...
- fields = set()
-
- # ... using __dict__
- try:
- fields.update(obj.__dict__)
- except AttributeError:
- pass
-
- # ... using __slots__
- _slots_finder(obj.__class__, fields)
- return fields
-
-
-def dump(obj, serialize_method=None, ignore_attribute=None, ignore=None,
- config=jsonrpclib.config.DEFAULT):
- """
- Transforms the given object into a JSON-RPC compliant form.
- Converts beans into dictionaries with a __jsonclass__ entry.
- Doesn't change primitive types.
-
- :param obj: An object to convert
- :param serialize_method: Custom serialization method
- :param ignore_attribute: Name of the object attribute containing the names
- of members to ignore
- :param ignore: A list of members to ignore
- :param config: A JSONRPClib Config instance
- :return: A JSON-RPC compliant object
- """
- # Normalize arguments
- serialize_method = serialize_method or config.serialize_method
- ignore_attribute = ignore_attribute or config.ignore_attribute
- ignore = ignore or []
-
- # Parse / return default "types"...
- # Apply additional types, override built-in types
- # (reminder: config.serialize_handlers is a dict)
- try:
- serializer = config.serialize_handlers[type(obj)]
- except KeyError:
- # Not a serializer
- pass
- else:
- if serializer is not None:
- return serializer(obj, serialize_method, ignore_attribute,
- ignore, config)
-
- # Primitive
- if isinstance(obj, utils.primitive_types):
- return obj
-
- # Iterative
- elif isinstance(obj, utils.iterable_types):
- # List, set or tuple
- return [dump(item, serialize_method, ignore_attribute, ignore, config)
- for item in obj]
-
- elif isinstance(obj, utils.DictType):
- # Dictionary
- return dict((key, dump(value, serialize_method,
- ignore_attribute, ignore, config))
- for key, value in obj.items())
-
- # It's not a standard type, so it needs __jsonclass__
- module_name = inspect.getmodule(type(obj)).__name__
- json_class = obj.__class__.__name__
-
- if module_name not in ('', '__main__'):
- json_class = '{0}.{1}'.format(module_name, json_class)
-
- # Keep the class name in the returned object
- return_obj = {"__jsonclass__": [json_class]}
-
- # If a serialization method is defined..
- if hasattr(obj, serialize_method):
- # Params can be a dict (keyword) or list (positional)
- # Attrs MUST be a dict.
- serialize = getattr(obj, serialize_method)
- params, attrs = serialize()
- return_obj['__jsonclass__'].append(params)
- return_obj.update(attrs)
- return return_obj
-
- else:
- # Otherwise, try to figure it out
- # Obviously, we can't assume to know anything about the
- # parameters passed to __init__
- return_obj['__jsonclass__'].append([])
-
- # Prepare filtering lists
- known_types = SUPPORTED_TYPES + tuple(config.serialize_handlers)
- ignore_list = getattr(obj, ignore_attribute, []) + ignore
-
- # Find fields and filter them by name
- fields = _find_fields(obj)
- fields.difference_update(ignore_list)
-
- # Dump field values
- attrs = {}
- for attr_name in fields:
- attr_value = getattr(obj, attr_name)
- if isinstance(attr_value, known_types) and \
- attr_value not in ignore_list:
- attrs[attr_name] = dump(attr_value, serialize_method,
- ignore_attribute, ignore, config)
- return_obj.update(attrs)
- return return_obj
-
-# ------------------------------------------------------------------------------
-
-
-def load(obj, classes=None):
- """
- If 'obj' is a dictionary containing a __jsonclass__ entry, converts the
- dictionary item into a bean of this class.
-
- :param obj: An object from a JSON-RPC dictionary
- :param classes: A custom {name: class} dictionary
- :return: The loaded object
- """
- # Primitive
- if isinstance(obj, utils.primitive_types):
- return obj
-
- # List, set or tuple
- elif isinstance(obj, utils.iterable_types):
- # This comes from a JSON parser, so it can only be a list...
- return [load(entry) for entry in obj]
-
- # Otherwise, it's a dict type
- elif '__jsonclass__' not in obj:
- return dict((key, load(value)) for key, value in obj.items())
-
- # It's a dictionary, and it has a __jsonclass__
- orig_module_name = obj['__jsonclass__'][0]
- params = obj['__jsonclass__'][1]
-
- # Validate the module name
- if not orig_module_name:
- raise TranslationError('Module name empty.')
-
- json_module_clean = re.sub(INVALID_MODULE_CHARS, '', orig_module_name)
- if json_module_clean != orig_module_name:
- raise TranslationError('Module name {0} has invalid characters.'
- .format(orig_module_name))
-
- # Load the class
- json_module_parts = json_module_clean.split('.')
- json_class = None
- if classes and len(json_module_parts) == 1:
- # Local class name -- probably means it won't work
- try:
- json_class = classes[json_module_parts[0]]
- except KeyError:
- raise TranslationError('Unknown class or module {0}.'
- .format(json_module_parts[0]))
-
- else:
- # Module + class
- json_class_name = json_module_parts.pop()
- json_module_tree = '.'.join(json_module_parts)
- try:
- # Use fromlist to load the module itself, not the package
- temp_module = __import__(json_module_tree,
- fromlist=[json_class_name])
- except ImportError:
- raise TranslationError('Could not import {0} from module {1}.'
- .format(json_class_name, json_module_tree))
-
- try:
- json_class = getattr(temp_module, json_class_name)
- except AttributeError:
- raise TranslationError("Unknown class {0}.{1}."
- .format(json_module_tree, json_class_name))
-
- # Create the object
- new_obj = None
- if isinstance(params, utils.ListType):
- try:
- new_obj = json_class(*params)
- except TypeError as ex:
- raise TranslationError("Error instantiating {0}: {1}"
- .format(json_class.__name__, ex))
-
- elif isinstance(params, utils.DictType):
- try:
- new_obj = json_class(**params)
- except TypeError as ex:
- raise TranslationError("Error instantiating {0}: {1}"
- .format(json_class.__name__, ex))
-
- else:
- raise TranslationError("Constructor args must be a dict or a list, "
- "not {0}".format(type(params).__name__))
-
- # Remove the class information, as it must be ignored during the
- # reconstruction of the object
- raw_jsonclass = obj.pop('__jsonclass__')
-
- for key, value in obj.items():
- # Recursive loading
- setattr(new_obj, key, load(value, classes))
-
- # Restore the class information for further usage
- obj['__jsonclass__'] = raw_jsonclass
-
- return new_obj
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonrpc.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonrpc.py
deleted file mode 100644
index 8ea3a9c8..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/jsonrpc.py
+++ /dev/null
@@ -1,1192 +0,0 @@
-#!/usr/bin/python
-# -- Content-Encoding: UTF-8 --
-"""
-============================
-JSONRPC Library (jsonrpclib)
-============================
-
-This library is a JSON-RPC v.2 (proposed) implementation which
-follows the xmlrpclib API for portability between clients. It
-uses the same Server / ServerProxy, loads, dumps, etc. syntax,
-while providing features not present in XML-RPC like:
-
-* Keyword arguments
-* Notifications
-* Versioning
-* Batches and batch notifications
-
-Eventually, I'll add a SimpleXMLRPCServer compatible library,
-and other things to tie the thing off nicely. :)
-
-For a quick-start, just open a console and type the following,
-replacing the server address, method, and parameters
-appropriately.
->>> import jsonrpclib
->>> server = jsonrpclib.Server('http://localhost:8181')
->>> server.add(5, 6)
-11
->>> server._notify.add(5, 6)
->>> batch = jsonrpclib.MultiCall(server)
->>> batch.add(3, 50)
->>> batch.add(2, 3)
->>> batch._notify.add(3, 5)
->>> batch()
-[53, 5]
-
-See https://github.com/tcalmant/jsonrpclib for more info.
-
-:authors: Josh Marshall, Thomas Calmant
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Module version
-__version_info__ = (0, 2, 5)
-__version__ = ".".join(str(x) for x in __version_info__)
-
-# Documentation strings format
-__docformat__ = "restructuredtext en"
-
-# ------------------------------------------------------------------------------
-
-# Library includes
-import jsonrpclib.config
-import jsonrpclib.utils as utils
-
-# Standard library
-import contextlib
-import logging
-import sys
-import uuid
-
-# Create the logger
-_logger = logging.getLogger(__name__)
-
-try:
- # Python 3
- # pylint: disable=F0401,E0611
- from urllib.parse import splittype
- from urllib.parse import splithost
- from xmlrpc.client import Transport as XMLTransport
- from xmlrpc.client import SafeTransport as XMLSafeTransport
- from xmlrpc.client import ServerProxy as XMLServerProxy
- from xmlrpc.client import _Method as XML_Method
-
-except ImportError:
- # Python 2
- # pylint: disable=F0401,E0611
- from urllib import splittype
- from urllib import splithost
- from xmlrpclib import Transport as XMLTransport
- from xmlrpclib import SafeTransport as XMLSafeTransport
- from xmlrpclib import ServerProxy as XMLServerProxy
- from xmlrpclib import _Method as XML_Method
-
-# ------------------------------------------------------------------------------
-# JSON library import
-
-# JSON class serialization
-from jsonrpclib import jsonclass
-
-try:
- # pylint: disable=F0401,E0611
- # Using cjson
- import cjson
- _logger.debug("Using cjson as JSON library")
-
- # Declare cjson methods
- def jdumps(obj, encoding='utf-8'):
- """
- Serializes ``obj`` to a JSON formatted string, using cjson.
- """
- return cjson.encode(obj)
-
- def jloads(json_string):
- """
- Deserializes ``json_string`` (a string containing a JSON document)
- to a Python object, using cjson.
- """
- return cjson.decode(json_string)
-
-except ImportError:
- # pylint: disable=F0401,E0611
- # Use json or simplejson
- try:
- import json
- _logger.debug("Using json as JSON library")
-
- except ImportError:
- try:
- import simplejson as json
- _logger.debug("Using simplejson as JSON library")
- except ImportError:
- _logger.error("No supported JSON library found")
- raise ImportError('You must have the cjson, json, or simplejson '
- 'module(s) available.')
-
- # Declare json methods
- if sys.version_info[0] < 3:
- def jdumps(obj, encoding='utf-8'):
- """
- Serializes ``obj`` to a JSON formatted string.
- """
- # Python 2 (explicit encoding)
- return json.dumps(obj, encoding=encoding)
-
- else:
- # Python 3
- def jdumps(obj, encoding='utf-8'):
- """
- Serializes ``obj`` to a JSON formatted string.
- """
- # Python 3 (the encoding parameter has been removed)
- return json.dumps(obj)
-
- def jloads(json_string):
- """
- Deserializes ``json_string`` (a string containing a JSON document)
- to a Python object.
- """
- return json.loads(json_string)
-
-# ------------------------------------------------------------------------------
-# XMLRPClib re-implementations
-
-
-class ProtocolError(Exception):
- """
- JSON-RPC error
-
- ProtocolError.args[0] can be:
- * an error message (string)
- * a (code, message) tuple
- """
- pass
-
-
-class AppError(ProtocolError):
- """
- Application error: the error code is not in the pre-defined ones
-
- AppError.args[0][0]: Error code
- AppError.args[0][1]: Error message or trace
- AppError.args[0][2]: Associated data
- """
- def data(self):
- """
- Retrieves the value found in the 'data' entry of the error, or None
-
- :return: The data associated to the error, or None
- """
- return self.args[0][2]
-
-
-class JSONParser(object):
- """
- Default JSON parser
- """
- def __init__(self, target):
- """
- Associates the target loader to the parser
-
- :param target: a JSONTarget instance
- """
- self.target = target
-
- def feed(self, data):
- """
- Feeds the associated target with the given data
- """
- self.target.feed(data)
-
- def close(self):
- """
- Does nothing
- """
- pass
-
-
-class JSONTarget(object):
- """
- Unmarshalls stream data to a string
- """
- def __init__(self):
- """
- Sets up the unmarshaller
- """
- self.data = []
-
- def feed(self, data):
- """
- Stores the given raw data into a buffer
- """
- # Store raw data as it might not contain whole wide-character
- self.data.append(data)
-
- def close(self):
- """
- Unmarshalls the buffered data
- """
- if not self.data:
- return ''
- else:
- # Use type to have a valid join (str vs. bytes)
- data = type(self.data[0])().join(self.data)
- try:
- # Convert the whole final string
- data = utils.from_bytes(data)
- except:
- # Try a pass-through
- pass
-
- return data
-
-
-class TransportMixIn(object):
- """ Just extends the XMLRPC transport where necessary. """
- # for Python 2.7 support
- _connection = None
-
- # List of non-overridable headers
- # Use the configuration to change the content-type
- readonly_headers = ('content-length', 'content-type')
-
- def __init__(self, config=jsonrpclib.config.DEFAULT, context=None):
- """
- Sets up the transport
-
- :param config: A JSONRPClib Config instance
- """
- # Store the configuration
- self._config = config
-
- # Store the SSL context
- self.context = context
-
- # Set up the user agent
- self.user_agent = config.user_agent
-
- # Additional headers: list of dictionaries
- self.additional_headers = []
-
- def push_headers(self, headers):
- """
- Adds a dictionary of headers to the additional headers list
-
- :param headers: A dictionary
- """
- self.additional_headers.append(headers)
-
- def pop_headers(self, headers):
- """
- Removes the given dictionary from the additional headers list.
- Also validates that given headers are on top of the stack
-
- :param headers: Headers to remove
- :raise AssertionError: The given dictionary is not on the latest stored
- in the additional headers list
- """
- assert self.additional_headers[-1] == headers
- self.additional_headers.pop()
-
- def emit_additional_headers(self, connection):
- """
- Puts headers as is in the request, filtered read only headers
-
- :param connection: The request connection
- """
- additional_headers = {}
-
- # Prepare the merged dictionary
- for headers in self.additional_headers:
- additional_headers.update(headers)
-
- # Remove forbidden keys
- for forbidden in self.readonly_headers:
- additional_headers.pop(forbidden, None)
-
- # Reversed order: in the case of multiple headers value definition,
- # the latest pushed has priority
- for key, value in additional_headers.items():
- key = str(key)
- if key.lower() not in self.readonly_headers:
- # Only accept replaceable headers
- connection.putheader(str(key), str(value))
-
- def send_content(self, connection, request_body):
- """
- Completes the request headers and sends the request body of a JSON-RPC
- request over a HTTPConnection
-
- :param connection: An HTTPConnection object
- :param request_body: JSON-RPC request body
- """
- # Convert the body first
- request_body = utils.to_bytes(request_body)
-
- # "static" headers
- connection.putheader("Content-Type", self._config.content_type)
- connection.putheader("Content-Length", str(len(request_body)))
-
- # Emit additional headers here in order not to override content-length
- self.emit_additional_headers(connection)
-
- connection.endheaders()
- if request_body:
- connection.send(request_body)
-
- def getparser(self):
- """
- Create an instance of the parser, and attach it to an unmarshalling
- object. Return both objects.
-
- :return: The parser and unmarshaller instances
- """
- target = JSONTarget()
- return JSONParser(target), target
-
-
-class Transport(TransportMixIn, XMLTransport):
- """
- Mixed-in HTTP transport
- """
- pass
-
-
-class SafeTransport(TransportMixIn, XMLSafeTransport):
- """
- Mixed-in HTTPS transport
- """
- pass
-
-# ------------------------------------------------------------------------------
-
-
-class ServerProxy(XMLServerProxy):
- """
- Unfortunately, much more of this class has to be copied since
- so much of it does the serialization.
- """
- def __init__(self, uri, transport=None, encoding=None,
- verbose=0, version=None, headers=None, history=None,
- config=jsonrpclib.config.DEFAULT, context=None):
- """
- Sets up the server proxy
-
- :param uri: Request URI
- :param transport: Custom transport handler
- :param encoding: Specified encoding
- :param verbose: Log verbosity level
- :param version: JSON-RPC specification version
- :param headers: Custom additional headers for each request
- :param history: History object (for tests)
- :param config: A JSONRPClib Config instance
- :param context: The optional SSLContext to use
- """
- # Store the configuration
- self._config = config
- self.__version = version or config.version
-
- schema, uri = splittype(uri)
- if schema not in ('http', 'https'):
- _logger.error("jsonrpclib only support http(s) URIs, not %s",
- schema)
- raise IOError('Unsupported JSON-RPC protocol.')
-
- self.__host, self.__handler = splithost(uri)
- if not self.__handler:
- # Not sure if this is in the JSON spec?
- self.__handler = '/'
-
- if transport is None:
- if schema == 'https':
- transport = SafeTransport(config=config, context=context)
- else:
- transport = Transport(config=config)
- self.__transport = transport
-
- self.__encoding = encoding
- self.__verbose = verbose
- self.__history = history
-
- # Global custom headers are injected into Transport
- self.__transport.push_headers(headers or {})
-
- def _request(self, methodname, params, rpcid=None):
- """
- Calls a method on the remote server
-
- :param methodname: Name of the method to call
- :param params: Method parameters
- :param rpcid: ID of the remote call
- :return: The parsed result of the call
- """
- request = dumps(params, methodname, encoding=self.__encoding,
- rpcid=rpcid, version=self.__version,
- config=self._config)
- response = self._run_request(request)
- check_for_errors(response)
- return response['result']
-
- def _request_notify(self, methodname, params, rpcid=None):
- """
- Calls a method as a notification
-
- :param methodname: Name of the method to call
- :param params: Method parameters
- :param rpcid: ID of the remote call
- """
- request = dumps(params, methodname, encoding=self.__encoding,
- rpcid=rpcid, version=self.__version, notify=True,
- config=self._config)
- response = self._run_request(request, notify=True)
- check_for_errors(response)
-
- def _run_request(self, request, notify=False):
- """
- Sends the given request to the remote server
-
- :param request: The request to send
- :param notify: Notification request flag (unused)
- :return: The response as a parsed JSON object
- """
- if self.__history is not None:
- self.__history.add_request(request)
-
- response = self.__transport.request(
- self.__host,
- self.__handler,
- request,
- verbose=self.__verbose
- )
-
- # Here, the XMLRPC library translates a single list
- # response to the single value -- should we do the
- # same, and require a tuple / list to be passed to
- # the response object, or expect the Server to be
- # outputting the response appropriately?
-
- if self.__history is not None:
- self.__history.add_response(response)
-
- if not response:
- return None
- else:
- return_obj = loads(response, self._config)
- return return_obj
-
- def __getattr__(self, name):
- """
- Returns a callable object to call the remote service
- """
- # Same as original, just with new _Method reference
- return _Method(self._request, name)
-
- def __close(self):
- """
- Closes the transport layer
- """
- try:
- self.__transport.close()
- except AttributeError:
- # Not available in Python 2.6
- pass
-
- def __call__(self, attr):
- """
- A workaround to get special attributes on the ServerProxy
- without interfering with the magic __getattr__
-
- (code from xmlrpclib in Python 2.7)
- """
- if attr == "close":
- return self.__close
-
- elif attr == "transport":
- return self.__transport
-
- raise AttributeError("Attribute {0} not found".format(attr))
-
- @property
- def _notify(self):
- """
- Like __getattr__, but sending a notification request instead of a call
- """
- return _Notify(self._request_notify)
-
- @contextlib.contextmanager
- def _additional_headers(self, headers):
- """
- Allows to specify additional headers, to be added inside the with
- block.
- Example of usage:
-
- >>> with client._additional_headers({'X-Test' : 'Test'}) as new_client:
- ... new_client.method()
- ...
- >>> # Here old headers are restored
- """
- self.__transport.push_headers(headers)
- yield self
- self.__transport.pop_headers(headers)
-
-# ------------------------------------------------------------------------------
-
-
-class _Method(XML_Method):
- """
- Some magic to bind an JSON-RPC method to an RPC server.
- """
- def __call__(self, *args, **kwargs):
- """
- Sends an RPC request and returns the unmarshalled result
- """
- if args and kwargs:
- raise ProtocolError("Cannot use both positional and keyword "
- "arguments (according to JSON-RPC spec.)")
- if args:
- return self.__send(self.__name, args)
- else:
- return self.__send(self.__name, kwargs)
-
- def __getattr__(self, name):
- """
- Returns a Method object for nested calls
- """
- if name == "__name__":
- return self.__name
- return _Method(self.__send, "{0}.{1}".format(self.__name, name))
-
-
-class _Notify(object):
- """
- Same as _Method, but to send notifications
- """
- def __init__(self, request):
- """
- Sets the method to call to send a request to the server
- """
- self._request = request
-
- def __getattr__(self, name):
- """
- Returns a Method object, to be called as a notification
- """
- return _Method(self._request, name)
-
-# ------------------------------------------------------------------------------
-# Batch implementation
-
-
-class MultiCallMethod(object):
- """
- Stores calls made to a MultiCall object for batch execution
- """
- def __init__(self, method, notify=False, config=jsonrpclib.config.DEFAULT):
- """
- Sets up the store
-
- :param method: Name of the method to call
- :param notify: Notification flag
- :param config: Request configuration
- """
- self.method = method
- self.params = []
- self.notify = notify
- self._config = config
-
- def __call__(self, *args, **kwargs):
- """
- Normalizes call parameters
- """
- if kwargs and args:
- raise ProtocolError('JSON-RPC does not support both ' +
- 'positional and keyword arguments.')
- if kwargs:
- self.params = kwargs
- else:
- self.params = args
-
- def request(self, encoding=None, rpcid=None):
- """
- Returns the request object as JSON-formatted string
- """
- return dumps(self.params, self.method, version=2.0,
- encoding=encoding, rpcid=rpcid, notify=self.notify,
- config=self._config)
-
- def __repr__(self):
- """
- String representation
- """
- return str(self.request())
-
- def __getattr__(self, method):
- """
- Updates the object for a nested call
- """
- self.method = "{0}.{1}".format(self.method, method)
- return self
-
-
-class MultiCallNotify(object):
- """
- Same as MultiCallMethod but for notifications
- """
- def __init__(self, multicall, config=jsonrpclib.config.DEFAULT):
- """
- Sets ip the store
-
- :param multicall: The parent MultiCall instance
- :param config: Request configuration
- """
- self.multicall = multicall
- self._config = config
-
- def __getattr__(self, name):
- """
- Returns the MultiCallMethod to use as a notification
- """
- new_job = MultiCallMethod(name, notify=True, config=self._config)
- self.multicall._job_list.append(new_job)
- return new_job
-
-
-class MultiCallIterator(object):
- """
- Iterates over the results of a MultiCall.
- Exceptions are raised in response to JSON-RPC faults
- """
- def __init__(self, results):
- """
- Sets up the results store
- """
- self.results = results
-
- def __get_result(self, item):
- """
- Checks for error and returns the "real" result stored in a MultiCall
- result.
- """
- check_for_errors(item)
- return item['result']
-
- def __iter__(self):
- """
- Iterates over all results
- """
- for item in self.results:
- yield self.__get_result(item)
- raise StopIteration
-
- def __getitem__(self, i):
- """
- Returns the i-th object of the results
- """
- return self.__get_result(self.results[i])
-
- def __len__(self):
- """
- Returns the number of results stored
- """
- return len(self.results)
-
-
-class MultiCall(object):
- """
- server -> a object used to boxcar method calls, where server should be a
- ServerProxy object.
-
- Methods can be added to the MultiCall using normal
- method call syntax e.g.:
-
- multicall = MultiCall(server_proxy)
- multicall.add(2,3)
- multicall.get_address("Guido")
-
- To execute the multicall, call the MultiCall object e.g.:
-
- add_result, address = multicall()
- """
- def __init__(self, server, config=jsonrpclib.config.DEFAULT):
- """
- Sets up the multicall
-
- :param server: A ServerProxy object
- :param config: Request configuration
- """
- self._server = server
- self._job_list = []
- self._config = config
-
- def _request(self):
- """
- Sends the request to the server and returns the responses
-
- :return: A MultiCallIterator object
- """
- if len(self._job_list) < 1:
- # Should we alert? This /is/ pretty obvious.
- return
- request_body = "[ {0} ]".format(
- ','.join(job.request() for job in self._job_list))
- responses = self._server._run_request(request_body)
- del self._job_list[:]
- if not responses:
- responses = []
- return MultiCallIterator(responses)
-
- @property
- def _notify(self):
- """
- Prepares a notification call
- """
- return MultiCallNotify(self, self._config)
-
- def __getattr__(self, name):
- """
- Registers a method call
- """
- new_job = MultiCallMethod(name, config=self._config)
- self._job_list.append(new_job)
- return new_job
-
- __call__ = _request
-
-# These lines conform to xmlrpclib's "compatibility" line.
-# Not really sure if we should include these, but oh well.
-Server = ServerProxy
-
-# ------------------------------------------------------------------------------
-
-
-class Fault(object):
- """
- JSON-RPC error class
- """
- def __init__(self, code=-32000, message='Server error', rpcid=None,
- config=jsonrpclib.config.DEFAULT, data=None):
- """
- Sets up the error description
-
- :param code: Fault code
- :param message: Associated message
- :param rpcid: Request ID
- :param config: A JSONRPClib Config instance
- :param data: Extra information added to an error description
- """
- self.faultCode = code
- self.faultString = message
- self.rpcid = rpcid
- self.config = config
- self.data = data
-
- def error(self):
- """
- Returns the error as a dictionary
-
- :returns: A {'code', 'message'} dictionary
- """
- return {'code': self.faultCode, 'message': self.faultString,
- 'data': self.data}
-
- def response(self, rpcid=None, version=None):
- """
- Returns the error as a JSON-RPC response string
-
- :param rpcid: Forced request ID
- :param version: JSON-RPC version
- :return: A JSON-RPC response string
- """
- if not version:
- version = self.config.version
-
- if rpcid:
- self.rpcid = rpcid
-
- return dumps(self, methodresponse=True, rpcid=self.rpcid,
- version=version, config=self.config)
-
- def dump(self, rpcid=None, version=None):
- """
- Returns the error as a JSON-RPC response dictionary
-
- :param rpcid: Forced request ID
- :param version: JSON-RPC version
- :return: A JSON-RPC response dictionary
- """
- if not version:
- version = self.config.version
-
- if rpcid:
- self.rpcid = rpcid
-
- return dump(self, is_response=True, rpcid=self.rpcid,
- version=version, config=self.config)
-
- def __repr__(self):
- """
- String representation
- """
- return '<Fault {0}: {1}>'.format(self.faultCode, self.faultString)
-
-
-class Payload(object):
- """
- JSON-RPC content handler
- """
- def __init__(self, rpcid=None, version=None,
- config=jsonrpclib.config.DEFAULT):
- """
- Sets up the JSON-RPC handler
-
- :param rpcid: Request ID
- :param version: JSON-RPC version
- :param config: A JSONRPClib Config instance
- """
- if not version:
- version = config.version
-
- self.id = rpcid
- self.version = float(version)
-
- def request(self, method, params=None):
- """
- Prepares a method call request
-
- :param method: Method name
- :param params: Method parameters
- :return: A JSON-RPC request dictionary
- """
- if not isinstance(method, utils.string_types):
- raise ValueError('Method name must be a string.')
-
- if not self.id:
- # Generate a request ID
- self.id = str(uuid.uuid4())
-
- request = {'id': self.id, 'method': method}
- if params or self.version < 1.1:
- request['params'] = params or []
-
- if self.version >= 2:
- request['jsonrpc'] = str(self.version)
-
- return request
-
- def notify(self, method, params=None):
- """
- Prepares a notification request
-
- :param method: Notification name
- :param params: Notification parameters
- :return: A JSON-RPC notification dictionary
- """
- # Prepare the request dictionary
- request = self.request(method, params)
-
- # Remove the request ID, as it's a notification
- if self.version >= 2:
- del request['id']
- else:
- request['id'] = None
-
- return request
-
- def response(self, result=None):
- """
- Prepares a response dictionary
-
- :param result: The result of method call
- :return: A JSON-RPC response dictionary
- """
- response = {'result': result, 'id': self.id}
-
- if self.version >= 2:
- response['jsonrpc'] = str(self.version)
- else:
- response['error'] = None
-
- return response
-
- def error(self, code=-32000, message='Server error.', data=None):
- """
- Prepares an error dictionary
-
- :param code: Error code
- :param message: Error message
- :return: A JSON-RPC error dictionary
- """
- error = self.response()
- if self.version >= 2:
- del error['result']
- else:
- error['result'] = None
- error['error'] = {'code': code, 'message': message}
- if data is not None:
- error['error']['data'] = data
- return error
-
-# ------------------------------------------------------------------------------
-
-
-def dump(params=None, methodname=None, rpcid=None, version=None,
- is_response=None, is_notify=None, config=jsonrpclib.config.DEFAULT):
- """
- Prepares a JSON-RPC dictionary (request, notification, response or error)
-
- :param params: Method parameters (if a method name is given) or a Fault
- :param methodname: Method name
- :param rpcid: Request ID
- :param version: JSON-RPC version
- :param is_response: If True, this is a response dictionary
- :param is_notify: If True, this is a notification request
- :param config: A JSONRPClib Config instance
- :return: A JSON-RPC dictionary
- """
- # Default version
- if not version:
- version = config.version
-
- if not is_response and params is None:
- params = []
-
- # Validate method name and parameters
- valid_params = [utils.TupleType, utils.ListType, utils.DictType, Fault]
- if is_response:
- valid_params.append(type(None))
-
- if isinstance(methodname, utils.string_types) and \
- not isinstance(params, tuple(valid_params)):
- """
- If a method, and params are not in a listish or a Fault,
- error out.
- """
- raise TypeError("Params must be a dict, list, tuple "
- "or Fault instance.")
-
- # Prepares the JSON-RPC content
- payload = Payload(rpcid=rpcid, version=version)
-
- if isinstance(params, Fault):
- # Prepare an error dictionary
- # pylint: disable=E1103
- return payload.error(params.faultCode, params.faultString, params.data)
-
- if not isinstance(methodname, utils.string_types) and not is_response:
- # Neither a request nor a response
- raise ValueError('Method name must be a string, or is_response '
- 'must be set to True.')
-
- if config.use_jsonclass:
- # Use jsonclass to convert the parameters
- params = jsonclass.dump(params, config=config)
-
- if is_response:
- # Prepare a response dictionary
- if rpcid is None:
- # A response must have a request ID
- raise ValueError('A method response must have an rpcid.')
- return payload.response(params)
-
- if is_notify:
- # Prepare a notification dictionary
- return payload.notify(methodname, params)
- else:
- # Prepare a method call dictionary
- return payload.request(methodname, params)
-
-
-def dumps(params=None, methodname=None, methodresponse=None,
- encoding=None, rpcid=None, version=None, notify=None,
- config=jsonrpclib.config.DEFAULT):
- """
- Prepares a JSON-RPC request/response string
-
- :param params: Method parameters (if a method name is given) or a Fault
- :param methodname: Method name
- :param methodresponse: If True, this is a response dictionary
- :param encoding: Result string encoding
- :param rpcid: Request ID
- :param version: JSON-RPC version
- :param notify: If True, this is a notification request
- :param config: A JSONRPClib Config instance
- :return: A JSON-RPC dictionary
- """
- # Prepare the dictionary
- request = dump(params, methodname, rpcid, version, methodresponse, notify,
- config)
-
- # Returns it as a JSON string
- return jdumps(request, encoding=encoding or "UTF-8")
-
-
-def load(data, config=jsonrpclib.config.DEFAULT):
- """
- Loads a JSON-RPC request/response dictionary. Calls jsonclass to load beans
-
- :param data: A JSON-RPC dictionary
- :param config: A JSONRPClib Config instance (or None for default values)
- :return: A parsed dictionary or None
- """
- if data is None:
- # Notification
- return None
-
- # if the above raises an error, the implementing server code
- # should return something like the following:
- # { 'jsonrpc':'2.0', 'error': fault.error(), id: None }
- if config.use_jsonclass:
- # Convert beans
- data = jsonclass.load(data, config.classes)
-
- return data
-
-
-def loads(data, config=jsonrpclib.config.DEFAULT):
- """
- Loads a JSON-RPC request/response string. Calls jsonclass to load beans
-
- :param data: A JSON-RPC string
- :param config: A JSONRPClib Config instance (or None for default values)
- :return: A parsed dictionary or None
- """
- if data == '':
- # Notification
- return None
-
- # Parse the JSON dictionary
- result = jloads(data)
-
- # Load the beans
- return load(result, config)
-
-# ------------------------------------------------------------------------------
-
-
-def check_for_errors(result):
- """
- Checks if a result dictionary signals an error
-
- :param result: A result dictionary
- :raise TypeError: Invalid parameter
- :raise NotImplementedError: Unknown JSON-RPC version
- :raise ValueError: Invalid dictionary content
- :raise ProtocolError: An error occurred on the server side
- :return: The result parameter
- """
- if not result:
- # Notification
- return result
-
- if not isinstance(result, utils.DictType):
- # Invalid argument
- raise TypeError('Response is not a dict.')
-
- if 'jsonrpc' in result and float(result['jsonrpc']) > 2.0:
- # Unknown JSON-RPC version
- raise NotImplementedError('JSON-RPC version not yet supported.')
-
- if 'result' not in result and 'error' not in result:
- # Invalid dictionary content
- raise ValueError('Response does not have a result or error key.')
-
- if 'error' in result and result['error']:
- # Server-side error
- if 'code' in result['error']:
- # Code + Message
- code = result['error']['code']
- try:
- # Get the message (jsonrpclib)
- message = result['error']['message']
- except KeyError:
- # Get the trace (jabsorb)
- message = result['error'].get('trace', '<no error message>')
-
- if -32700 <= code <= -32000:
- # Pre-defined errors
- # See http://www.jsonrpc.org/specification#error_object
- raise ProtocolError((code, message))
- else:
- # Application error
- data = result['error'].get('data', None)
- raise AppError((code, message, data))
-
- elif isinstance(result['error'], dict) and len(result['error']) == 1:
- # Error with a single entry ('reason', ...): use its content
- error_key = result['error'].keys()[0]
- raise ProtocolError(result['error'][error_key])
-
- else:
- # Use the raw error content
- raise ProtocolError(result['error'])
-
- return result
-
-
-def isbatch(request):
- """
- Tests if the given request is a batch call, i.e. a list of multiple calls
- :param request: a JSON-RPC request object
- :return: True if the request is a batch call
- """
- if not isinstance(request, (utils.ListType, utils.TupleType)):
- # Not a list: not a batch call
- return False
- elif len(request) < 1:
- # Only one request: not a batch call
- return False
- elif not isinstance(request[0], utils.DictType):
- # One of the requests is not a dictionary, i.e. a JSON Object
- # therefore it is not a valid JSON-RPC request
- return False
- elif 'jsonrpc' not in request[0].keys():
- # No "jsonrpc" version in the JSON object: not a request
- return False
-
- try:
- version = float(request[0]['jsonrpc'])
- except ValueError:
- # Bad version of JSON-RPC
- raise ProtocolError('"jsonrpc" key must be a float(able) value.')
-
- if version < 2:
- # Batch call were not supported before JSON-RPC 2.0
- return False
-
- return True
-
-
-def isnotification(request):
- """
- Tests if the given request is a notification
-
- :param request: A request dictionary
- :return: True if the request is a notification
- """
- if 'id' not in request:
- # 2.0 notification
- return True
-
- if request['id'] is None:
- # 1.0 notification
- return True
-
- return False
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/threadpool.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/threadpool.py
deleted file mode 100644
index a38b5b83..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/threadpool.py
+++ /dev/null
@@ -1,490 +0,0 @@
-#!/usr/bin/env python
-# -- Content-Encoding: UTF-8 --
-"""
-Cached thread pool, inspired from Pelix/iPOPO Thread Pool
-
-:author: Thomas Calmant
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Documentation strings format
-__docformat__ = "restructuredtext en"
-
-# Module version
-__version_info__ = (0, 2, 5)
-__version__ = ".".join(str(x) for x in __version_info__)
-
-# ------------------------------------------------------------------------------
-
-# Standard library
-import logging
-import threading
-
-try:
- # Python 3
- # pylint: disable=F0401
- import queue
-except ImportError:
- # Python 2
- # pylint: disable=F0401
- import Queue as queue
-
-# ------------------------------------------------------------------------------
-
-
-class EventData(object):
- """
- A threading event with some associated data
- """
- def __init__(self):
- """
- Sets up the event
- """
- self.__event = threading.Event()
- self.__data = None
- self.__exception = None
-
- @property
- def data(self):
- """
- Returns the associated value
- """
- return self.__data
-
- @property
- def exception(self):
- """
- Returns the exception used to stop the wait() method
- """
- return self.__exception
-
- def clear(self):
- """
- Clears the event
- """
- self.__event.clear()
- self.__data = None
- self.__exception = None
-
- def is_set(self):
- """
- Checks if the event is set
- """
- return self.__event.is_set()
-
- def set(self, data=None):
- """
- Sets the event
- """
- self.__data = data
- self.__exception = None
- self.__event.set()
-
- def raise_exception(self, exception):
- """
- Raises an exception in wait()
-
- :param exception: An Exception object
- """
- self.__data = None
- self.__exception = exception
- self.__event.set()
-
- def wait(self, timeout=None):
- """
- Waits for the event or for the timeout
-
- :param timeout: Wait timeout (in seconds)
- :return: True if the event as been set, else False
- """
- # The 'or' part is for Python 2.6
- result = self.__event.wait(timeout) or self.__event.is_set()
- # pylint: disable=E0702
- # Pylint seems to miss the "is None" check below
- if self.__exception is None:
- return result
- else:
- raise self.__exception
-
-
-class FutureResult(object):
- """
- An object to wait for the result of a threaded execution
- """
- def __init__(self, logger=None):
- """
- Sets up the FutureResult object
-
- :param logger: The Logger to use in case of error (optional)
- """
- self._logger = logger or logging.getLogger(__name__)
- self._done_event = EventData()
- self.__callback = None
- self.__extra = None
-
- def __notify(self):
- """
- Notify the given callback about the result of the execution
- """
- if self.__callback is not None:
- try:
- self.__callback(self._done_event.data,
- self._done_event.exception,
- self.__extra)
- except Exception as ex:
- self._logger.exception("Error calling back method: %s", ex)
-
- def set_callback(self, method, extra=None):
- """
- Sets a callback method, called once the result has been computed or in
- case of exception.
-
- The callback method must have the following signature:
- ``callback(result, exception, extra)``.
-
- :param method: The method to call back in the end of the execution
- :param extra: Extra parameter to be given to the callback method
- """
- self.__callback = method
- self.__extra = extra
- if self._done_event.is_set():
- # The execution has already finished
- self.__notify()
-
- def execute(self, method, args, kwargs):
- """
- Execute the given method and stores its result.
- The result is considered "done" even if the method raises an exception
-
- :param method: The method to execute
- :param args: Method positional arguments
- :param kwargs: Method keyword arguments
- :raise Exception: The exception raised by the method
- """
- # Normalize arguments
- if args is None:
- args = []
-
- if kwargs is None:
- kwargs = {}
-
- try:
- # Call the method
- result = method(*args, **kwargs)
- except Exception as ex:
- # Something went wrong: propagate to the event and to the caller
- self._done_event.raise_exception(ex)
- raise
- else:
- # Store the result
- self._done_event.set(result)
- finally:
- # In any case: notify the call back (if any)
- self.__notify()
-
- def done(self):
- """
- Returns True if the job has finished, else False
- """
- return self._done_event.is_set()
-
- def result(self, timeout=None):
- """
- Waits up to timeout for the result the threaded job.
- Returns immediately the result if the job has already been done.
-
- :param timeout: The maximum time to wait for a result (in seconds)
- :raise OSError: The timeout raised before the job finished
- :raise Exception: The exception encountered during the call, if any
- """
- if self._done_event.wait(timeout):
- return self._done_event.data
- else:
- raise OSError("Timeout raised")
-
-# ------------------------------------------------------------------------------
-
-
-class ThreadPool(object):
- """
- Executes the tasks stored in a FIFO in a thread pool
- """
- def __init__(self, max_threads, min_threads=1, queue_size=0, timeout=60,
- logname=None):
- """
- Sets up the thread pool.
-
- Threads are kept alive 60 seconds (timeout argument).
-
- :param max_threads: Maximum size of the thread pool
- :param min_threads: Minimum size of the thread pool
- :param queue_size: Size of the task queue (0 for infinite)
- :param timeout: Queue timeout (in seconds, 60s by default)
- :param logname: Name of the logger
- :raise ValueError: Invalid number of threads
- """
- # Validate parameters
- try:
- max_threads = int(max_threads)
- if max_threads < 1:
- raise ValueError("Pool size must be greater than 0")
- except (TypeError, ValueError) as ex:
- raise ValueError("Invalid pool size: {0}".format(ex))
-
- try:
- min_threads = int(min_threads)
- if min_threads < 0:
- min_threads = 0
- elif min_threads > max_threads:
- min_threads = max_threads
- except (TypeError, ValueError) as ex:
- raise ValueError("Invalid pool size: {0}".format(ex))
-
- # The logger
- self._logger = logging.getLogger(logname or __name__)
-
- # The loop control event
- self._done_event = threading.Event()
- self._done_event.set()
-
- # The task queue
- try:
- queue_size = int(queue_size)
- except (TypeError, ValueError):
- # Not a valid integer
- queue_size = 0
-
- self._queue = queue.Queue(queue_size)
- self._timeout = timeout
- self.__lock = threading.RLock()
-
- # The thread pool
- self._min_threads = min_threads
- self._max_threads = max_threads
- self._threads = []
-
- # Thread count
- self._thread_id = 0
-
- # Current number of threads, active and alive
- self.__nb_threads = 0
- self.__nb_active_threads = 0
-
- def start(self):
- """
- Starts the thread pool. Does nothing if the pool is already started.
- """
- if not self._done_event.is_set():
- # Stop event not set: we're running
- return
-
- # Clear the stop event
- self._done_event.clear()
-
- # Compute the number of threads to start to handle pending tasks
- nb_pending_tasks = self._queue.qsize()
- if nb_pending_tasks > self._max_threads:
- nb_threads = self._max_threads
- elif nb_pending_tasks < self._min_threads:
- nb_threads = self._min_threads
- else:
- nb_threads = nb_pending_tasks
-
- # Create the threads
- for _ in range(nb_threads):
- self.__start_thread()
-
- def __start_thread(self):
- """
- Starts a new thread, if possible
- """
- with self.__lock:
- if self.__nb_threads >= self._max_threads:
- # Can't create more threads
- return False
-
- if self._done_event.is_set():
- # We're stopped: do nothing
- return False
-
- # Prepare thread and start it
- name = "{0}-{1}".format(self._logger.name, self._thread_id)
- self._thread_id += 1
-
- thread = threading.Thread(target=self.__run, name=name)
- thread.daemon = True
- self._threads.append(thread)
- thread.start()
- return True
-
- def stop(self):
- """
- Stops the thread pool. Does nothing if the pool is already stopped.
- """
- if self._done_event.is_set():
- # Stop event set: we're stopped
- return
-
- # Set the stop event
- self._done_event.set()
-
- with self.__lock:
- # Add something in the queue (to unlock the join())
- try:
- for _ in self._threads:
- self._queue.put(self._done_event, True, self._timeout)
- except queue.Full:
- # There is already something in the queue
- pass
-
- # Copy the list of threads to wait for
- threads = self._threads[:]
-
- # Join threads outside the lock
- for thread in threads:
- while thread.is_alive():
- # Wait 3 seconds
- thread.join(3)
- if thread.is_alive():
- # Thread is still alive: something might be wrong
- self._logger.warning("Thread %s is still alive...",
- thread.name)
-
- # Clear storage
- del self._threads[:]
- self.clear()
-
- def enqueue(self, method, *args, **kwargs):
- """
- Queues a task in the pool
-
- :param method: Method to call
- :return: A FutureResult object, to get the result of the task
- :raise ValueError: Invalid method
- :raise Full: The task queue is full
- """
- if not hasattr(method, '__call__'):
- raise ValueError("{0} has no __call__ member."
- .format(method.__name__))
-
- # Prepare the future result object
- future = FutureResult(self._logger)
-
- # Use a lock, as we might be "resetting" the queue
- with self.__lock:
- # Add the task to the queue
- self._queue.put((method, args, kwargs, future), True,
- self._timeout)
-
- if self.__nb_active_threads == self.__nb_threads:
- # All threads are taken: start a new one
- self.__start_thread()
-
- return future
-
- def clear(self):
- """
- Empties the current queue content.
- Returns once the queue have been emptied.
- """
- with self.__lock:
- # Empty the current queue
- try:
- while True:
- self._queue.get_nowait()
- self._queue.task_done()
- except queue.Empty:
- # Queue is now empty
- pass
-
- # Wait for the tasks currently executed
- self.join()
-
- def join(self, timeout=None):
- """
- Waits for all the tasks to be executed
-
- :param timeout: Maximum time to wait (in seconds)
- :return: True if the queue has been emptied, else False
- """
- if self._queue.empty():
- # Nothing to wait for...
- return True
- elif timeout is None:
- # Use the original join
- self._queue.join()
- return True
- else:
- # Wait for the condition
- with self._queue.all_tasks_done:
- self._queue.all_tasks_done.wait(timeout)
- return not bool(self._queue.unfinished_tasks)
-
- def __run(self):
- """
- The main loop
- """
- with self.__lock:
- self.__nb_threads += 1
-
- while not self._done_event.is_set():
- try:
- # Wait for an action (blocking)
- task = self._queue.get(True, self._timeout)
- if task is self._done_event:
- # Stop event in the queue: get out
- self._queue.task_done()
- with self.__lock:
- self.__nb_threads -= 1
- return
- except queue.Empty:
- # Nothing to do yet
- pass
- else:
- with self.__lock:
- self.__nb_active_threads += 1
-
- # Extract elements
- method, args, kwargs, future = task
- try:
- # Call the method
- future.execute(method, args, kwargs)
- except Exception as ex:
- self._logger.exception("Error executing %s: %s",
- method.__name__, ex)
- finally:
- # Mark the action as executed
- self._queue.task_done()
-
- # Thread is not active anymore
- self.__nb_active_threads -= 1
-
- # Clean up thread if necessary
- with self.__lock:
- if self.__nb_threads > self._min_threads:
- # No more work for this thread, and we're above the
- # minimum number of threads: stop this one
- self.__nb_threads -= 1
- return
-
- with self.__lock:
- # Thread stops
- self.__nb_threads -= 1
diff --git a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/utils.py b/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/utils.py
deleted file mode 100644
index 31183742..00000000
--- a/external_libs/python/jsonrpclib-pelix-0.2.5/jsonrpclib/utils.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/python
-# -- Content-Encoding: UTF-8 --
-"""
-Utility methods, for compatibility between Python version
-
-:author: Thomas Calmant
-:copyright: Copyright 2015, isandlaTech
-:license: Apache License 2.0
-:version: 0.2.5
-
-..
-
- Copyright 2015 isandlaTech
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-"""
-
-# Module version
-__version_info__ = (0, 2, 5)
-__version__ = ".".join(str(x) for x in __version_info__)
-
-# Documentation strings format
-__docformat__ = "restructuredtext en"
-
-# ------------------------------------------------------------------------------
-
-import sys
-
-# ------------------------------------------------------------------------------
-
-if sys.version_info[0] < 3:
- # Python 2
- import types
- try:
- string_types = (
- types.StringType,
- types.UnicodeType
- )
- except NameError:
- # Python built without unicode support
- string_types = (types.StringType,)
-
- numeric_types = (
- types.IntType,
- types.LongType,
- types.FloatType
- )
-
- def to_bytes(string):
- """
- Converts the given string into bytes
- """
- if type(string) is unicode:
- return str(string)
- return string
-
- def from_bytes(data):
- """
- Converts the given bytes into a string
- """
- if type(data) is str:
- return data
- return str(data)
-
-else:
- # Python 3
- string_types = (
- bytes,
- str
- )
-
- numeric_types = (
- int,
- float
- )
-
- def to_bytes(string):
- """
- Converts the given string into bytes
- """
- if type(string) is bytes:
- return string
- return bytes(string, "UTF-8")
-
- def from_bytes(data):
- """
- Converts the given bytes into a string
- """
- if type(data) is str:
- return data
- return str(data, "UTF-8")
-
-# ------------------------------------------------------------------------------
-# Common
-
-DictType = dict
-
-ListType = list
-TupleType = tuple
-
-iterable_types = (
- list,
- set, frozenset,
- tuple
-)
-
-value_types = (
- bool,
- type(None)
-)
-
-primitive_types = string_types + numeric_types + value_types