Ruby-Cogs/extendedaudio/extendedaudio.py

133 lines
No EOL
5 KiB
Python

import asyncio
import logging
from typing import Optional
import discord
from redbot.core import Config, commands
from redbot.core.bot import Red
from redbot.core.utils.chat_formatting import box
log = logging.getLogger("red.valerie.extendedaudio")
class ExtendedAudio(commands.Cog):
"""Extends Red's core Audio cog with additional features"""
def __init__(self, bot: Red):
self.bot = bot
self.config = Config.get_conf(self, identifier=117117117)
default_guild = {
"channel_status": True, # Whether to update voice channel name with current song
"status_format": "🎵 {title}", # Format for the channel name
}
self.config.register_guild(**default_guild)
self.task = self.bot.loop.create_task(self.initialize())
self.audio = None
async def initialize(self):
"""Initialize the cog"""
await self.bot.wait_until_ready()
try:
self.audio = self.bot.get_cog("Audio")
if not self.audio:
log.error("Audio cog not loaded! Some features may not work.")
except Exception as e:
log.error(f"Failed to initialize ExtendedAudio: {e}")
def cog_unload(self):
"""Cleanup when cog unloads"""
if self.task:
self.task.cancel()
@commands.group()
@commands.guild_only()
@commands.admin_or_permissions(manage_guild=True)
async def audioset(self, ctx: commands.Context):
"""Configure ExtendedAudio settings"""
pass
@audioset.command(name="channelstatus")
async def set_channel_status(self, ctx: commands.Context, enabled: bool):
"""Toggle voice channel status updates
This will update the voice channel name with the currently playing song
Example: [p]audioset channelstatus true
"""
await self.config.guild(ctx.guild).channel_status.set(enabled)
state = "enabled" if enabled else "disabled"
await ctx.send(f"Voice channel status updates {state}.")
@audioset.command(name="statusformat")
async def set_status_format(self, ctx: commands.Context, *, format_str: str):
"""Set the format for voice channel status updates
Available variables:
{title} - Song title
Example: [p]audioset statusformat 🎵 {title}
"""
await self.config.guild(ctx.guild).status_format.set(format_str)
example = format_str.format(title="Never Gonna Give You Up")
await ctx.send(
f"Status format set! Example:\n"
f"{box(example)}"
)
@commands.Cog.listener()
async def on_red_audio_track_start(self, guild: discord.Guild, track: dict, requester: discord.Member):
"""Update voice channel name when a new track starts"""
if not guild or not track:
return
try:
# Check if channel status updates are enabled
if not await self.config.guild(guild).channel_status():
return
# Get the voice channel
voice_client = guild.voice_client
if not voice_client or not voice_client.channel:
return
channel = voice_client.channel
# Get the format and create the new name
format_str = await self.config.guild(guild).status_format()
new_name = format_str.format(title=track.get("title", "Unknown"))
# Update channel name if different
if channel.name != new_name:
await channel.edit(name=new_name)
except discord.Forbidden:
log.warning(f"Missing permissions to edit channel name in {guild.name}")
except Exception as e:
log.error(f"Error updating channel status in {guild.name}: {e}")
@commands.Cog.listener()
async def on_red_audio_queue_end(self, guild: discord.Guild, *args, **kwargs):
"""Reset voice channel name when queue ends"""
if not guild:
return
try:
# Check if channel status updates are enabled
if not await self.config.guild(guild).channel_status():
return
# Get the voice channel
voice_client = guild.voice_client
if not voice_client or not voice_client.channel:
return
channel = voice_client.channel
# Reset channel name if it was modified (contains 🎵)
if "🎵" in channel.name:
original_name = channel.name.split("🎵")[-1].strip()
await channel.edit(name=original_name)
except discord.Forbidden:
log.warning(f"Missing permissions to edit channel name in {guild.name}")
except Exception as e:
log.error(f"Error resetting channel status in {guild.name}: {e}")