Beispiel #1
0
    def _prepare_request(self, command, query):
        """
        Prepares the command url, and converts the query json.

        :param command: The Url command parameter
        :type  command: str

        :param query: Will get json encoded.

        :return: params and a url, for use with requests etc.
        """
        from pytgbot.api_types.sendable import Sendable
        from pytgbot.api_types import as_array
        import json

        params = {}
        for key in query.keys():
            element = query[key]
            if element is not None:
                if isinstance(element, Sendable):
                    params[key] = json.dumps(as_array(element))
                else:
                    params[key] = element
        url = self._base_url.format(api_key=n(self.api_key),
                                    command=n(command))
        return url, params
Beispiel #2
0
    def _prepare_request(self, command, query):
        """
        :param command: The Url command parameter
        :type  command: str

        :param query: will get json encoded.
        :type  query: dict

        :return:
        """
        from luckydonaldUtils.encoding import to_native as n
        from pytgbot.api_types.sendable import Sendable
        from pytgbot.api_types import as_array
        from DictObject import DictObject
        import json

        params = {}
        for key in query.keys():
            element = query[key]
            if element is not None:
                if isinstance(element, Sendable):
                    params[key] = json.dumps(as_array(element))
                else:
                    params[key] = element
        url = self._base_url.format(api_key=n(self.api_key), command=n(command))
        return DictObject(url=url, params=params)
Beispiel #3
0
    def _prepare_request(self, command, query):
        """
        :param command: The Url command parameter
        :type  command: str

        :param query: will get json encoded.
        :type  query: dict

        :return:
        """
        from luckydonaldUtils.encoding import to_native as n
        from pytgbot.api_types.sendable import Sendable
        from pytgbot.api_types import as_array
        from DictObject import DictObject
        import json

        params = {}
        for key in query.keys():
            element = query[key]
            if element is not None:
                if isinstance(element, Sendable):
                    params[key] = json.dumps(as_array(element))
                else:
                    params[key] = element
        url = self._base_url.format(api_key=n(self.api_key), command=n(command))
        return DictObject(url=url, params=params)
Beispiel #4
0
    def _validate_input(function_name, arguments):
        """
        This will check if the arguments fit the functions needed parameters.
        Returns a tuple of cli command name and the arguments formated as unicode strings.

        :param function_name: The name of the called function.
        :type function_name: str
        :param arguments: given arguments, as a list.
        :type arguments: list of str or tuple of str
        :returns: unicode cli command and a list of unicode parameters.
        :rtype: tuple of (str, list of str)
        """
        if function_name not in functions:
            raise UnknownFunction(function_name)
        command_name    = functions[function_name][FUNC_CMD]
        arguments_types = functions[function_name][FUNC_ARGS]
        """:type arguments_types: list of pytg.argument_types.Argument"""
        if len(arguments) > len(arguments_types):
            raise ValueError(
                "Error in function {function_name}: {expected_number} paramters expected, but {given_number} were given.".format(
                    function_name=function_name, expected_number=len(arguments_types), given_number=len(arguments))
            )
        # end if
        i = 0
        new_args = []
        for func_type in arguments_types:
            """:type func_type: pytg.argument_types.Argument"""
            if i >= len(arguments):  # if to many arguments
                if not func_type.optional:
                    raise ValueError(
                        "Error in function {function_name}: Not enough parameter given, {arg_name} missing. Arguments got: {arguments}".format(
                            function_name=function_name, arguments=arguments, arg_name=str(func_type))
                    )
                else:
                    logger.debug("Skipping missing optional parameter #{number} {arg_name} (type {type}) in function {function_name}.".format(
                        type=func_type.__class__.__name__, function_name=function_name, number=i, arg_name=str(func_type))
                    )
                    continue  # do not increment i, we are still processing the same arg.
                # end if optional
            # end if to many arguments
            arg = arguments[i]
            logger.debug("Parsing {function_name}: Argument {arg} - {type} ({opt})".format(
                function_name=n(function_name), arg=n(arg), type=func_type,
                opt=("optional" if hasattr(func_type, "_optional") else "needed")
            ))
            # arg is the given one, which should be func_type.

            try:
                arg_value = func_type.parse(arg)
            except Exception as err:
                logger.debug("Got error", exc_info=True)
                if func_type.optional:
                    logger.debug("Skipping unfitting optional parameter #{number} {param} (type {type}) in function {function_name}.".format(type=func_type.__class__.__name__, function_name=function_name, param=str(func_type), number=i))
                    continue  # do not increment i, we are still processing the same arg.
                raise ValueError("Error in function {function_name}: parameter #{number} {param} is not type {type}. ({error})".format(
                    function_name=function_name, number=i, type=func_type.__class__.__name__, param=str(func_type), error=str(err)))
            new_args.append(u(arg_value))
            i += 1
        return command_name, new_args
