Esempio n. 1
0
    async def validate(
        self,
        method: str,
        data: dict,
        response: Any,
        ctx_api: Union["ABCAPI", "API"],
    ) -> Union[Any, NoReturn]:
        if isinstance(response, dict):
            return response
        elif isinstance(response, str):
            return json.loads(response)

        logger.info(
            "VK returned object of invalid type ({}). Request will be rescheduled with {}",
            type(response).__name__,
            ctx_api.request_rescheduler.__class__.__name__,
        )

        return await self.validate(
            method,
            data,
            await
            ctx_api.request_rescheduler.reschedule(ctx_api, method, data,
                                                   response),
            ctx_api,
        )
Esempio n. 2
0
    async def validate(
        self,
        method: str,
        data: dict,
        response: typing.Any,
        ctx_api: typing.Union["ABCAPI", "API"],
    ) -> typing.Union[typing.Any, typing.NoReturn]:
        if isinstance(response, dict):
            return response
        elif isinstance(response, str):
            return json.loads(response)

        logger.info(
            f"VK returned object of invalid type ({type(response)})."
            f"Request will be rescheduled with {ctx_api.request_rescheduler.__class__.__name__!r}"
        )

        return await self.validate(
            method,
            data,
            await
            ctx_api.request_rescheduler.reschedule(ctx_api, method, data,
                                                   response),
            ctx_api,
        )
Esempio n. 3
0
    def run_forever(
            self,
            loop: Optional[AbstractEventLoop] = None
    ) -> NoReturn:  # type: ignore
        """Runs startup tasks and makes the loop running forever"""

        if not len(self.tasks):
            logger.warning("You ran loop with 0 tasks. Is it ok?")

        loop = loop or get_event_loop()

        try:
            [
                loop.run_until_complete(startup_task)
                for startup_task in self.on_startup
            ]

            if self.auto_reload:
                loop.create_task(watch_to_reload(self.auto_reload_dir))

            for task in self.tasks:
                loop.create_task(task)

            loop.run_forever()
        except KeyboardInterrupt:
            logger.info("Keyboard Interrupt")
        finally:
            [
                loop.run_until_complete(shutdown_task)
                for shutdown_task in self.on_shutdown
            ]
            if loop.is_running():
                loop.close()
Esempio n. 4
0
async def watch_to_reload(check_dir: str):
    """
    Coro which see changes in your code and restart him.
    :return:
    """
    async for _ in awatch(check_dir):
        logger.info("Changes were found. Restarting...")
        restart()
Esempio n. 5
0
    async def run_polling(self,
                          custom_polling: Optional[ABCPolling] = None
                          ) -> NoReturn:
        polling = custom_polling or self.polling
        logger.info(f"Starting polling for {polling.api!r}")

        async for event in polling.listen():  # type: ignore
            logger.debug(f"New event was received: {event}")
            for update in event["updates"]:
                await self.router.route(update, polling.api)
Esempio n. 6
0
    async def run_polling(self, custom_polling: Optional["ABCPolling"] = None):
        polling = custom_polling or self.polling
        logger.info("Starting polling for {!r}", polling.api)

        async for event in polling.listen():
            logger.debug("New event was received: {}", event)
            for update in event["updates"]:
                if not self.task_each_event:
                    await self.router.route(update, polling.api)
                else:
                    self.loop.create_task(self.router.route(update, polling.api))
Esempio n. 7
0
    async def run_polling(self, custom_polling: Optional["ABCPolling"] = None) -> NoReturn:
        polling = custom_polling or self.polling
        logger.info(f"Starting polling for {polling.api!r}")

        async for event in polling.listen():  # type: ignore
            logger.debug(f"New event was received: {event}")
            for update in event.get("updates", []):
                if not self.task_each_event:
                    await self.router.route(update, polling.api)
                else:
                    self.loop.create_task(self.router.route(update, polling.api))
