From f6c24ec92f880cf595a8727d019cb7f61f997a6d Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Mon, 1 Feb 2021 11:42:05 +0800 Subject: [PATCH 1/2] :bug: change matcher check-run --- nonebot/message.py | 59 ++++++++++++++++------------------------------ nonebot/rule.py | 7 +++++- 2 files changed, 26 insertions(+), 40 deletions(-) diff --git a/nonebot/message.py b/nonebot/message.py index c6974b2c..cb64a4e0 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -99,47 +99,30 @@ def run_postprocessor(func: T_RunPostProcessor) -> T_RunPostProcessor: return func -async def _check_matcher(priority: int, bot: "Bot", event: "Event", - state: T_State) -> Iterable[Type[Matcher]]: - current_matchers = matchers[priority].copy() - - async def _check(Matcher: Type[Matcher], bot: "Bot", event: "Event", - state: T_State) -> Optional[Type[Matcher]]: +async def _check_matcher(priority: int, Matcher: Type[Matcher], bot: "Bot", + event: "Event", state: T_State) -> None: + if Matcher.expire_time and datetime.now() > Matcher.expire_time: try: - if (not Matcher.expire_time or datetime.now() <= Matcher.expire_time - ) and await Matcher.check_perm( - bot, event) and await Matcher.check_rule(bot, event, state): - return Matcher - except Exception as e: - logger.opt(colors=True, exception=e).error( - f"Rule check failed for {Matcher}." - ) - return None - - async def _check_expire(Matcher: Type[Matcher]) -> Optional[Type[Matcher]]: - if Matcher.expire_time and datetime.now() > Matcher.expire_time: - return Matcher - return None - - checking_tasks = [ - _check(Matcher, bot, event, state) for Matcher in current_matchers - ] - checking_expire_tasks = [ - _check_expire(Matcher) for Matcher in current_matchers - ] - results = await asyncio.gather(*checking_tasks) - expired = await asyncio.gather(*checking_expire_tasks) - for expired_matcher in filter(lambda x: x, expired): - try: - matchers[priority].remove(expired_matcher) # type: ignore + matchers[priority].remove(Matcher) except Exception: pass - for temp_matcher in filter(lambda x: x and x.temp, results): + return + + try: + if not await Matcher.check_perm( + bot, event) or not await Matcher.check_rule(bot, event, state): + return + except Exception as e: + logger.opt(colors=True, exception=e).error( + f"Rule check failed for {Matcher}.") + + if Matcher.temp: try: - matchers[priority].remove(temp_matcher) # type: ignore + matchers[priority].remove(Matcher) except Exception: pass - return filter(lambda x: x, results) # type: ignore + + await _run_matcher(Matcher, bot, event, state) async def _run_matcher(Matcher: Type[Matcher], bot: "Bot", event: "Event", @@ -244,11 +227,9 @@ async def handle_event(bot: "Bot", event: "Event"): if show_log: logger.debug(f"Checking for matchers in priority {priority}...") - run_matchers = await _check_matcher(priority, bot, event, state) - pending_tasks = [ - _run_matcher(matcher, bot, event, state.copy()) - for matcher in run_matchers + _check_matcher(priority, matcher, bot, event, state.copy()) + for matcher in matchers[priority] ] results = await asyncio.gather(*pending_tasks, return_exceptions=True) diff --git a/nonebot/rule.py b/nonebot/rule.py index d2b8f1fd..6ef79461 100644 --- a/nonebot/rule.py +++ b/nonebot/rule.py @@ -282,7 +282,8 @@ def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule: 根据正则表达式进行匹配。 - 可以通过 ``state["_matched"]`` 获取正则表达式匹配成功的文本。 + 可以通过 ``state["_matched"]`` ``state["_matched_groups"]`` ``state["_matched_dict"]`` + 获取正则表达式匹配成功的文本。 :参数: @@ -302,9 +303,13 @@ def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule: matched = pattern.search(str(event.get_message())) if matched: state["_matched"] = matched.group() + state["_matched_groups"] = matched.groups() + state["_matched_dict"] = matched.groupdict() return True else: state["_matched"] = None + state["_matched_groups"] = None + state["_matched_dict"] = None return False return Rule(_regex) From 616e07cd2d108c5f01bb4e165a738c9193a7523d Mon Sep 17 00:00:00 2001 From: nonebot Date: Mon, 1 Feb 2021 03:49:26 +0000 Subject: [PATCH 2/2] :memo: update api docs --- docs/api/adapters/ding.md | 15 +++++++++++++++ docs/api/rule.md | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/api/adapters/ding.md b/docs/api/adapters/ding.md index 32fbb891..c64125ac 100644 --- a/docs/api/adapters/ding.md +++ b/docs/api/adapters/ding.md @@ -197,6 +197,16 @@ sidebarDepth: 0 @指定手机号人员 +### _static_ `atDingtalkIds(*dingtalkIds)` + +@指定 id,@ 默认会在消息段末尾。 +所以你可以在消息中使用 @{senderId} 占位,发送出去之后 @ 就会出现在占位的位置: +``python +message = MessageSegment.text(f"@{event.senderId},你好") +message += MessageSegment.atDingtalkIds(event.senderId) +`` + + ### _static_ `text(text)` 发送 `text` 类型消息 @@ -212,6 +222,11 @@ sidebarDepth: 0 "标记 text 文本的 extension 属性,需要与 text 消息段相加。 +### _static_ `code(code_language, code)` + +"发送 code 消息段 + + ### _static_ `markdown(title, text)` 发送 `markdown` 类型消息 diff --git a/docs/api/rule.md b/docs/api/rule.md index cb3fd05f..61be1f68 100644 --- a/docs/api/rule.md +++ b/docs/api/rule.md @@ -177,7 +177,8 @@ Rule(async_function, run_sync(sync_function)) 根据正则表达式进行匹配。 - 可以通过 `state["_matched"]` 获取正则表达式匹配成功的文本。 + 可以通过 `state["_matched"]` `state["_matched_groups"]` `state["_matched_dict"]` + 获取正则表达式匹配成功的文本。