Beispiel #5
0
    def _validate_input(function_name, arguments):
        """
        This will check if the arguments fit the functions needed parameters.
        Returns a tuple of cli command name and the arguments formated as unicode strings.

        :param function_name: The name of the called function.
        :type function_name: str
        :param arguments: given arguments, as a list.
        :type arguments: list of str or tuple of str
        :returns: unicode cli command and a list of unicode parameters.
        :rtype: tuple of (str, list of str)
        """
        if function_name not in functions:
            raise UnknownFunction(function_name)
        command_name    = functions[function_name][FUNC_CMD]
        arguments_types = functions[function_name][FUNC_ARGS]
        """:type arguments_types: list of pytg.argument_types.Argument"""
        if len(arguments) > len(arguments_types):
            raise ValueError(
                "Error in function {function_name}: {expected_number} paramters expected, but {given_number} were given.".format(
                    function_name=function_name, expected_number=len(arguments_types), given_number=len(arguments))
            )
        # end if
        i = 0
        new_args = []
        for func_type in arguments_types:
            """:type func_type: pytg.argument_types.Argument"""
            if i >= len(arguments):  # if to many arguments
                if not func_type.optional:
                    raise ValueError(
                        "Error in function {function_name}: Not enough parameter given, {arg_name} missing. Arguments got: {arguments}".format(
                            function_name=function_name, arguments=arguments, arg_name=str(func_type))
                    )
                else:
                    logger.debug("Skipping missing optional parameter #{number} {arg_name} (type {type}) in function {function_name}.".format(
                        type=func_type.__class__.__name__, function_name=function_name, number=i, arg_name=str(func_type))
                    )
                    continue  # do not increment i, we are still processing the same arg.
                # end if optional
            # end if to many arguments
            arg = arguments[i]
            logger.debug("Parsing {function_name}: Argument {arg} - {type} ({opt})".format(
                function_name=n(function_name), arg=n(arg), type=func_type,
                opt=("optional" if hasattr(func_type, "_optional") else "needed")
            ))
            # arg is the given one, which should be func_type.

            try:
                arg_value = func_type.parse(arg)
            except Exception as err:
                logger.debug("Got error", exc_info=True)
                if func_type.optional:
                    logger.debug("Skipping unfitting optional parameter #{number} {param} (type {type}) in function {function_name}.".format(type=func_type.__class__.__name__, function_name=function_name, param=str(func_type), number=i))
                    continue  # do not increment i, we are still processing the same arg.
                raise ValueError("Error in function {function_name}: parameter #{number} {param} is not type {type}. ({error})".format(
                    function_name=function_name, number=i, type=func_type.__class__.__name__, param=str(func_type), error=str(err)))
            new_args.append(u(arg_value))
            i += 1
        return command_name, new_args
Beispiel #6
0
    def __getattr__(self, name):
        """
        Directly pulls the content form the dict itself,
        works as long as _key_map is correct.

        >>> b = DictObject({"foo": {"lol": True}, "hello":42, "ponies":'are pretty!'})
        >>> b.notexist
        Traceback (most recent call last):
            ...
        AttributeError: notexist

        >>> b = DictObject()
        >>> b.notexist
        Traceback (most recent call last):
            ...
        AttributeError: notexist
        """
        _exception = None  # py2
        try:
            value = dict.__getattribute__(
                self, n(name)
            )  # Raise exception if not found in original dict's attributes either
            return value
        except AttributeError:
            try:
                if n(name) in self.__dict__:
                    return self.__dict__[n(name)]
                if self._attribute_to_key_map:
                    key_name = self._attribute_to_key_map[n(
                        name)]  # Check if we have this set.
                    self.on_get(key_name)
                    value = dict.__getitem__(self, key_name)  # self[key_name]
                    value = self.after_get(key_name, value)
                    return value
                else:
                    if not sys.version < '3':  # python 2.7
                        raise suppress_context(AttributeError(name))
                    # print("_attribute_to_key_map not defined.")
                    _exception = AttributeError(name)
                    _exception.__cause__ = None

            except KeyError:
                if not sys.version < '3':  # python 2.7
                    raise suppress_context(AttributeError(name))
                _exception = AttributeError(name)
                _exception.__cause__ = None
            finally:
                if _exception:
                    raise _exception
        finally:
            if _exception:
                raise _exception
Beispiel #7
0
    def __delitem__(self, key):
        """
        Deletes an item by key.

        >>> b = DictObject({"test": "123", "littlepip": 'best pony!', 'something': 'else'})
        >>> del b["test"]
        >>> b == {'littlepip': 'best pony!', 'something': 'else'}
        True

        >>> del b.something
        >>> b == {'littlepip': 'best pony!'}
        True

        >>> b.clear()
        >>> b == {}
        True

        :param key: The key to delete.
        :return: Nothing.
        """
        if self.on_del(key):
            attribute_name = self.get_attribute_name_by_key(key)
            del self._attribute_to_key_map[n(attribute_name)]
            dict.__delitem__(self, key)
            self.after_del(key)
