Skip to content

Commit

Permalink
❇️ new builtin plugin: help & inspect
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed Dec 4, 2024
1 parent 15c0cf8 commit 326611a
Show file tree
Hide file tree
Showing 16 changed files with 589 additions and 2 deletions.
191 changes: 191 additions & 0 deletions arclet/entari/builtins/help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import random
from typing import Optional

from arclet.alconna import (
Alconna,
Args,
Arparma,
CommandMeta,
Field,
Option,
Subcommand,
SubcommandResult,
command_manager,
namespace,
store_true,
)
from tarina import lang

from arclet.entari import Session, command, metadata, plugin_config

config = plugin_config()
help_text: str = config.get("help_text", "help")
help_alias: list[str] = config.get("help_alias", ["帮助", "命令帮助"])
help_all_alias: list[str] = config.get("help_all_alias", ["所有帮助", "所有命令帮助"])
page_size: Optional[int] = config.get("page_size", None)

metadata(
"help",
["RF-Tar-Railt <[email protected]>"],
description="展示所有命令帮助",
)


with namespace("builtin/help") as ns:
ns.disable_builtin_options = {"shortcut"}

help_cmd = Alconna(
help_text,
Args[
"query#选择某条命令的id或者名称查看具体帮助;/?",
str,
Field(
"-1",
completion=lambda: f"试试 {random.randint(0, len(command_manager.get_commands()))}",
unmatch_tips=lambda x: f"预期输入为某个命令的id或者名称,而不是 {x}\n例如:/帮助 0",
),
],
Option(
"--page",
Args["index", int],
help_text="查看指定页数的命令帮助",
),
Subcommand(
"--namespace",
Args["target?;#指定的命名空间", str],
Option("--list", help_text="列出所有命名空间", action=store_true, default=False),
alias=["-N", "命名空间"],
help_text="是否列出命令所属命名空间",
),
Option("--hide", alias=["-H", "隐藏"], help_text="是否列出隐藏命令", action=store_true, default=False),
meta=CommandMeta(
description="显示所有命令帮助",
usage="可以使用 --hide 参数来显示隐藏命令,使用 -P 参数来显示命令所属插件名称",
example=f"${help_text} 1",
),
)

for alias in set(help_alias):
help_cmd.shortcut(alias, {"prefix": True, "fuzzy": False})
for alias in set(help_all_alias):
help_cmd.shortcut(alias, {"args": ["--hide"], "prefix": True, "fuzzy": False})


def help_cmd_handle(arp: Arparma, interactive: bool = False):
is_namespace = arp.query[SubcommandResult]("namespace")
page = arp.query[int]("page.index", 1)
target_namespace = is_namespace.args.get("target") if is_namespace else None
cmds = [
i
for i in command_manager.get_commands(target_namespace or "")
if not i.meta.hide or arp.query[bool]("hide.value", False)
]
if is_namespace and is_namespace.options["list"].value and not target_namespace:
namespaces = {i.namespace: 0 for i in cmds}
return "\n".join(
f" 【{str(index).rjust(len(str(len(namespaces))), '0')}{n}" for index, n in enumerate(namespaces.keys())
)

help_names = set()
for i in cmds:
help_names.update(i.namespace_config.builtin_option_name["help"])

footer = lang.require("manager", "help_footer").format(help="|".join(sorted(help_names, key=lambda x: len(x))))
show_namespace = is_namespace and not is_namespace.options["list"].value and not target_namespace
if (query := arp.all_matched_args["query"]) != "-1":
if query.isdigit():
index = int(query)
if index < 0 or index >= len(cmds):
return "查询失败!"
slot = cmds[index]
elif not (slot := next((i for i in cmds if query == i.command), None)):
command_string = "\n".join(
(
f"【{str(index).rjust(len(str(len(cmds))), '0')}】"
f"{f'{slot.namespace}::' if show_namespace else ''}{slot.header_display} : "
f"{slot.meta.description}"
)
for index, slot in enumerate(cmds)
if query in str(slot.command)
)
if not command_string:
return "查询失败!"
return f"{command_string}\n{footer}"
return slot.get_help()

if not page_size:
header = lang.require("manager", "help_header")
command_string = "\n".join(
(
f" 【{str(index).rjust(len(str(len(cmds))), '0')}】"
f"{f'{slot.namespace}::' if show_namespace else ''}{slot.header_display} : "
f"{slot.meta.description}"
)
for index, slot in enumerate(cmds)
)
return f"{header}\n{command_string}\n{footer}"

max_page = len(cmds) // page_size + 1
if page < 1 or page > max_page:
page = 1
max_length = page_size
if interactive:
footer += "\n" + "输入 '<', 'a' 或 '>', 'd' 来翻页"

def _(_page: int):
header = (
lang.require("manager", "help_header")
+ "\t"
+ lang.require("manager", "help_pages").format(current=_page, total=max_page)
)
command_string = "\n".join(
(
f" 【{str(index).rjust(len(str(_page * max_length)), '0')}】"
f"{f'{slot.namespace}::' if show_namespace else ''}{slot.header_display} : "
f"{slot.meta.description}"
)
for index, slot in enumerate(
cmds[(_page - 1) * max_length : _page * max_length], start=(_page - 1) * max_length
)
)
return f"{header}\n{command_string}\n{footer}"

if not interactive:
return _(page)

