Esempio n. 1
0
 async def get_server(self) -> dict:
     logger.debug("Getting polling server...")
     if self.user_id is None:
         self.user_id = (await self.api.request("users.get",
                                                {}))["response"][0]["id"]
     return (await self.api.request("messages.getLongPollServer",
                                    {}))["response"]
Esempio n. 2
0
 async def validate_request(self, request: dict) -> dict:
     """ Validates requests from VK,
     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
Esempio n. 3
0
 async def get_server(self) -> dict:
     logger.debug("Getting polling server...")
     if self.group_id is None:
         self.group_id = (await self.api.request("groups.getById", {}))["response"][0]["id"]
     return (await self.api.request("groups.getLongPollServer", {"group_id": self.group_id}))[
         "response"
     ]
Esempio n. 4
0
 async def pre(self,
               method: str,
               url: str,
               data: typing.Optional[dict] = None,
               **kwargs):
     logger.debug(f"{method.upper()} Request to {url}; data={data} " +
                  "; ".join(f"{k}={v}" for k, v in kwargs.items()))
Esempio n. 5
0
 async def get_callback_confirmation_code(self) -> str:
     logger.debug("Getting callback confirmation code...")
     return (await self.api.request(
         "groups.getCallbackConfirmationCode",
         {
             "group_id": self.group_id,
         },
     ))["response"]["code"]
Esempio n. 6
0
 async def get_callback_servers(
         self,
         servers_ids: Optional[List[int]] = None) -> List[Dict[str, Any]]:
     logger.debug("Getting callback servers...")
     data: Dict[str, Any] = {"group_id": self.group_id}
     if servers_ids is not None:
         data.update({"server_ids": ",".join(map(str, servers_ids))})
     return (await self.api.request("groups.getCallbackServers",
                                    data))["response"]["items"]
Esempio n. 7
0
 async def validate_response(
     self, method: str, data: dict, response: typing.Union[dict, str]
 ) -> typing.Union[dict, typing.NoReturn]:
     """ Validates response from VK,
     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
Esempio n. 8
0
def restart():
    """ https://github.com/cherrypy/cherrypy/blob/0857fa81eb0ab647c7b59a019338bab057f7748b/cherrypy/process/wspbus.py#L305 """
    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)
Esempio n. 9
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. 10
0
 async def add_callback_server(self) -> int:
     logger.debug("Adding callback server...")
     data = {
         "group_id": self.group_id,
         "url": self.url,
         "title": self.title,
         "secret_key": self.secret_key,
     }
     return (await self.api.request("groups.addCallbackServer",
                                    data))["response"]["server_id"]
Esempio n. 11
0
    async def route(self, event: dict, ctx_api: "ABCAPI") -> None:
        logger.debug("Routing update {}".format(event))

        for view in self.views.values():
            try:
                if not await view.process_event(event):
                    continue
                await view.handle_event(event, ctx_api, self.state_dispenser)
            except BaseException as e:
                await self.error_handler.handle(e)
Esempio n. 12
0
 async def request(self, method: str, data: dict) -> dict:
     """ Makes a single request opening a session """
     async with self.http as session:
         response = await session.request_text(
             "POST",
             self.API_URL + method,
             data=data,  # type: ignore
             params={"access_token": self.token, "v": self.API_VERSION},
         )
         logger.debug("Request {} with {} data returned {}".format(method, data, response))
         return await self.validate_response(method, data, response)
Esempio n. 13
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. 14
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. 15
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.loop_wrapper.add_task(bot.run_polling(custom_polling=polling))
    bot.loop_wrapper.run_forever(bot.loop)
Esempio n. 16
0
    async def set_callback_settings(self,
                                    server_id: int,
                                    params: Optional[Dict[str, bool]] = None):
        """Search values in https://dev.vk.com/method/groups.getCallbackSettings"""
        logger.debug("Setting callback settings...")

        data = {"group_id": self.group_id, "server_id": server_id}

        if params is not None:
            for k, v in params.items():
                data.update({k: v})
        await self.api.request("groups.setCallbackSettings", data)
Esempio n. 17
0
 async def get_event(self, server: dict) -> dict:
     logger.debug("Making long request to get event with longpoll...")
     return await self.api.http_client.request_json(
         "{}?act=a_check&key={}&ts={}&wait={}&rps_delay={}".format(
             server["server"],
             server["key"],
             server["ts"],
             self.wait,
             self.rps_delay,
         ),
         method="POST",
     )
