GraiaProject / Ariadne

一个优雅且完备的 Python QQ 自动化框架,基于 Mirai API HTTP v2。 Powered by Graia Project.
https://graia.cn/ariadne
GNU Affero General Public License v3.0
741 stars 45 forks source link

[Feature] 通用的 help 解决方案 #192

Open djkcyl opened 2 years ago

djkcyl commented 2 years ago

使用场景

通过一个统一的方式注册help菜单,然后通过特定的格式输出

你想要的解决方案

例如使用类似:

@help.register("name1")
@channel.use(
    ListenerSchema(
        listening_events=[FriendMessage],
        inline_dispatchers=[
            Twilight(
                [FullMatch("添加管理员"), "adminid" @ WildcardMatch(optional=True)],
            )
        ],
    )
)

...

@help.register("name1")
@channel.use(
    ListenerSchema(
        listening_events=[FriendMessage],
        inline_dispatchers=[
            Twilight(
                [FullMatch("添加黑名单"), "userid" @ WildcardMatch(optional=True)],
            )
        ],
    )
)

...

@help.register("name2")
@channel.use(
    ListenerSchema(
        listening_events=[FriendMessage],
        inline_dispatchers=[
            Twilight(
                [FullMatch("查看状态")],
            )
        ],
    )
)

>> print(help.gen_help())

1. name1
   添加管理员 <adminid>
   添加黑名单 <userid>

2. name2
   查看状态

大概就是这样的实现(? 当然只是举个例子,实际应该不会这么草率

RF-Tar-Railt commented 2 years ago

try this

@help.register("foo", auto=True)  # default: True
@listen(GroupMessage)
async def bar(...):
    """
    qwertyuiop

    Usage:
        blablabla

    Example:
        blablabla
    """
    ...

@help.register("foo", auto=False)
@help.description("...")
@listen(GroupMessage)
async def bar(...):
    ...
RF-Tar-Railt commented 2 years ago

try this

@help.register("foo", auto=True)  # default: True
@listen(GroupMessage)
async def bar(...):
    """
    qwertyuiop

    Usage:
        blablabla

    Example:
        blablabla
    """
    ...

@help.register("foo", auto=False)
@help.description("...")
@listen(GroupMessage)
async def bar(...):
    ...

the behaviour between help.register and help.description is like click.command and click.option

RF-Tar-Railt commented 2 years ago

也许需要约定一个协议类


class HelpInfo(TypedDict):
    ...

@runtime_checkable
class HelpProvider(Protocol):
    def help_info(self) -> HelpInfo: ...

消息链匹配器(base-parser, twilight, alc-dispatcher, commander, etc.)应提供可能的"help_info"接口,否则help_generator或视作为普通的消息事件监听

RF-Tar-Railt commented 2 years ago

也许需要约定一个协议类


class HelpInfo(TypedDict):
    ...

@runtime_checkable
class HelpProvider(Protocol):
    def help_info(self) -> HelpInfo: ...

消息链匹配器(base-parser, twilight, alc-dispatcher, commander, etc.)应提供可能的"help_info"接口,否则help_generator或视作为普通的消息事件监听

顺带一提,HelpInfo或许会被扬掉

RF-Tar-Railt commented 2 years ago
help = HelpRecoder()
# or help = HelpRecoder.current(), that record as one global recorder

@help.record("name1")  # title
@help.usage("foo")  # short,or sub-title
@help.description("foo bar")  # long
@help.example("baz qux")
@listen(...)
async def _(...):
    ...

@help.record("name2", auto_gen=True)  # default to False;auto_gen will try to call the HelpProvider to provider possible help info with higher priority
@help.usage("foo1")  # using it when provider missing "usage"
@listen(...)
@decorate(DetectPrefix("#"))  # if it is HelpProvider, it may generate info like "#<...>"
asycn def _(...):
    ...
RF-Tar-Railt commented 2 years ago
help = HelpRecoder()
# or help = HelpRecoder.current(), that record as one global recorder

@help.record("name1")  # title
@help.usage("foo")  # short,or sub-title
@help.description("foo bar")  # long
@help.example("baz qux")
@listen(...)
async def _(...):
    ...

@help.record("name2", auto_gen=True)  # default to False;auto_gen will try to call the HelpProvider to provider possible help info with higher priority
@help.usage("foo1")  # using it when provider missing "usage"
@listen(...)
@decorate(DetectPrefix("#"))  # if it is HelpProvider, it may generate info like "#<...>"
asycn def _(...):
    ...

可以去掉usage, 塞进record里

record(title: str, *, sub_title: str | None = None, auto_gen: bool = False)