def generator(_page: int):
while True:
resp = yield _(_page)
if resp == "a" or resp == "<":
_page -= 1
if _page < 1:
_page = max_page
elif resp == "d" or resp == ">":
_page += 1
if _page > max_page:
_page = 1
else:
return

return generator(page)


disp = command.mount(help_cmd)


@disp.on_execute()
async def _(arp: Arparma):
return help_cmd_handle(arp)


@disp.handle()
async def _(arp: Arparma, session: Session):
resp = help_cmd_handle(arp, True)
if isinstance(resp, str):
return await session.send(resp)
msg = await session.prompt(next(resp), timeout=15)
while msg:
try:
msg = await session.prompt(resp.send(msg.extract_plain_text().strip().lower()), timeout=15)
except StopIteration:
return
56 changes: 56 additions & 0 deletions arclet/entari/builtins/inspect/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from arclet.alconna import Alconna, Args, CommandMeta
from satori.element import At, Author, Sharp, select

from arclet.entari import MessageEvent, Session, command, metadata
from arclet.entari.command.model import Match

from .i18n import Lang

metadata(
"inspect",
["RF-Tar-Railt <[email protected]>"],
description="Inspect on any user, group or channel",
)

cmd = command.mount(
Alconna(
"inspect",
Args["target?", [At, Sharp]],
meta=CommandMeta(Lang.entari_plugin_inspect.description(), example="inspect @user\ninspect #channel\ninspect"),
)
)


SceneNames = {
"DIRECT": Lang.entari_plugin_inspect.scene.direct,
"TEXT": Lang.entari_plugin_inspect.scene.text,
"VOICE": Lang.entari_plugin_inspect.scene.voice,
"CATEGORY": Lang.entari_plugin_inspect.scene.category,
}


@cmd.handle()
async def inspect(session: Session[MessageEvent], target: Match["At | Sharp"]):
event = session.context
texts = [
Lang.entari_plugin_inspect.platform(platform=session.account.platform),
Lang.entari_plugin_inspect.self(self_id=session.account.self_id),
Lang.entari_plugin_inspect.scene.name(scene=SceneNames[session.channel.type.name]()),
Lang.entari_plugin_inspect.guild(guild_id=event.guild.id if event.guild else None),
Lang.entari_plugin_inspect.channel(channel_id=session.channel.id),
]
if event.quote and (authors := select(event.quote, Author)):
texts.append(Lang.entari_plugin_inspect.user(user_id=authors[0].id))
await session.send_message("\n".join(texts))
return
if target.available:
if isinstance(target.result, At) and target.result.id:
await session.send_message(Lang.entari_plugin_inspect.user(user_id=target.result.id))
elif isinstance(target.result, Sharp) and target.result.id:
await session.send_message(Lang.entari_plugin_inspect.channel(channel_id=target.result.id))
else:
await session.send_message(Lang.entari_plugin_inspect.invalid())
return
texts.append(Lang.entari_plugin_inspect.user(user_id=session.user.id))
await session.send_message("\n".join(texts))
return
6 changes: 6 additions & 0 deletions arclet/entari/builtins/inspect/i18n/.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"default": "zh-CN",
"frozen": [],
"require": [],
"name": "entari::plugin_inspect"
}
83 changes: 83 additions & 0 deletions arclet/entari/builtins/inspect/i18n/.lang.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"title": "Lang Schema",
"description": "Schema for lang file",
"type": "object",
"properties": {
"entari::plugin_inspect": {
"title": "Entari::plugin_inspect",
"description": "Scope 'entari::plugin_inspect' of lang item",
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"title": "description",
"description": "value of lang item type 'description'",
"type": "string"
},
"platform": {
"title": "platform",
"description": "value of lang item type 'platform'",
"type": "string"
},
"self": {
"title": "self",
"description": "value of lang item type 'self'",
"type": "string"
},
"scene": {
"title": "Scene",
"description": "Scope 'scene' of lang item",
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"title": "name",
"description": "value of lang item type 'name'",
"type": "string"
},
"direct": {
"title": "direct",
"description": "value of lang item type 'direct'",
"type": "string"
},
"text": {
"title": "text",
"description": "value of lang item type 'text'",
"type": "string"
},
"voice": {
"title": "voice",
"description": "value of lang item type 'voice'",
"type": "string"
},
"category": {
"title": "category",
"description": "value of lang item type 'category'",
"type": "string"
}
}
},
"user": {
"title": "user",
"description": "value of lang item type 'user'",
"type": "string"
},
"channel": {
"title": "channel",
"description": "value of lang item type 'channel'",
"type": "string"
},
"guild": {
"title": "guild",
"description": "value of lang item type 'guild'",
"type": "string"
},
"invalid": {
"title": "invalid",
"description": "value of lang item type 'invalid'",
"type": "string"
}
}
}
}
}
27 changes: 27 additions & 0 deletions arclet/entari/builtins/inspect/i18n/.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"$schema": ".template.schema.json",
"scopes": [
{
"scope": "entari::plugin_inspect",
"types": [
"description",
"platform",
"self",
{
"subtype": "scene",
"types": [
"name",
"direct",
"text",
"voice",
"category"
]
},
"user",
"channel",
"guild",
"invalid"
]
}
]
}
Loading

0 comments on commit 326611a

Please sign in to comment.