Ejemplo n.º 1
0
def update_thread(manager, connection, stop):
    while True:

        # Read the size and position of the update message
        data = b''
        while True:
            try:
                data += connection.partial_receive(1)
                size = Decoder.decode_message_size(data)
                break
            except IndexError:
                pass
            except:  # pylint: disable=bare-except
                # TODO: is there a better way to catch exceptions when the
                #      thread is forcibly stopped (e.g. by CTRL+c)?
                return
            if stop.is_set():
                connection.close()
                return

        # Read and decode the update message
        data = connection.receive(size)
        update = Decoder.decode_message(data, KRPC.StreamUpdate)

        # Add the data to the cache
        manager.update(update.results)
Ejemplo n.º 2
0
def decode_default_value(value, typ):
    value = base64.b64decode(value)
    value = array.array('B', value).tostring()
    # Note: following is a workaround for decoding EnumerationType,
    # as set_values has not been called
    if not isinstance(typ, EnumerationType):
        return Decoder.decode(value, typ)
    return Decoder.decode(value, Types().sint32_type)
Ejemplo n.º 3
0
 def decode_default_value(self, value, typ):
     value = base64.b64decode(value)
     # Note: following is a workaround for decoding EnumerationType,
     # as set_values has not been called
     value = array.array('B', value).tostring()
     if not isinstance(typ, EnumerationType):
         return Decoder.decode(value, typ)
     return Decoder.decode(value, self.types.sint32_type)
Ejemplo n.º 4
0
    def receive_message(self, typ):
        """ Receive a protobuf message and decode it """

        # Read the size and position of the response message
        data = b''
        while True:
            try:
                data += self.partial_receive(1)
                size = Decoder.decode_message_size(data)
                break
            except IndexError:
                pass

        # Read and decode the response message
        data = self.receive(size)
        return Decoder.decode_message(data, typ)
Ejemplo n.º 5
0
    def _invoke(self, service, procedure, args, param_names, param_types,
                return_type):
        """ Execute an RPC """

        # Build the request
        call = self._build_call(service, procedure, args, param_names,
                                param_types, return_type)
        request = KRPC.Request()
        request.calls.extend([call])

        # Send the request
        with self._rpc_connection_lock:
            self._rpc_connection.send_message(request)
            response = self._rpc_connection.receive_message(KRPC.Response)

        # Check for an error response
        if response.HasField('error'):
            raise self._build_error(response.error)

        # Check for an error in the procedure results
        if response.results[0].HasField('error'):
            raise self._build_error(response.results[0].error)

        # Decode the response and return the (optional) result
        result = None
        if return_type is not None:
            result = Decoder.decode(response.results[0].value, return_type)
            if isinstance(result, KRPC.Event):
                result = Event(self, result)
        return result
Ejemplo n.º 6
0
 def _run_test_decode_value(self, typ, cases):
     for decoded, encoded in cases:
         value = Decoder.decode(unhexlify(encoded), self.types.as_type(typ))
         if typ in ('float','double'):
             self.assertEqual(str(decoded)[0:8], str(value)[0:8])
         else:
             self.assertEqual(decoded, value)
Ejemplo n.º 7
0
 def _run_test_decode_value(self, typ, cases):
     for decoded, encoded in cases:
         value = Decoder.decode(unhexlify(encoded), self.types.as_type(typ))
         if typ in ('float', 'double'):
             self.assertEqual(str(decoded)[0:8], str(value)[0:8])
         else:
             self.assertEqual(decoded, value)
Ejemplo n.º 8
0
    def _receive_response(self):
        """ Receive data from the server and decode it into a KRPC.Response object """

        # Read the size and position of the response message
        data = b''
        while True:
            try:
                data += self._rpc_connection.partial_receive(1)
                size, _ = Decoder.decode_size_and_position(data)
                break
            except IndexError:
                pass

        # Read and decode the response message
        data = self._rpc_connection.receive(size)
        return Decoder.decode(data, self._response_type)
Ejemplo n.º 9
0
 def _run_test_decode_value(self, typ, cases):
     for decoded, encoded in cases:
         value = Decoder.decode(unhexlify(encoded), typ)
         if typ.python_type == float:
             self.assertEqual(str(decoded)[0:8], str(value)[0:8])
         else:
             self.assertEqual(decoded, value)
