Skip to content

Commit

Permalink
✨ several event for command
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed Jan 28, 2025
1 parent 9b113f1 commit 63fda21
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 17 deletions.
49 changes: 41 additions & 8 deletions arclet/entari/command/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@

from arclet.alconna import Alconna, Arparma, Duplication, Empty, output_manager
from arclet.alconna.builtin import generate_duplication
from arclet.letoderea import STOP, Contexts, Param, Propagator, Provider
from arclet.alconna.exceptions import SpecialOptionTriggered
from arclet.letoderea import STOP, Contexts, Param, Propagator, Provider, post
from arclet.letoderea.exceptions import ProviderUnsatisfied
from arclet.letoderea.provider import ProviderFactory
from nepattern.util import CUnionType
from satori.element import Text
from tarina.generic import get_origin

from ..config import EntariConfig
from ..event.base import Reply
from ..event.command import CommandOutput, CommandParse, CommandReceive
from ..message import MessageChain
from ..session import Session
from .model import CommandResult, Match, Query
Expand Down Expand Up @@ -58,25 +61,55 @@ class AlconnaSuppiler(Propagator):
def __init__(self, cmd: Alconna):
self.cmd = cmd

async def supply(self, message: MessageChain, session: Optional[Session] = None):
async def before_supply(
self, message: MessageChain, session: Optional[Session] = None, reply: Optional[Reply] = None
):
if session and (recv := await post(CommandReceive(session, self.cmd, message, reply))):
message = recv.value.copy()
return {"_message": message}

async def supply(self, ctx: Contexts):
_message: MessageChain = ctx.pop("_message")
with output_manager.capture(self.cmd.name) as cap:
output_manager.set_action(lambda x: x, self.cmd.name)
try:
_res = self.cmd.parse(message)
_res = self.cmd.parse(_message)
except Exception as e:
_res = Arparma(self.cmd._hash, message, False, error_info=e)
_res = Arparma(self.cmd._hash, _message, False, error_info=e)
may_help_text: Optional[str] = cap.get("output", None)
return {"_result": CommandResult(self.cmd, _res, may_help_text)}

async def after_supply(self, ctx: Contexts, session: Optional[Session] = None):
alc_result: CommandResult = ctx.pop("_result")
_res = alc_result.result
if session and (pres := await post(CommandParse(session, self.cmd, _res))):
if isinstance(pres.value, Arparma):
_res = pres.value
elif not pres.value:
return STOP
if _res.matched:
return {"alc_result": CommandResult(self.cmd, _res, may_help_text)}
if may_help_text:
return {"alc_result": CommandResult(self.cmd, _res, alc_result.output)}
if alc_result.output:
if session:
await session.send(MessageChain(may_help_text))
_t = str(_res.error_info) if isinstance(_res.error_info, SpecialOptionTriggered) else "error"
if ores := await post(CommandOutput(session, self.cmd, _t, alc_result.output)):
if not ores.value:
return STOP
elif ores.value is True:
msg = MessageChain(alc_result.output)
else:
msg = MessageChain(ores.value)
else:
msg = MessageChain(alc_result.output)
await session.send(msg)
return STOP
return {"alc_result": CommandResult(self.cmd, _res, may_help_text)}
return {"alc_result": alc_result}
return STOP

def compose(self):
yield self.before_supply, True, 65
yield self.supply, True, 70
yield self.after_supply, True, 75


class AlconnaProvider(Provider[Any]):
Expand Down
43 changes: 42 additions & 1 deletion arclet/entari/event/command.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from dataclasses import dataclass
from typing import Union
from typing import Optional, Union

from arclet.alconna import Alconna, Arparma
from arclet.letoderea import Contexts, Provider, make_event

from ..message import MessageChain
from ..session import Session
from .base import Reply


@dataclass
Expand All @@ -22,3 +25,41 @@ async def __call__(self, context: Contexts):
return context.get("command")

__result_type__: "type[str | MessageChain]" = Union[str, MessageChain]


@dataclass
@make_event(name="entari.event/command/output")
class CommandOutput:
"""依据输出信息的类型,将字符串转换为消息对象以便发送。"""

session: Session
command: Alconna
type: str
content: str

__result_type__: "type[bool | str | MessageChain]" = Union[bool, str, MessageChain]


@dataclass
@make_event(name="entari.event/command/before_parse")
class CommandReceive:
"""尝试解析命令时调用"""

session: Session
command: Alconna
content: MessageChain
reply: Optional[Reply] = None

__result_type__: "type[MessageChain]" = MessageChain


@dataclass
@make_event(name="entari.event/command/after_parse")
class CommandParse:
"""解析完命令后调用"""

session: Session
command: Alconna
result: Arparma

__result_type__: "type[Arparma | bool]" = Union[Arparma, bool]
17 changes: 12 additions & 5 deletions arclet/entari/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ async def message_create(
if source:
sess = Session(self.account, source)
sess.elements = msg
res = await es.post(SendRequest(self.account, channel_id, msg, sess))
if res and res.value:
value = res.value
if value is True:
if res := await es.post(SendRequest(self.account, channel_id, msg, sess)):
if not res.value:
return []
msg = value
elif res.value is True:
pass
else:
msg = res.value
send = str(msg)
res = await self.call_api(
Api.MESSAGE_CREATE,
Expand Down Expand Up @@ -140,6 +141,12 @@ async def waiter(content: MessageChain, session: Session[MessageEvent]):
def stop(self) -> NoReturn:
raise HandlerStop()

@property
def quote(self):
if isinstance(self.event, MessageEvent):
return self.event.quote
return None

@property
def user(self) -> User:
if not self.event.user:
Expand Down
6 changes: 3 additions & 3 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 63fda21

Please sign in to comment.