Skip to content

Commit

Permalink
Merge pull request #673 from RockChinQ/refactor/asyncio/control-flow
Browse files Browse the repository at this point in the history
Refactor: 请求处理控制流
  • Loading branch information
RockChinQ authored Jan 28, 2024
2 parents a064c24 + d130c37 commit 2b0faea
Show file tree
Hide file tree
Showing 134 changed files with 2,828 additions and 3,268 deletions.
58 changes: 0 additions & 58 deletions .github/workflows/update-cmdpriv-template.yml

This file was deleted.

38 changes: 0 additions & 38 deletions pkg/boot/app.py

This file was deleted.

54 changes: 0 additions & 54 deletions pkg/boot/log.py

This file was deleted.

File renamed without changes.
108 changes: 108 additions & 0 deletions pkg/command/cmdmgr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from __future__ import annotations

import typing

from ..core import app, entities as core_entities
from ..openai import entities as llm_entities
from ..openai.session import entities as session_entities
from . import entities, operator, errors

from .operators import func, plugin, default, reset, list as list_cmd, last, next, delc, resend, prompt, cfg, cmd, help, version, update


class CommandManager:
"""命令管理器
"""

ap: app.Application

cmd_list: list[operator.CommandOperator]

def __init__(self, ap: app.Application):
self.ap = ap

async def initialize(self):
# 实例化所有类
self.cmd_list = [cls(self.ap) for cls in operator.preregistered_operators]

# 设置所有类的子节点
for cmd in self.cmd_list:
cmd.children = [child for child in self.cmd_list if child.parent_class == cmd.__class__]

# 初始化所有类
for cmd in self.cmd_list:
await cmd.initialize()

async def _execute(
self,
context: entities.ExecuteContext,
operator_list: list[operator.CommandOperator],
operator: operator.CommandOperator = None
) -> typing.AsyncGenerator[entities.CommandReturn, None]:
"""执行命令
"""

found = False
if len(context.crt_params) > 0:
for oper in operator_list:
if (context.crt_params[0] == oper.name \
or context.crt_params[0] in oper.alias) \
and (oper.parent_class is None or oper.parent_class == operator.__class__):
found = True

context.crt_command = context.crt_params[0]
context.crt_params = context.crt_params[1:]

async for ret in self._execute(
context,
oper.children,
oper
):
yield ret
break

if not found:
if operator is None:
yield entities.CommandReturn(
error=errors.CommandNotFoundError(context.crt_params[0])
)
else:
if operator.lowest_privilege > context.privilege:
yield entities.CommandReturn(
error=errors.CommandPrivilegeError(operator.name)
)
else:
async for ret in operator.execute(context):
yield ret


async def execute(
self,
command_text: str,
query: core_entities.Query,
session: session_entities.Session
) -> typing.AsyncGenerator[entities.CommandReturn, None]:
"""执行命令
"""

privilege = 1
if query.sender_id == self.ap.cfg_mgr.data['admin_qq'] \
or query.sender_id in self.ap.cfg_mgr['admin_qq']:
privilege = 2

ctx = entities.ExecuteContext(
query=query,
session=session,
command_text=command_text,
command='',
crt_command='',
params=command_text.split(' '),
crt_params=command_text.split(' '),
privilege=privilege
)

async for ret in self._execute(
ctx,
self.cmd_list
):
yield ret
43 changes: 43 additions & 0 deletions pkg/command/entities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

import typing

import pydantic
import mirai

from ..core import app, entities as core_entities
from ..openai.session import entities as session_entities
from . import errors, operator


class CommandReturn(pydantic.BaseModel):

text: typing.Optional[str]
"""文本
"""

image: typing.Optional[mirai.Image]

error: typing.Optional[errors.CommandError]= None

class Config:
arbitrary_types_allowed = True


class ExecuteContext(pydantic.BaseModel):

query: core_entities.Query

session: session_entities.Session

command_text: str

command: str

crt_command: str

params: list[str]

crt_params: list[str]

privilege: int
33 changes: 33 additions & 0 deletions pkg/command/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@


class CommandError(Exception):

def __init__(self, message: str = None):
self.message = message

def __str__(self):
return self.message


class CommandNotFoundError(CommandError):

def __init__(self, message: str = None):
super().__init__("未知命令: "+message)


class CommandPrivilegeError(CommandError):

def __init__(self, message: str = None):
super().__init__("权限不足: "+message)


class ParamNotEnoughError(CommandError):

def __init__(self, message: str = None):
super().__init__("参数不足: "+message)


class CommandOperationError(CommandError):

def __init__(self, message: str = None):
super().__init__("操作失败: "+message)
Loading

0 comments on commit 2b0faea

Please sign in to comment.