Ejemplo n.º 10
0
    def _invoke(self,
                service,
                procedure,
                args=[],
                kwargs={},
                param_names=[],
                param_types=[],
                return_type=None):
        """ Execute an RPC """

        # Build the request
        request = self._build_request(service, procedure, args, kwargs,
                                      param_names, param_types, return_type)

        # Send the request
        with self._rpc_connection_lock:
            self._send_request(request)
            response = self._receive_response()

        # Check for an error response
        if response.has_error:
            raise RPCError(response.error)

        # Decode the response and return the (optional) result
        result = None
        if return_type is not None:
            result = Decoder.decode(response.return_value, return_type)
        return result
Ejemplo n.º 11
0
Archivo: client.py Proyecto: 602p/krpc
    def _receive_response(self):
        """ Receive data from the server and decode it into a KRPC.Response object """

        # Read the size and position of the response message
        data = b""
        while True:
            try:
                data += self._rpc_connection.partial_receive(1)
                size, position = Decoder.decode_size_and_position(data)
                break
            except IndexError:
                pass

        # Read and decode the response message
        data = self._rpc_connection.receive(size)
        return Decoder.decode(data, self._response_type)
Ejemplo n.º 12
0
 def test_decode_message_delimited(self):
     typ = krpc.schema.KRPC.Request
     message = '1c' + '0a0b536572766963654e616d65120d50726f6365647572654e616d65'
     request = Decoder.decode_delimited(unhexlify(message),
                                        self.types.as_type('KRPC.Request'))
     self.assertEqual('ServiceName', request.service)
     self.assertEqual('ProcedureName', request.procedure)
Ejemplo n.º 13
0
 def __init__(self, name, position, type, attributes, documentation, default_argument=None):
     self.name = name
     self.type = types.get_parameter_type(position, type, attributes)
     self.has_default_argument = default_argument is not None
     if default_argument is not None:
         default_argument = Decoder.decode(str(bytearray(default_argument)), self.type)
     self.default_argument = default_argument
     self.documentation = documentation
Ejemplo n.º 14
0
def update_thread(connection, stop):
    stream_message_type = Types().as_type('KRPC.StreamMessage')
    response_type = Types().as_type('KRPC.Response')

    while True:

        # Read the size and position of the response message
        data = b''
        while True:
            try:
                data += connection.partial_receive(1)
                size,position = Decoder.decode_size_and_position(data)
                break
            except IndexError:
                pass
            except:
                #TODO: is there a better way to catch exceptions when the thread is forcibly stopped (e.g. by CTRL+c)?
                return
            if stop.is_set():
                connection.close()
                return

        # Read and decode the response message
        data = connection.receive(size)
        response = Decoder.decode(data, stream_message_type)

        # Add the data to the cache
        with _stream_cache_lock:
            for response in response.responses:
                id = response.id
                if id not in _stream_cache:
                    continue

                # Check for an error response
                if response.response.has_error:
                    _stream_cache[id].value = RPCError(response.response.error)
                    continue

                # Decode the return value and store it in the cache
                typ = _stream_cache[id].return_type
                value = Decoder.decode(response.response.return_value, typ)
                _stream_cache[id].update(value)
Ejemplo n.º 15
0
def update_thread(connection, stop, cache, cache_lock):
    stream_message_type = Types().as_type('KRPC.StreamMessage')

    while True:

        # Read the size and position of the response message
        data = b''
        while True:
            try:
                data += connection.partial_receive(1)
                size, _ = Decoder.decode_size_and_position(data)
                break
            except IndexError:
                pass
            except:  # pylint: disable=bare-except
                # TODO: is there a better way to catch exceptions when the
                #      thread is forcibly stopped (e.g. by CTRL+c)?
                return
            if stop.is_set():
                connection.close()
                return

        # Read and decode the response message
        data = connection.receive(size)
        response = Decoder.decode(data, stream_message_type)

        # Add the data to the cache
        with cache_lock:
            for response in response.responses:
                if response.id not in cache:
                    continue

                # Check for an error response
                if response.response.has_error:
                    cache[response.id].value = RPCError(
                        response.response.error)
                    continue

                # Decode the return value and store it in the cache
                typ = cache[response.id].return_type
                value = Decoder.decode(response.response.return_value, typ)
                cache[response.id].update(value)