Beispiel #8
0
 def __setattr__(self, name, value):
     if name.startswith("_"):
         # self._attribute_to_key_map = value
         super(DictObject, self).__setattr__(name, value)
         return
     else:
         key_name = self._attribute_to_key_map[n(name)] if n(
             name
         ) in self._attribute_to_key_map else name  # if there is a key representing this attribute
     # update this key, too
     value = self.on_set(name, value)
     self._add_to_object_part(
         name, value)  # needed allways to keep items  beeing recursive.
     self._attribute_to_key_map[n(
         name
     )] = key_name  # needed only on adding new element. (not when updating)
     # object.__setattr__(self, key, value)
     dict.__setitem__(
         self, self._attribute_to_key_map[n(name)],
         DictObject.objectify(value))  # self[self._key_map[key]] = value
     self.after_set(name, value)
Beispiel #9
0
def iterm_show_file(filename,
                    data=None,
                    inline=True,
                    width="auto",
                    height="auto",
                    preserve_aspect_ratio=True):
    """

    https://iterm2.com/documentation-images.html
    
    :param filename: 
    :param data: 
    :param inline: 
    :param width:  
    :param height: 
    :param preserve_aspect_ratio: 
    
    Size:
        - N   (Number only): N character cells.
        - Npx (Number + px): N pixels.
        - N%  (Number + %):  N percent of the session's width or height.
        - auto:              The image's inherent size will be used to determine an appropriate dimension.
    :return: 
    """
    width = str(width) if width is not None else "auto"
    height = str(height) if height is not None else "auto"
    if data is None:
        data = read_file_to_buffer(filename)
    # end if
    data_bytes = data.getvalue()
    output = "\033]1337;File=" \
             "name={filename};size={size};inline={inline};" \
             "preserveAspectRatio={preserve};width={width};height={height}:{data}\a\n".format(
        filename=n(b64encode(b(filename))), size=len(data_bytes), inline=1 if inline else 0,
        width=width, height=height, preserve=1 if preserve_aspect_ratio else 0,
        data=n(b64encode(data_bytes)),
    )
    #sys.stdout.write(output)
    return output
Beispiel #10
0
	def do(self, command):
		"""
		Send a request to the api.

		:param action:
		:param data:
		:param query:
		:return:
		"""
		headers = {"Active-Remote": self.token, "Easter-Egg": "http://flutterb.at/4458"}
		url = base_url.format(command=n(command), host=self.host, port=self.port, headers=headers)
		r = requests.get(url, verify=False)  # Allow unsigned certificates.
		return r
Beispiel #11
0
    def __delattr__(self, name):
        """
        >>> b = DictObject({"foo": {"lol": True}, "hello":42, "ponies":'are pretty!'})
        >>> b._lol = "hey"
        >>> b._lol
        'hey'
        >>> b['_lol']
        Traceback (most recent call last):
            ...
        KeyError: '_lol'

        >>> del b._lol
        """
        # object.__delattr__(self, item)
        if name in self.__dict__:
            del self.__dict__[name]
        if n(name) in self._attribute_to_key_map:
            key = self._attribute_to_key_map[n(name)]
            if self.on_del(key):
                dict.__delitem__(self, key)
                del self._attribute_to_key_map[n(name)]
            self.after_del(key)
Beispiel #12
0
    def merge_dict(self, d):
        """
        ---------------
         Merging dicts
        ---------------

        You know what is more fun than a dict?
        Adding more dict to it.

            >>> first_dict  = {"best pony":'Littlepip'}
            >>> second_dict = {"best fiction":"Fallout: Equestria"}

        There we got some Dicts. Let's merge!

            >>> a = DictObject( first_dict )
            >>> a.merge_dict( second_dict ) # doctest: +ELLIPSIS
            {...}

        but you can go all fancy and use the += operator:

            >>> a += {"4458":"just google it?"}


            >>> a == {'4458': 'just google it?', 'best fiction':'Fallout: Equestria', 'best pony': 'Littlepip'}
            True

        This will overwrite existing values.

            >>> other_test = DictObject( {"key":"original value"} )

            >>> other_test += {"key":"changed value"}

            >>> other_test["key"] == 'changed value'
            True

        TypeError will be raised, if the given element is not a dict:

            >>> other_test += 1234
            Traceback (most recent call last):
                ...
            TypeError: Argument is no dict.

        """
        if not isinstance(d, dict):
            raise TypeError("Argument is no dict.")
        # self._dict = d
        for a, b in list(d.items()):
            attribute_name = self.get_attribute_name_by_key(a)
            self._add_to_object_part(a, b)
            self._attribute_to_key_map[n(attribute_name)] = a
        return self
