new help command, fixed queue and loop display, thumbnails and urls added to database

This commit is contained in:
2025-11-27 23:04:01 +00:00
parent 7f8f77fb76
commit fa2afbdd99
5 changed files with 393 additions and 545 deletions

177
help.py
View File

@@ -1,81 +1,126 @@
from collections.abc import Mapping
from typing import List
import discord
from discord.app_commands import Command
from discord.ext import commands
from discord.ext.commands.cog import Cog
from discord import app_commands
import config
class AstroHelp(commands.MinimalHelpCommand):
class HelpView(discord.ui.View):
def __init__(self, mapping, ctx):
super().__init__(timeout=180)
self.ctx = ctx
self.mapping = mapping
self.add_item(HelpSelect(mapping, ctx))
def __init__(self):
super().__init__()
self.command_attrs = {
'name': "help",
'aliases': ["commands", "?"],
'cooldown': commands.CooldownMapping.from_cooldown(2, 5.0, commands.BucketType.user)
}
class HelpSelect(discord.ui.Select):
def __init__(self, mapping, ctx):
self.mapping = mapping
self.ctx = ctx
options = [
discord.SelectOption(
label='Home',
description='Back to main menu',
emoji='🏠',
value='home'
)
]
# Dynamically add categories (Cogs)
for cog, cmds in mapping.items():
if not cmds: continue
# Use attributes safely
cog_name = getattr(cog, "name", "Other").replace("🎶 ", "")
emoji = getattr(cog, "emoji", "📄")
options.append(discord.SelectOption(
label=cog_name,
description=f"{len(cmds)} commands available",
emoji=emoji,
value=cog_name
))
super().__init__(placeholder="Select a category...", min_values=1, max_values=1, options=options)
# Called when using help no args
async def send_bot_help(self, mapping: Mapping[Cog, List[Command]]):
async def callback(self, interaction: discord.Interaction):
if interaction.user != self.ctx.author:
return await interaction.response.send_message("Create your own help command with /help", ephemeral=True)
# Our embed message
value = self.values[0]
if value == 'home':
await interaction.response.edit_message(embed=get_home_embed(self.ctx), view=self.view)
return
# Find the selected cog
selected_cog = None
selected_commands = []
for cog, cmds in self.mapping.items():
cog_name_clean = getattr(cog, "name", "Other").replace("🎶 ", "")
if cog_name_clean == value:
selected_cog = cog
selected_commands = cmds
break
embed = discord.Embed(
title="Help",
color=config.get_color("main"))
embed.add_field(name="",
value="Use `help <command>` or `help <category>` for more details",
inline=False)
title=f"{getattr(selected_cog, 'emoji', '')} {value} Commands",
color=config.get_color("main") if hasattr(config, 'get_color') else discord.Color.blue()
)
embed.set_footer(text=f"Prefix: {self.context.prefix}")
for cmd in selected_commands:
# Get description
desc = cmd.short_doc or cmd.description or "No description provided."
embed.add_field(
name=f"/{cmd.name}",
value=desc,
inline=False
)
await interaction.response.edit_message(embed=embed, view=self.view)
# grabs iterable of (Cog, list[Command])
for cog, commands in mapping.items():
def get_home_embed(ctx):
embed = discord.Embed(
title="🤖 Bot Help Menu",
description=f"Hello **{ctx.author.name}**! Select a category below to see available commands.",
color=discord.Color.purple()
)
if ctx.bot.user.avatar:
embed.set_thumbnail(url=ctx.bot.user.avatar.url)
embed.add_field(name=" How to use", value="Use the dropdown menu below to navigate categories.\nMost commands work as `/command` or `=command`.", inline=False)
return embed
# Grab commands only the user can access
# Safe to ignore warning
filtered = await self.filter_commands(commands, sort=True)
class GroovyHelp(commands.Cog):
def __init__(self, client):
self.client = client
self.name = "Help"
self.emoji = "🆘"
# For each command we grab the signature
command_signatures = [
# Rmove prefix and format command name
f"``{self.get_command_signature(c)[1:]}``" for c in filtered]
@commands.hybrid_command(name="help", description="Show the help menu")
async def help(self, ctx: commands.Context):
bot = ctx.bot
mapping = {}
for cog_name in bot.cogs:
cog = bot.get_cog(cog_name)
# --- FIXED FILTERING LOGIC ---
visible_cmds = []
for cmd in cog.get_commands():
if cmd.hidden:
continue
try:
# Check if user has permission to run this command
if await cmd.can_run(ctx):
visible_cmds.append(cmd)
except commands.CommandError:
continue
# -----------------------------
# Check if cog has any commands
if command_signatures:
if visible_cmds:
# Sort alphabetically
visible_cmds.sort(key=lambda x: x.name)
mapping[cog] = visible_cmds
# Use get incase cog is None
cog_name = getattr(cog, "name", "No Category")
# Add cog section to help message
embed.add_field(
name=f"{cog_name}",
value="\n".join(command_signatures),
inline=True)
# Display message
channel = self.get_destination()
await channel.send(embed=embed)
# Help for specific command
async def send_command_help(self, command):
embed = discord.Embed(
title=self.get_command_signature(command)[1:],
color=config.get_color("main"))
embed.set_footer(text=f"Prefix: {self.context.prefix}")
embed.add_field(name="Description", value=command.help)
alias = command.aliases
if alias:
embed.add_field(name="Aliases", value=", ".join(alias), inline=False)
channel = self.get_destination()
await channel.send(embed=embed)
# TODO add error support see
# https://gist.github.com/InterStella0/b78488fb28cadf279dfd3164b9f0cf96
# and
# https://gist.github.com/EvieePy/7822af90858ef65012ea500bcecf1612
embed = get_home_embed(ctx)
view = HelpView(mapping, ctx)
await ctx.send(embed=embed, view=view)