示例#1
0
 async def validate_request(self, request: dict) -> dict:
     """ Validates requests from Telegram,
     to change validations change API.request_validators (list of RequestValidator's) """
     for validator in self.request_validators:
         request = await validator.validate(request)
     logger.debug("API request was validated")
     return request  # type: ignore
示例#2
0
 async def validate_response(
     self, method: str, data: dict, response: typing.Union[dict, str]
 ) -> typing.Union[typing.Any, typing.NoReturn]:
     """ Validates response from Telegram,
     to change validations change API.response_validators (list of ResponseValidator's) """
     for validator in self.response_validators:
         response = await validator.validate(method, data, response, self)
     logger.debug("API response was validated")
     return response  # type: ignore
示例#3
0
def restart():
    args = sys.argv[:]
    logger.debug("Restarting: %s" % " ".join(args))
    args.insert(0, sys.executable)
    if sys.platform == "win32":
        args = ['"%s"' % arg for arg in args]

    os.chdir(_startup_cwd)
    os.execv(sys.executable, args)
示例#4
0
    async def route(self, update: dict, ctx_api: "ABCAPI"):
        logger.debug("Routing update {}".format(update))

        for view in self.views.values():
            try:
                if not await view.process_update(update):
                    continue
                await view.handle_update(update, ctx_api, self.state_dispenser)
            except BaseException as e:
                await self.error_handler.handle(e)
 def synchronous_wrapper(*args, **kwargs):
     try:
         return func(*args, **kwargs)
     except exception as e:
         if exception_handler is not None:
             return exception_handler(e, *args, **kwargs)
         elif just_log:
             logger.error(
                 f"{func.__name__} (handling with swear) has thrown an exception: \n\n{traceback.format_exc()}"
             )
         elif just_return:
             return e
     finally:
         logger.debug(f"Function {func.__name__} was handled with swear")
示例#6
0
    async def handle_update(self, update: dict, ctx_api: "ABCAPI",
                            state_dispenser: "ABCStateDispenser") -> Any:

        logger.debug("Handling update ({}) with message view".format(
            update.get("update_id")))
        context_variables = {}
        message = message_min(update, ctx_api)
        message.state_peer = await state_dispenser.cast(
            self.get_state_key(update))

        for text_ax in self.default_text_approximators:
            message.text = text_ax(message)

        for middleware in self.middlewares:
            response = await middleware.pre(message)
            if response == MiddlewareResponse(False):
                return
            elif isinstance(response, dict):
                context_variables.update(response)

        handle_responses = []
        handlers = []

        for handler in self.handlers:
            result = await handler.filter(message)
            logger.debug("Handler {} returned {}".format(handler, result))

            if result is False:
                continue

            elif isinstance(result, dict):
                context_variables.update(result)

            handler_response = await handler.handle(message,
                                                    **context_variables)
            handle_responses.append(handler_response)
            handlers.append(handler)

            return_handler = self.handler_return_manager.get_handler(
                handler_response)
            if return_handler is not None:
                await return_handler(self.handler_return_manager,
                                     handler_response, message,
                                     context_variables)

            if handler.blocking:
                break

        for middleware in self.middlewares:
            await middleware.post(message, self, handle_responses, handlers)
示例#7
0
    async def run_polling(self,
                          custom_polling: Optional[ABCPolling] = None,
                          apis_count: int = 0) -> NoReturn:
        polling = custom_polling or self.polling
        logger.info("Polling will be started!")

        async for update in polling.listen():  # type: ignore
            logger.debug("New update: {}", update)

            if self.apis:
                self.api = self.apis[apis_count]

            if not self.task_each_update:
                await self.router.route(update, self.api)
            else:
                self.loop.create_task(self.router.route(update, self.api))
示例#8
0
    async def request(self,
                      method: str,
                      data: typing.Optional[dict] = None) -> dict:
        """Makes a single request opening a session"""
        data = await self.validate_request(data)

        async with self.http as session:
            response = await session.request_text(
                "POST",
                url=self.request_url + method,
                json=data,
            )

            logger.debug("Request {} with {} data returned {}".format(
                method, data, response))
            return await self.validate_response(method, data, response)
示例#9
0
def run_multibot(bot: Bot,
                 apis: Iterable[ABCAPI],
                 polling_type: Type[ABCPolling] = BotPolling):
    """Add run_polling with polling constructed from derived apis
    :param bot: Bot main instance (api is not required)
    :param apis: Iterable of apis
    :param polling_type: polling type to be ran
    """
    for i, api_instance in enumerate(apis):
        logger.debug(f"Connecting API (index: {i})")
        polling = polling_type().construct(api_instance)
        api_instance.http = SingleSessionManager(AiohttpClient)
        bot.apis = apis
        bot.loop_wrapper.add_task(
            bot.run_polling(custom_polling=polling, apis_count=i))

    bot.loop_wrapper.run_forever(bot.loop)
示例#10
0
 async def request_many(
     self,
     requests: typing.Iterable[APIRequest]  # type: ignore
 ) -> typing.AsyncIterator[dict]:
     """ Makes many requests opening one session """
     async with self.http as session:
         for request in requests:
             method, data = request.method, await self.validate_request(
                 request.data)  # type: ignore
             response = await session.request_text(
                 "POST",
                 url=self.request_url + method,
                 json=data,
             )
             logger.debug("Request {} with {} data returned {}".format(
                 method, data, response))
             yield await self.validate_response(method, data, response)
示例#11
0
    async def reschedule(
        self,
        ctx_api: typing.Union["ABCAPI", "API"],
        method: str,
        data: dict,
        recent_response: typing.Any,
    ) -> dict:
        logger.debug(
            "Tottle uses request_rescheduler when Telegram "
            "doesn't respond properly for an amount of time. Starting..."
        )

        attempt_number = 1
        while not isinstance(recent_response, dict):
            logger.info(f"Attempt №{attempt_number}. Making request...")
            blocking_sleep(self.delay * attempt_number)
            recent_response = await ctx_api.request(method, data)
            attempt_number += 1
            logger.debug(f"Attempt succeed? - {isinstance(recent_response, dict)}")

        logger.info(f"Finally succeed after {self.delay ** attempt_number} seconds!")
        return recent_response
示例#12
0
    async def cast(self, peer_id: Optional[int]) -> Optional[StatePeer]:
        if peer_id is None:
            return None

        logger.debug(f"Casting state for peer_id {peer_id}")
        return await self.get(peer_id)