Beispiel #13
0
    def __setitem__(self, key, value):
        """
        Updates the value, or creates a new item.

        >>> b = DictObject({"foo": {"lol": True}, "hello":42, "ponies":'are pretty!'})
        >>> b["foo"] = "updated value"
        >>> b == {'ponies': 'are pretty!', 'foo': 'updated value', 'hello': 42}
        True
        >>> b.foo
        'updated value'
        >>> b["foo"]
        'updated value'
        >>> b["bar"] = "created value"
        >>> b == {'ponies': 'are pretty!', 'foo': 'updated value', 'bar': 'created value', 'hello': 42}
        True
        >>> b["bar"]
        'created value'
        >>> b.bar
        'created value'
        >>> b.barz = "more created value"
        >>> b["barz"]
        'more created value'
        >>> b.barz
        'more created value'
        >>> b.barz = "changed this."
        >>> b["barz"]
        'changed this.'
        >>> b.barz
        'changed this.'
        """
        attribute_name = self.get_attribute_name_by_key(key)
        unique_attribute_name = attribute_name
        # check, if there is already a key representing this attribute
        if n(attribute_name
             ) in self._attribute_to_key_map and self._attribute_to_key_map[n(
                 attribute_name)] != key:
            # This attribute is already set, but the key is not.
            # Now search for the next free one
            i = 1
            while i != 0:
                unique_attribute_name = attribute_name + "_" + str(i)
                i = i + 1 if (
                    n(unique_attribute_name) in self._attribute_to_key_map and
                    self._attribute_to_key_map[n(unique_attribute_name)] != key
                ) else 0
            # if is not free name, continue to increase,
            # else, if is free, set to 0 to exit loop
            # end while
            logger.warn(
                "\nCRITICAL WARNING in DictObject: Mapped key '%s' to attribute '%s', "
                "because attribute '%s' was already set by key '%s'." %
                (key, unique_attribute_name, attribute_name,
                 self._attribute_to_key_map[n(attribute_name)]))
        value = self.on_set(key, value)
        self._add_to_object_part(key, value)
        self._attribute_to_key_map[n(unique_attribute_name)] = key
        self.after_set(key, value)
    def _receiver(self):
        from ..env import NODE_PORT
        from errno import ECONNREFUSED

        logger.info("Starting receiver on {host}:{port}".format(
            host=ServiceInfos().hostname, port=NODE_PORT))
        while not self._do_quit:  # retry connection
            self.s = socket.socket(
                socket.AF_INET,  # Internet
                socket.SOCK_STREAM)  # TCP
            try:
                self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                self.s.bind((ServiceInfos().hostname, NODE_PORT))
                self.s.listen(5)
                logger.debug("Socket Set up.")
                while not self._do_quit and self.s:
                    self.client, address = self.s.accept()

                    buffer = _EMPTY_RAW_BYTE
                    answer = _EMPTY_RAW_BYTE
                    completed = -1  # -1 = answer size yet unknown, >0 = got remaining answer size
                    while (not self._do_quit
                           ) and self.s and self.client:  # read loop
                        while 1:  # retry if CTRL+C'd
                            try:
                                # self.s.setblocking(True)
                                answer = self.client.recv(1)
                                # recv() returns an empty string if the remote end is closed
                                if len(answer) == 0:
                                    logger.debug("Remote end closed.")
                                    self.reset_client()
                                # end if
                                # logger.debug("received byte: {}".format(answer))
                                break
                            except socket.error as err:
                                if self._do_quit:
                                    self.reset_client()
                                # end if
                                from errno import EINTR
                                if err.errno != EINTR:  # interrupted system call
                                    raise
                                else:
                                    logger.exception(
                                        "Uncatched exception in reading message from {client}."
                                        .format(client=address))
                                    self.reset_client()
                                    break  # to the retry connection look again.
                                # end if
                            # end try
                        # end while: ctrl+c protection
                        if not self.s or not self.client:  # check if socket is still open
                            break
                        if completed == 0:
                            logger.debug("Hit end.")
                            if answer != _LINE_BREAK:
                                raise ValueError(
                                    "Message does not end with a double linebreak."
                                )
                            if buffer == _EMPTY_RAW_BYTE:
                                logger.debug("skipping second linebreak.")
                                completed = -1
                                continue
                            logger.debug(
                                "Received Message from {client}: {buffer}".
                                format(client=address, buffer=buffer))
                            text = n(buffer)
                            if len(text) > 0 and text.strip() != "":
                                self._add_message(text)
                            else:
                                logger.warn("Striped text was empty.")
                            answer = _EMPTY_RAW_BYTE
                            buffer = _EMPTY_RAW_BYTE
                            # completed = 0 (unchanged)
                            continue
                        buffer += answer
                        if completed < -1 and buffer[:len(
                                _ANSWER_SYNTAX)] != _ANSWER_SYNTAX[:len(buffer
                                                                        )]:
                            raise ArithmeticError(
                                "Server response does not fit. (Got >{}<)".
                                format(buffer))
                        if completed <= -1 and buffer.startswith(
                                _ANSWER_SYNTAX) and buffer.endswith(
                                    _LINE_BREAK):
                            completed = int(n(
                                buffer[len(_ANSWER_SYNTAX):-1]))  # TODO regex.
                            buffer = _EMPTY_RAW_BYTE
                        completed -= 1
                    # end while: read loop
                # end while: for connected clients
            except socket.error as error:
                # if error.errno in [ECONNREFUSED] and not self._do_quit:
                #   continue
                # # end if
                logger.error(
                    "Socket failed with network error: {e}\nRetrying...".
                    format(e=error))
            except Exception as error:
                logger.error("Socket failed: {e}\nRetrying...".format(e=error))
            # end try
            self.reset_socket()
        # end while not ._do_quit: retry connection
        self.reset_socket()
