Enhance ExtendedAudio cog by adding new configuration options for embed color, thumbnail display, and progress bar visibility. Update command handling for setting these options and improve the display of song update messages with embedded content, including track information and progress bars.
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run

This commit is contained in:
Valerie 2025-05-28 02:07:09 -04:00
parent fb2b2a0ce7
commit 58469e28df

View file

@ -3,6 +3,7 @@ import logging
import time import time
from typing import Optional, List, Dict from typing import Optional, List, Dict
from collections import defaultdict from collections import defaultdict
from datetime import datetime
import discord import discord
from redbot.core import Config, commands from redbot.core import Config, commands
@ -27,7 +28,9 @@ class ExtendedAudio(commands.Cog):
self.config = Config.get_conf(self, identifier=117117117) self.config = Config.get_conf(self, identifier=117117117)
default_guild = { default_guild = {
"status_channel": None, # Channel ID to post song updates "status_channel": None, # Channel ID to post song updates
"status_format": "🎵 Now Playing: **{title}**\nRequested by: {requester}\nDuration: {duration}\nArtist: {author}", # Format for the status message "embed_color": None, # Custom embed color (optional)
"show_thumbnail": True, # Whether to show track thumbnails in embeds
"show_progress": True, # Whether to show a progress bar
"allowed_channels": [], # List of allowed voice channel IDs "allowed_channels": [], # List of allowed voice channel IDs
"bot_managed_only": False, # Whether to only allow bot-created channels "bot_managed_only": False, # Whether to only allow bot-created channels
"last_status_message": None, # ID of the last status message (for cleanup) "last_status_message": None, # ID of the last status message (for cleanup)
@ -70,15 +73,44 @@ class ExtendedAudio(commands.Cog):
guild = ctx.guild guild = ctx.guild
conf = await self.config.guild(guild).all() conf = await self.config.guild(guild).all()
status_channel = ctx.guild.get_channel(conf["status_channel"]) if conf["status_channel"] else None status_channel = ctx.guild.get_channel(conf["status_channel"]) if conf["status_channel"] else None
msg = ( embed_color = conf["embed_color"]
f"**Current Settings**\n" if embed_color:
f"Status Channel: {status_channel.mention if status_channel else 'Not Set'}\n" embed_color = discord.Color(embed_color)
f"Status Format: {conf['status_format']}\n" else:
f"Clean Old Messages: {'Enabled' if conf['clean_old_messages'] else 'Disabled'}\n\n" embed_color = discord.Color.blue()
f"Available Variables: {humanize_list([f'{{' + k + '}}' for k in SUPPORTED_VARIABLES.keys()])}\n"
f"Use `{ctx.prefix}extendedaudioset statuschannel` to set the channel for song updates." embed = discord.Embed(
title="ExtendedAudio Settings",
color=embed_color,
timestamp=datetime.now()
) )
await ctx.send(box(msg)) embed.add_field(
name="Status Channel",
value=status_channel.mention if status_channel else "Not Set",
inline=False
)
embed.add_field(
name="Embed Color",
value=str(embed_color) if embed_color else "Default (Blue)",
inline=True
)
embed.add_field(
name="Show Thumbnails",
value="Enabled" if conf["show_thumbnail"] else "Disabled",
inline=True
)
embed.add_field(
name="Show Progress Bar",
value="Enabled" if conf["show_progress"] else "Disabled",
inline=True
)
embed.add_field(
name="Clean Old Messages",
value="Enabled" if conf["clean_old_messages"] else "Disabled",
inline=True
)
await ctx.send(embed=embed)
@extendedaudioset.command(name="statuschannel") @extendedaudioset.command(name="statuschannel")
async def set_status_channel(self, ctx: commands.Context, channel: Optional[discord.TextChannel] = None): async def set_status_channel(self, ctx: commands.Context, channel: Optional[discord.TextChannel] = None):
@ -90,51 +122,40 @@ class ExtendedAudio(commands.Cog):
await self.config.guild(ctx.guild).status_channel.set(channel.id) await self.config.guild(ctx.guild).status_channel.set(channel.id)
await ctx.send(f"Song updates will now be posted in {channel.mention}") await ctx.send(f"Song updates will now be posted in {channel.mention}")
@extendedaudioset.command(name="statusformat") @extendedaudioset.command(name="embedcolor")
async def set_status_format(self, ctx: commands.Context, *, format_str: str): async def set_embed_color(self, ctx: commands.Context, color: discord.Color = None):
"""Set the format for song update messages. """Set the color for song update embeds.
Available variables: Leave empty to reset to default (blue).
{title} - Song title Use hex colors like #FF0000 for red.
{requester} - User who requested the song
{duration} - Duration of the song
{author} - Song author/artist
Example: [p]extendedaudioset statusformat 🎵 Now Playing: **{title}** by {author}
""" """
# Validate format string if color:
try: await self.config.guild(ctx.guild).embed_color.set(color.value)
# Test with sample data msg = f"Embed color set to {color}"
test_data = { else:
"title": "Test Song", await self.config.guild(ctx.guild).embed_color.set(None)
"requester": "Test User", msg = "Embed color reset to default (blue)"
"duration": "3:45",
"author": "Test Artist"
}
format_str.format(**test_data)
except KeyError as e:
invalid_var = str(e).strip("'")
supported = humanize_list([f"{{" + k + "}}" for k in SUPPORTED_VARIABLES.keys()])
await ctx.send(
f"Invalid variable `{invalid_var}` in format string.\n"
f"Supported variables are: {supported}"
)
return
except Exception as e:
await ctx.send(f"Invalid format string: {e}")
return
await self.config.guild(ctx.guild).status_format.set(format_str) embed = discord.Embed(
example = format_str.format( title="Color Updated",
title="Never Gonna Give You Up", description=msg,
requester="Rick Astley", color=color or discord.Color.blue()
duration="3:32",
author="Rick Astley"
)
await ctx.send(
f"Status format set! Example:\n"
f"{example}"
) )
await ctx.send(embed=embed)
@extendedaudioset.command(name="thumbnail")
async def set_show_thumbnail(self, ctx: commands.Context, enabled: bool):
"""Set whether to show track thumbnails in embeds."""
await self.config.guild(ctx.guild).show_thumbnail.set(enabled)
state = "will" if enabled else "will not"
await ctx.send(f"Track thumbnails {state} be shown in song updates.")
@extendedaudioset.command(name="progress")
async def set_show_progress(self, ctx: commands.Context, enabled: bool):
"""Set whether to show a progress bar in embeds."""
await self.config.guild(ctx.guild).show_progress.set(enabled)
state = "will" if enabled else "will not"
await ctx.send(f"Progress bars {state} be shown in song updates.")
@extendedaudioset.command(name="cleanmessages") @extendedaudioset.command(name="cleanmessages")
async def set_clean_messages(self, ctx: commands.Context, enabled: bool): async def set_clean_messages(self, ctx: commands.Context, enabled: bool):
@ -147,6 +168,25 @@ class ExtendedAudio(commands.Cog):
state = "will" if enabled else "will not" state = "will" if enabled else "will not"
await ctx.send(f"Old status messages {state} be deleted when new songs play.") await ctx.send(f"Old status messages {state} be deleted when new songs play.")
def format_duration(self, milliseconds: int) -> str:
"""Format milliseconds into a readable duration."""
seconds = milliseconds // 1000
minutes = seconds // 60
hours = minutes // 60
if hours > 0:
return f"{hours}:{minutes % 60:02d}:{seconds % 60:02d}"
else:
return f"{minutes}:{seconds % 60:02d}"
def create_progress_bar(self, current: int, total: int, length: int = 20) -> str:
"""Create a text progress bar."""
filled = int((current / total) * length)
bar = "" * filled + "" * (length - filled)
current_time = self.format_duration(current)
total_time = self.format_duration(total)
return f"{current_time} {bar} {total_time}"
@commands.Cog.listener() @commands.Cog.listener()
async def on_red_audio_track_start(self, guild: discord.Guild, track: dict, requester: discord.Member): async def on_red_audio_track_start(self, guild: discord.Guild, track: dict, requester: discord.Member):
"""Post song information when a new track starts""" """Post song information when a new track starts"""
@ -163,25 +203,57 @@ class ExtendedAudio(commands.Cog):
if not channel: if not channel:
return return
# Get the format and create the message # Get guild settings
format_str = await self.config.guild(guild).status_format() guild_settings = await self.config.guild(guild).all()
embed_color = discord.Color(guild_settings["embed_color"]) if guild_settings["embed_color"] else discord.Color.blue()
# Prepare variables # Create embed
duration = track.length if hasattr(track, "length") else 0 embed = discord.Embed(
minutes = duration // 60000 # Convert milliseconds to minutes title="Now Playing",
seconds = (duration % 60000) // 1000 # Convert remaining milliseconds to seconds color=embed_color,
duration_str = f"{minutes}:{seconds:02d}" timestamp=datetime.now()
)
message = format_str.format( # Add track info
title=track.title if hasattr(track, "title") else "Unknown", embed.add_field(
requester=requester.display_name, name="Title",
duration=duration_str, value=track.title if hasattr(track, "title") else "Unknown",
author=track.author if hasattr(track, "author") else "Unknown" inline=False
)
if hasattr(track, "author"):
embed.add_field(name="Artist", value=track.author, inline=True)
embed.add_field(name="Requested By", value=requester.mention, inline=True)
# Add duration/progress
if guild_settings["show_progress"] and hasattr(track, "length"):
duration = track.length
progress_bar = self.create_progress_bar(0, duration)
embed.add_field(name="Duration", value=progress_bar, inline=False)
elif hasattr(track, "length"):
embed.add_field(
name="Duration",
value=self.format_duration(track.length),
inline=True
)
# Add thumbnail if enabled and available
if (
guild_settings["show_thumbnail"]
and hasattr(track, "thumbnail")
and track.thumbnail
):
embed.set_thumbnail(url=track.thumbnail)
# Set footer with additional info
embed.set_footer(
text=f"Track {track.track_id if hasattr(track, 'track_id') else 'Unknown ID'}"
) )
# Clean up old message if enabled # Clean up old message if enabled
if await self.config.guild(guild).clean_old_messages(): if guild_settings["clean_old_messages"]:
last_message_id = await self.config.guild(guild).last_status_message() last_message_id = guild_settings["last_status_message"]
if last_message_id: if last_message_id:
try: try:
old_message = await channel.fetch_message(last_message_id) old_message = await channel.fetch_message(last_message_id)
@ -190,7 +262,7 @@ class ExtendedAudio(commands.Cog):
pass pass
# Send new message # Send new message
new_message = await channel.send(message) new_message = await channel.send(embed=embed)
await self.config.guild(guild).last_status_message.set(new_message.id) await self.config.guild(guild).last_status_message.set(new_message.id)
except Exception as e: except Exception as e: