mirror of
https://github.com/nonebot/nonebot2.git
synced 2024-11-24 00:55:07 +08:00
⚗️ add matcher group #11
This commit is contained in:
parent
2e87c40434
commit
ecbe465232
@ -278,3 +278,172 @@ class Matcher(metaclass=MatcherMeta):
|
||||
logger.info(f"Matcher {self} running complete")
|
||||
current_bot.reset(b_t)
|
||||
current_event.reset(e_t)
|
||||
|
||||
|
||||
class MatcherGroup:
|
||||
|
||||
def __init__(self,
|
||||
type_: str = "",
|
||||
rule: Rule = Rule(),
|
||||
permission: Permission = Permission(),
|
||||
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):
|
||||
self.matchers: List[Type[Matcher]] = []
|
||||
|
||||
self.type = type_
|
||||
self.rule = rule
|
||||
self.permission = permission
|
||||
self.handlers = handlers
|
||||
self.temp = temp
|
||||
self.priority = priority
|
||||
self.block = block
|
||||
self.module = module
|
||||
self.default_state = default_state
|
||||
self.expire_time = expire_time
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f"<MatcherGroup from {self.module or 'unknow'}, type={self.type}, "
|
||||
f"priority={self.priority}, temp={self.temp}>")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.__repr__()
|
||||
|
||||
def new(self,
|
||||
type_: str = "",
|
||||
rule: Rule = Rule(),
|
||||
permission: Permission = Permission(),
|
||||
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]:
|
||||
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:
|
||||
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=prompt)
|
||||
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 finish(
|
||||
self,
|
||||
prompt: Optional[Union[str, Message,
|
||||
MessageSegment]] = None) -> NoReturn:
|
||||
bot: Bot = current_bot.get()
|
||||
event: Event = current_event.get()
|
||||
if prompt:
|
||||
await bot.send(event=event, message=prompt)
|
||||
raise FinishedException
|
||||
|
||||
async def pause(
|
||||
self,
|
||||
prompt: Optional[Union[str, Message,
|
||||
MessageSegment]] = None) -> NoReturn:
|
||||
bot: Bot = current_bot.get()
|
||||
event: Event = current_event.get()
|
||||
if prompt:
|
||||
await bot.send(event=event, message=prompt)
|
||||
raise PausedException
|
||||
|
||||
async def reject(
|
||||
self,
|
||||
prompt: Optional[Union[str, Message,
|
||||
MessageSegment]] = None) -> NoReturn:
|
||||
bot: Bot = current_bot.get()
|
||||
event: Event = current_event.get()
|
||||
if prompt:
|
||||
await bot.send(event=event, message=prompt)
|
||||
raise RejectedException
|
||||
|
Loading…
Reference in New Issue
Block a user