mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-12-01 01:25:07 +08:00
✨ add full match Matcher
This commit is contained in:
parent
6ceaf51af7
commit
9f12404338
@ -11,6 +11,7 @@
|
|||||||
- `on_request` => {ref}``on_request` <nonebot.plugin.on.on_request>`
|
- `on_request` => {ref}``on_request` <nonebot.plugin.on.on_request>`
|
||||||
- `on_startswith` => {ref}``on_startswith` <nonebot.plugin.on.on_startswith>`
|
- `on_startswith` => {ref}``on_startswith` <nonebot.plugin.on.on_startswith>`
|
||||||
- `on_endswith` => {ref}``on_endswith` <nonebot.plugin.on.on_endswith>`
|
- `on_endswith` => {ref}``on_endswith` <nonebot.plugin.on.on_endswith>`
|
||||||
|
- `on_fullmatch` => {ref}``on_fullmatch` <nonebot.plugin.on.on_fullmatch>`
|
||||||
- `on_keyword` => {ref}``on_keyword` <nonebot.plugin.on.on_keyword>`
|
- `on_keyword` => {ref}``on_keyword` <nonebot.plugin.on.on_keyword>`
|
||||||
- `on_command` => {ref}``on_command` <nonebot.plugin.on.on_command>`
|
- `on_command` => {ref}``on_command` <nonebot.plugin.on.on_command>`
|
||||||
- `on_shell_command` => {ref}``on_shell_command` <nonebot.plugin.on.on_shell_command>`
|
- `on_shell_command` => {ref}``on_shell_command` <nonebot.plugin.on.on_shell_command>`
|
||||||
@ -274,6 +275,7 @@ from nonebot.plugin import CommandGroup as CommandGroup
|
|||||||
from nonebot.plugin import MatcherGroup as MatcherGroup
|
from nonebot.plugin import MatcherGroup as MatcherGroup
|
||||||
from nonebot.plugin import load_plugins as load_plugins
|
from nonebot.plugin import load_plugins as load_plugins
|
||||||
from nonebot.plugin import on_metaevent as on_metaevent
|
from nonebot.plugin import on_metaevent as on_metaevent
|
||||||
|
from nonebot.plugin import on_fullmatch as on_fullmatch
|
||||||
from nonebot.plugin import on_startswith as on_startswith
|
from nonebot.plugin import on_startswith as on_startswith
|
||||||
from nonebot.plugin import load_from_json as load_from_json
|
from nonebot.plugin import load_from_json as load_from_json
|
||||||
from nonebot.plugin import load_from_toml as load_from_toml
|
from nonebot.plugin import load_from_toml as load_from_toml
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
- `on_request` => {ref}``on_request` <nonebot.plugin.on.on_request>`
|
- `on_request` => {ref}``on_request` <nonebot.plugin.on.on_request>`
|
||||||
- `on_startswith` => {ref}``on_startswith` <nonebot.plugin.on.on_startswith>`
|
- `on_startswith` => {ref}``on_startswith` <nonebot.plugin.on.on_startswith>`
|
||||||
- `on_endswith` => {ref}``on_endswith` <nonebot.plugin.on.on_endswith>`
|
- `on_endswith` => {ref}``on_endswith` <nonebot.plugin.on.on_endswith>`
|
||||||
|
- `on_fullmatch` => {ref}``on_fullmatch` <nonebot.plugin.on.on_fullmatch>`
|
||||||
- `on_keyword` => {ref}``on_keyword` <nonebot.plugin.on.on_keyword>`
|
- `on_keyword` => {ref}``on_keyword` <nonebot.plugin.on.on_keyword>`
|
||||||
- `on_command` => {ref}``on_command` <nonebot.plugin.on.on_command>`
|
- `on_command` => {ref}``on_command` <nonebot.plugin.on.on_command>`
|
||||||
- `on_shell_command` => {ref}``on_shell_command` <nonebot.plugin.on.on_shell_command>`
|
- `on_shell_command` => {ref}``on_shell_command` <nonebot.plugin.on.on_shell_command>`
|
||||||
@ -61,6 +62,7 @@ from .on import MatcherGroup as MatcherGroup
|
|||||||
from .on import on_metaevent as on_metaevent
|
from .on import on_metaevent as on_metaevent
|
||||||
from .plugin import get_plugin as get_plugin
|
from .plugin import get_plugin as get_plugin
|
||||||
from .load import load_plugins as load_plugins
|
from .load import load_plugins as load_plugins
|
||||||
|
from .on import on_fullmatch as on_fullmatch
|
||||||
from .on import on_startswith as on_startswith
|
from .on import on_startswith as on_startswith
|
||||||
from .load import load_from_json as load_from_json
|
from .load import load_from_json as load_from_json
|
||||||
from .load import load_from_toml as load_from_toml
|
from .load import load_from_toml as load_from_toml
|
||||||
|
@ -21,6 +21,7 @@ from nonebot.rule import (
|
|||||||
command,
|
command,
|
||||||
keyword,
|
keyword,
|
||||||
endswith,
|
endswith,
|
||||||
|
fullmatch,
|
||||||
startswith,
|
startswith,
|
||||||
shell_command,
|
shell_command,
|
||||||
)
|
)
|
||||||
@ -283,6 +284,30 @@ def on_endswith(
|
|||||||
return on_message(endswith(msg, ignorecase) & rule, **kwargs, _depth=_depth + 1)
|
return on_message(endswith(msg, ignorecase) & rule, **kwargs, _depth=_depth + 1)
|
||||||
|
|
||||||
|
|
||||||
|
def on_fullmatch(
|
||||||
|
msg: Union[str, Tuple[str, ...]],
|
||||||
|
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = None,
|
||||||
|
ignorecase: bool = False,
|
||||||
|
_depth: int = 0,
|
||||||
|
**kwargs,
|
||||||
|
) -> Matcher:
|
||||||
|
"""
|
||||||
|
注册一个消息事件响应器,并且当消息的**文本部分**与指定内容完全一致时响应。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
msg: 指定消息全匹配内容
|
||||||
|
rule: 事件响应规则
|
||||||
|
ignorecase: 是否忽略大小写
|
||||||
|
permission: 事件响应权限
|
||||||
|
handlers: 事件处理函数列表
|
||||||
|
temp: 是否为临时事件响应器(仅执行一次)
|
||||||
|
priority: 事件响应器优先级
|
||||||
|
block: 是否阻止事件向更低优先级传递
|
||||||
|
state: 默认 state
|
||||||
|
"""
|
||||||
|
return on_message(fullmatch(msg, ignorecase) & rule, **kwargs, _depth=_depth + 1)
|
||||||
|
|
||||||
|
|
||||||
def on_keyword(
|
def on_keyword(
|
||||||
keywords: Set[str],
|
keywords: Set[str],
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
rule: Optional[Union[Rule, T_RuleChecker]] = None,
|
||||||
@ -611,6 +636,28 @@ class MatcherGroup:
|
|||||||
self.matchers.append(matcher)
|
self.matchers.append(matcher)
|
||||||
return matcher
|
return matcher
|
||||||
|
|
||||||
|
def on_fullmatch(self, msg: Union[str, Tuple[str, ...]], **kwargs) -> Type[Matcher]:
|
||||||
|
"""
|
||||||
|
注册一个消息事件响应器,并且当消息的**文本部分**与指定内容完全一致时响应。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
msg: 指定消息全匹配内容
|
||||||
|
rule: 事件响应规则
|
||||||
|
ignorecase: 是否忽略大小写
|
||||||
|
permission: 事件响应权限
|
||||||
|
handlers: 事件处理函数列表
|
||||||
|
temp: 是否为临时事件响应器(仅执行一次)
|
||||||
|
priority: 事件响应器优先级
|
||||||
|
block: 是否阻止事件向更低优先级传递
|
||||||
|
state: 默认 state
|
||||||
|
"""
|
||||||
|
final_kwargs = self.base_kwargs.copy()
|
||||||
|
final_kwargs.update(kwargs)
|
||||||
|
final_kwargs.pop("type", None)
|
||||||
|
matcher = on_fullmatch(msg, **final_kwargs, _depth=1)
|
||||||
|
self.matchers.append(matcher)
|
||||||
|
return matcher
|
||||||
|
|
||||||
def on_keyword(self, keywords: Set[str], **kwargs) -> Type[Matcher]:
|
def on_keyword(self, keywords: Set[str], **kwargs) -> Type[Matcher]:
|
||||||
"""
|
"""
|
||||||
注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。
|
注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。
|
||||||
|
@ -79,6 +79,18 @@ def on_endswith(
|
|||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
state: Optional[T_State] = ...,
|
state: Optional[T_State] = ...,
|
||||||
) -> Type[Matcher]: ...
|
) -> Type[Matcher]: ...
|
||||||
|
def on_fullmatch(
|
||||||
|
msg: Union[str, Tuple[str, ...]],
|
||||||
|
rule: Optional[Optional[Union[Rule, T_RuleChecker]]] = ...,
|
||||||
|
ignorecase: bool = ...,
|
||||||
|
*,
|
||||||
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[T_State] = ...,
|
||||||
|
) -> Type[Matcher]: ...
|
||||||
def on_keyword(
|
def on_keyword(
|
||||||
keywords: Set[str],
|
keywords: Set[str],
|
||||||
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
@ -261,6 +273,19 @@ class MatcherGroup:
|
|||||||
block: bool = ...,
|
block: bool = ...,
|
||||||
state: Optional[T_State] = ...,
|
state: Optional[T_State] = ...,
|
||||||
) -> Type[Matcher]: ...
|
) -> Type[Matcher]: ...
|
||||||
|
def on_fullmatch(
|
||||||
|
self,
|
||||||
|
msg: Union[str, Tuple[str, ...]],
|
||||||
|
*,
|
||||||
|
ignorecase: bool = ...,
|
||||||
|
rule: Optional[Union[Rule, T_RuleChecker]] = ...,
|
||||||
|
permission: Optional[Union[Permission, T_PermissionChecker]] = ...,
|
||||||
|
handlers: Optional[List[Union[T_Handler, Dependent]]] = ...,
|
||||||
|
temp: bool = ...,
|
||||||
|
priority: int = ...,
|
||||||
|
block: bool = ...,
|
||||||
|
state: Optional[T_State] = ...,
|
||||||
|
) -> Type[Matcher]: ...
|
||||||
def on_keyword(
|
def on_keyword(
|
||||||
self,
|
self,
|
||||||
keywords: Set[str],
|
keywords: Set[str],
|
||||||
|
@ -171,6 +171,47 @@ def endswith(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule
|
|||||||
return Rule(EndswithRule(msg, ignorecase))
|
return Rule(EndswithRule(msg, ignorecase))
|
||||||
|
|
||||||
|
|
||||||
|
class FullmatchRule:
|
||||||
|
"""检查消息纯文本是否与指定字符串全匹配。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
msg: 指定消息全匹配字符串元组
|
||||||
|
ignorecase: 是否忽略大小写
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("msg", "ignorecase")
|
||||||
|
|
||||||
|
def __init__(self, msg: Tuple[str, ...], ignorecase: bool = False):
|
||||||
|
self.msg = msg
|
||||||
|
self.ignorecase = ignorecase
|
||||||
|
|
||||||
|
async def __call__(
|
||||||
|
self, type: str = EventType(), text: str = EventPlainText()
|
||||||
|
) -> bool:
|
||||||
|
if type != "message":
|
||||||
|
return False
|
||||||
|
return bool(
|
||||||
|
text
|
||||||
|
and any(
|
||||||
|
full.lower() == text.lower() if self.ignorecase else full == text
|
||||||
|
for full in self.msg
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def fullmatch(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule:
|
||||||
|
"""完全匹配消息。
|
||||||
|
|
||||||
|
参数:
|
||||||
|
msg: 指定消息全匹配字符串元组
|
||||||
|
ignorecase: 是否忽略大小写
|
||||||
|
"""
|
||||||
|
if isinstance(msg, str):
|
||||||
|
msg = (msg,)
|
||||||
|
|
||||||
|
return Rule(FullmatchRule(msg, ignorecase))
|
||||||
|
|
||||||
|
|
||||||
class KeywordsRule:
|
class KeywordsRule:
|
||||||
"""检查消息纯文本是否包含指定关键字。
|
"""检查消息纯文本是否包含指定关键字。
|
||||||
|
|
||||||
|
@ -105,6 +105,43 @@ async def test_endswith(
|
|||||||
assert await dependent(event=event) == expected
|
assert await dependent(event=event) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"msg,ignorecase,type,text,expected",
|
||||||
|
[
|
||||||
|
("fullmatch", False, "message", "fullmatch", True),
|
||||||
|
("fullmatch", False, "message", "Fullmatch", False),
|
||||||
|
("fullmatch", True, "message", "fullmatch", True),
|
||||||
|
("fullmatch", True, "message", "Fullmatch", True),
|
||||||
|
("fullmatch", False, "message", "fullfoo", False),
|
||||||
|
("fullmatch", False, "message", "_fullmatch_", False),
|
||||||
|
(("fullmatch", "foo"), False, "message", "fullmatchfoo", False),
|
||||||
|
("fullmatch", False, "notice", "foo", False),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_fullmatch(
|
||||||
|
app: App,
|
||||||
|
msg: Union[str, Tuple[str, ...]],
|
||||||
|
ignorecase: bool,
|
||||||
|
type: str,
|
||||||
|
text: str,
|
||||||
|
expected: bool,
|
||||||
|
):
|
||||||
|
from nonebot.rule import FullmatchRule, fullmatch
|
||||||
|
|
||||||
|
test_fullmatch = fullmatch(msg, ignorecase)
|
||||||
|
dependent = list(test_fullmatch.checkers)[0]
|
||||||
|
checker = dependent.call
|
||||||
|
|
||||||
|
assert isinstance(checker, FullmatchRule)
|
||||||
|
assert checker.msg == (msg,) if isinstance(msg, str) else msg
|
||||||
|
assert checker.ignorecase == ignorecase
|
||||||
|
|
||||||
|
message = make_fake_message()(text)
|
||||||
|
event = make_fake_event(_type=type, _message=message)()
|
||||||
|
assert await dependent(event=event) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"kws,type,text,expected",
|
"kws,type,text,expected",
|
||||||
|
@ -122,14 +122,15 @@ matcher = on_message()
|
|||||||
5. `on_notice`: 创建通知事件响应器。
|
5. `on_notice`: 创建通知事件响应器。
|
||||||
6. `on_startswith`: 创建消息开头匹配事件响应器。
|
6. `on_startswith`: 创建消息开头匹配事件响应器。
|
||||||
7. `on_endswith`: 创建消息结尾匹配事件响应器。
|
7. `on_endswith`: 创建消息结尾匹配事件响应器。
|
||||||
8. `on_keyword`: 创建消息关键词匹配事件响应器。
|
8. `on_fullmatch`: 创建消息完全匹配事件响应器。
|
||||||
9. `on_command`: 创建命令消息事件响应器。
|
9. `on_keyword`: 创建消息关键词匹配事件响应器。
|
||||||
10. `on_shell_command`: 创建 shell 命令消息事件响应器。
|
10. `on_command`: 创建命令消息事件响应器。
|
||||||
11. `on_regex`: 创建正则表达式匹配事件响应器。
|
11. `on_shell_command`: 创建 shell 命令消息事件响应器。
|
||||||
12. `CommandGroup`: 创建具有共同命令名称前缀的命令组。
|
12. `on_regex`: 创建正则表达式匹配事件响应器。
|
||||||
13. `MatcherGroup`: 创建具有共同参数的响应器组。
|
13. `CommandGroup`: 创建具有共同命令名称前缀的命令组。
|
||||||
|
14. `MatcherGroup`: 创建具有共同参数的响应器组。
|
||||||
|
|
||||||
其中,`on_metaevent` `on_message` `on_request` `on_notice` 函数都是在 `on` 的基础上添加了对应的事件类型 `type`;`on_startswith` `on_endswith` `on_keyword` `on_command` `on_shell_command` `on_regex` 函数都是在 `on_message` 的基础上添加了对应的匹配规则 `rule`。
|
其中,`on_metaevent` `on_message` `on_request` `on_notice` 函数都是在 `on` 的基础上添加了对应的事件类型 `type`;`on_startswith` `on_endswith` `on_fullmatch` `on_keyword` `on_command` `on_shell_command` `on_regex` 函数都是在 `on_message` 的基础上添加了对应的匹配规则 `rule`。
|
||||||
|
|
||||||
## 自定义规则
|
## 自定义规则
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user