Generate help embed from function signature

pull/132/head
stijndcl 2022-09-19 14:29:14 +02:00
parent 9c36f59e04
commit 65e1034372
2 changed files with 44 additions and 12 deletions

View File

@ -1,3 +1,4 @@
import re
from typing import Mapping, Optional
import discord
@ -63,6 +64,30 @@ class CustomHelpCommand(commands.MinimalHelpCommand):
def command_not_found(self, string: str, /) -> str:
return f"Found no command named `{string}`."
@overrides
def get_command_signature(self, command: commands.Command, /) -> str:
signature_list = [command.name]
# Perform renaming for hybrid commands
if hasattr(command.callback, "__discord_app_commands_param_rename__"):
renames = command.callback.__discord_app_commands_param_rename__
else:
renames = {}
sig = command.params
for name, param in sig.items():
name = renames.get(name, name)
is_optional = param.default is not param.empty
# Wrap optional arguments in square brackets
if is_optional:
name = f"[{name}]"
signature_list.append(name)
return " ".join(signature_list)
@overrides
async def send_bot_help(self, mapping: Mapping[Optional[commands.Cog], list[commands.Command]], /):
embed = self._help_embed_base("Categories")
@ -122,10 +147,15 @@ class CustomHelpCommand(commands.MinimalHelpCommand):
This allows re-using this logic for Group commands that can be invoked by themselves.
"""
embed.description = command.help
# Regex borrowed from https://stackoverflow.com/a/59843498/13568999
# Remove single newlines but keep double newlines
# This allows short lines in the docstring, but joins them together for the help description
embed.description = re.sub(
r"([^\S\n]*\n(?:[^\S\n]*\n)+[^\S\n]*)|[^\S\n]*\n[^\S\n]*", lambda x: x.group(1) or " ", command.help
)
if command.usage:
embed.add_field(name="Signature", value=f"{command.name} {command.usage}", inline=False)
signature = self.get_command_signature(command)
embed.add_field(name="Signature", value=signature, inline=False)
if command.aliases:
embed.add_field(name="Aliases", value=", ".join(command.aliases), inline=False)

View File

@ -27,21 +27,23 @@ class School(commands.Cog):
def __init__(self, client: Didier):
self.client = client
@commands.hybrid_command(name="deadlines", description="Show upcoming deadlines")
@commands.hybrid_command(name="deadlines")
async def deadlines(self, ctx: commands.Context):
"""Show upcoming deadlines"""
"""Show upcoming deadlines."""
async with self.client.postgres_session as session:
deadlines = await get_deadlines(session)
embed = Deadlines(deadlines).to_embed()
await ctx.reply(embed=embed, mention_author=False, ephemeral=False)
@commands.hybrid_command(
name="les", description="Show your personalized schedule for a given day.", aliases=["Sched", "Schedule"]
)
@commands.hybrid_command(name="les", aliases=["sched", "schedule"])
@app_commands.rename(day_dt="date")
async def les(self, ctx: commands.Context, day_dt: Optional[app_commands.Transform[date, DateTransformer]] = None):
"""Show your personalized schedule for a given day."""
"""Show your personalized schedule for a given day.
If no day is provided, this defaults to the schedule for the current day. When invoked during a weekend,
it will skip forward to the next weekday instead.
"""
if day_dt is None:
day_dt = date.today()
@ -62,14 +64,14 @@ class School(commands.Cog):
@commands.hybrid_command(
name="menu",
description="Show the menu in the Ghent University restaurants.",
aliases=["Eten", "Food"],
aliases=["eten", "food"],
)
@app_commands.rename(day_dt="date")
async def menu(self, ctx: commands.Context, day_dt: Optional[app_commands.Transform[date, DateTransformer]] = None):
"""Show the menu in the Ghent University restaurants.
Menus are Dutch, as a lot of dishes have very weird translations
If no day is provided, this defaults to the schedule for the current day.
Menus are shown in Dutch by default, as a lot of dishes have very weird translations.
"""
if day_dt is None:
day_dt = date.today()