Example #1
0
async def _run_matcher(
    Matcher: Type[Matcher],
    bot: "Bot",
    event: "Event",
    state: T_State,
    stack: Optional[AsyncExitStack] = None,
    dependency_cache: Optional[T_DependencyCache] = None,
) -> None:
    logger.info(f"Event will be handled by {Matcher}")

    matcher = Matcher()

    coros = list(
        map(
            lambda x: run_coro_with_catch(
                x(
                    matcher=matcher,
                    bot=bot,
                    event=event,
                    state=state,
                    stack=stack,
                    dependency_cache=dependency_cache,
                ),
                (SkippedException, ),
            ),
            _run_preprocessors,
        ))
    if coros:
        try:
            await asyncio.gather(*coros)
        except IgnoredException:
            logger.opt(colors=True).info(
                f"Matcher {matcher} running is <b>cancelled</b>")
            return
        except Exception as e:
            logger.opt(colors=True, exception=e).error(
                "<r><bg #f8bbd0>Error when running RunPreProcessors. "
                "Running cancelled!</bg #f8bbd0></r>")
            return

    exception = None

    try:
        logger.debug(f"Running matcher {matcher}")
        await matcher.run(bot, event, state, stack, dependency_cache)
    except Exception as e:
        logger.opt(colors=True, exception=e).error(
            f"<r><bg #f8bbd0>Running matcher {matcher} failed.</bg #f8bbd0></r>"
        )
        exception = e

    coros = list(
        map(
            lambda x: run_coro_with_catch(
                x(
                    matcher=matcher,
                    exception=exception,
                    bot=bot,
                    event=event,
                    state=state,
                    stack=stack,
                    dependency_cache=dependency_cache,
                ),
                (SkippedException, ),
            ),
            _run_postprocessors,
        ))
    if coros:
        try:
            await asyncio.gather(*coros)
        except Exception as e:
            logger.opt(colors=True, exception=e).error(
                "<r><bg #f8bbd0>Error when running RunPostProcessors</bg #f8bbd0></r>"
            )

    if matcher.block:
        raise StopPropagation
    return
Example #2
0
async def bind_handle_first_receive(matcher: Matcher,
                                    arg: Message = CommandArg()):
    if arg.extract_plain_text():
        matcher.set_arg("cookie", arg)
Example #3
0
from nonebot.matcher import Matcher

test_type_updater = Matcher.new(type_="test")

test_custom_updater = Matcher.new(type_="test")


@test_custom_updater.type_updater
async def _() -> str:
    return "custom"
Example #4
0
class CQHttp:
    message_matcher = Matcher.new("message")
    message_handlers = []

    notice_matcher = Matcher.new("notice")
    notice_handlers = []

    request_matcher = Matcher.new("request")
    request_handlers = []

    metaevent_matcher = Matcher.new("meta_event")
    metaevent_handlers = []

    _loop: asyncio.AbstractEventLoop

    @staticmethod
    async def _run_handlers(handlers: List[_NoneBotHandler], bot: CQBot,
                            event: NoneBotEvent):
        asyncio.ensure_future(
            asyncio.gather(
                *map(lambda f: f(bot, event), handlers),  # type: ignore
                return_exceptions=True))

    def __init__(self):
        get_driver().on_startup(
            lambda: setattr(self, "_loop", asyncio.get_running_loop()))

        @self.message_matcher.handle()
        async def handle_message(bot: CQBot, event: NoneBotEvent):
            return await self._run_handlers(self.message_handlers, bot, event)

        @self.notice_matcher.handle()
        async def handle_notice(bot: CQBot, event: NoneBotEvent):
            return await self._run_handlers(self.notice_handlers, bot, event)

        @self.request_matcher.handle()
        async def handle_request(bot: CQBot, event: NoneBotEvent):
            return await self._run_handlers(self.request_handlers, bot, event)

        @self.metaevent_matcher.handle()
        async def handle_metaevent(bot: CQBot, event: NoneBotEvent):
            return await self._run_handlers(self.metaevent_handlers, bot,
                                            event)

    @property
    def asgi(self):
        return get_asgi()

    @property
    def server_app(self):
        return get_app()

    @property
    def logger(self):
        from nonetrip.log import logger

        return logger

    @property
    def loop(self) -> asyncio.AbstractEventLoop:
        assert isinstance(self._loop, asyncio.AbstractEventLoop)
        return self._loop

    @property
    def bot(self) -> CQBot:
        for bot in get_bots().values():
            if not isinstance(bot, CQBot):
                continue
            return bot
        raise ApiNotAvailable("nonetrip")

    def _handler_factory(
        self,
        function: Callable[[Event], Coroutine],
        post_type: Optional[str] = None,
    ) -> _NoneBotHandler:
        async def handler(bot: CQBot, event: NoneBotEvent):
            if post_type is not None and event.post_type != post_type:
                return
            nonebot_event = Event.from_payload(event)
            if nonebot_event is None:
                return
            return await function(nonebot_event)

        return handler

    @singledispatchmethod
    def on_message(self, arg: _AsyncCallable_T) -> _AsyncCallable_T:
        self.message_matcher.append_handler(self._handler_factory(arg))
        return arg

    @on_message.register  # type:ignore
    def _on_specified_message(self, arg: str) -> _HandlerDecorator:
        def wrapper(function: _AsyncCallable_T) -> _AsyncCallable_T:
            self.message_matcher.append_handler(
                self._handler_factory(function, arg))
            return function

        return wrapper

    @singledispatchmethod
    def on_notice(self, arg):
        self.notice_matcher.append_handler(self._handler_factory(arg))
        return arg

    @on_notice.register  # type: ignore
    def _on_specified_notice(self, arg: str) -> _HandlerDecorator:
        def wrapper(function: _AsyncCallable_T) -> _AsyncCallable_T:
            self.notice_matcher.append_handler(
                self._handler_factory(function, arg))
            return function

        return wrapper

    @singledispatchmethod
    def on_request(self, arg: _AsyncCallable_T) -> _AsyncCallable_T:
        self.request_matcher.append_handler(self._handler_factory(arg))
        return arg

    @on_request.register  # type: ignore
    def _on_specified_request(self, arg: str) -> _HandlerDecorator:
        def wrapper(function: _AsyncCallable_T) -> _AsyncCallable_T:
            self.request_matcher.append_handler(
                self._handler_factory(function, arg))
            return function

        return wrapper

    @singledispatchmethod
    def on_metaevent(self, arg: _AsyncCallable_T) -> _AsyncCallable_T:
        self.metaevent_matcher.append_handler(self._handler_factory(arg))
        return arg

    @on_metaevent.register  # type:ignore
    def _on_specified_metaevent(self, arg: str) -> _HandlerDecorator:
        def wrapper(function: _AsyncCallable_T) -> _AsyncCallable_T:
            self.metaevent_matcher.append_handler(
                self._handler_factory(function, arg))
            return function

        return wrapper

    on_meta_event = on_metaevent

    async def send(self, event: Event, message: "Message_T", **kwargs):
        bot = get_bots().get(str(event.self_id))
        assert (bot is not None) and isinstance(bot, CQBot)
        message = message if isinstance(message, Message) else Message(message)
        return await bot.send(NoneBotEvent(**event), NoneBotMessage(message),
                              **kwargs)

    async def call_action(self, action: str, **kwargs):
        return await self.bot.call_api(action, **kwargs)

    def __getattr__(self, key: str) -> Callable[..., Coroutine]:
        return partial(self.call_action, key)