⚗️ add type and permission updater hook

This commit is contained in:
yanyongyu 2021-03-03 16:06:19 +08:00
parent 464f0d4a89
commit 9e04e497b7
7 changed files with 200 additions and 29 deletions

View File

@ -291,7 +291,7 @@ Event 基类。提供获取关键信息的方法,其余信息可直接获取
* `Literal["message", "notice", "request", "meta_event"]` * `Literal["message", "notice", "request", "meta_event"]`
* `str` * 其他自定义 `str`

View File

@ -197,6 +197,36 @@ sidebarDepth: 0
### `_default_type_updater`
* **类型**
`Optional[T_ArgsParser]`
* **说明**
事件响应器类型更新函数
### `_default_permission_updater`
* **类型**
`Optional[T_ArgsParser]`
* **说明**
事件响应器权限更新函数
### `__init__()` ### `__init__()`
实例化 Matcher 以便运行 实例化 Matcher 以便运行
@ -341,6 +371,38 @@ sidebarDepth: 0
### _classmethod_ `type_updater(func)`
* **说明**
装饰一个函数来更改当前事件响应器的默认响应事件类型更新函数
* **参数**
* `func: T_TypeUpdater`: 响应事件类型更新函数
### _classmethod_ `permission_updater(func)`
* **说明**
装饰一个函数来更改当前事件响应器的默认会话权限更新函数
* **参数**
* `func: T_PermissionUpdater`: 会话权限更新函数
### _classmethod_ `handle()` ### _classmethod_ `handle()`

View File

@ -212,3 +212,35 @@ sidebarDepth: 0
* **说明** * **说明**
ArgsParser 即消息参数解析函数,在 Matcher.got 获取参数时被运行。 ArgsParser 即消息参数解析函数,在 Matcher.got 获取参数时被运行。
## `T_TypeUpdater`
* **类型**
`Callable[[Bot, Event, T_State, str], Awaitable[str]]`
* **说明**
TypeUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新响应的事件类型。默认会更新为 `message`
## `T_PermissionUpdater`
* **类型**
`Callable[[Bot, Event, T_State, Permission], Awaitable[Permission]]`
* **说明**
PermissionUpdater 在 Matcher.pause, Matcher.reject 时被运行,用于更新会话对象权限。默认会更新为当前事件的触发对象。

View File

@ -381,7 +381,7 @@ class Event(abc.ABC, BaseModel):
:返回: :返回:
* ``Literal["message", "notice", "request", "meta_event"]`` * ``Literal["message", "notice", "request", "meta_event"]``
* ``str`` * 其他自定义 ``str``
""" """
raise NotImplementedError raise NotImplementedError
@ -457,7 +457,7 @@ class Event(abc.ABC, BaseModel):
raise NotImplementedError raise NotImplementedError
@abc.abstractmethod @abc.abstractmethod
def get_message(self) -> "Message": def get_message(self) -> Message:
""" """
:说明: :说明:

View File