Beispiel #15
0
 assert isinstance(update, Update)
 last_update_id = update.update_id
 print(update)
 if not update.inline_query:
     continue
 query_obj = update.inline_query
 assert isinstance(query_obj, InlineQuery)
 inline_query_id = query_obj.id
 query = query_obj.query
 print(query)
 foo = list()
 foo.append(InlineQueryResultArticle(
     id=query+"_normal",
     title="test 1 (normal)",
     input_message_content=InputTextMessageContent(query),
     description='Will send {}'.format(repr(n(query)))
 ))
 foo.append(InlineQueryResultArticle(
     id=query+"_markdown",
     title="test 2 (markdown)",
     input_message_content=InputTextMessageContent(query, parse_mode="Markdown"),
     description='Will send {}'.format(repr(n(query)))
 ))
 foo.append(InlineQueryResultArticle(
     id=query+"_html",
     title="test 3 (html)",
     input_message_content=InputTextMessageContent(query, parse_mode="HTML"),
     description='Will send {}'.format(repr(n(query)))
 ))
 try:
     success = bot.answer_inline_query(inline_query_id, foo, cache_time=2)
Beispiel #16
0
    def _prepare_fileupload(self, _command, _file_is_optional, file_param_name,
                            kwargs, value):
        """
        :param file_param_name: For what field the file should be uploaded.
        :type  file_param_name: str

        :param value: File to send. You can either pass a file_id as String to resend a file
                      file that is already on the Telegram servers, or upload a new file,
                      specifying the file path as :class:`pytgbot.api_types.sendable.files.InputFile`.
                      If `_file_is_optional` is set to `True`, it can also be set to `None`.
        :type  value: pytgbot.api_types.sendable.files.InputFile | str | None

        :param _command: Overwrite the command to be send.
                         Default is to convert `file_param_name` to camel case (`"voice_note"` -> `"sendVoiceNote"`)
        :type  _command: str|None

        :param _file_is_optional: If the file (`value`) is allowed to be None.
        :type  _file_is_optional: bool

        :param kwargs: will get json encoded.

        :return: The json response from the server, or, if `self.return_python_objects` is `True`, a parsed return type.
        :rtype: DictObject.DictObject | pytgbot.api_types.receivable.Receivable

        :raises TgApiTypeError, TgApiParseException, TgApiServerException: Everything from :meth:`Bot.do`, and :class:`TgApiTypeError`
        """
        from ..api_types.sendable.files import InputFile
        from luckydonaldUtils.encoding import unicode_type
        from luckydonaldUtils.encoding import to_native as n
        if value is None and _file_is_optional:
            # Is None but set optional, so do nothing.
            pass
        elif isinstance(value, str):
            kwargs[file_param_name] = str(value)
        elif isinstance(value, unicode_type):
            kwargs[file_param_name] = n(value)
        elif isinstance(value, InputFile):
            files = value.get_request_files(file_param_name)
            if "files" in kwargs and kwargs["files"]:
                # already are some files there, merge them.
                assert isinstance(kwargs["files"], dict), \
                    'The files should be of type dict, but are of type {}.'.format(type(kwargs["files"]))
                for key in files.keys():
                    assert key not in kwargs[
                        "files"], '{key} would be overwritten!'
                    kwargs["files"][key] = files[key]
                # end for
            else:
                # no files so far
                kwargs["files"] = files
            # end if
        else:
            raise TgApiTypeError(
                "Parameter {key} is not type (str, {text_type}, {input_file_type}), but type {type}"
                .format(key=file_param_name,
                        type=type(value),
                        input_file_type=InputFile,
                        text_type=unicode_type))
        # end if
        if not _command:
            # command as camelCase  # "voice_note" -> "sendVoiceNote"  # https://stackoverflow.com/a/10984923/3423324
            command = re.sub(r'(?!^)_([a-zA-Z])', lambda m: m.group(1).upper(),
                             "send_" + file_param_name)
        else:
            command = _command
        # end def
        return command
