QChatGPT/pkg/command/operator.py

114 lines
3.7 KiB
Python
Raw Normal View History

2024-01-28 00:16:42 +08:00
from __future__ import annotations
import typing
import abc
from ..core import app, entities as core_entities
from . import entities
preregistered_operators: list[typing.Type[CommandOperator]] = []
2024-03-08 19:56:57 +08:00
"""预注册命令算子列表。在初始化时,所有算子类会被注册到此列表中。"""
2024-01-28 00:16:42 +08:00
def operator_class(
name: str,
2024-03-08 19:56:57 +08:00
help: str = "",
2024-01-28 18:21:43 +08:00
usage: str = None,
alias: list[str] = [],
2024-01-28 00:16:42 +08:00
privilege: int=1, # 1为普通用户2为管理员
parent_class: typing.Type[CommandOperator] = None
) -> typing.Callable[[typing.Type[CommandOperator]], typing.Type[CommandOperator]]:
2024-03-08 19:56:57 +08:00
"""命令类装饰器
Args:
name (str): 名称
help (str, optional): 帮助信息. Defaults to "".
usage (str, optional): 使用说明. Defaults to None.
alias (list[str], optional): 别名. Defaults to [].
privilege (int, optional): 权限1为普通用户可用2为仅管理员可用. Defaults to 1.
parent_class (typing.Type[CommandOperator], optional): 父节点若为None则为顶级命令. Defaults to None.
Returns:
2024-03-08 20:22:06 +08:00
typing.Callable[[typing.Type[CommandOperator]], typing.Type[CommandOperator]]: 装饰器
2024-03-08 19:56:57 +08:00
"""
2024-01-28 00:16:42 +08:00
def decorator(cls: typing.Type[CommandOperator]) -> typing.Type[CommandOperator]:
2024-03-08 19:38:26 +08:00
assert issubclass(cls, CommandOperator)
2024-01-28 00:16:42 +08:00
cls.name = name
cls.alias = alias
cls.help = help
2024-01-28 18:21:43 +08:00
cls.usage = usage
2024-01-28 00:16:42 +08:00
cls.parent_class = parent_class
2024-02-06 21:26:03 +08:00
cls.lowest_privilege = privilege
2024-01-28 00:16:42 +08:00
preregistered_operators.append(cls)
return cls
return decorator
class CommandOperator(metaclass=abc.ABCMeta):
2024-03-03 16:34:59 +08:00
"""命令算子抽象类
2024-03-22 16:41:46 +08:00
以下的参数均不需要在子类中设置只需要在使用装饰器注册类时作为参数传递即可
命令支持级联即一个命令可以有多个子命令子命令可以有子命令以此类推
处理命令时若有子命令会以当前参数列表的第一个参数去匹配子命令若匹配成功则转移到子命令中执行
若没有匹配成功或没有子命令则执行当前命令
2024-01-28 00:16:42 +08:00
"""
ap: app.Application
name: str
"""名称,搜索到时若符合则使用"""
2024-02-06 23:57:21 +08:00
path: str
2024-03-22 16:41:46 +08:00
"""路径所有父节点的name的连接用于定义命令权限由管理器在初始化时自动设置。
"""
2024-02-06 23:57:21 +08:00
2024-01-28 00:16:42 +08:00
alias: list[str]
"""同name"""
help: str
"""此节点的帮助信息"""
2024-01-28 18:21:43 +08:00
usage: str = None
2024-03-22 16:41:46 +08:00
"""用法"""
2024-01-28 18:21:43 +08:00
2024-02-20 11:47:04 +08:00
parent_class: typing.Union[typing.Type[CommandOperator], None] = None
2024-01-28 00:16:42 +08:00
"""父节点类。标记以供管理器在初始化时编织父子关系。"""
lowest_privilege: int = 0
"""最低权限。若权限低于此值,则不予执行。"""
children: list[CommandOperator]
"""子节点。解析命令时,若节点有子节点,则以下一个参数去匹配子节点,
若有匹配中的转移到子节点中执行若没有匹配中的或没有子节点执行此节点"""
def __init__(self, ap: app.Application):
self.ap = ap
self.children = []
async def initialize(self):
pass
@abc.abstractmethod
async def execute(
self,
context: entities.ExecuteContext
) -> typing.AsyncGenerator[entities.CommandReturn, None]:
2024-03-22 16:41:46 +08:00
"""实现此方法以执行命令
支持多次yield以返回多个结果
例如一个安装插件的命令可能会有下载解压安装等多个步骤每个步骤都可以返回一个结果
Args:
context (entities.ExecuteContext): 命令执行上下文
Yields:
entities.CommandReturn: 命令返回封装
"""
2024-01-28 00:16:42 +08:00
pass