add matcher group for plugin #90

This commit is contained in:
yanyongyu
2020-12-04 01:41:23 +08:00
parent b24649b6af
commit 5b42454a55
5 changed files with 910 additions and 245 deletions

View File

@ -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"<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: 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