Ejemplo n.º 16
0
def update_thread(connection):
    stream_message_type = Types().as_type('KRPC.StreamMessage')
    response_type = Types().as_type('KRPC.Response')

    while True:

        # Read the size and position of the response message
        data = b''
        while True:
            try:
                data += connection.partial_receive(1)
                size,position = Decoder.decode_size_and_position(data)
                break
            except IndexError:
                pass
            except socket.error:
                return

        # Read and decode the response message
        try:
            data = connection.receive(size)
        except socket.error:
            return
        response = Decoder.decode(data, stream_message_type)

        # Add the data to the cache
        with _stream_cache_lock:
            for response in response.responses:
                id = response.id
                if id not in _stream_cache:
                    continue

                # Check for an error response
                if response.response.HasField('error'):
                    _stream_cache[id].value = RPCError(response.response.error)
                    continue

                # Decode the return value and store it in the cache
                typ = _stream_cache[id].return_type
                value = Decoder.decode(response.response.return_value, typ)
                _stream_cache[id].update(value)
Ejemplo n.º 17
0
Archivo: service.py Proyecto: 602p/krpc
 def _parse_procedure(cls, procedure):
     param_names = [_to_snake_case(param.name) for param in procedure.parameters]
     param_types = [cls._client._types.get_parameter_type(i, param.type, procedure.attributes) for i,param in enumerate(procedure.parameters)]
     param_required = [not param.HasField('default_argument') for param in procedure.parameters]
     param_default = []
     for param,typ in zip(procedure.parameters, param_types):
         if param.HasField('default_argument'):
             param_default.append(Decoder.decode(param.default_argument, typ))
         else:
             param_default.append(None)
     return_type = None
     if procedure.HasField('return_type'):
         return_type = cls._client._types.get_return_type(procedure.return_type, procedure.attributes)
     return param_names, param_types, param_required, param_default, return_type
Ejemplo n.º 18
0
 def _parse_procedure(cls, procedure):
     param_names = [_to_snake_case(param.name) for param in procedure.parameters]
     param_types = [cls._client._types.get_parameter_type(i, param.type, procedure.attributes) for i,param in enumerate(procedure.parameters)]
     param_required = [not param.has_default_argument for param in procedure.parameters]
     param_default = []
     for param,typ in zip(procedure.parameters, param_types):
         if param.has_default_argument:
             param_default.append(Decoder.decode(param.default_argument, typ))
         else:
             param_default.append(None)
     return_type = None
     if procedure.has_return_type:
         return_type = cls._client._types.get_return_type(procedure.return_type, procedure.attributes)
     return param_names, param_types, param_required, param_default, return_type
Ejemplo n.º 19
0
 def __init__(self,
              name,
              position,
              type,
              attributes,
              documentation,
              default_argument=None):
     self.name = name
     self.type = types.get_parameter_type(position, type, attributes)
     self.has_default_argument = default_argument is not None
     if default_argument is not None:
         default_argument = Decoder.decode(str(bytearray(default_argument)),
                                           self.type)
     self.default_argument = default_argument
     self.documentation = documentation
Ejemplo n.º 20
0
 def __init__(self, name, type, documentation, default_value=None):
     super(Parameter, self).__init__()
     self.name = name
     self.type = as_type(self.types, type)
     self.has_default_value = default_value is not None
     if default_value is not None:
         # Note: following is a workaround for decoding EnumerationType,
         # as set_values has not been called
         if not isinstance(self.type, EnumerationType):
             typ = self.type
         else:
             typ = self.types.sint32_type
         default_value = Decoder.decode(
             str(bytearray(base64.b64decode(default_value))), typ)
     self.default_value = default_value
     self.documentation = documentation
Ejemplo n.º 21
0
 def __init__(
     self, name, position, type, attributes, documentation, default_value=None
 ):  # pylint: disable=redefined-builtin
     super(Parameter, self).__init__()
     self.name = name
     self.type = self.types.get_parameter_type(position, type, attributes)
     self.has_default_value = default_value is not None
     if default_value is not None:
         # Note: following is a workaround for decoding EnumType, as set_values has not been called
         if not isinstance(self.type, EnumType):
             typ = self.type
         else:
             typ = self.types.as_type("int32")
         default_value = Decoder.decode(str(bytearray(base64.b64decode(default_value))), typ)
     self.default_value = default_value
     self.documentation = documentation
