import os import discord import mutagen from . import play_utils from discord.ext import commands import logging logger = logging.getLogger(__name__) class Play(commands.Cog): def __init__(self, bot): self.bot = bot self.temp_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "temp") @discord.slash_command(name="grajcuj", description="grajcujmy wszyscy!") async def play( self, ctx: discord.ApplicationContext, query: str = discord.Option(str, "co zagrać??", required=True), source: str = discord.Option(str, "co zagrać??", required=True, choices=["local", "soundcloud", "youtube"]) ): await ctx.defer(ephemeral=True) if source == "local": candidates = await play_utils.PlayUtils(self.bot).search_local(query) if candidates: embed = discord.Embed(title="Wyniki wyszukiwania", description="Wybierz plik do odtworzenia:", color=discord.Color.blue()) view = discord.ui.View(disable_on_timeout=True) for i, candidate in enumerate(candidates, start=1): filename = os.path.basename(candidate) metadata = None if os.path.splitext(filename)[1].lower() in ['.mp3', '.wav', '.opus']: metadata = mutagen.File(candidate) title = metadata.get('title', None) if metadata and title: embed.add_field(name=f"{i}. {title}", value="\u200b", inline=False) else: embed.add_field(name=f"{i}. {filename}", value="\u200b", inline=False) button = discord.ui.Button(label=f"Play {i}") async def button_callback(interaction: discord.Interaction, candidate=candidate): await ctx.interaction.delete_original_response() await play_utils.PlayUtils(self.bot).play(ctx, candidate) button.callback = button_callback view.add_item(button) await ctx.respond(embed=embed, view=view, ephemeral=True) else: await ctx.respond("Nie znaleziono pliku do odtworzenia", ephemeral=True) @discord.slash_command(name="grajcuj_zkompresowane", description="grajcujmy wszyscy w wysokiej jakosci!") async def play_compressed( self, ctx: discord.ApplicationContext, query: str = discord.Option(str, "co zagrać??", required=True), source: str = discord.Option(str, "skąd zagrać??", required=True, choices=["local", "soundcloud", "youtube"]) ): await ctx.defer(ephemeral=True) if source == "local": candidates = await play_utils.PlayUtils(self.bot).search_local(query) if candidates: embed = discord.Embed(title="Wyniki wyszukiwania", description="Wybierz plik do odtworzenia:", color=discord.Color.blue()) view = discord.ui.View(disable_on_timeout=True) for i, candidate in enumerate(candidates, start=1): filename = os.path.basename(candidate) metadata = None if os.path.splitext(filename)[1].lower() in ['.mp3', '.wav', '.opus']: metadata = mutagen.File(candidate) title = metadata.get('title', None) if metadata and title: embed.add_field(name=f"{i}. {title}", value="\u200b", inline=False) else: embed.add_field(name=f"{i}. {filename}", value="\u200b", inline=False) button = discord.ui.Button(label=f"Play {i}") async def button_callback(interaction: discord.Interaction, candidate=candidate): await interaction.response.defer(ephemeral=True) try: await ctx.interaction.delete_original_response() # Compress the file before playing compressed_path = await play_utils.PlayUtils(self.bot).compress(ctx, candidate) if compressed_path: try: await play_utils.PlayUtils(self.bot).play(ctx, compressed_path, delete_after_play=True) except Exception as e: # Clean up the compressed file if play fails if os.path.exists(compressed_path): try: os.remove(compressed_path) logger.info(f"Cleaned up temporary file after play error: {compressed_path}") except Exception as cleanup_error: logger.error(f"Error cleaning up file {compressed_path}: {str(cleanup_error)}") raise e except Exception as e: logger.error(f"Error in play_compressed: {str(e)}", exc_info=True) await ctx.respond(f"Error playing compressed file: {str(e)}", ephemeral=True) button.callback = button_callback view.add_item(button) await ctx.respond(embed=embed, view=view, ephemeral=True) else: await ctx.respond("Nie znaleziono pliku do odtworzenia", ephemeral=True) else: # For YouTube/SoundCloud try: url, title = await play_utils.PlayUtils(self.bot).get_url(ctx, query) if not url: return filename = await play_utils.PlayUtils(self.bot).download(ctx, url) if not filename: return # Compress the downloaded file compressed_filename = await play_utils.PlayUtils(self.bot).compress(ctx, filename) if compressed_filename: await play_utils.PlayUtils(self.bot).play(ctx, compressed_filename, title) except Exception as e: logger.error(f"Error in play_compressed: {str(e)}") await ctx.respond(f"Error: {str(e)}", ephemeral=True) @discord.slash_command(name="grajcuj_plik", description="grajcuj plik") async def play_file(self, ctx: discord.ApplicationContext, attachment: discord.Attachment = discord.Option(discord.Attachment, "co zagrać??", required=True)): await ctx.defer() file_path = os.path.join(self.temp_dir, attachment.filename) await attachment.save(file_path) await play_utils.PlayUtils(self.bot).play(ctx, file_path) def setup(bot): bot.add_cog(Play(bot))