Beispiel #17
0
 def _receiver(self):
     while not self._do_quit:  # retry connection
         self.s = socket.socket()  # errors?
         try:
             self.s.connect((self.host, self.port))
         except socket.error as error:
             self.s.close()
             if error.errno == ECONNREFUSED and not self._do_quit:
                 continue
             raise error  # Not the error we are looking for, re-raise
         except Exception as error:
             self.s.close()
             raise error
         logger.debug("Socket Connected.")
         try:
             self.s.sendall(_REGISTER_SESSION)
         except Exception as error:
             self.s.close()
             raise error  #retry?
         logger.debug("CLI session registered.")
         buffer = EMPTY_RAW_BYTE
         answer = EMPTY_RAW_BYTE
         completed = -1  # -1 = answer size yet unknown, >0 = got remaining answer size
         while not self._do_quit:  # read loop
             while 1:  #retry if CTRL+C'd
                 try:
                     self.s.setblocking(True)
                     answer = self.s.recv(1)
                     # recv() returns an empty string if the remote end is closed
                     if len(answer) == 0:
                         self.s.close()
                         raise ConnectionError("Remote end closed.")
                     break
                 except socket.error as err:
                     if self._do_quit:
                         self.s.close()
                         return
                     if err.errno != EINTR:
                         raise
                     else:
                         logger.exception(
                             "Uncatched exception in reading answer from cli."
                         )
                         self.s.close()
                         break  # to the retry connection look again.
             #end while: ctrl+c protection
             if completed == 0:
                 logger.debug("Hit end.")
                 if answer != _LINE_BREAK:
                     raise ValueError(
                         "Message does not end with a double linebreak.")
                 if buffer == EMPTY_RAW_BYTE:
                     logger.debug("skipping second linebreak.")
                     completed = -1
                     continue
                 logger.debug("Received Message: %s", buffer)
                 text = n(buffer)
                 if len(text) > 0 and text.strip() != "":
                     self._add_message(text)
                 else:
                     logger.warn("Striped text was empty.")
                 answer = EMPTY_RAW_BYTE
                 buffer = EMPTY_RAW_BYTE
                 #completed = 0 (unchanged)
                 continue
             buffer += answer
             # logger.debug("{!s:<2.2s}: {!s}".format(repr(answer)[1:-1]), buffer)# Fixed mallformatting of sting.
             if completed < -1 and buffer[:len(
                     _ANSWER_SYNTAX)] != _ANSWER_SYNTAX[:len(buffer)]:
                 raise ArithmeticError(
                     "Server response does not fit. (Got >{}<)".format(
                         buffer))
             if completed <= -1 and buffer.startswith(
                     _ANSWER_SYNTAX) and buffer.endswith(_LINE_BREAK):
                 completed = int(n(
                     buffer[len(_ANSWER_SYNTAX):-1]))  #TODO regex.
                 buffer = EMPTY_RAW_BYTE
             completed -= 1
         #end while: read loop
         if self.s:
             self.s.close()
             self.s = None
     #end while not ._do_quit: retry connection
     if self.s:
         self.s.close()
         self.s = None
Beispiel #18
0
    def _do_send(self, command, answer_timeout=default_answer_timeout, retry_connect=2):
        """
        You can force retry with retry_connect=2 (3 tries, default settings, first try + 2 retries)
        retry_connect=0 , retry_connect=False and retry_connect=None  means not to retry,
        retry_connect=True or retry_connect= -1 means to retry infinite times.

        :type command: builtins.str
        :type answer_timeout: builtins.float or builtins.int
        :param retry_connect: How often the initial connection should be retried. default: 2. Negative number means infinite.
        :type  retry_connect: int
        :return:
        """
        if isinstance(retry_connect, int):
            pass  # correct
        elif isinstance(retry_connect, bool):
            if retry_connect:  # True = forever
                retry_connect = -1
            else:
                retry_connect = 0
        elif retry_connect is None:
            retry_connect = 0  # not forever.
        else:
            raise ValueError("retry_connect is not type int, bool or None.")
        retry_connect_original = retry_connect

        if not isinstance(command, (text_type, binary_type)):
            raise TypeError("Command to send is not a unicode(?) string. (Instead of %s you used %s.) " % (str(text_type), str(type(command))))
        logger.debug("Sending command >%s<" % n(command))
        with self._socked_used:
            while not self._do_quit:
                if self.s:
                    self.s.close()
                    self.s = None
                self.s = socket.socket()
                try:
                    self.s.connect((self.host, self.port_out))
                except socket_error as error:
                    self.s.close()
                    if error.errno == ECONNREFUSED and not self._do_quit:
                        if retry_connect != 0:
                            sleep(1)
                            if retry_connect > 0:
                                retry_connect -= 1
                            continue
                        else:
                            raise ConnectionError("Could not establish connection to the cli port, failed after {number} tries. (called with retry_connect={retry_connect})".format(number=(retry_connect_original + 1), retry_connect=retry_connect_original))
                    raise error  # Not the error we are looking for, re-raise
                except Exception as error:
                    self.s.close()
                    raise error
                logger.debug("Socket Connected.")
                try:
                    self.s.sendall(b(command))
                except Exception as error:
                    self.s.close()
                    raise error  # retry?
                logger.debug("All Sent.")
                completed = -1  # -1 = answer size yet unknown, >0 = got remaining answer size
                buffer = b("")
                self.s.settimeout(answer_timeout)  # in seconds.
                while completed != 0:
                    try:
                        while 1:  # retry if CTRL+C'd
                            try:
                                answer = self.s.recv(1)
                                # recv() returns an empty string if the remote end is closed
                                if len(answer) == 0:
                                    raise ConnectionError("Remote end closed")
                                break
                            except socket_error as err:
                                if err.errno != EINTR:
                                    raise
                                else:
                                    logger.exception("Uncatched exception in reading answer from cli.")
                        self.s.settimeout(max(self.default_answer_timeout, answer_timeout))  # in seconds.
                        # If there was input the input is now either the default one or the given one, which waits longer.
                        buffer += answer
                        if completed < -1 and buffer[:len(_ANSWER_SYNTAX)] != _ANSWER_SYNTAX[:len(buffer)]:
                            raise ArithmeticError("Server response does not fit.")
                        if completed <= -1 and buffer.startswith(_ANSWER_SYNTAX) and buffer.endswith(_LINE_BREAK):
                            completed = int(n(buffer[7:-1]))  # TODO regex.
                            buffer = b("")
                        completed -= 1
                    except ConnectionError:
                        self.s.close()
                        raise
                    except socket.timeout:
                        raise NoResponse(command)
                    except KeyboardInterrupt:
                        logger.exception("Exception while reading the Answer for \"%s\". Got so far: >%s< of %i\n" % (n(command), n(buffer), completed))  # TODO remove me
                        self.s.close()
                        raise
                    except Exception:
                        logger.exception("Exception while reading the Answer for \"%s\". Got so far: >%s<\n" % (n(command), n(buffer)))  # TODO remove me
                        self.s.close()
                        raise
                        # raise error
                # end while completed != 0
                if self.s:
                    self.s.close()
                    self.s = None
                return u(buffer)
            # end while not self._do_quit
        # end with lock
        if self.s:
            self.s.close()