Esempio n. 8
0
    async def handle_event(self, event: T_contra, ctx_api: "ABCAPI",
                           state_dispenser: "ABCStateDispenser") -> Any:
        logger.debug("Handling event ({}) with message view".format(
            self.get_event_type(event)))

        context_variables: dict = {}
        handle_responses = []
        handlers = []

        mw_instances = await self.pre_middleware(event, context_variables)
        if mw_instances is None:
            logger.info("Handling stopped, pre_middleware returned error")
            return

        for handler_basement in self.get_handler_basements(event):
            event_model = self.get_event_model(handler_basement, event)

            if isinstance(event_model, dict):
                event_model["ctx_api"] = ctx_api
            else:
                setattr(event_model, "unprepared_ctx_api", ctx_api)

            result = await handler_basement.handler.filter(event_model)
            logger.debug("Handler {} returned {}".format(
                handler_basement.handler, result))

            if result is False:
                continue

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

            handler_response = await handler_basement.handler.handle(
                event_model, **context_variables)
            handle_responses.append(handler_response)
            handlers.append(handler_basement.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,
                    event_model,
                    context_variables,
                )

            if handler_basement.handler.blocking:
                break

        await self.post_middleware(mw_instances, handle_responses, handlers)
Esempio n. 9
0
    async def handle_event(self, event: T_contra, ctx_api: "ABCAPI",
                           state_dispenser: "ABCStateDispenser") -> None:
        # For user event mapping, consider checking out
        # https://dev.vk.com/api/user-long-poll/getting-started
        logger.debug("Handling event ({}) with message view".format(
            self.get_event_type(event)))
        context_variables: dict = {}
        message = await self.get_message(event, ctx_api)
        message.state_peer = await state_dispenser.cast(
            self.get_state_key(message))

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

        mw_instances = await self.pre_middleware(message, context_variables)
        if mw_instances is None:
            logger.info("Handling stopped, pre_middleware returned error")
            return

        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

        await self.post_middleware(mw_instances, handle_responses, handlers)
Esempio n. 10
0
    async def reschedule(
        self,
        ctx_api: Union["ABCAPI", "API"],
        method: str,
        data: dict,
        recent_response: Any,
    ) -> dict:
        logger.debug(
            "Usage of blocking rescheduler is assumed when VK doesn't respond to "
            "all requests for an amount of time. Starting..."
        )

        attempt_number = 1
        while not isinstance(recent_response, dict):
            logger.info(f"Attempt number {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
Esempio n. 11
0
    async def handle_event(self, event: dict, ctx_api: "ABCAPI",
                           state_dispenser: "ABCStateDispenser") -> Any:

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

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

        if await self.pre_middleware(message, context_variables) is False:
            return logger.info(
                "Handling stopped, pre_middleware returned error")

        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

        await self.post_middleware(self, handle_responses, handlers)
Esempio n. 12
0
    async def handle_event(
        self, event: dict, ctx_api: "ABCAPI", state_dispenser: "ABCStateDispenser"
    ) -> Any:
        logger.debug("Handling event ({}) with message view".format(event.get("event_id")))

        handler_basement = self.handlers[GroupEventType(event["type"])]
        context_variables: dict = {}

        event_model = handler_basement.dataclass(**event)

        if isinstance(event_model, dict):
            event_model["ctx_api"] = ctx_api
        else:
            setattr(event_model, "unprepared_ctx_api", ctx_api)

        if await self.pre_middleware(event_model, context_variables):
            return logger.info("Handling stopped, pre_middleware returned error")

        result = await handler_basement.handler.filter(event_model)
        logger.debug("Handler {} returned {}".format(handler_basement.handler, result))

        if result is False:
            return

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

        handler_response = await handler_basement.handler.handle(event_model, **context_variables)

        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, event_model, context_variables,
            )

        await self.post_middleware(self, [handler_response], [handler_basement.handler])
Esempio n. 13
0
 def run_forever(self) -> NoReturn:
     logger.info("Loop will be ran forever")
     self.loop_wrapper.add_task(self.run_polling())
     self.loop_wrapper.run_forever(self.loop)