Ejemplo n.º 22
0
    def update(self, results):
        with self._update_lock:
            for result in results:
                if result.id not in self._streams:
                    continue

                # Check for an error response
                if result.result.HasField('error'):
                    self._update_stream(
                        result.id,
                        self._conn._build_error(result.result.error))
                    continue

                # Decode the return value and store it in the cache
                typ = self._streams[result.id].return_type
                value = Decoder.decode(result.result.value, typ)
                self._update_stream(result.id, value)
Ejemplo n.º 23
0
 def _parse_procedure(cls, procedure):
     param_names = [snake_case(param.name)
                    for param in procedure.parameters]
     param_types = [cls._client._types.as_type(param.type)
                    for param in procedure.parameters]
     param_required = [not param.default_value
                       for param in procedure.parameters]
     param_default = []
     for param, typ in zip(procedure.parameters, param_types):
         if param.default_value:
             param_default.append(Decoder.decode(param.default_value, typ))
         else:
             param_default.append(None)
     return_type = None
     if not Types.is_none_type(procedure.return_type):
         return_type = cls._client._types.as_type(procedure.return_type)
     return param_names, param_types, param_required, \
         param_default, return_type
Ejemplo n.º 24
0
Archivo: client.py Proyecto: 602p/krpc
    def _invoke(self, service, procedure, args=[], kwargs={}, param_names=[], param_types=[], return_type=None):
        """ Execute an RPC """

        # Build the request
        request = self._build_request(service, procedure, args, kwargs, param_names, param_types, return_type)

        # Send the request
        with self._rpc_connection_lock:
            self._send_request(request)
            response = self._receive_response()

        # Check for an error response
        if response.HasField("error"):
            raise RPCError(response.error)

        # Decode the response and return the (optional) result
        result = None
        if return_type is not None:
            result = Decoder.decode(response.return_value, return_type)
        return result
Ejemplo n.º 25
0
 def _parse_procedure(cls, procedure):
     param_names = [
         snake_case(param.name) for param in procedure.parameters
     ]
     param_types = [
         cls._client._types.as_type(param.type)
         for param in procedure.parameters
     ]
     param_required = [
         not param.default_value for param in procedure.parameters
     ]
     param_default = []
     for param, typ in zip(procedure.parameters, param_types):
         if param.default_value:
             param_default.append(Decoder.decode(param.default_value, typ))
         else:
             param_default.append(None)
     return_type = None
     if not Types.is_none_type(procedure.return_type):
         return_type = cls._client._types.as_type(procedure.return_type)
     return param_names, param_types, param_required, \
         param_default, return_type
Ejemplo n.º 26
0
 def __init__(
         self,
         name,
         position,
         type,  # pylint: disable=redefined-builtin
         attributes,
         documentation,
         default_value=None):
     super(Parameter, self).__init__()
     self.name = name
     self.type = self.types.get_parameter_type(position, type, attributes)
     self.has_default_value = default_value is not None
     if default_value is not None:
         # Note: following is a workaround for decoding EnumType,
         # as set_values has not been called
         if not isinstance(self.type, EnumType):
             typ = self.type
         else:
             typ = self.types.as_type('int32')
         default_value = Decoder.decode(
             str(bytearray(base64.b64decode(default_value))), typ)
     self.default_value = default_value
     self.documentation = documentation
Ejemplo n.º 27
0
 def test_decode_message(self):
     message = '0a0b536572766963654e616d65120d50726f6365647572654e616d65'
     request = Decoder.decode(unhexlify(message),
                              self.types.as_type('KRPC.Request'))
     self.assertEqual('ServiceName', request.service)
     self.assertEqual('ProcedureName', request.procedure)
Ejemplo n.º 28
0
 def test_decode_value(self):
     value = Decoder.decode(unhexlify('ac02'), self.types.as_type('int32'))
     self.assertEqual(int(300), value)
Ejemplo n.º 29
0
 def test_decode_message(self):
     message = '0a0b536572766963654e616d65120d50726f6365647572654e616d65'
     call = Decoder.decode(
         unhexlify(message), self.types.procedure_call_type)
     self.assertEqual('ServiceName', call.service)
     self.assertEqual('ProcedureName', call.procedure)
Ejemplo n.º 30
0
 def test_message_size(self):
     message = '1c'
     size = Decoder.decode_message_size(unhexlify(message))
     self.assertEqual(28, size)
Ejemplo n.º 31
0
 def test_decode_size_and_position(self):
     message = '1c'
     size,position = Decoder.decode_size_and_position(unhexlify(message))
     self.assertEqual(28, size)
     self.assertEqual(1, position)
