From 5b42454a555603b5503ade156de9a0524b5fab97 Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Fri, 4 Dec 2020 01:41:23 +0800 Subject: [PATCH] :sparkles: add matcher group for plugin #90 --- docs/api/matcher.md | 45 ----- docs/api/plugin.md | 469 ++++++++++++++++++++++++++++++++++++++++++++ nonebot/matcher.py | 198 ------------------- nonebot/plugin.py | 311 ++++++++++++++++++++++++++++- nonebot/plugin.pyi | 132 ++++++++++++- 5 files changed, 910 insertions(+), 245 deletions(-) diff --git a/docs/api/matcher.md b/docs/api/matcher.md index b061cd64..9e72b658 100644 --- a/docs/api/matcher.md +++ b/docs/api/matcher.md @@ -450,48 +450,3 @@ sidebarDepth: 0 * `**kwargs`: 其他传递给 `bot.send` 的参数,请参考对应 adapter 的 bot 对象 api - - - -## _class_ `MatcherGroup` - -基类:`object` - -事件响应器组合,统一管理。用法同 `Matcher` - - -### `__init__(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)` - - -* **说明** - - 创建一个事件响应器组合,参数为默认值,与 `Matcher.new` 一致 - - - -### `matchers` - - -* **类型** - - `List[Type[Matcher]]` - - - -* **说明** - - 组内事件响应器列表 - - - -### `new(type_='', rule=None, permission=None, handlers=None, temp=False, priority=1, block=False, *, module=None, default_state=None, expire_time=None)` - - -* **说明** - - 在组中创建一个新的事件响应器,参数留空则使用组合默认值 - - -:::danger 警告 -如果使用 handlers 参数覆盖组合默认值则该事件响应器不会随组合一起添加新的事件处理函数 -::: diff --git a/docs/api/plugin.md b/docs/api/plugin.md index 043b6222..91d7320e 100644 --- a/docs/api/plugin.md +++ b/docs/api/plugin.md @@ -593,6 +593,475 @@ def something_else(): +## _class_ `MatcherGroup` + +基类:`object` + +事件响应器组合,统一管理。为 `Matcher` 创建提供默认属性。 + + +### `__init__(**kwargs)` + + +* **说明** + + 创建一个事件响应器组合,参数为默认值,与 `on` 一致 + + + +### `matchers` + + +* **类型** + + `List[Type[Matcher]]` + + + +* **说明** + + 组内事件响应器列表 + + + +### `base_kwargs` + + +* **类型**: `Dict[str, Any]` + + +* **说明**: 其他传递给 `on` 的参数默认值 + + +### `on(**kwargs)` + + +* **说明** + + 注册一个基础事件响应器,可自定义类型。 + + + +* **参数** + + + * `type: str`: 事件响应器类型 + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `permission: Optional[Permission]`: 事件响应权限 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_metaevent(**kwargs)` + + +* **说明** + + 注册一个元事件响应器。 + + + +* **参数** + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_message(**kwargs)` + + +* **说明** + + 注册一个消息事件响应器。 + + + +* **参数** + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `permission: Optional[Permission]`: 事件响应权限 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_notice(**kwargs)` + + +* **说明** + + 注册一个通知事件响应器。 + + + +* **参数** + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_request(**kwargs)` + + +* **说明** + + 注册一个请求事件响应器。 + + + +* **参数** + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_startswith(msg, rule=None, **kwargs)` + + +* **说明** + + 注册一个消息事件响应器,并且当消息的\*\*文本部分\*\*以指定内容开头时响应。 + + + +* **参数** + + + * `msg: str`: 指定消息开头内容 + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `permission: Optional[Permission]`: 事件响应权限 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_endswith(msg, rule=None, **kwargs)` + + +* **说明** + + 注册一个消息事件响应器,并且当消息的\*\*文本部分\*\*以指定内容结尾时响应。 + + + +* **参数** + + + * `msg: str`: 指定消息结尾内容 + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `permission: Optional[Permission]`: 事件响应权限 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_keyword(keywords, rule=None, **kwargs)` + + +* **说明** + + 注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。 + + + +* **参数** + + + * `keywords: Set[str]`: 关键词列表 + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `permission: Optional[Permission]`: 事件响应权限 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_command(cmd, rule=None, aliases=None, **kwargs)` + + +* **说明** + + 注册一个消息事件响应器,并且当消息以指定命令开头时响应。 + + 命令匹配规则参考: [命令形式匹配](rule.html#command-command) + + + +* **参数** + + + * `cmd: Union[str, Tuple[str, ...]]`: 指定命令内容 + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `aliases: Optional[Set[Union[str, Tuple[str, ...]]]]`: 命令别名 + + + * `permission: Optional[Permission]`: 事件响应权限 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + +### `on_regex(pattern, flags=0, rule=None, **kwargs)` + + +* **说明** + + 注册一个消息事件响应器,并且当消息匹配正则表达式时响应。 + + 命令匹配规则参考: [正则匹配](rule.html#regex-regex-flags-0) + + + +* **参数** + + + * `pattern: str`: 正则表达式 + + + * `flags: Union[int, re.RegexFlag]`: 正则匹配标志 + + + * `rule: Optional[Union[Rule, RuleChecker]]`: 事件响应规则 + + + * `permission: Optional[Permission]`: 事件响应权限 + + + * `handlers: Optional[List[Handler]]`: 事件处理函数列表 + + + * `temp: bool`: 是否为临时事件响应器(仅执行一次) + + + * `priority: int`: 事件响应器优先级 + + + * `block: bool`: 是否阻止事件向更低优先级传递 + + + * `state: Optional[dict]`: 默认的 state + + + +* **返回** + + + * `Type[Matcher]` + + + ## `load_plugin(module_path)` diff --git a/nonebot/matcher.py b/nonebot/matcher.py index b38ef47e..1c2eabe6 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -449,201 +449,3 @@ class Matcher(metaclass=MatcherMeta): logger.info(f"Matcher {self} running complete") current_bot.reset(b_t) current_event.reset(e_t) - - -class MatcherGroup: - """事件响应器组合,统一管理。用法同 ``Matcher``""" - - def __init__(self, - type_: str = "", - rule: Optional[Rule] = None, - permission: Optional[Permission] = None, - handlers: Optional[list] = None, - temp: bool = False, - priority: int = 1, - block: bool = False, - *, - module: Optional[str] = None, - default_state: Optional[dict] = None, - expire_time: Optional[datetime] = None): - """ - :说明: - - 创建一个事件响应器组合,参数为默认值,与 ``Matcher.new`` 一致 - """ - self.matchers: List[Type[Matcher]] = [] - """ - :类型: ``List[Type[Matcher]]`` - :说明: 组内事件响应器列表 - """ - - self.type = type_ - self.rule = rule or Rule() - self.permission = permission or Permission() - self.handlers = handlers - self.temp = temp - self.priority = priority - self.block = block - self.module = module - self.expire_time = expire_time - - self._default_state = default_state - - self._default_parser: Optional[ArgsParser] = None - - def __repr__(self) -> str: - return ( - f"") - - def __str__(self) -> str: - return self.__repr__() - - def new(self, - type_: str = "", - rule: Optional[Rule] = None, - permission: Optional[Permission] = None, - handlers: Optional[list] = None, - temp: bool = False, - priority: int = 1, - block: bool = False, - *, - module: Optional[str] = None, - default_state: Optional[dict] = None, - expire_time: Optional[datetime] = None) -> Type[Matcher]: - """ - :说明: - - 在组中创建一个新的事件响应器,参数留空则使用组合默认值 - - \:\:\:danger 警告 - 如果使用 handlers 参数覆盖组合默认值则该事件响应器不会随组合一起添加新的事件处理函数 - \:\:\: - """ - matcher = Matcher.new(type_=type_ or self.type, - rule=self.rule & rule, - permission=permission or self.permission, - handlers=handlers or self.handlers, - temp=temp or self.temp, - priority=priority or self.priority, - block=block or self.block, - module=module or self.module, - default_state=default_state or - self._default_state, - expire_time=expire_time or self.expire_time) - self.matchers.append(matcher) - return matcher - - def args_parser(self, func: ArgsParser) -> ArgsParser: - self._default_parser = func - for matcher in self.matchers: - matcher.args_parser(func) - return func - - def handle(self) -> Callable[[Handler], Handler]: - - def _decorator(func: Handler) -> Handler: - self.handlers.append(func) - return func - - return _decorator - - def receive(self) -> Callable[[Handler], Handler]: - - async def _receive(bot: Bot, event: Event, state: dict) -> NoReturn: - raise PausedException - - if self.handlers: - # 已有前置handlers则接受一条新的消息,否则视为接收初始消息 - self.handlers.append(_receive) - - def _decorator(func: Handler) -> Handler: - if not self.handlers or self.handlers[-1] is not func: - self.handlers.append(func) - - return func - - return _decorator - - def got( - self, - key: str, - prompt: Optional[str] = None, - args_parser: Optional[ArgsParser] = None - ) -> Callable[[Handler], Handler]: - - async def _key_getter(bot: Bot, event: Event, state: dict): - state["_current_key"] = key - if key not in state: - if prompt: - await bot.send(event=event, - message=str(prompt).format(state)) - raise PausedException - else: - state["_skip_key"] = True - - async def _key_parser(bot: Bot, event: Event, state: dict): - if key in state and state.get("_skip_key"): - del state["_skip_key"] - return - parser = args_parser or self._default_parser - if parser: - await parser(bot, event, state) - else: - state[state["_current_key"]] = str(event.message) - - self.handlers.append(_key_getter) - self.handlers.append(_key_parser) - - def _decorator(func: Handler) -> Handler: - if not hasattr(self.handlers[-1], "__wrapped__"): - parser = self.handlers.pop() - - @wraps(func) - async def wrapper(bot: Bot, event: Event, state: dict): - await parser(bot, event, state) - await func(bot, event, state) - if "_current_key" in state: - del state["_current_key"] - - self.handlers.append(wrapper) - - return func - - return _decorator - - async def send(self, message: Union[str, Message, MessageSegment], - **kwargs): - bot = current_bot.get() - event = current_event.get() - await bot.send(event=event, message=message, **kwargs) - - async def finish(self, - message: Optional[Union[str, Message, - MessageSegment]] = None, - **kwargs) -> NoReturn: - bot = current_bot.get() - event = current_event.get() - if message: - await bot.send(event=event, message=message, **kwargs) - raise FinishedException - - async def pause(self, - prompt: Optional[Union[str, Message, - MessageSegment]] = None, - **kwargs) -> NoReturn: - bot = current_bot.get() - event = current_event.get() - if prompt: - await bot.send(event=event, message=prompt, **kwargs) - raise PausedException - - async def reject(self, - prompt: Optional[Union[str, Message, - MessageSegment]] = None, - **kwargs) -> NoReturn: - bot = current_bot.get() - event = current_event.get() - if prompt: - await bot.send(event=event, message=prompt, **kwargs) - raise RejectedException diff --git a/nonebot/plugin.py b/nonebot/plugin.py index f94d6e0e..1f876534 100644 --- a/nonebot/plugin.py +++ b/nonebot/plugin.py @@ -9,6 +9,7 @@ import re import sys import pkgutil import importlib +from datetime import datetime from dataclasses import dataclass from importlib._bootstrap import _load from contextvars import Context, ContextVar, copy_context @@ -18,7 +19,7 @@ from nonebot.matcher import Matcher from nonebot.permission import Permission from nonebot.typing import Handler, RuleChecker from nonebot.rule import Rule, startswith, endswith, keyword, command, regex -from nonebot.typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, ModuleType +from nonebot.typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, ArgsParser, ModuleType plugins: Dict[str, "Plugin"] = {} """ @@ -485,6 +486,314 @@ class CommandGroup: return on_command(cmd, **final_kwargs) +class MatcherGroup: + """事件响应器组合,统一管理。为 ``Matcher`` 创建提供默认属性。""" + + def __init__(self, **kwargs): + """ + :说明: + + 创建一个事件响应器组合,参数为默认值,与 ``on`` 一致 + """ + self.matchers: List[Type[Matcher]] = [] + """ + :类型: ``List[Type[Matcher]]`` + :说明: 组内事件响应器列表 + """ + self.base_kwargs: Dict[str, Any] = kwargs + """ + - **类型**: ``Dict[str, Any]`` + - **说明**: 其他传递给 ``on`` 的参数默认值 + """ + + def on(self, **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个基础事件响应器,可自定义类型。 + + :参数: + + * ``type: str``: 事件响应器类型 + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``permission: Optional[Permission]``: 事件响应权限 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + final_kwargs = self.base_kwargs.copy() + final_kwargs.update(kwargs) + matcher = Matcher.new(**final_kwargs) + self.matchers.append(matcher) + _tmp_matchers.get().add(matcher) + return matcher + + def on_metaevent(self, **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个元事件响应器。 + + :参数: + + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + final_kwargs = self.base_kwargs.copy() + final_kwargs.update(kwargs) + final_kwargs["type"] = "meta_event" + matcher = Matcher.new(**final_kwargs) + self.matchers.append(matcher) + _tmp_matchers.get().add(matcher) + return matcher + + def on_message(self, **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个消息事件响应器。 + + :参数: + + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``permission: Optional[Permission]``: 事件响应权限 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + final_kwargs = self.base_kwargs.copy() + final_kwargs.update(kwargs) + final_kwargs["type"] = "message" + matcher = Matcher.new(**final_kwargs) + self.matchers.append(matcher) + _tmp_matchers.get().add(matcher) + return matcher + + def on_notice(self, **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个通知事件响应器。 + + :参数: + + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + final_kwargs = self.base_kwargs.copy() + final_kwargs.update(kwargs) + final_kwargs["type"] = "notice" + matcher = Matcher.new(**final_kwargs) + self.matchers.append(matcher) + _tmp_matchers.get().add(matcher) + return matcher + + def on_request(self, **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个请求事件响应器。 + + :参数: + + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + final_kwargs = self.base_kwargs.copy() + final_kwargs.update(kwargs) + final_kwargs["type"] = "request" + matcher = Matcher.new(**final_kwargs) + self.matchers.append(matcher) + _tmp_matchers.get().add(matcher) + return matcher + + def on_startswith(self, + msg: str, + rule: Optional[Optional[Union[Rule, RuleChecker]]] = None, + **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个消息事件响应器,并且当消息的**文本部分**以指定内容开头时响应。 + + :参数: + + * ``msg: str``: 指定消息开头内容 + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``permission: Optional[Permission]``: 事件响应权限 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + return self.on_message(rule=startswith(msg) & rule, **kwargs) + + def on_endswith(self, + msg: str, + rule: Optional[Optional[Union[Rule, RuleChecker]]] = None, + **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个消息事件响应器,并且当消息的**文本部分**以指定内容结尾时响应。 + + :参数: + + * ``msg: str``: 指定消息结尾内容 + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``permission: Optional[Permission]``: 事件响应权限 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + return self.on_message(rule=endswith(msg) & rule, **kwargs) + + def on_keyword(self, + keywords: Set[str], + rule: Optional[Union[Rule, RuleChecker]] = None, + **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。 + + :参数: + + * ``keywords: Set[str]``: 关键词列表 + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``permission: Optional[Permission]``: 事件响应权限 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + return self.on_message(rule=keyword(*keywords) & rule, **kwargs) + + def on_command(self, + cmd: Union[str, Tuple[str, ...]], + rule: Optional[Union[Rule, RuleChecker]] = None, + aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None, + **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个消息事件响应器,并且当消息以指定命令开头时响应。 + + 命令匹配规则参考: `命令形式匹配 `_ + + :参数: + + * ``cmd: Union[str, Tuple[str, ...]]``: 指定命令内容 + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``aliases: Optional[Set[Union[str, Tuple[str, ...]]]]``: 命令别名 + * ``permission: Optional[Permission]``: 事件响应权限 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + + async def _strip_cmd(bot, event, state: dict): + message = event.message + event.message = message.__class__( + str(message)[len(state["_prefix"]["raw_command"]):].strip()) + + handlers = kwargs.pop("handlers", []) + handlers.insert(0, _strip_cmd) + + commands = set([cmd]) | (aliases or set()) + return self.on_message(rule=command(*commands) & rule, + handlers=handlers, + **kwargs) + + def on_regex(self, + pattern: str, + flags: Union[int, re.RegexFlag] = 0, + rule: Optional[Rule] = None, + **kwargs) -> Type[Matcher]: + """ + :说明: + + 注册一个消息事件响应器,并且当消息匹配正则表达式时响应。 + + 命令匹配规则参考: `正则匹配 `_ + + :参数: + + * ``pattern: str``: 正则表达式 + * ``flags: Union[int, re.RegexFlag]``: 正则匹配标志 + * ``rule: Optional[Union[Rule, RuleChecker]]``: 事件响应规则 + * ``permission: Optional[Permission]``: 事件响应权限 + * ``handlers: Optional[List[Handler]]``: 事件处理函数列表 + * ``temp: bool``: 是否为临时事件响应器(仅执行一次) + * ``priority: int``: 事件响应器优先级 + * ``block: bool``: 是否阻止事件向更低优先级传递 + * ``state: Optional[dict]``: 默认的 state + + :返回: + + - ``Type[Matcher]`` + """ + return self.on_message(rule=regex(pattern, flags) & rule, **kwargs) + + def load_plugin(module_path: str) -> Optional[Plugin]: """ :说明: diff --git a/nonebot/plugin.pyi b/nonebot/plugin.pyi index 37d775d6..607c1d27 100644 --- a/nonebot/plugin.pyi +++ b/nonebot/plugin.pyi @@ -188,13 +188,143 @@ class CommandGroup: def command(self, cmd: Union[str, Tuple[str, ...]], + *, rule: Optional[Union[Rule, RuleChecker]] = ..., aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ..., permission: Optional[Permission] = ..., - *, handlers: Optional[List[Handler]] = ..., temp: bool = ..., priority: int = ..., block: bool = ..., state: Optional[dict] = ...) -> Type[Matcher]: ... + + +class MatcherGroup: + + def __init__(self, + *, + type: str = ..., + rule: Optional[Union[Rule, RuleChecker]] = ..., + permission: Optional[Permission] = ..., + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...): + ... + + def on(self, + *, + type: str = ..., + rule: Optional[Union[Rule, RuleChecker]] = ..., + permission: Optional[Permission] = ..., + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...) -> Type[Matcher]: + ... + + def on_metaevent(self, + *, + rule: Optional[Union[Rule, RuleChecker]] = None, + handlers: Optional[List[Handler]] = None, + temp: bool = False, + priority: int = 1, + block: bool = False, + state: Optional[dict] = None) -> Type[Matcher]: + ... + + def on_message(self, + *, + rule: Optional[Union[Rule, RuleChecker]] = None, + permission: Optional[Permission] = None, + handlers: Optional[List[Handler]] = None, + temp: bool = False, + priority: int = 1, + block: bool = True, + state: Optional[dict] = None) -> Type[Matcher]: + ... + + def on_notice(self, + *, + rule: Optional[Union[Rule, RuleChecker]] = None, + handlers: Optional[List[Handler]] = None, + temp: bool = False, + priority: int = 1, + block: bool = False, + state: Optional[dict] = None) -> Type[Matcher]: + ... + + def on_request(self, + *, + rule: Optional[Union[Rule, RuleChecker]] = None, + handlers: Optional[List[Handler]] = None, + temp: bool = False, + priority: int = 1, + block: bool = False, + state: Optional[dict] = None) -> Type[Matcher]: + ... + + def on_startswith(self, + *, + msg: str, + rule: Optional[Optional[Union[Rule, RuleChecker]]] = ..., + permission: Optional[Permission] = ..., + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...) -> Type[Matcher]: + ... + + def on_endswith(self, + *, + msg: str, + rule: Optional[Optional[Union[Rule, RuleChecker]]] = ..., + permission: Optional[Permission] = ..., + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...) -> Type[Matcher]: + ... + + def on_keyword(self, + *, + keywords: Set[str], + rule: Optional[Optional[Union[Rule, RuleChecker]]] = ..., + permission: Optional[Permission] = ..., + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...) -> Type[Matcher]: + ... + + def on_command(self, + *, + cmd: Union[str, Tuple[str, ...]], + rule: Optional[Union[Rule, RuleChecker]] = ..., + aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ..., + permission: Optional[Permission] = ..., + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...) -> Type[Matcher]: + ... + + def on_regex(self, + *, + pattern: str, + flags: Union[int, re.RegexFlag] = 0, + rule: Optional[Rule] = ..., + permission: Optional[Permission] = ..., + handlers: Optional[List[Handler]] = ..., + temp: bool = ..., + priority: int = ..., + block: bool = ..., + state: Optional[dict] = ...) -> Type[Matcher]: + ...