Beispiel #19
0
def short_custom_base64_url_encode(string, encode_replacements=REPLACEMENTS):
    base = n(urlsafe_b64encode(b(string))).rstrip("=")
    return multi_replace(base, encode_replacements)
Beispiel #20
0
 def _receiver(self):
     while not self._do_quit:  # retry connection
         self.s = socket.socket()  # errors?
         try:
             self.s.connect((self.host, self.port))
         except socket.error as error:
             self.s.close()
             if error.errno == ECONNREFUSED and not self._do_quit:
                 continue
             raise error  # Not the error we are looking for, re-raise
         except Exception as error:
             self.s.close()
             raise error
         logger.debug("Socket Connected.")
         try:
             self.s.sendall(_REGISTER_SESSION)
         except Exception as error:
             self.s.close()
             raise error  # retry?
         logger.debug("CLI session registered.")
         buffer = EMPTY_RAW_BYTE
         answer = EMPTY_RAW_BYTE
         completed = -1  # -1 = answer size yet unknown, >0 = got remaining answer size
         while not self._do_quit:  # read loop
             while 1:  # retry if CTRL+C'd
                 try:
                     self.s.setblocking(True)
                     answer = self.s.recv(1)
                     # recv() returns an empty string if the remote end is closed
                     if len(answer) == 0:
                         self.s.close()
                         raise ConnectionError("Remote end closed.")
                     break
                 except socket.error as err:
                     if self._do_quit:
                         self.s.close()
                         return
                     if err.errno != EINTR:
                         raise
                     else:
                         logger.exception("Uncatched exception in reading answer from cli.")
                         self.s.close()
                         break  # to the retry connection look again.
             # end while: ctrl+c protection
             if completed == 0:
                 logger.debug("Hit end.")
                 if answer != _LINE_BREAK:
                     raise ValueError("Message does not end with a double linebreak.")
                 if buffer == EMPTY_RAW_BYTE:
                     logger.debug("skipping second linebreak.")
                     completed = -1
                     continue
                 logger.debug("Received Message: %s", buffer)
                 text = n(buffer)
                 if len(text) > 0 and text.strip() != "":
                     self._add_message(text)
                 else:
                     logger.warn("Striped text was empty.")
                 answer = EMPTY_RAW_BYTE
                 buffer = EMPTY_RAW_BYTE
                 # completed = 0 (unchanged)
                 continue
             buffer += answer
             # logger.debug("{!s:<2.2s}: {!s}".format(repr(answer)[1:-1]), buffer)# Fixed mallformatting of sting.
             if completed < -1 and buffer[:len(_ANSWER_SYNTAX)] != _ANSWER_SYNTAX[:len(buffer)]:
                 raise ArithmeticError("Server response does not fit. (Got >{}<)".format(buffer))
             if completed <= -1 and buffer.startswith(_ANSWER_SYNTAX) and buffer.endswith(_LINE_BREAK):
                 completed = int(n(buffer[len(_ANSWER_SYNTAX):-1]))  # TODO regex.
                 buffer = EMPTY_RAW_BYTE
             completed -= 1
         # end while: read loop
         if self.s:
             self.s.close()
             self.s = None
     # end while not ._do_quit: retry connection
     if self.s:
         self.s.close()
         self.s = None
Beispiel #21
0
 last_update_id = update.update_id
 print(update)
 if not update.inline_query:
     continue
 query_obj = update.inline_query
 assert isinstance(query_obj, InlineQuery)
 inline_query_id = query_obj.id
 query = query_obj.query
 print(query)
 foo = list()
 foo.append(
     InlineQueryResultArticle(
         id=query + "_normal",
         title="test 1 (normal)",
         input_message_content=InputTextMessageContent(query),
         description='Will send {}'.format(repr(n(query)))))
 foo.append(
     InlineQueryResultArticle(
         id=query + "_markdown",
         title="test 2 (markdown)",
         input_message_content=InputTextMessageContent(
             query, parse_mode="Markdown"),
         description='Will send {}'.format(repr(n(query)))))
 foo.append(
     InlineQueryResultArticle(
         id=query + "_html",
         title="test 3 (html)",
         input_message_content=InputTextMessageContent(
             query, parse_mode="HTML"),
         description='Will send {}'.format(repr(n(query)))))
 try:
