add some matcher function like nb1 session

This commit is contained in:
yanyongyu 2020-08-18 11:28:33 +08:00
parent 6435e29e8b
commit 76cfe34fa5
2 changed files with 57 additions and 45 deletions

View File

@ -7,9 +7,9 @@ from datetime import datetime
from collections import defaultdict from collections import defaultdict
from nonebot.rule import Rule from nonebot.rule import Rule
from nonebot.permission import Permission, EVERYBODY, USER from nonebot.permission import Permission, USER
from nonebot.typing import Bot, Event, Handler from nonebot.typing import Bot, Event, Handler, ArgsParser
from nonebot.typing import Type, List, Dict, Optional, NoReturn from nonebot.typing import Type, List, Dict, Callable, Optional, NoReturn
from nonebot.exception import PausedException, RejectedException, FinishedException from nonebot.exception import PausedException, RejectedException, FinishedException
matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list) matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list)
@ -28,15 +28,13 @@ class Matcher:
_default_state: dict = {} _default_state: dict = {}
# _default_parser: Optional[Callable[[Event, dict], None]] = None _default_parser: Optional[ArgsParser] = None
# _args_parser: Optional[Callable[[Event, dict], None]] = None
def __init__(self): def __init__(self):
"""实例化 Matcher 以便运行 """实例化 Matcher 以便运行
""" """
self.handlers = self.handlers.copy() self.handlers = self.handlers.copy()
self.state = self._default_state.copy() self.state = self._default_state.copy()
# self.parser = self._args_parser or self._default_parser
@classmethod @classmethod
def new(cls, def new(cls,
@ -85,13 +83,13 @@ class Matcher:
""" """
return await cls.rule(bot, event, state) return await cls.rule(bot, event, state)
# @classmethod @classmethod
# def args_parser(cls, func: Callable[[Event, dict], None]): def args_parser(cls, func: ArgsParser) -> ArgsParser:
# cls._default_parser = func cls._default_parser = func
# return func return func
@classmethod @classmethod
def handle(cls): def handle(cls) -> Callable[[Handler], Handler]:
"""直接处理消息事件""" """直接处理消息事件"""
def _decorator(func: Handler) -> Handler: def _decorator(func: Handler) -> Handler:
@ -101,7 +99,7 @@ class Matcher:
return _decorator return _decorator
@classmethod @classmethod
def receive(cls): def receive(cls) -> Callable[[Handler], Handler]:
"""接收一条新消息并处理""" """接收一条新消息并处理"""
def _decorator(func: Handler) -> Handler: def _decorator(func: Handler) -> Handler:
@ -109,6 +107,8 @@ class Matcher:
async def _handler(bot: Bot, event: Event, state: dict) -> NoReturn: async def _handler(bot: Bot, event: Event, state: dict) -> NoReturn:
raise PausedException raise PausedException
if cls.handlers:
# 已有前置handlers则接受一条新的消息否则视为接收初始消息
cls.handlers.append(_handler) cls.handlers.append(_handler)
cls.handlers.append(func) cls.handlers.append(func)
@ -116,47 +116,56 @@ class Matcher:
return _decorator return _decorator
# @classmethod @classmethod
# def got(cls, def got(
# key: str, cls,
# prompt: Optional[str] = None, key: str,
# args_parser: Optional[Callable[[Event, dict], None]] = None): prompt: Optional[str] = None,
args_parser: Optional[ArgsParser] = None
) -> Callable[[Handler], Handler]:
# def _decorator(func: Handler) -> Handler: def _decorator(func: Handler) -> Handler:
# @wraps(func) async def _key_getter(bot: Bot, event: Event, state: dict):
# def _handler(event: Event, state: dict): if key not in state:
# if key not in state: state["_current_key"] = key
# if state.get("__current_arg__", None) == key: if prompt:
# state[key] = event.message await bot.send_private_msg(user_id=event.user_id,
# del state["__current_arg__"] message=prompt)
# return func(event, state) raise PausedException
# state["__current_arg__"] = key
# cls._args_parser = args_parser
# raise RejectedException
# return func(event, state) async def _key_parser(bot: Bot, event: Event, state: dict):
parser = args_parser or cls._default_parser
if parser:
await parser(bot, event, state)
else:
state[state["_current_key"]] = str(event.message)
# cls.handlers.append(_handler) if cls.handlers:
# 已有前置handlers则接受一条新的消息否则视为接收初始消息
cls.handlers.append(_key_getter)
cls.handlers.append(_key_parser)
cls.handlers.append(func)
# return func return func
# return _decorator return _decorator
# @classmethod @classmethod
# def finish(cls, prompt: Optional[str] = None): def finish(cls) -> NoReturn:
# raise FinishedException raise FinishedException
# @classmethod @classmethod
# def reject(cls, prompt: Optional[str] = None): def pause(cls) -> NoReturn:
# raise RejectedException raise PausedException
@classmethod
def reject(cls) -> NoReturn:
raise RejectedException
# 运行handlers # 运行handlers
async def run(self, bot: Bot, event: Event, state): async def run(self, bot: Bot, event: Event, state: dict):
try: try:
# if self.parser:
# await self.parser(event, state) # type: ignore
# Refresh preprocess state # Refresh preprocess state
self.state.update(state) self.state.update(state)
@ -167,6 +176,7 @@ class Matcher:
if BotType and not isinstance(bot, BotType): if BotType and not isinstance(bot, BotType):
continue continue
await handler(bot, event, self.state) await handler(bot, event, self.state)
except RejectedException: except RejectedException:
self.handlers.insert(0, handler) # type: ignore self.handlers.insert(0, handler) # type: ignore
matcher = Matcher.new( matcher = Matcher.new(

View File

@ -37,9 +37,11 @@ PreProcessor = Callable[[Bot, Event, dict], Union[Awaitable[None],
Awaitable[NoReturn]]] Awaitable[NoReturn]]]
Matcher = TypeVar("Matcher", bound="MatcherClass") Matcher = TypeVar("Matcher", bound="MatcherClass")
Handler = Callable[[Bot, Event, Dict[Any, Any]], Union[Awaitable[None], Handler = Callable[[Bot, Event, dict], Union[Awaitable[None],
Awaitable[NoReturn]]] Awaitable[NoReturn]]]
Rule = TypeVar("Rule", bound="RuleClass") Rule = TypeVar("Rule", bound="RuleClass")
RuleChecker = Callable[[Bot, Event, dict], Awaitable[bool]] RuleChecker = Callable[[Bot, Event, dict], Awaitable[bool]]
Permission = TypeVar("Permission", bound="PermissionClass") Permission = TypeVar("Permission", bound="PermissionClass")
PermissionChecker = Callable[[Bot, Event], Awaitable[bool]] PermissionChecker = Callable[[Bot, Event], Awaitable[bool]]
ArgsParser = Callable[[Bot, Event, dict], Union[Awaitable[None],
Awaitable[NoReturn]]]