diff --git a/Config/Colors.py b/Config/Colors.py index 1f55a3d..c990c2a 100644 --- a/Config/Colors.py +++ b/Config/Colors.py @@ -1,7 +1,7 @@ from Config.Singleton import Singleton -class Colors(Singleton): +class VColors(Singleton): def __init__(self) -> None: self.__red = 0xDC143C self.__green = 0x1F8B4C diff --git a/Config/Configs.py b/Config/Configs.py index 09395bb..523f7e1 100644 --- a/Config/Configs.py +++ b/Config/Configs.py @@ -2,7 +2,7 @@ from decouple import config from Config.Singleton import Singleton -class Configs(Singleton): +class VConfigs(Singleton): def __init__(self) -> None: if not super().created: self.BOT_PREFIX = '!' diff --git a/Views/Embeds.py b/Config/Embeds.py similarity index 98% rename from Views/Embeds.py rename to Config/Embeds.py index 894bf52..801a818 100644 --- a/Views/Embeds.py +++ b/Config/Embeds.py @@ -1,16 +1,16 @@ from Config.Messages import Messages from Config.Exceptions import VulkanError from discord import Embed -from Config.Configs import Configs -from Config.Colors import Colors +from Config.Configs import VConfigs +from Config.Colors import VColors from datetime import timedelta -class Embeds: +class VEmbeds: def __init__(self) -> None: - self.__config = Configs() + self.__config = VConfigs() self.__messages = Messages() - self.__colors = Colors() + self.__colors = VColors() def ONE_SONG_LOOPING(self, info: dict) -> Embed: title = self.__messages.ONE_SONG_LOOPING diff --git a/Config/Emojis.py b/Config/Emojis.py new file mode 100644 index 0000000..d34b4d2 --- /dev/null +++ b/Config/Emojis.py @@ -0,0 +1,20 @@ +from Config.Singleton import Singleton + + +class VEmojis(Singleton): + def __init__(self) -> None: + if not super().created: + self.SKIP = "⏩" + self.BACK = "⏪" + self.PAUSE = "⏸️" + self.PLAY = "▶️" + self.STOP = "⏹️" + self.LOOP_ONE = "🔂" + self.LOOP_OFF = "➡️" + self.LOOP_ALL = "🔁" + self.SHUFFLE = "🔀" + self.QUEUE = "📜" + self.MUSIC = "🎧" + self.ERROR = "❌" + self.DOWNLOADING = "📥" + self.SUCCESS = "✅" diff --git a/Config/Helper.py b/Config/Helper.py index 656bfa6..49ee40c 100644 --- a/Config/Helper.py +++ b/Config/Helper.py @@ -1,11 +1,11 @@ from Config.Singleton import Singleton -from Config.Configs import Configs +from Config.Configs import VConfigs class Helper(Singleton): def __init__(self) -> None: if not super().created: - config = Configs() + config = VConfigs() self.HELP_SKIP = 'Skip the current playing song.' self.HELP_SKIP_LONG = 'Skip the playing of the current song, does not work if loop one is activated. \n\nArguments: None.' self.HELP_RESUME = 'Resumes the song player.' diff --git a/Config/Messages.py b/Config/Messages.py index 47ab1b5..aaa24a7 100644 --- a/Config/Messages.py +++ b/Config/Messages.py @@ -1,11 +1,13 @@ from Config.Singleton import Singleton -from Config.Configs import Configs +from Config.Configs import VConfigs +from Config.Emojis import VEmojis class Messages(Singleton): def __init__(self) -> None: if not super().created: - configs = Configs() + self.__emojis = VEmojis() + configs = VConfigs() self.STARTUP_MESSAGE = 'Starting Vulkan...' self.STARTUP_COMPLETE_MESSAGE = 'Vulkan is now operating.' @@ -16,67 +18,67 @@ class Messages(Singleton): self.SONGS_ADDED = 'Downloading `{}` songs to add to the queue' self.SONG_ADDED = 'Downloading the song `{}` to add to the queue' - self.SONG_ADDED_TWO = '🎧 Song added to the queue' - self.SONG_PLAYING = '🎧 Song playing now' - self.SONG_PLAYER = '🎧 Song Player' - self.QUEUE_TITLE = '🎧 Songs in Queue' - self.ONE_SONG_LOOPING = '🎧 Looping One Song' - self.ALL_SONGS_LOOPING = '🎧 Looping All Songs' - self.SONG_PAUSED = '⏸️ Song paused' - self.SONG_RESUMED = '▶️ Song playing' - self.EMPTY_QUEUE = f'📜 Song queue is empty, use {configs.BOT_PREFIX}play to add new songs' - self.SONG_DOWNLOADING = '📥 Downloading...' + self.SONG_ADDED_TWO = f'{self.__emojis.MUSIC} Song added to the queue' + self.SONG_PLAYING = f'{self.__emojis.MUSIC} Song playing now' + self.SONG_PLAYER = f'{self.__emojis.MUSIC} Song Player' + self.QUEUE_TITLE = f'{self.__emojis.MUSIC} Songs in Queue' + self.ONE_SONG_LOOPING = f'{self.__emojis.MUSIC} Looping One Song' + self.ALL_SONGS_LOOPING = f'{self.__emojis.MUSIC} Looping All Songs' + self.SONG_PAUSED = f'{self.__emojis.PAUSE} Song paused' + self.SONG_RESUMED = f'{self.__emojis.PLAY} Song playing' + self.EMPTY_QUEUE = f'{self.__emojis.QUEUE} Song queue is empty, use {configs.BOT_PREFIX}play to add new songs' + self.SONG_DOWNLOADING = f'{self.__emojis.DOWNLOADING} Downloading...' - self.HISTORY_TITLE = '🎧 Played Songs' - self.HISTORY_EMPTY = '📜 There is no musics in history' + self.HISTORY_TITLE = f'{self.__emojis.MUSIC} Played Songs' + self.HISTORY_EMPTY = f'{self.__emojis.QUEUE} There is no musics in history' self.SONG_MOVED_SUCCESSFULLY = 'Song `{}` in position `{}` moved to the position `{}` successfully' self.SONG_REMOVED_SUCCESSFULLY = 'Song `{}` removed successfully' - self.LOOP_ALL_ON = f'❌ Vulkan is looping all songs, use {configs.BOT_PREFIX}loop off to disable this loop first' - self.LOOP_ONE_ON = f'❌ Vulkan is looping one song, use {configs.BOT_PREFIX}loop off to disable this loop first' - self.LOOP_ALL_ALREADY_ON = '🔁 Vulkan is already looping all songs' - self.LOOP_ONE_ALREADY_ON = '🔂 Vulkan is already looping the current song' - self.LOOP_ALL_ACTIVATE = '🔁 Looping all songs' - self.LOOP_ONE_ACTIVATE = '🔂 Looping the current song' - self.LOOP_DISABLE = '➡️ Loop disabled' - self.LOOP_ALREADY_DISABLE = '❌ Loop is already disabled' - self.LOOP_ON = f'❌ This command cannot be invoked with any loop activated. Use {configs.BOT_PREFIX}loop off to disable loop' - self.BAD_USE_OF_LOOP = f"""❌ Invalid arguments of Loop command. Use {configs.BOT_PREFIX}help loop to more information. - -> Available Arguments: ["all", "off", "one", ""]""" + self.LOOP_ALL_ON = f'{self.__emojis.ERROR} Vulkan is looping all songs, use {configs.BOT_PREFIX}loop off to disable this loop first' + self.LOOP_ONE_ON = f'{self.__emojis.ERROR} Vulkan is looping one song, use {configs.BOT_PREFIX}loop off to disable this loop first' + self.LOOP_ALL_ALREADY_ON = f'{self.__emojis.LOOP_ALL} Vulkan is already looping all songs' + self.LOOP_ONE_ALREADY_ON = f'{self.__emojis.LOOP_ONE} Vulkan is already looping the current song' + self.LOOP_ALL_ACTIVATE = f'{self.__emojis.LOOP_ALL} Looping all songs' + self.LOOP_ONE_ACTIVATE = f'{self.__emojis.LOOP_ONE} Looping the current song' + self.LOOP_DISABLE = f'{self.__emojis.LOOP_OFF} Loop disabled' + self.LOOP_ALREADY_DISABLE = f'{self.__emojis.ERROR} Loop is already disabled' + self.LOOP_ON = f'{self.__emojis.ERROR} This command cannot be invoked with any loop activated. Use {configs.BOT_PREFIX}loop off to disable loop' + self.BAD_USE_OF_LOOP = f"""{self.__emojis.ERROR} Invalid arguments of Loop command. Use {configs.BOT_PREFIX}help loop to more information. + -> Available Arguments: ["all", "off", "one", ""]""" - self.SONGS_SHUFFLED = '🔀 Songs shuffled successfully' - self.ERROR_SHUFFLING = '❌ Error while shuffling the songs' - self.ERROR_MOVING = '❌ Error while moving the songs' - self.LENGTH_ERROR = '❌ Numbers must be between 1 and queue length, use -1 for the last song' - self.ERROR_NUMBER = '❌ This command require a number' - self.ERROR_PLAYING = '❌ Error while playing songs' - self.COMMAND_NOT_FOUND = f'❌ Command not found, type {configs.BOT_PREFIX}help to see all commands' - self.UNKNOWN_ERROR = f'❌ Unknown Error, if needed, use {configs.BOT_PREFIX}reset to reset the player of your server' - self.ERROR_MISSING_ARGUMENTS = f'❌ Missing arguments in this command. Type {configs.BOT_PREFIX}help "command" to see more info about this command' - self.NOT_PREVIOUS = '❌ There is none previous song to play' - self.PLAYER_NOT_PLAYING = f'❌ No song playing. Use {configs.BOT_PREFIX}play to start the player' + self.SONGS_SHUFFLED = f'{self.__emojis.SHUFFLE} Songs shuffled successfully' + self.ERROR_SHUFFLING = f'{self.__emojis.ERROR} Error while shuffling the songs' + self.ERROR_MOVING = f'{self.__emojis.ERROR} Error while moving the songs' + self.LENGTH_ERROR = f'{self.__emojis.ERROR} Numbers must be between 1 and queue length, use -1 for the last song' + self.ERROR_NUMBER = f'{self.__emojis.ERROR} This command require a number' + self.ERROR_PLAYING = f'{self.__emojis.ERROR} Error while playing songs' + self.COMMAND_NOT_FOUND = f'{self.__emojis.ERROR} Command not found, type {configs.BOT_PREFIX}help to see all commands' + self.UNKNOWN_ERROR = f'{self.__emojis.ERROR} Unknown Error, if needed, use {configs.BOT_PREFIX}reset to reset the player of your server' + self.ERROR_MISSING_ARGUMENTS = f'{self.__emojis.ERROR} Missing arguments in this command. Type {configs.BOT_PREFIX}help "command" to see more info about this command' + self.NOT_PREVIOUS = f'{self.__emojis.ERROR} There is none previous song to play' + self.PLAYER_NOT_PLAYING = f'{self.__emojis.ERROR} No song playing. Use {configs.BOT_PREFIX}play to start the player' self.IMPOSSIBLE_MOVE = 'That is impossible :(' self.ERROR_TITLE = 'Error :-(' self.COMMAND_NOT_FOUND_TITLE = 'This is strange :-(' self.NO_CHANNEL = 'To play some music, connect to any voice channel first.' self.NO_GUILD = f'This server does not has a Player, try {configs.BOT_PREFIX}reset' self.INVALID_INPUT = f'This URL was too strange, try something better or type {configs.BOT_PREFIX}help play' - self.DOWNLOADING_ERROR = "❌ It's impossible to download and play this video" - self.EXTRACTING_ERROR = '❌ An error ocurred while searching for the songs' + self.DOWNLOADING_ERROR = f"{self.__emojis.ERROR} It's impossible to download and play this video" + self.EXTRACTING_ERROR = f'{self.__emojis.ERROR} An error ocurred while searching for the songs' - self.ERROR_IN_PROCESS = "❌ Due to a internal error your player was restarted, skipping the song." + self.ERROR_IN_PROCESS = f"{self.__emojis.ERROR} Due to a internal error your player was restarted, skipping the song." self.MY_ERROR_BAD_COMMAND = 'This string serves to verify if some error was raised by myself on purpose' self.BAD_COMMAND_TITLE = 'Misuse of command' - self.BAD_COMMAND = f'❌ Bad usage of this command, type {configs.BOT_PREFIX}help "command" to understand the command better' - self.VIDEO_UNAVAILABLE = '❌ Sorry. This video is unavailable for download.' - self.ERROR_DUE_LOOP_ONE_ON = f'❌ This command cannot be executed with loop one activated. Use {configs.BOT_PREFIX}loop off to disable loop.' + self.BAD_COMMAND = f'{self.__emojis.ERROR} Bad usage of this command, type {configs.BOT_PREFIX}help "command" to understand the command better' + self.VIDEO_UNAVAILABLE = f'{self.__emojis.ERROR} Sorry. This video is unavailable for download.' + self.ERROR_DUE_LOOP_ONE_ON = f'{self.__emojis.ERROR} This command cannot be executed with loop one activated. Use {configs.BOT_PREFIX}loop off to disable loop.' class SearchMessages(Singleton): def __init__(self) -> None: if not super().created: - config = Configs() + config = VConfigs() self.UNKNOWN_INPUT = f'This type of input was too strange, try something else or type {config.BOT_PREFIX}help play' self.UNKNOWN_INPUT_TITLE = 'Nothing Found' self.GENERIC_TITLE = 'URL could not be processed' diff --git a/DiscordCogs/ControlCog.py b/DiscordCogs/ControlCog.py index 5b3ae94..a3cce55 100644 --- a/DiscordCogs/ControlCog.py +++ b/DiscordCogs/ControlCog.py @@ -1,10 +1,10 @@ from discord import Embed from discord.ext.commands import Cog, command -from Config.Configs import Configs +from Config.Configs import VConfigs from Config.Helper import Helper -from Config.Colors import Colors +from Config.Colors import VColors from Music.VulkanBot import VulkanBot -from Views.Embeds import Embeds +from Config.Embeds import VEmbeds helper = Helper() @@ -14,9 +14,9 @@ class ControlCog(Cog): def __init__(self, bot: VulkanBot): self.__bot = bot - self.__config = Configs() - self.__colors = Colors() - self.__embeds = Embeds() + self.__config = VConfigs() + self.__colors = VColors() + self.__embeds = VEmbeds() self.__commands = { 'MUSIC': ['resume', 'pause', 'loop', 'stop', 'skip', 'play', 'queue', 'clear', diff --git a/DiscordCogs/MusicCog.py b/DiscordCogs/MusicCog.py index b54fce8..d97e71f 100644 --- a/DiscordCogs/MusicCog.py +++ b/DiscordCogs/MusicCog.py @@ -1,4 +1,3 @@ -from discord import Guild, Client from discord.ext.commands import Context, command, Cog from Config.Helper import Helper from Handlers.ClearHandler import ClearHandler @@ -16,8 +15,10 @@ from Handlers.ResumeHandler import ResumeHandler from Handlers.HistoryHandler import HistoryHandler from Handlers.QueueHandler import QueueHandler from Handlers.LoopHandler import LoopHandler -from Views.EmoteView import EmoteView -from Views.EmbedView import EmbedView +from Views.EmoteCogResponse import EmoteCommandResponse +from Views.EmbedCogResponse import EmbedCommandResponse +from Views.PlayerView import PlayerView +from Music.VulkanBot import VulkanBot helper = Helper() @@ -29,8 +30,8 @@ class MusicCog(Cog): Execute the handler and then create a specific View to be showed in Discord """ - def __init__(self, bot) -> None: - self.__bot: Client = bot + def __init__(self, bot: VulkanBot) -> None: + self.__bot: VulkanBot = bot @command(name="play", help=helper.HELP_PLAY, description=helper.HELP_PLAY_LONG, aliases=['p', 'tocar']) async def play(self, ctx: Context, *args) -> None: @@ -39,8 +40,8 @@ class MusicCog(Cog): response = await controller.run(args) if response is not None: - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -52,7 +53,7 @@ class MusicCog(Cog): controller = QueueHandler(ctx, self.__bot) response = await controller.run() - view2 = EmbedView(response) + view2 = EmbedCommandResponse(response) await view2.run() except Exception as e: print(f'[ERROR IN COG] -> {e}') @@ -64,9 +65,9 @@ class MusicCog(Cog): response = await controller.run() if response.success: - view = EmoteView(response) + view = EmoteCommandResponse(response) else: - view = EmbedView(response) + view = EmbedCommandResponse(response) await view.run() except Exception as e: @@ -79,9 +80,9 @@ class MusicCog(Cog): response = await controller.run() if response.success: - view = EmoteView(response) + view = EmoteCommandResponse(response) else: - view = EmbedView(response) + view = EmbedCommandResponse(response) await view.run() except Exception as e: @@ -93,8 +94,8 @@ class MusicCog(Cog): controller = PauseHandler(ctx, self.__bot) response = await controller.run() - view1 = EmoteView(response) - view2 = EmbedView(response) + view1 = EmoteCommandResponse(response) + view2 = EmbedCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -106,8 +107,8 @@ class MusicCog(Cog): controller = ResumeHandler(ctx, self.__bot) response = await controller.run() - view1 = EmoteView(response) - view2 = EmbedView(response) + view1 = EmoteCommandResponse(response) + view2 = EmbedCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -120,8 +121,8 @@ class MusicCog(Cog): response = await controller.run() if response is not None: - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -133,8 +134,8 @@ class MusicCog(Cog): controller = HistoryHandler(ctx, self.__bot) response = await controller.run() - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -146,8 +147,8 @@ class MusicCog(Cog): controller = LoopHandler(ctx, self.__bot) response = await controller.run(args) - view1 = EmoteView(response) - view2 = EmbedView(response) + view1 = EmoteCommandResponse(response) + view2 = EmbedCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -159,7 +160,7 @@ class MusicCog(Cog): controller = ClearHandler(ctx, self.__bot) response = await controller.run() - view = EmoteView(response) + view = EmoteCommandResponse(response) await view.run() except Exception as e: print(f'[ERROR IN COG] -> {e}') @@ -170,8 +171,8 @@ class MusicCog(Cog): controller = NowPlayingHandler(ctx, self.__bot) response = await controller.run() - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -183,8 +184,8 @@ class MusicCog(Cog): controller = ShuffleHandler(ctx, self.__bot) response = await controller.run() - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -196,8 +197,8 @@ class MusicCog(Cog): controller = MoveHandler(ctx, self.__bot) response = await controller.run(pos1, pos2) - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -209,8 +210,8 @@ class MusicCog(Cog): controller = RemoveHandler(ctx, self.__bot) response = await controller.run(position) - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: @@ -222,13 +223,18 @@ class MusicCog(Cog): controller = ResetHandler(ctx, self.__bot) response = await controller.run() - view1 = EmbedView(response) - view2 = EmoteView(response) + view1 = EmbedCommandResponse(response) + view2 = EmoteCommandResponse(response) await view1.run() await view2.run() except Exception as e: print(f'[ERROR IN COG] -> {e}') + @command(name='rafael') + async def rafael(self, ctx: Context) -> None: + view = PlayerView() + await ctx.send(view=view) + def setup(bot): bot.add_cog(MusicCog(bot)) diff --git a/DiscordCogs/RandomCog.py b/DiscordCogs/RandomCog.py index 6ec53c7..7de8a2f 100644 --- a/DiscordCogs/RandomCog.py +++ b/DiscordCogs/RandomCog.py @@ -2,7 +2,7 @@ from random import randint, random from Music.VulkanBot import VulkanBot from discord.ext.commands import Context, command, Cog from Config.Helper import Helper -from Views.Embeds import Embeds +from Config.Embeds import VEmbeds helper = Helper() @@ -11,7 +11,7 @@ class RandomCog(Cog): """Class to listen to commands of type Random""" def __init__(self, bot: VulkanBot): - self.__embeds = Embeds() + self.__embeds = VEmbeds() @command(name='random', help=helper.HELP_RANDOM, description=helper.HELP_RANDOM_LONG, aliases=['rand']) async def random(self, ctx: Context, arg: str) -> None: diff --git a/Handlers/AbstractHandler.py b/Handlers/AbstractHandler.py index de9d592..a1f188d 100644 --- a/Handlers/AbstractHandler.py +++ b/Handlers/AbstractHandler.py @@ -5,9 +5,9 @@ from discord import Client, Guild, ClientUser, Member from Config.Messages import Messages from Music.VulkanBot import VulkanBot from Handlers.HandlerResponse import HandlerResponse -from Config.Configs import Configs +from Config.Configs import VConfigs from Config.Helper import Helper -from Views.Embeds import Embeds +from Config.Embeds import VEmbeds class AbstractHandler(ABC): @@ -18,9 +18,9 @@ class AbstractHandler(ABC): self.__bot_user: ClientUser = self.__bot.user self.__id = self.__bot_user.id self.__messages = Messages() - self.__config = Configs() + self.__config = VConfigs() self.__helper = Helper() - self.__embeds = Embeds() + self.__embeds = VEmbeds() self.__bot_member: Member = self.__get_member() @abstractmethod @@ -48,7 +48,7 @@ class AbstractHandler(ABC): return self.__bot @property - def config(self) -> Configs: + def config(self) -> VConfigs: return self.__config @property @@ -64,7 +64,7 @@ class AbstractHandler(ABC): return self.__ctx @property - def embeds(self) -> Embeds: + def embeds(self) -> VEmbeds: return self.__embeds def __get_member(self) -> Member: diff --git a/Music/Downloader.py b/Music/Downloader.py index 3b97c8d..97a22d0 100644 --- a/Music/Downloader.py +++ b/Music/Downloader.py @@ -1,6 +1,6 @@ import asyncio from typing import List -from Config.Configs import Configs +from Config.Configs import VConfigs from yt_dlp import YoutubeDL, DownloadError from concurrent.futures import ThreadPoolExecutor from Music.Song import Song @@ -9,7 +9,7 @@ from Config.Exceptions import DownloadingError class Downloader: - config = Configs() + config = VConfigs() __YDL_OPTIONS = {'format': 'bestaudio/best', 'default_search': 'auto', 'playliststart': 0, @@ -34,7 +34,7 @@ class Downloader: __BASE_URL = 'https://www.youtube.com/watch?v={}' def __init__(self) -> None: - self.__config = Configs() + self.__config = VConfigs() self.__music_keys_only = ['resolution', 'fps', 'quality'] self.__not_extracted_keys_only = ['ie_key'] self.__not_extracted_not_keys = ['entries'] diff --git a/Music/Playlist.py b/Music/Playlist.py index 33bcbce..82be37f 100644 --- a/Music/Playlist.py +++ b/Music/Playlist.py @@ -1,6 +1,6 @@ from collections import deque from typing import List -from Config.Configs import Configs +from Config.Configs import VConfigs from Music.Song import Song import random @@ -8,7 +8,7 @@ import random class Playlist: def __init__(self) -> None: - self.__configs = Configs() + self.__configs = VConfigs() self.__queue = deque() # Store the musics to play self.__songs_history = deque() # Store the musics played @@ -62,7 +62,7 @@ class Playlist: # Att played song info if played_song != None: if not self.__looping_one and not self.__looping_all: - if played_song.problematic == False: + if not played_song.problematic: self.__songs_history.appendleft(played_song) if len(self.__songs_history) > self.__configs.MAX_SONGS_HISTORY: @@ -90,6 +90,7 @@ class Playlist: self.__queue.appendleft(self.__current) last_song = self.__songs_history.popleft() # Get the last song + print(f'Setando como {last_song} 2') self.__current = last_song return self.__current # return the song diff --git a/Music/SpotifySearcher.py b/Music/SpotifySearcher.py index f663b3a..c423dd5 100644 --- a/Music/SpotifySearcher.py +++ b/Music/SpotifySearcher.py @@ -2,14 +2,14 @@ from spotipy import Spotify from spotipy.oauth2 import SpotifyClientCredentials from spotipy.exceptions import SpotifyException from Config.Exceptions import SpotifyError -from Config.Configs import Configs +from Config.Configs import VConfigs from Config.Messages import SpotifyMessages class SpotifySearch(): def __init__(self) -> None: self.__messages = SpotifyMessages() - self.__config = Configs() + self.__config = VConfigs() self.__connected = False self.__connect() diff --git a/Music/VulkanBot.py b/Music/VulkanBot.py index 5b2ce45..8a8ba2a 100644 --- a/Music/VulkanBot.py +++ b/Music/VulkanBot.py @@ -1,18 +1,18 @@ from asyncio import AbstractEventLoop from discord import Guild, Status, Game, Message from discord.ext.commands.errors import CommandNotFound, MissingRequiredArgument -from Config.Configs import Configs +from Config.Configs import VConfigs from discord.ext.commands import Bot, Context from Config.Messages import Messages -from Views.Embeds import Embeds +from Config.Embeds import VEmbeds class VulkanBot(Bot): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.__configs = Configs() + self.__configs = VConfigs() self.__messages = Messages() - self.__embeds = Embeds() + self.__embeds = VEmbeds() self.remove_command("help") def startBot(self) -> None: diff --git a/Music/VulkanInitializer.py b/Music/VulkanInitializer.py index 6121aeb..b366257 100644 --- a/Music/VulkanInitializer.py +++ b/Music/VulkanInitializer.py @@ -4,13 +4,13 @@ from discord.bot import Bot from discord import Intents from Music.VulkanBot import VulkanBot from os import listdir -from Config.Configs import Configs +from Config.Configs import VConfigs from Config.Exceptions import VulkanError class VulkanInitializer: def __init__(self, willListen: bool) -> None: - self.__config = Configs() + self.__config = VConfigs() self.__intents = Intents.default() self.__intents.message_content = True self.__intents.members = True diff --git a/Parallelism/PlayerProcess.py b/Parallelism/PlayerProcess.py index 5cbc522..b3caec7 100644 --- a/Parallelism/PlayerProcess.py +++ b/Parallelism/PlayerProcess.py @@ -5,13 +5,13 @@ from asyncio import AbstractEventLoop, Semaphore from multiprocessing import Process, Queue, RLock from threading import Lock, Thread from typing import Callable, List -from discord import Client, Guild, FFmpegPCMAudio, VoiceChannel, TextChannel +from discord import Guild, FFmpegPCMAudio, VoiceChannel, TextChannel from Music.Playlist import Playlist from Music.Song import Song -from Config.Configs import Configs +from Config.Configs import VConfigs from Config.Messages import Messages from Music.VulkanBot import VulkanBot -from Views.Embeds import Embeds +from Config.Embeds import VEmbeds from Parallelism.Commands import VCommands, VCommandsType @@ -21,7 +21,7 @@ class TimeoutClock: self.__task = loop.create_task(self.__executor()) async def __executor(self): - await asyncio.sleep(Configs().VC_TIMEOUT) + await asyncio.sleep(VConfigs().VC_TIMEOUT) await self.__callback() def cancel(self): @@ -56,8 +56,8 @@ class PlayerProcess(Process): self.__author: User = None self.__botMember: Member = None - self.__configs: Configs = None - self.__embeds: Embeds = None + self.__configs: VConfigs = None + self.__embeds: VEmbeds = None self.__messages: Messages = None self.__messagesToDelete: List[Message] = [] self.__playing = False @@ -73,9 +73,9 @@ class PlayerProcess(Process): self.__loop = asyncio.get_event_loop_policy().new_event_loop() asyncio.set_event_loop(self.__loop) - self.__configs = Configs() + self.__configs = VConfigs() self.__messages = Messages() - self.__embeds = Embeds() + self.__embeds = VEmbeds() self.__semStopPlaying = Semaphore(0) self.__loop.run_until_complete(self._run()) @@ -108,9 +108,13 @@ class PlayerProcess(Process): self.__timer.cancel() async def __playPlaylistSongs(self) -> None: + """If the player is not running trigger to play a new song""" if not self.__playing: + song = None with self.__playlistLock: - song = self.__playlist.next_song() + with self.__playerLock: + if not (self.__guild.voice_client.is_playing() or self.__guild.voice_client.is_paused()): + song = self.__playlist.next_song() if song is not None: self.__loop.create_task(self.__playSong(song), name=f'Song {song.identifier}') @@ -151,40 +155,40 @@ class PlayerProcess(Process): self.__playerLock.release() def __playNext(self, error) -> None: - with self.__playerLock: - if self.__forceStop: # If it's forced to stop player - self.__forceStop = False - return None + with self.__playlistLock: + with self.__playerLock: + if self.__forceStop: # If it's forced to stop player + self.__forceStop = False + return None - with self.__playlistLock: song = self.__playlist.next_song() - if song is not None: - self.__loop.create_task(self.__playSong(song), name=f'Song {song.identifier}') - else: - with self.__playlistLock: + if song is not None: + self.__loop.create_task(self.__playSong(song), name=f'Song {song.identifier}') + else: self.__playlist.loop_off() - self.__playingSong = None - self.__playing = False + self.__playingSong = None + self.__playing = False async def __playPrev(self, voiceChannelID: int) -> None: with self.__playlistLock: song = self.__playlist.prev_song() - if song is not None: - if self.__guild.voice_client is None: # If not connect, connect to the user voice channel - self.__voiceChannelID = voiceChannelID - self.__voiceChannel = self.__guild.get_channel(self.__voiceChannelID) - await self.__connectToVoiceChannel() + with self.__playerLock: + if song is not None: + if self.__guild.voice_client is None: # If not connect, connect to the user voice channel + self.__voiceChannelID = voiceChannelID + self.__voiceChannel = self.__guild.get_channel(self.__voiceChannelID) + await self.__connectToVoiceChannel() - # If already playing, stop the current play - if self.__guild.voice_client.is_playing() or self.__guild.voice_client.is_paused(): - # Will forbidden next_song to execute after stopping current player - self.__forceStop = True - self.__guild.voice_client.stop() - self.__playing = False + # If already playing, stop the current play + if self.__guild.voice_client.is_playing() or self.__guild.voice_client.is_paused(): + # Will forbidden next_song to execute after stopping current player + self.__forceStop = True + self.__guild.voice_client.stop() + self.__playing = False - self.__loop.create_task(self.__playSong(song), name=f'Song {song.identifier}') + self.__loop.create_task(self.__playSong(song), name=f'Song {song.identifier}') def __commandsReceiver(self) -> None: while True: diff --git a/Utils/Utils.py b/Utils/Utils.py index 95db315..26b6dd3 100644 --- a/Utils/Utils.py +++ b/Utils/Utils.py @@ -1,8 +1,8 @@ import re import asyncio -from Config.Configs import Configs +from Config.Configs import VConfigs from functools import wraps, partial -config = Configs() +config = VConfigs() class Utils: diff --git a/Views/AbstractView.py b/Views/AbstractCogResponse.py similarity index 95% rename from Views/AbstractView.py rename to Views/AbstractCogResponse.py index 41e71b1..36d7b68 100644 --- a/Views/AbstractView.py +++ b/Views/AbstractCogResponse.py @@ -5,7 +5,7 @@ from discord import Message from Music.VulkanBot import VulkanBot -class AbstractView(ABC): +class AbstractCommandResponse(ABC): def __init__(self, response: HandlerResponse) -> None: self.__response: HandlerResponse = response self.__context: Context = response.ctx diff --git a/Views/EmbedView.py b/Views/EmbedCogResponse.py similarity index 70% rename from Views/EmbedView.py rename to Views/EmbedCogResponse.py index 0e21d5d..dba8053 100644 --- a/Views/EmbedView.py +++ b/Views/EmbedCogResponse.py @@ -1,8 +1,8 @@ -from Views.AbstractView import AbstractView +from Views.AbstractCogResponse import AbstractCommandResponse from Handlers.HandlerResponse import HandlerResponse -class EmbedView(AbstractView): +class EmbedCommandResponse(AbstractCommandResponse): def __init__(self, response: HandlerResponse) -> None: super().__init__(response) diff --git a/Views/EmoteCogResponse.py b/Views/EmoteCogResponse.py new file mode 100644 index 0000000..79b4a3e --- /dev/null +++ b/Views/EmoteCogResponse.py @@ -0,0 +1,16 @@ +from Config.Emojis import VEmojis +from Views.AbstractCogResponse import AbstractCommandResponse +from Handlers.HandlerResponse import HandlerResponse + + +class EmoteCommandResponse(AbstractCommandResponse): + + def __init__(self, response: HandlerResponse) -> None: + super().__init__(response) + self.__emojis = VEmojis() + + async def run(self) -> None: + if self.response.success: + await self.message.add_reaction(self.__emojis.SUCCESS) + else: + await self.message.add_reaction(self.__emojis.ERROR) diff --git a/Views/EmoteView.py b/Views/EmoteView.py deleted file mode 100644 index a70202d..0000000 --- a/Views/EmoteView.py +++ /dev/null @@ -1,14 +0,0 @@ -from Views.AbstractView import AbstractView -from Handlers.HandlerResponse import HandlerResponse - - -class EmoteView(AbstractView): - - def __init__(self, response: HandlerResponse) -> None: - super().__init__(response) - - async def run(self) -> None: - if self.response.success: - await self.message.add_reaction('✅') - else: - await self.message.add_reaction('❌') diff --git a/Views/PlayerView.py b/Views/PlayerView.py new file mode 100644 index 0000000..79e6a5c --- /dev/null +++ b/Views/PlayerView.py @@ -0,0 +1,47 @@ +from typing import Optional +from discord.ui import View, Button, button +from Config.Emojis import VEmojis +from discord import Interaction, ButtonStyle + +emojis = VEmojis() + + +class PlayerView(View): + def __init__(self, timeout: Optional[float] = 180): + super().__init__(timeout=timeout) + + @button(label="Back", style=ButtonStyle.secondary, emoji=emojis.BACK) + async def prevCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Pause", style=ButtonStyle.secondary, emoji=emojis.PAUSE) + async def pauseCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Play", style=ButtonStyle.secondary, emoji=emojis.PLAY) + async def playCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Stop", style=ButtonStyle.secondary, emoji=emojis.STOP) + async def stopCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Skip", style=ButtonStyle.secondary, emoji=emojis.SKIP) + async def skipCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Songs", style=ButtonStyle.secondary, emoji=emojis.QUEUE) + async def songsCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Loop Off", style=ButtonStyle.grey, emoji=emojis.LOOP_OFF) + async def loopOffCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Loop All", style=ButtonStyle.secondary, emoji=emojis.LOOP_ALL) + async def loopAllCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello") + + @button(label="Loop One", style=ButtonStyle.secondary, emoji=emojis.LOOP_ONE) + async def loopOneCallback(self, button: Button, interaction: Interaction) -> None: + await interaction.response.send_message("Hello")