mirror of https://github.com/stijndcl/didier
Create help command implementation
parent
bf28611ddc
commit
c5317b5d27
|
@ -25,7 +25,7 @@ class Currency(commands.Cog):
|
|||
super().__init__()
|
||||
self.client = client
|
||||
|
||||
@commands.command(name="Award")
|
||||
@commands.command(name="award")
|
||||
@commands.check(is_owner)
|
||||
async def award(
|
||||
self,
|
||||
|
@ -38,11 +38,11 @@ class Currency(commands.Cog):
|
|||
await crud.add_dinks(session, user.id, amount)
|
||||
plural = pluralize("Didier Dink", amount)
|
||||
await ctx.reply(
|
||||
f"**{ctx.author.display_name}** heeft **{user.display_name}** **{amount}** {plural} geschonken.",
|
||||
f"**{ctx.author.display_name}** has awarded **{user.display_name}** **{amount}** {plural}.",
|
||||
mention_author=False,
|
||||
)
|
||||
|
||||
@commands.group(name="bank", aliases=["B"], case_insensitive=True, invoke_without_command=True)
|
||||
@commands.group(name="bank", aliases=["b"], case_insensitive=True, invoke_without_command=True)
|
||||
async def bank(self, ctx: commands.Context):
|
||||
"""Show your Didier Bank information"""
|
||||
async with self.client.postgres_session as session:
|
||||
|
@ -57,7 +57,7 @@ class Currency(commands.Cog):
|
|||
|
||||
await ctx.reply(embed=embed, mention_author=False)
|
||||
|
||||
@bank.group(name="Upgrade", aliases=["U", "Upgrades"], case_insensitive=True, invoke_without_command=True)
|
||||
@bank.group(name="upgrade", aliases=["u", "upgrades"], case_insensitive=True, invoke_without_command=True)
|
||||
async def bank_upgrades(self, ctx: commands.Context):
|
||||
"""List the upgrades you can buy & their prices"""
|
||||
async with self.client.postgres_session as session:
|
||||
|
@ -77,7 +77,7 @@ class Currency(commands.Cog):
|
|||
|
||||
await ctx.reply(embed=embed, mention_author=False)
|
||||
|
||||
@bank_upgrades.command(name="Capacity", aliases=["C"])
|
||||
@bank_upgrades.command(name="capacity", aliases=["c"])
|
||||
async def bank_upgrade_capacity(self, ctx: commands.Context):
|
||||
"""Upgrade the capacity level of your bank"""
|
||||
async with self.client.postgres_session as session:
|
||||
|
@ -88,7 +88,7 @@ class Currency(commands.Cog):
|
|||
await ctx.reply("You don't have enough Didier Dinks to do this.", mention_author=False)
|
||||
await self.client.reject_message(ctx.message)
|
||||
|
||||
@bank_upgrades.command(name="Interest", aliases=["I"])
|
||||
@bank_upgrades.command(name="interest", aliases=["i"])
|
||||
async def bank_upgrade_interest(self, ctx: commands.Context):
|
||||
"""Upgrade the interest level of your bank"""
|
||||
async with self.client.postgres_session as session:
|
||||
|
@ -99,7 +99,7 @@ class Currency(commands.Cog):
|
|||
await ctx.reply("You don't have enough Didier Dinks to do this.", mention_author=False)
|
||||
await self.client.reject_message(ctx.message)
|
||||
|
||||
@bank_upgrades.command(name="Rob", aliases=["R"])
|
||||
@bank_upgrades.command(name="rob", aliases=["r"])
|
||||
async def bank_upgrade_rob(self, ctx: commands.Context):
|
||||
"""Upgrade the rob level of your bank"""
|
||||
async with self.client.postgres_session as session:
|
||||
|
@ -118,7 +118,7 @@ class Currency(commands.Cog):
|
|||
plural = pluralize("Didier Dink", bank.dinks)
|
||||
await ctx.reply(f"**{ctx.author.display_name}** has **{bank.dinks}** {plural}.", mention_author=False)
|
||||
|
||||
@commands.command(name="Invest", aliases=["Deposit", "Dep"])
|
||||
@commands.command(name="invest", aliases=["deposit", "dep"])
|
||||
async def invest(self, ctx: commands.Context, amount: typing.Annotated[typing.Union[str, int], abbreviated_number]):
|
||||
"""Invest a given amount of Didier Dinks"""
|
||||
async with self.client.postgres_session as session:
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from typing import List, Mapping, Optional
|
||||
from typing import Mapping, Optional
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from overrides import overrides
|
||||
|
||||
from didier import Didier
|
||||
from didier.utils.discord.colours import error_red
|
||||
|
||||
|
||||
class CustomHelpCommand(commands.MinimalHelpCommand):
|
||||
|
@ -13,32 +14,146 @@ class CustomHelpCommand(commands.MinimalHelpCommand):
|
|||
The default is ugly as hell, so we do some fiddling with it
|
||||
"""
|
||||
|
||||
@overrides
|
||||
async def command_callback(self, ctx: commands.Context, /, *, command: Optional[str] = None):
|
||||
"""Slightly modify the original command_callback to better suit my needs"""
|
||||
|
||||
# No argument provided: send a list of all cogs
|
||||
if command is None:
|
||||
mapping = self.get_bot_mapping()
|
||||
return await self.send_bot_help(mapping)
|
||||
|
||||
command = command.lower()
|
||||
|
||||
# Hide cogs the user is not allowed to see
|
||||
cogs = list(ctx.bot.cogs.values())
|
||||
cogs = await self._filter_cogs(cogs)
|
||||
# Allow fetching cogs case-insensitively
|
||||
cog = self._get_cog(cogs, command)
|
||||
if cog is not None:
|
||||
return await self.send_cog_help(cog)
|
||||
|
||||
# Traverse tree of commands
|
||||
keys = command.split(" ")
|
||||
current_command = ctx.bot.all_commands.get(keys[0])
|
||||
|
||||
# No command found
|
||||
if current_command is None:
|
||||
return await self.send_error_message(self.command_not_found(keys[0]))
|
||||
|
||||
# Look for subcommands
|
||||
for key in keys[1:]:
|
||||
try:
|
||||
found = current_command.all_commands.get(key) # type: ignore
|
||||
except AttributeError:
|
||||
return await self.send_error_message(self.subcommand_not_found(current_command, key))
|
||||
else:
|
||||
if found is None:
|
||||
return await self.send_error_message(self.subcommand_not_found(current_command, key))
|
||||
|
||||
current_command = found
|
||||
|
||||
if isinstance(current_command, commands.Group):
|
||||
return await self.send_group_help(current_command)
|
||||
else:
|
||||
return await self.send_command_help(current_command)
|
||||
|
||||
@overrides
|
||||
def command_not_found(self, string: str, /) -> str:
|
||||
return f"Found no command named `{string}`."
|
||||
|
||||
@overrides
|
||||
async def send_bot_help(self, mapping: Mapping[Optional[commands.Cog], list[commands.Command]], /):
|
||||
embed = self._help_embed_base("Categories")
|
||||
filtered_cogs = await self._filter_cogs(list(mapping.keys()))
|
||||
embed.description = "\n".join(list(map(lambda cog: cog.qualified_name, filtered_cogs)))
|
||||
await self.context.reply(embed=embed, mention_author=False)
|
||||
|
||||
@overrides
|
||||
async def send_cog_help(self, cog: commands.Cog, /):
|
||||
embed = self._help_embed_base(cog.qualified_name)
|
||||
embed.description = cog.description
|
||||
|
||||
commands_names = list(map(lambda c: c.qualified_name, cog.get_commands()))
|
||||
commands_names.sort()
|
||||
|
||||
embed.add_field(name="Commands", value=", ".join(commands_names), inline=False)
|
||||
|
||||
return await self.context.reply(embed=embed, mention_author=False)
|
||||
|
||||
@overrides
|
||||
async def send_command_help(self, command: commands.Command, /):
|
||||
embed = self._help_embed_base(command.qualified_name)
|
||||
self._add_command_help(embed, command)
|
||||
|
||||
return await self.context.reply(embed=embed, mention_author=False)
|
||||
|
||||
@overrides
|
||||
async def send_group_help(self, group: commands.Group, /):
|
||||
embed = self._help_embed_base(group.qualified_name)
|
||||
|
||||
if group.invoke_without_command:
|
||||
self._add_command_help(embed, group)
|
||||
|
||||
subcommand_names = list(map(lambda c: c.name, group.commands))
|
||||
subcommand_names.sort()
|
||||
|
||||
embed.add_field(name="Subcommands", value=", ".join(subcommand_names))
|
||||
|
||||
return await self.context.reply(embed=embed, mention_author=False)
|
||||
|
||||
@overrides
|
||||
async def send_error_message(self, error: str, /):
|
||||
embed = discord.Embed(colour=error_red(), title="Help", description=error)
|
||||
return await self.context.reply(embed=embed, mention_author=False)
|
||||
|
||||
@overrides
|
||||
def subcommand_not_found(self, command: commands.Command, string: str, /) -> str:
|
||||
return f"Found no subcommand named `{string}` for command `{command.qualified_name}`."
|
||||
|
||||
def _help_embed_base(self, title: str) -> discord.Embed:
|
||||
"""Create the base structure for the embeds that get sent with the Help commands"""
|
||||
embed = discord.Embed(title=title, colour=discord.Colour.blue())
|
||||
embed.set_footer(text="Syntax: Didier Help [Categorie] of Didier Help [Commando]")
|
||||
embed = discord.Embed(title=title.title(), colour=discord.Colour.blue())
|
||||
return embed
|
||||
|
||||
async def _filter_cogs(self, cogs: List[commands.Cog]) -> List[commands.Cog]:
|
||||
def _add_command_help(self, embed: discord.Embed, command: commands.Command):
|
||||
"""Add command-related information to an embed
|
||||
|
||||
This allows re-using this logic for Group commands that can be invoked by themselves.
|
||||
"""
|
||||
embed.description = command.help
|
||||
|
||||
if command.usage:
|
||||
embed.add_field(name="Signature", value=f"{command.name} {command.usage}", inline=False)
|
||||
|
||||
if command.aliases:
|
||||
embed.add_field(name="Aliases", value=", ".join(command.aliases), inline=False)
|
||||
|
||||
def _get_cog(self, cogs: list[commands.Cog], name: str) -> Optional[commands.Cog]:
|
||||
"""Try to find a cog, case-insensitively"""
|
||||
for cog in cogs:
|
||||
if cog.qualified_name.lower() == name:
|
||||
return cog
|
||||
|
||||
return None
|
||||
|
||||
async def _filter_cogs(self, cogs: list[commands.Cog]) -> list[commands.Cog]:
|
||||
"""Filter the list of cogs down to all those that the user can see"""
|
||||
# Remove cogs that we never want to see in the help page because they
|
||||
# don't contain commands
|
||||
filtered_cogs = list(filter(lambda cog: cog is not None and cog.qualified_name.lower() not in ("tasks",), cogs))
|
||||
filtered_cogs = list(
|
||||
filter(lambda cog: cog is not None and cog.qualified_name.lower() not in ("tasks", "debugcog"), cogs)
|
||||
)
|
||||
|
||||
# Remove owner-only cogs
|
||||
# Remove owner-only cogs for people that shouldn't see them
|
||||
if not await self.context.bot.is_owner(self.context.author):
|
||||
filtered_cogs = list(filter(lambda cog: cog.qualified_name.lower() not in ("owner",), filtered_cogs))
|
||||
|
||||
return list(sorted(filtered_cogs, key=lambda cog: cog.qualified_name))
|
||||
|
||||
@overrides
|
||||
async def send_bot_help(self, mapping: Mapping[Optional[commands.Cog], List[commands.Command]], /):
|
||||
embed = self._help_embed_base("Categorieën")
|
||||
filtered_cogs = await self._filter_cogs(list(mapping.keys()))
|
||||
embed.description = "\n".join(list(map(lambda cog: cog.qualified_name, filtered_cogs)))
|
||||
await self.get_destination().send(embed=embed)
|
||||
|
||||
|
||||
async def setup(client: Didier):
|
||||
"""Load the cog"""
|
||||
client.help_command = CustomHelpCommand()
|
||||
attributes = {"aliases": ["h", "man"]}
|
||||
|
||||
client.help_command = CustomHelpCommand(command_attrs=attributes)
|
||||
|
|
|
@ -190,8 +190,10 @@ class Tasks(commands.Cog):
|
|||
await self.client.wait_until_ready()
|
||||
|
||||
@check_birthdays.error
|
||||
@pull_schedules.error
|
||||
@pull_ufora_announcements.error
|
||||
@remove_old_ufora_announcements.error
|
||||
@reset_wordle_word.error
|
||||
async def _on_tasks_error(self, error: BaseException):
|
||||
"""Error handler for all tasks"""
|
||||
print("".join(traceback.format_exception(type(error), error, error.__traceback__)))
|
||||
|
|
Loading…
Reference in New Issue