mirror of
				https://github.com/nonebot/nonebot2.git
				synced 2025-10-31 15:06:42 +00:00 
			
		
		
		
	⚗️ add pre and post processor #40
This commit is contained in:
		| @@ -5,19 +5,37 @@ from nonebot.log import logger | |||||||
| from nonebot.rule import TrieRule | from nonebot.rule import TrieRule | ||||||
| from nonebot.utils import escape_tag | from nonebot.utils import escape_tag | ||||||
| from nonebot.matcher import matchers | from nonebot.matcher import matchers | ||||||
| from nonebot.typing import Set, Type, Union, NoReturn |  | ||||||
| from nonebot.typing import Bot, Event, Matcher, PreProcessor |  | ||||||
| from nonebot.exception import IgnoredException, ExpiredException | from nonebot.exception import IgnoredException, ExpiredException | ||||||
| from nonebot.exception import StopPropagation, _ExceptionContainer | from nonebot.exception import StopPropagation, _ExceptionContainer | ||||||
|  | from nonebot.typing import Set, Type, Union, NoReturn, Bot, Event, Matcher | ||||||
|  | from nonebot.typing import EventPreProcessor, RunPreProcessor, EventPostProcessor, RunPostProcessor | ||||||
|  |  | ||||||
| _event_preprocessors: Set[PreProcessor] = set() | _event_preprocessors: Set[EventPreProcessor] = set() | ||||||
|  | _event_postprocessors: Set[EventPostProcessor] = set() | ||||||
|  | _run_preprocessors: Set[RunPreProcessor] = set() | ||||||
|  | _run_postprocessors: Set[RunPostProcessor] = set() | ||||||
|  |  | ||||||
|  |  | ||||||
| def event_preprocessor(func: PreProcessor) -> PreProcessor: | def event_preprocessor(func: EventPreProcessor) -> EventPreProcessor: | ||||||
|     _event_preprocessors.add(func) |     _event_preprocessors.add(func) | ||||||
|     return func |     return func | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def event_postprocessor(func: EventPostProcessor) -> EventPostProcessor: | ||||||
|  |     _event_postprocessors.add(func) | ||||||
|  |     return func | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def run_preprocessor(func: RunPreProcessor) -> RunPreProcessor: | ||||||
|  |     _run_preprocessors.add(func) | ||||||
|  |     return func | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def run_postprocessor(func: RunPostProcessor) -> RunPostProcessor: | ||||||
|  |     _run_postprocessors.add(func) | ||||||
|  |     return func | ||||||
|  |  | ||||||
|  |  | ||||||
| async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event, | async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event, | ||||||
|                        state: dict) -> Union[None, NoReturn]: |                        state: dict) -> Union[None, NoReturn]: | ||||||
|     if Matcher.expire_time and datetime.now() > Matcher.expire_time: |     if Matcher.expire_time and datetime.now() > Matcher.expire_time: | ||||||
| @@ -35,7 +53,24 @@ async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event, | |||||||
|     logger.info(f"Event will be handled by {Matcher}") |     logger.info(f"Event will be handled by {Matcher}") | ||||||
|  |  | ||||||
|     matcher = Matcher() |     matcher = Matcher() | ||||||
|     # TODO: BeforeMatcherRun |  | ||||||
|  |     coros = list( | ||||||
|  |         map(lambda x: x(matcher, bot, event, state), _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 | ||||||
|  |  | ||||||
|  |     exceptions = [] | ||||||
|  |  | ||||||
|     try: |     try: | ||||||
|         logger.debug(f"Running matcher {matcher}") |         logger.debug(f"Running matcher {matcher}") | ||||||
|         await matcher.run(bot, event, state) |         await matcher.run(bot, event, state) | ||||||
| @@ -43,12 +78,24 @@ async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event, | |||||||
|         logger.opt(colors=True, exception=e).error( |         logger.opt(colors=True, exception=e).error( | ||||||
|             f"<r><bg #f8bbd0>Running matcher {matcher} failed.</bg #f8bbd0></r>" |             f"<r><bg #f8bbd0>Running matcher {matcher} failed.</bg #f8bbd0></r>" | ||||||
|         ) |         ) | ||||||
|  |         exceptions.append(e) | ||||||
|  |  | ||||||
|     exceptions = [] |  | ||||||
|     if Matcher.temp: |     if Matcher.temp: | ||||||
|         exceptions.append(ExpiredException) |         exceptions.append(ExpiredException) | ||||||
|     if Matcher.block: |     if Matcher.block: | ||||||
|         exceptions.append(StopPropagation) |         exceptions.append(StopPropagation) | ||||||
|  |  | ||||||
|  |     coros = list( | ||||||
|  |         map(lambda x: x(matcher, exceptions, bot, event, state), | ||||||
|  |             _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 exceptions: |     if exceptions: | ||||||
|         raise _ExceptionContainer(exceptions) |         raise _ExceptionContainer(exceptions) | ||||||
|  |  | ||||||
| @@ -77,10 +124,8 @@ async def handle_event(bot: Bot, event: Event): | |||||||
|     if show_log: |     if show_log: | ||||||
|         logger.opt(colors=True).info(log_msg) |         logger.opt(colors=True).info(log_msg) | ||||||
|  |  | ||||||
|     coros = [] |  | ||||||
|     state = {} |     state = {} | ||||||
|     for preprocessor in _event_preprocessors: |     coros = list(map(lambda x: x(bot, event, state), _event_preprocessors)) | ||||||
|         coros.append(preprocessor(bot, event, state)) |  | ||||||
|     if coros: |     if coros: | ||||||
|         try: |         try: | ||||||
|             logger.debug("Running PreProcessors...") |             logger.debug("Running PreProcessors...") | ||||||
| @@ -89,6 +134,11 @@ async def handle_event(bot: Bot, event: Event): | |||||||
|             logger.opt( |             logger.opt( | ||||||
|                 colors=True).info(f"Event {event.name} is <b>ignored</b>") |                 colors=True).info(f"Event {event.name} is <b>ignored</b>") | ||||||
|             return |             return | ||||||
|  |         except Exception as e: | ||||||
|  |             logger.opt(colors=True, exception=e).error( | ||||||
|  |                 "<r><bg #f8bbd0>Error when running EventPreProcessors. " | ||||||
|  |                 "Event ignored!</bg #f8bbd0></r>") | ||||||
|  |             return | ||||||
|  |  | ||||||
|     # Trie Match |     # Trie Match | ||||||
|     _, _ = TrieRule.get_value(bot, event, state) |     _, _ = TrieRule.get_value(bot, event, state) | ||||||
| @@ -121,3 +171,13 @@ async def handle_event(bot: Bot, event: Event): | |||||||
|                     ) |                     ) | ||||||
|                     del matchers[priority][index - i] |                     del matchers[priority][index - i] | ||||||
|                     i += 1 |                     i += 1 | ||||||
|  |  | ||||||
|  |     coros = list(map(lambda x: x(bot, event, state), _event_postprocessors)) | ||||||
|  |     if coros: | ||||||
|  |         try: | ||||||
|  |             logger.debug("Running PostProcessors...") | ||||||
|  |             await asyncio.gather(*coros) | ||||||
|  |         except Exception as e: | ||||||
|  |             logger.opt(colors=True, exception=e).error( | ||||||
|  |                 "<r><bg #f8bbd0>Error when running EventPostProcessors</bg #f8bbd0></r>" | ||||||
|  |             ) | ||||||
|   | |||||||
| @@ -92,14 +92,41 @@ MessageSegment = TypeVar("MessageSegment", bound="BaseMessageSegment") | |||||||
|   所有 MessageSegment 的基类。 |   所有 MessageSegment 的基类。 | ||||||
| """ | """ | ||||||
|  |  | ||||||
| PreProcessor = Callable[[Bot, Event, dict], Union[Awaitable[None], | EventPreProcessor = Callable[[Bot, Event, dict], Union[Awaitable[None], | ||||||
|                                                   Awaitable[NoReturn]]] |                                                        Awaitable[NoReturn]]] | ||||||
| """ | """ | ||||||
| :类型: ``Callable[[Bot, Event, dict], Union[Awaitable[None], Awaitable[NoReturn]]]`` | :类型: ``Callable[[Bot, Event, dict], Union[Awaitable[None], Awaitable[NoReturn]]]`` | ||||||
|  |  | ||||||
| :说明: | :说明: | ||||||
|  |  | ||||||
|   消息预处理函数 PreProcessor 类型 |   事件预处理函数 EventPreProcessor 类型 | ||||||
|  | """ | ||||||
|  | EventPostProcessor = Callable[[Bot, Event, dict], Union[Awaitable[None], | ||||||
|  |                                                         Awaitable[NoReturn]]] | ||||||
|  | """ | ||||||
|  | :类型: ``Callable[[Bot, Event, dict], Union[Awaitable[None], Awaitable[NoReturn]]]`` | ||||||
|  |  | ||||||
|  | :说明: | ||||||
|  |  | ||||||
|  |   事件预处理函数 EventPostProcessor 类型 | ||||||
|  | """ | ||||||
|  | RunPreProcessor = Callable[["Matcher", Bot, Event, dict], | ||||||
|  |                            Union[Awaitable[None], Awaitable[NoReturn]]] | ||||||
|  | """ | ||||||
|  | :类型: ``Callable[[Matcher, Bot, Event, dict], Union[Awaitable[None], Awaitable[NoReturn]]]`` | ||||||
|  |  | ||||||
|  | :说明: | ||||||
|  |  | ||||||
|  |   事件响应器运行前预处理函数 RunPreProcessor 类型 | ||||||
|  | """ | ||||||
|  | RunPostProcessor = Callable[["Matcher", List[Any], Bot, Event, dict], | ||||||
|  |                             Union[Awaitable[None], Awaitable[NoReturn]]] | ||||||
|  | """ | ||||||
|  | :类型: ``Callable[[Matcher, List[Any], Bot, Event, dict], Union[Awaitable[None], Awaitable[NoReturn]]]`` | ||||||
|  |  | ||||||
|  | :说明: | ||||||
|  |  | ||||||
|  |   事件响应器运行前预处理函数 RunPostProcessor 类型,第二个参数包含运行时产生的错误以及 ``ExpiredException``, ``StopPropagation`` (如果存在) | ||||||
| """ | """ | ||||||
|  |  | ||||||
| Matcher = TypeVar("Matcher", bound="MatcherClass") | Matcher = TypeVar("Matcher", bound="MatcherClass") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user