Beispiel #22
0
    def _do_send(self,
                 command,
                 answer_timeout=default_answer_timeout,
                 retry_connect=2):
        """
		You can force retry with retry_connect=2 (3 tries, default settings, first try + 2 retries)
		retry_connect=0 , retry_connect=False and retry_connect=None  means not to retry,
		retry_connect=True or retry_connect= -1 means to retry infinite times.

		:type command: builtins.str
		:type answer_timeout: builtins.float or builtins.int
		:param retry_connect: How often the initial connection should be retried. default: 2. Negative number means infinite.
		:type  retry_connect: int
		:return:
		"""
        if isinstance(retry_connect, int):
            pass  # correct
        elif isinstance(retry_connect, bool):
            if retry_connect:  # True = forever
                retry_connect = -1
            else:
                retry_connect = 0
        elif retry_connect is None:
            retry_connect = 0  # not forever.
        else:
            raise ValueError("retry_connect is not type int, bool or None.")
        retry_connect_original = retry_connect

        if not isinstance(command, (text_type, binary_type)):
            raise TypeError(
                "Command to send is not a unicode(?) string. (Instead of %s you used %s.) "
                % (str(text_type), str(type(command))))
        logger.debug("Sending command >%s<" % n(command))
        with self._socked_used:
            while not self._do_quit:
                if self.s:
                    self.s.close()
                    self.s = None
                self.s = socket.socket()
                try:
                    self.s.connect((self.host, self.port_out))
                except socket_error as error:
                    self.s.close()
                    if error.errno == ECONNREFUSED and not self._do_quit:
                        if retry_connect != 0:
                            sleep(1)
                            if retry_connect > 0:
                                retry_connect -= 1
                            continue
                        else:
                            raise ConnectionError(
                                "Could not establish connection to the cli port, failed after {number} tries. (called with retry_connect={retry_connect})"
                                .format(number=(retry_connect_original + 1),
                                        retry_connect=retry_connect_original))
                    raise error  # Not the error we are looking for, re-raise
                except Exception as error:
                    self.s.close()
                    raise error
                logger.debug("Socket Connected.")
                try:
                    self.s.sendall(b(command))
                except Exception as error:
                    self.s.close()
                    raise error  #retry?
                logger.debug("All Sent.")
                completed = -1  # -1 = answer size yet unknown, >0 = got remaining answer size
                buffer = b("")
                self.s.settimeout(answer_timeout)  # in seconds.
                while completed != 0:
                    try:
                        while 1:  #retry if CTRL+C'd
                            try:
                                answer = self.s.recv(1)
                                # recv() returns an empty string if the remote end is closed
                                if len(answer) == 0:
                                    raise ConnectionError("Remote end closed")
                                break
                            except socket_error as err:
                                if err.errno != EINTR:
                                    raise
                                else:
                                    logger.exception(
                                        "Uncatched exception in reading answer from cli."
                                    )
                        self.s.settimeout(
                            max(self.default_answer_timeout,
                                answer_timeout))  # in seconds.
                        # If there was input the input is now either the default one or the given one, which waits longer.
                        buffer += answer
                        if completed < -1 and buffer[:len(
                                _ANSWER_SYNTAX)] != _ANSWER_SYNTAX[:len(buffer
                                                                        )]:
                            raise ArithmeticError(
                                "Server response does not fit.")
                        if completed <= -1 and buffer.startswith(
                                _ANSWER_SYNTAX) and buffer.endswith(
                                    _LINE_BREAK):
                            completed = int(n(buffer[7:-1]))  #TODO regex.
                            buffer = b("")
                        completed -= 1
                    except ConnectionError:
                        self.s.close()
                        raise
                    except socket.timeout:
                        raise NoResponse(command)
                    except KeyboardInterrupt as error:
                        logger.exception(
                            "Exception while reading the Answer for \"%s\". Got so far: >%s< of %i\n"
                            % (n(command), n(buffer),
                               completed))  # TODO remove me
                        self.s.close()
                        raise
                    except Exception as error:
                        logger.exception(
                            "Exception while reading the Answer for \"%s\". Got so far: >%s<\n"
                            % (n(command), n(buffer)))  #TODO remove me
                        self.s.close()
                        raise
                        #raise error
                # end while completed != 0
                if self.s:
                    self.s.close()
                    self.s = None
                return u(buffer)
            # end while not self._do_quit
        # end with lock
        if self.s:
            self.s.close()
Beispiel #23
0
def short_custom_base64_url_decode(base, encode_replacements=REPLACEMENTS):
    replacements = revert_replacements(encode_replacements)
    base = multi_replace(n(base), replacements)
    # add missing padding # http://stackoverflow.com/a/9807138
    return n(urlsafe_b64decode(base + '=' * (4 - len(base) % 4)))