Ejemplo n.º 32
0
 def test_decode_unicode_string(self):
     value = Decoder.decode(unhexlify('03e284a2'), self.types.as_type('string'))
     self.assertEqual(b'\xe2\x84\xa2'.decode('utf-8'), value)
Ejemplo n.º 33
0
 def test_decode_value_delimited(self):
     value = Decoder.decode_delimited(unhexlify('02'+'ac02'), self.types.as_type('int32'))
     self.assertEqual(300, value)
Ejemplo n.º 34
0
 def test_message_size(self):
     message = '1c'
     size = Decoder.decode_message_size(unhexlify(message))
     self.assertEqual(28, size)
Ejemplo n.º 35
0
 def test_guid(self):
     self.assertEqual(
         '6f271b39-00dd-4de4-9732-f0d3a68838df',
         Decoder.guid(unhexlify('391b276fdd00e44d9732f0d3a68838df')))
Ejemplo n.º 36
0
 def test_decode_class(self):
     typ = self.types.as_type('Class(ServiceName.ClassName)')
     value = Decoder.decode(unhexlify('ac02'), typ)
     self.assertTrue(isinstance(value, typ.python_type))
     self.assertEqual(300, value._object_id)
Ejemplo n.º 37
0
 def test_decode_value_delimited(self):
     value = Decoder.decode_delimited(unhexlify('02' + 'ac02'),
                                      self.types.as_type('int32'))
     self.assertEqual(300, value)
Ejemplo n.º 38
0
 def test_guid(self):
     self.assertEqual('6f271b39-00dd-4de4-9732-f0d3a68838df', Decoder.guid(unhexlify('391b276fdd00e44d9732f0d3a68838df')))
Ejemplo n.º 39
0
 def test_decode_value(self):
     value = Decoder.decode(unhexlify('ac02'), self.types.uint32_type)
     self.assertEqual(int(300), value)
Ejemplo n.º 40
0
 def test_decode_message(self):
     message = '0a0b536572766963654e616d65120d50726f6365647572654e616d65'
     request = Decoder.decode(unhexlify(message), self.types.as_type('KRPC.Request'))
     self.assertEqual('ServiceName', request.service)
     self.assertEqual('ProcedureName', request.procedure)
Ejemplo n.º 41
0
 def test_decode_message_delimited(self):
     typ = krpc.schema.KRPC.Request
     message = '1c'+'0a0b536572766963654e616d65120d50726f6365647572654e616d65'
     request = Decoder.decode_delimited(unhexlify(message), self.types.as_type('KRPC.Request'))
     self.assertEqual('ServiceName', request.service)
     self.assertEqual('ProcedureName', request.procedure)
Ejemplo n.º 42
0
 def test_decode_message(self):
     message = '0a0b536572766963654e616d65120d50726f6365647572654e616d65'
     call = Decoder.decode(unhexlify(message),
                           self.types.procedure_call_type)
     self.assertEqual('ServiceName', call.service)
     self.assertEqual('ProcedureName', call.procedure)
Ejemplo n.º 43
0
 def test_decode_unicode_string(self):
     value = Decoder.decode(unhexlify('03e284a2'), self.types.string_type)
     self.assertEqual(b'\xe2\x84\xa2'.decode('utf-8'), value)
Ejemplo n.º 44
0
 def test_decode_class(self):
     typ = self.types.class_type('ServiceName', 'ClassName')
     value = Decoder.decode(unhexlify('ac02'), typ)
     self.assertTrue(isinstance(value, typ.python_type))
     self.assertEqual(300, value._object_id)
Ejemplo n.º 45
0
 def test_decode_class_none(self):
     typ = self.types.class_type('ServiceName', 'ClassName')
     value = Decoder.decode(unhexlify('00'), typ)
     self.assertIsNone(value)
Ejemplo n.º 46
0
 def test_decode_class_none(self):
     typ = self.types.as_type('Class(ServiceName.ClassName)')
     value = Decoder.decode(unhexlify('00'), typ)
     self.assertIsNone(value)
Ejemplo n.º 47
0
 def test_decode_size_and_position(self):
     message = '1c'
     size, position = Decoder.decode_size_and_position(unhexlify(message))
     self.assertEqual(28, size)
     self.assertEqual(1, position)