@ -15,7 +15,7 @@ from typing import Type, List, Dict, Union, Mapping, Iterable, Callable, Optiona
from nonebot.rule import Rule from nonebot.rule import Rule
from nonebot.log import logger from nonebot.log import logger
from nonebot.permission import Permission, USER from nonebot.permission import Permission, USER
from nonebot.typing import T_State, T_StateFactory, T_Handler, T_ArgsParser from nonebot.typing import T_State, T_StateFactory, T_Handler, T_ArgsParser, T_TypeUpdater, T_PermissionUpdater
from nonebot.exception import PausedException, RejectedException, FinishedException, StopPropagation from nonebot.exception import PausedException, RejectedException, FinishedException, StopPropagation
if TYPE_CHECKING: if TYPE_CHECKING:
@ -106,6 +106,16 @@ class Matcher(metaclass=MatcherMeta):
:类型: ``Optional[T_ArgsParser]`` :类型: ``Optional[T_ArgsParser]``
:说明: 事件响应器默认参数解析函数 :说明: 事件响应器默认参数解析函数
""" """
_default_type_updater: Optional[T_TypeUpdater] = None
"""
:类型: ``Optional[T_ArgsParser]``
:说明: 事件响应器类型更新函数
"""
_default_permission_updater: Optional[T_PermissionUpdater] = None
"""
:类型: ``Optional[T_ArgsParser]``
:说明: 事件响应器权限更新函数
"""
def __init__(self): def __init__(self):
"""实例化 Matcher 以便运行""" """实例化 Matcher 以便运行"""
@ -245,6 +255,35 @@ class Matcher(metaclass=MatcherMeta):
cls._default_parser = func cls._default_parser = func
return func return func
@classmethod
def type_updater(cls, func: T_TypeUpdater) -> T_TypeUpdater:
"""
:说明:
装饰一个函数来更改当前事件响应器的默认响应事件类型更新函数
:参数:
* ``func: T_TypeUpdater``: 响应事件类型更新函数
"""
cls._default_type_updater = func
return func
@classmethod
def permission_updater(cls,
func: T_PermissionUpdater) -> T_PermissionUpdater:
"""
:说明:
装饰一个函数来更改当前事件响应器的默认会话权限更新函数
:参数:
* ``func: T_PermissionUpdater``: 会话权限更新函数
"""
cls._default_permission_updater = func
return func
@staticmethod @staticmethod
def process_handler(handler: T_Handler) -> T_Handler: def process_handler(handler: T_Handler) -> T_Handler:
signature = inspect.signature(handler, follow_wrapped=False) signature = inspect.signature(handler, follow_wrapped=False)
@ -548,31 +587,49 @@ class Matcher(metaclass=MatcherMeta):
except RejectedException: except RejectedException:
self.handlers.insert(0, handler) # type: ignore self.handlers.insert(0, handler) # type: ignore
Matcher.new( if self._default_type_updater:
"message", type_ = await self._default_type_updater(
bot, event, state, self.type)
else:
type_ = "message"
if self._default_permission_updater:
permission = await self._default_permission_updater(
bot, event, state, self.permission)
else:
permission = USER(event.get_session_id(), perm=self.permission)
Matcher.new(type_,
Rule(), Rule(),
USER(event.get_session_id(), permission,
perm=self.permission), # type:ignore
self.handlers, self.handlers,
temp=True, temp=True,
priority=0, priority=0,
block=True, block=True,
module=self.module, module=self.module,
default_state=self.state, default_state=self.state,
expire_time=datetime.now() + bot.config.session_expire_timeout) expire_time=datetime.now() +
bot.config.session_expire_timeout)
except PausedException: except PausedException:
Matcher.new( if self._default_type_updater:
"message", type_ = await self._default_type_updater(
bot, event, state, self.type)
else:
type_ = "message"
if self._default_permission_updater:
permission = await self._default_permission_updater(
bot, event, state, self.permission)
else:
permission = USER(event.get_session_id(), perm=self.permission)
Matcher.new(type_,
Rule(), Rule(),
USER(event.get_session_id(), permission,
perm=self.permission), # type:ignore
self.handlers, self.handlers,
temp=True, temp=True,
priority=0, priority=0,
block=True, block=True,
module=self.module, module=self.module,
default_state=self.state, default_state=self.state,
expire_time=datetime.now() + bot.config.session_expire_timeout) expire_time=datetime.now() +
bot.config.session_expire_timeout)
except FinishedException: except FinishedException:
pass pass
except StopPropagation: except StopPropagation:

View File

@ -21,8 +21,9 @@ from collections.abc import Callable as BaseCallable
from typing import Any, Dict, Union, TypeVar, Optional, Callable, NoReturn, Awaitable, TYPE_CHECKING from typing import Any, Dict, Union, TypeVar, Optional, Callable, NoReturn, Awaitable, TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from nonebot.adapters import Bot, Event
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from nonebot.adapters import Bot, Event
from nonebot.permission import Permission
T_Wrapped = TypeVar("T_Wrapped", bound=BaseCallable) T_Wrapped = TypeVar("T_Wrapped", bound=BaseCallable)
@ -152,3 +153,20 @@ T_ArgsParser = Callable[["Bot", "Event", T_State], Union[Awaitable[None],
ArgsParser 即消息参数解析函数 Matcher.got 获取参数时被运行 ArgsParser 即消息参数解析函数 Matcher.got 获取参数时被运行
""" """
T_TypeUpdater = Callable[["Bot", "Event", T_State, str], Awaitable[str]]
"""
:类型: ``Callable[[Bot, Event, T_State, str], Awaitable[str]]``
:说明:
TypeUpdater Matcher.pause, Matcher.reject 时被运行用于更新响应的事件类型默认会更新为 ``message``
"""
T_PermissionUpdater = Callable[["Bot", "Event", T_State, "Permission"],
Awaitable["Permission"]]
"""
:类型: ``Callable[[Bot, Event, T_State, Permission], Awaitable[Permission]]``
:说明:
PermissionUpdater Matcher.pause, Matcher.reject 时被运行用于更新会话对象权限默认会更新为当前事件的触发对象
"""

View File

@ -9,6 +9,8 @@ sidebar: auto
- 修改 `nonebot` 项目结构,分离所有 `adapter` - 修改 `nonebot` 项目结构,分离所有 `adapter`
- 修改插件加载逻辑,使用 `import hook` (PEP 302) - 修改插件加载逻辑,使用 `import hook` (PEP 302)
- 适配 `pydantic` ~1.8 - 适配 `pydantic` ~1.8
- 移除 4 种内置事件类型限制,允许自定义事件类型
- 新增会话权限更新自定义,会话中断时更新权限以做到多人会话
## v2.0.0a10 ## v2.0.0a10