Esempio n. 18
0
 async def listen(self) -> AsyncIterator[dict]:  # type: ignore
     server = await self.get_server()
     logger.debug("Starting listening to longpoll")
     while not self.stop:
         try:
             event = await self.get_event(server)
             if not event.get("ts"):
                 server = await self.get_server()
                 continue
             server["ts"] = event["ts"]
             yield event
         except BaseException as e:
             await self.error_handler.handle(e)
Esempio n. 19
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. 20
0
    async def pre_middleware(self, event: "MessageMin",
                             context_variables: dict) -> Optional[Exception]:
        """Run all of the pre middleware methods and return an exception if any error occurs"""
        self.middleware_instances.clear()
        for middleware in self.middlewares:
            mw_instance = middleware(event)
            await mw_instance.pre()
            if not mw_instance.can_forward:
                logger.debug(
                    f"{mw_instance} returned error {mw_instance.error}")
                return mw_instance.error

            self.middleware_instances.append(mw_instance)
            context_variables.update(mw_instance.context_update)
Esempio n. 21
0
def run_multibot(
    user: "******", apis: Iterable["ABCAPI"], polling_type: Type["ABCPolling"] = UserPolling
):
    """Add run_polling with polling constructed from derived apis
    :param user: User 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("Connecting API (index: {})", i)
        polling = polling_type().construct(api_instance)
        api_instance.http_client = SingleAiohttpClient()
        user.loop_wrapper.add_task(user.run_polling(custom_polling=polling))
    user.loop_wrapper.run_forever(user.loop)
Esempio n. 22
0
 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")
Esempio n. 23
0
 async def edit_callback_server(self,
                                server_id: int,
                                secret_key: Optional[str] = None):
     logger.debug("Editing callback server...")
     data = {
         "group_id": self.group_id,
         "server_id": server_id,
         "url": self.url,
         "title": self.title,
         "secret_key": self.secret_key,
     }
     if secret_key is not None:
         data.update({"secret_key": secret_key})
     await self.api.request("groups.editCallbackServer", data)
Esempio n. 24
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 = {}
        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)

        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)
Esempio n. 25
0
 async def listen(self) -> AsyncGenerator[dict, None]:
     server = await self.get_server()
     logger.debug("Starting listening to longpoll")
     while not self.stop:
         try:
             event = await self.get_event(server)
             if not event.get("ts"):
                 server = await self.get_server()
                 continue
             server["ts"] = event["ts"]
             yield event
         except ServerConnectionError:
             server = await self.get_server()
         except Exception as e:
             await self.error_handler.handle(e)
Esempio n. 26
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",
                 self.API_URL + method,
                 data=data,  # noqa
                 params={"access_token": self.token, "v": self.API_VERSION},  # noqa
             )
             logger.debug("Request {} with {} data returned {}".format(method, data, response))
             yield await self.validate_response(method, data, response)
Esempio n. 27
0
 async def request_many(
     self, requests: Iterable[APIRequest]  # type: ignore
 ) -> AsyncIterator[dict]:
     """Makes many requests opening one session"""
     for request in requests:
         method, data = request.method, await self.validate_request(request.data)  # type: ignore
         async with self.token_generator as token:
             response = await self.http_client.request_json(
                 self.API_URL + method,
                 method="POST",
                 data=data,  # noqa
                 params={"access_token": token, "v": self.API_VERSION},  # noqa
             )
         logger.debug("Request {} with {} data returned {}".format(method, data, response))
         yield await self.validate_response(method, data, response)
Esempio n. 28
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. 29
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 = {}

        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)

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

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

        for middleware in self.middlewares:
            await middleware.post(event_model, self, [handler_response],
                                  [handler_basement.handler])
Esempio n. 30
0
    async def post_middleware(
        self,
        mw_instances: List[BaseMiddleware],
        handle_responses: Optional[List] = None,
        handlers: Optional[List["ABCHandler"]] = None,
    ):
        for middleware in mw_instances:
            # Update or leave value
            middleware.handle_responses = handle_responses or middleware.handle_responses
            middleware.handlers = handlers or middleware.handlers

            await middleware.post()
            if not middleware.can_forward:
                logger.debug("{} post returned error {}", middleware,
                             middleware.error)
                return middleware.error