2024-03-16 20:08:48 +00:00
|
|
|
import discord
|
|
|
|
from discord.ext import commands
|
2024-03-29 17:17:51 +00:00
|
|
|
|
2024-08-05 09:53:34 +00:00
|
|
|
from lib.constants import CONST
|
2024-08-18 09:16:18 +00:00
|
|
|
from lib.embed_builder import EmbedBuilder
|
2024-08-05 09:53:34 +00:00
|
|
|
from lib.exceptions.LumiExceptions import LumiException
|
2024-03-16 20:08:48 +00:00
|
|
|
|
2024-03-23 10:45:48 +00:00
|
|
|
|
2024-06-15 22:45:24 +00:00
|
|
|
class LumiHelp(commands.HelpCommand):
|
2024-03-19 15:13:08 +00:00
|
|
|
def __init__(self, **options):
|
|
|
|
super().__init__(**options)
|
2024-03-25 20:18:33 +00:00
|
|
|
self.verify_checks = True
|
|
|
|
self.command_attrs = {
|
|
|
|
"aliases": ["h"],
|
|
|
|
"help": "Show a list of commands, or information about a specific command when an argument is passed.",
|
2024-04-12 10:51:52 +00:00
|
|
|
"name": "help",
|
2024-07-15 14:01:30 +00:00
|
|
|
"hidden": True,
|
2024-03-25 20:18:33 +00:00
|
|
|
}
|
2024-03-17 12:59:13 +00:00
|
|
|
|
|
|
|
def get_command_qualified_name(self, command):
|
2024-08-14 10:34:19 +00:00
|
|
|
return f"`{self.context.clean_prefix}{command.qualified_name}`"
|
2024-03-17 12:59:13 +00:00
|
|
|
|
|
|
|
async def send_bot_help(self, mapping):
|
2024-08-14 10:34:19 +00:00
|
|
|
embed = EmbedBuilder.create_success_embed(
|
2024-08-05 09:53:34 +00:00
|
|
|
ctx=self.context,
|
|
|
|
author_text="Help Command",
|
|
|
|
show_name=False,
|
|
|
|
)
|
2024-04-12 00:31:31 +00:00
|
|
|
|
2024-06-15 22:45:24 +00:00
|
|
|
for cog, lumi_commands in mapping.items():
|
|
|
|
filtered = await self.filter_commands(lumi_commands, sort=True)
|
2024-03-18 14:11:22 +00:00
|
|
|
|
2024-03-17 12:59:13 +00:00
|
|
|
if command_signatures := [
|
2024-03-19 14:32:01 +00:00
|
|
|
self.get_command_qualified_name(c) for c in filtered
|
2024-03-17 12:59:13 +00:00
|
|
|
]:
|
|
|
|
# Remove duplicates using set() and convert back to a list
|
|
|
|
unique_command_signatures = list(set(command_signatures))
|
|
|
|
cog_name = getattr(cog, "qualified_name", "Help")
|
2024-07-15 14:01:30 +00:00
|
|
|
embed.add_field(
|
|
|
|
name=cog_name,
|
|
|
|
value=", ".join(sorted(unique_command_signatures)),
|
|
|
|
inline=False,
|
|
|
|
)
|
2024-03-17 12:59:13 +00:00
|
|
|
|
|
|
|
channel = self.get_destination()
|
|
|
|
await channel.send(embed=embed)
|
|
|
|
|
|
|
|
async def send_command_help(self, command):
|
2024-08-05 09:53:34 +00:00
|
|
|
embed = EmbedBuilder.create_success_embed(
|
|
|
|
ctx=self.context,
|
|
|
|
author_text=f"{self.context.clean_prefix}{command.qualified_name}",
|
2024-07-15 14:01:30 +00:00
|
|
|
description=command.help,
|
2024-08-05 09:53:34 +00:00
|
|
|
show_name=False,
|
2024-03-29 11:14:31 +00:00
|
|
|
)
|
2024-03-17 12:59:13 +00:00
|
|
|
|
2024-08-14 10:34:19 +00:00
|
|
|
usage_value = (
|
|
|
|
f"`{self.context.clean_prefix}{command.qualified_name} {command.signature}`"
|
2024-07-15 14:01:30 +00:00
|
|
|
)
|
2024-03-18 14:11:22 +00:00
|
|
|
for alias in command.aliases:
|
2024-08-14 10:34:19 +00:00
|
|
|
usage_value += f"\n`{self.context.clean_prefix}{alias} {command.signature}`"
|
2024-03-29 11:14:31 +00:00
|
|
|
embed.add_field(name="Usage", value=usage_value, inline=False)
|
2024-03-18 14:11:22 +00:00
|
|
|
|
2024-03-17 12:59:13 +00:00
|
|
|
channel = self.get_destination()
|
|
|
|
await channel.send(embed=embed)
|
|
|
|
|
2024-03-18 14:40:58 +00:00
|
|
|
async def send_error_message(self, error):
|
2024-08-05 09:53:34 +00:00
|
|
|
raise LumiException(error)
|
2024-03-17 12:59:13 +00:00
|
|
|
|
|
|
|
async def send_group_help(self, group):
|
2024-08-05 09:53:34 +00:00
|
|
|
raise LumiException(
|
|
|
|
CONST.STRINGS["error_command_not_found"].format(group.qualified_name),
|
2024-07-15 14:01:30 +00:00
|
|
|
)
|
2024-03-17 12:59:13 +00:00
|
|
|
|
|
|
|
async def send_cog_help(self, cog):
|
2024-08-05 09:53:34 +00:00
|
|
|
raise LumiException(
|
|
|
|
CONST.STRINGS["error_command_not_found"].format(cog.qualified_name),
|
2024-07-15 14:01:30 +00:00
|
|
|
)
|
2024-03-25 20:18:33 +00:00
|
|
|
|
|
|
|
async def command_callback(self, ctx, *, command=None):
|
|
|
|
await self.prepare_help_command(ctx, command)
|
|
|
|
bot = ctx.bot
|
|
|
|
|
|
|
|
if command is None:
|
|
|
|
mapping = self.get_bot_mapping()
|
|
|
|
return await self.send_bot_help(mapping)
|
|
|
|
|
|
|
|
# Check if it's a cog
|
|
|
|
cog = bot.get_cog(command)
|
|
|
|
if cog is not None:
|
|
|
|
return await self.send_cog_help(cog)
|
|
|
|
|
2024-08-05 09:53:34 +00:00
|
|
|
maybe_coro = discord.utils.maybe_coroutine # type: ignore
|
2024-03-25 20:18:33 +00:00
|
|
|
|
|
|
|
# If it's not a cog then it's a command.
|
|
|
|
# Since we want to have detailed errors when someone
|
|
|
|
# passes an invalid subcommand, we need to walk through
|
|
|
|
# the command group chain ourselves.
|
|
|
|
keys = command.split(" ")
|
|
|
|
|
|
|
|
cmd = bot.all_commands.get(keys[0].removeprefix(self.context.prefix))
|
|
|
|
if cmd is None:
|
|
|
|
string = await maybe_coro(
|
2024-07-17 11:47:26 +00:00
|
|
|
self.command_not_found,
|
|
|
|
self.remove_mentions(keys[0]),
|
2024-03-25 20:18:33 +00:00
|
|
|
)
|
|
|
|
return await self.send_error_message(string)
|
|
|
|
|
|
|
|
for key in keys[1:]:
|
|
|
|
try:
|
|
|
|
found = cmd.all_commands.get(key)
|
|
|
|
except AttributeError:
|
|
|
|
string = await maybe_coro(
|
2024-07-17 11:47:26 +00:00
|
|
|
self.subcommand_not_found,
|
|
|
|
cmd,
|
|
|
|
self.remove_mentions(key),
|
2024-03-25 20:18:33 +00:00
|
|
|
)
|
|
|
|
return await self.send_error_message(string)
|
|
|
|
else:
|
|
|
|
if found is None:
|
|
|
|
string = await maybe_coro(
|
2024-07-17 11:47:26 +00:00
|
|
|
self.subcommand_not_found,
|
|
|
|
cmd,
|
|
|
|
self.remove_mentions(key),
|
2024-03-25 20:18:33 +00:00
|
|
|
)
|
|
|
|
return await self.send_error_message(string)
|
|
|
|
cmd = found
|
|
|
|
|
|
|
|
return await self.send_command_help(cmd)
|