From d30ff93dc18ae0aab0850708e31ee39c2ab87b4b Mon Sep 17 00:00:00 2001 From: Rafael Vargas Date: Fri, 25 Mar 2022 00:42:58 -0400 Subject: [PATCH] Adding Moving and Remove Songs Controllers --- Commands/Music.py | 34 ++++++++++-------- Controllers/MoveController.py | 63 +++++++++++++++++++++++++++++++++ Controllers/RemoveController.py | 52 +++++++++++++++++++++++++++ Exceptions/Exceptions.py | 25 +++++++++++++ Music/Player.py | 1 - Music/Playlist.py | 47 ++++++++++-------------- Views/Embeds.py | 51 ++++++++++++++++++++++++-- 7 files changed, 227 insertions(+), 46 deletions(-) create mode 100644 Controllers/MoveController.py create mode 100644 Controllers/RemoveController.py diff --git a/Commands/Music.py b/Commands/Music.py index be17151..35e639a 100644 --- a/Commands/Music.py +++ b/Commands/Music.py @@ -6,8 +6,10 @@ from discord.ext.commands import Context from Config.Config import Configs from Config.Helper import Helper from Controllers.ClearController import ClearController +from Controllers.MoveController import MoveController from Controllers.NowPlayingController import NowPlayingController from Controllers.PlayerController import PlayersController +from Controllers.RemoveController import RemoveController from Music.Player import Player from Utils.Utils import is_connected from Controllers.SkipController import SkipController @@ -166,8 +168,10 @@ class Music(commands.Cog): controller = NowPlayingController(ctx, self.__bot) response = await controller.run() - view = EmbedView(response) - await view.run() + view1 = EmbedView(response) + view2 = EmoteView(response) + await view1.run() + await view2.run() @commands.command(name='shuffle', help=helper.HELP_SHUFFLE, description=helper.HELP_SHUFFLE_LONG, aliases=['aleatorio']) async def shuffle(self, ctx: Context) -> None: @@ -180,21 +184,23 @@ class Music(commands.Cog): @commands.command(name='move', help=helper.HELP_MOVE, description=helper.HELP_MOVE_LONG, aliases=['m', 'mover']) async def move(self, ctx: Context, pos1, pos2='1') -> None: - player = self.__get_player(ctx) - if player is None: - return - else: - description = await player.move(pos1, pos2) - await self.__send_embed(ctx, self.__config.SONG_PLAYER, description, 'blue') + controller = MoveController(ctx, self.__bot) + + response = await controller.run(pos1, pos2) + view1 = EmbedView(response) + view2 = EmoteView(response) + await view1.run() + await view2.run() @commands.command(name='remove', help=helper.HELP_REMOVE, description=helper.HELP_REMOVE_LONG, aliases=['remover']) async def remove(self, ctx: Context, position) -> None: - player = self.__get_player(ctx) - if player is None: - return - else: - description = await player.remove(position) - await self.__send_embed(ctx, self.__config.SONG_PLAYER, description, 'blue') + controller = RemoveController(ctx, self.__bot) + + response = await controller.run(position) + view1 = EmbedView(response) + view2 = EmoteView(response) + await view1.run() + await view2.run() @commands.command(name='reset', help=helper.HELP_RESET, description=helper.HELP_RESET_LONG, aliases=['resetar']) async def reset(self, ctx: Context) -> None: diff --git a/Controllers/MoveController.py b/Controllers/MoveController.py new file mode 100644 index 0000000..c0f170b --- /dev/null +++ b/Controllers/MoveController.py @@ -0,0 +1,63 @@ +from typing import Union +from discord.ext.commands import Context +from discord import Client +from Controllers.AbstractController import AbstractController +from Controllers.ControllerResponse import ControllerResponse +from Exceptions.Exceptions import BadCommandUsage, Error, InvalidInput, NumberRequired, UnknownError, WrongLength +from Music.Downloader import Downloader + + +class MoveController(AbstractController): + def __init__(self, ctx: Context, bot: Client) -> None: + super().__init__(ctx, bot) + self.__down = Downloader() + + async def run(self, pos1: str, pos2: str) -> ControllerResponse: + if not self.player.playing: + embed = self.embeds.NOT_PLAYING() + error = BadCommandUsage() + return ControllerResponse(self.ctx, embed, error) + + error = self.__validate_input(pos1, pos2) + if error: + embed = self.embeds.ERROR_EMBED(error.message) + return ControllerResponse(self.ctx, embed, error) + + pos1, pos2 = self.__sanitize_input(pos1, pos2) + playlist = self.player.playlist + + if not playlist.validate_position(pos1) or not playlist.validate_position(pos2): + error = InvalidInput() + embed = self.embeds.PLAYLIST_RANGE_ERROR() + return ControllerResponse(self.ctx, embed, error) + try: + song = self.player.playlist.move_songs(pos1, pos2) + + songs = self.player.playlist.songs_to_preload + await self.__down.preload(songs) + + song_name = song.title if song.title else song.identifier + embed = self.embeds.SONG_MOVED(song_name, pos1, pos2) + return ControllerResponse(self.ctx, embed) + except: + embed = self.embeds.ERROR_MOVING() + error = UnknownError() + return ControllerResponse(self.ctx, embed, error) + + def __validate_input(self, pos1: str, pos2: str) -> Union[Error, None]: + try: + pos1 = int(pos1) + pos2 = int(pos2) + except: + return NumberRequired(self.config.ERROR_NUMBER) + + def __sanitize_input(self, pos1: int, pos2: int) -> tuple: + pos1 = int(pos1) + pos2 = int(pos2) + + if pos1 == -1: + pos1 = len(self.player.playlist) + if pos2 == -1: + pos2 = len(self.player.playlist) + + return pos1, pos2 diff --git a/Controllers/RemoveController.py b/Controllers/RemoveController.py new file mode 100644 index 0000000..037dd70 --- /dev/null +++ b/Controllers/RemoveController.py @@ -0,0 +1,52 @@ +from typing import Union +from discord.ext.commands import Context +from discord import Client +from Controllers.AbstractController import AbstractController +from Controllers.ControllerResponse import ControllerResponse +from Exceptions.Exceptions import BadCommandUsage, Error, ErrorRemoving, InvalidInput, NumberRequired, UnknownError + + +class RemoveController(AbstractController): + def __init__(self, ctx: Context, bot: Client) -> None: + super().__init__(ctx, bot) + + async def run(self, position: str) -> ControllerResponse: + if not self.player.playlist: + embed = self.embeds.NOT_PLAYING() + error = BadCommandUsage() + return ControllerResponse(self.ctx, embed, error) + + error = self.__validate_input(position) + if error: + embed = self.embeds.ERROR_EMBED(error.message) + return ControllerResponse(self.ctx, embed, error) + + position = self.__sanitize_input(position) + if not self.player.playlist.validate_position(position): + error = InvalidInput() + embed = self.embeds.PLAYLIST_RANGE_ERROR() + return ControllerResponse(self.ctx, embed, error) + + try: + song = self.player.playlist.remove_song(position) + name = song.title if song.title else song.identifier + + embed = self.embeds.SONG_REMOVED(name) + return ControllerResponse(self.ctx, embed) + except: + error = ErrorRemoving() + embed = self.embeds.ERROR_REMOVING() + return ControllerResponse(self.ctx, embed, error) + + def __validate_input(self, position: str) -> Union[Error, None]: + try: + position = int(position) + except: + return NumberRequired(self.config.ERROR_NUMBER) + + def __sanitize_input(self, position: str) -> int: + position = int(position) + + if position == -1: + position = len(self.player.playlist) + return position diff --git a/Exceptions/Exceptions.py b/Exceptions/Exceptions.py index efcb084..c158cf8 100644 --- a/Exceptions/Exceptions.py +++ b/Exceptions/Exceptions.py @@ -37,3 +37,28 @@ class BadCommandUsage(Error): class UnknownError(Error): def __init__(self, message='', title='', *args: object) -> None: super().__init__(message, title, *args) + + +class InvalidInput(Error): + def __init__(self, message='', title='', *args: object) -> None: + super().__init__(message, title, *args) + + +class WrongLength(Error): + def __init__(self, message='', title='', *args: object) -> None: + super().__init__(message, title, *args) + + +class ErrorMoving(Error): + def __init__(self, message='', title='', *args: object) -> None: + super().__init__(message, title, *args) + + +class ErrorRemoving(Error): + def __init__(self, message='', title='', *args: object) -> None: + super().__init__(message, title, *args) + + +class NumberRequired(Error): + def __init__(self, message='', title='', *args: object) -> None: + super().__init__(message, title, *args) diff --git a/Music/Player.py b/Music/Player.py index 22ef4d6..079c813 100644 --- a/Music/Player.py +++ b/Music/Player.py @@ -216,7 +216,6 @@ class Player(commands.Cog): def history(self) -> Embed: history = self.__playlist.songs_history - print(f'Player -> {history}') if len(history) == 0: text = self.__config.HISTORY_EMPTY diff --git a/Music/Playlist.py b/Music/Playlist.py index c115767..4d9b823 100644 --- a/Music/Playlist.py +++ b/Music/Playlist.py @@ -18,6 +18,18 @@ class Playlist(IPlaylist): self.__current: Song = None + def validate_position(self, position: int) -> bool: + if position not in range(1, len(self.__queue) + 1): + return False + else: + return True + + def validate_positions_list(self, positions: list) -> bool: + for position in positions: + if not self.validate_position(position): + return False + return True + @property def songs_history(self) -> deque: return self.__songs_history @@ -113,38 +125,17 @@ class Playlist(IPlaylist): break def move_songs(self, pos1, pos2) -> str: - if pos1 == -1: - pos1 = len(self.__queue) - if pos2 == -1: - pos2 = len(self.__queue) + song = self.__queue[pos1-1] + self.__queue.remove(song) + self.__queue.insert(pos2-1, song) - if pos2 not in range(1, len(self.__queue) + 1) or pos1 not in range(1, len(self.__queue) + 1): - return self.__config.LENGTH_ERROR - - try: - song = self.__queue[pos1-1] - self.__queue.remove(song) - self.__queue.insert(pos2-1, song) - - song1_name = song.title if song.title else song.identifier - - return self.__config.SONG_MOVED_SUCCESSFULLY.format(song1_name, pos1, pos2) - except: - return self.__config.ERROR_MOVING + return song def remove_song(self, position) -> str: - if position == -1: - position = len(self.__queue) + song = self.__queue[position-1] + self.__queue.remove(song) - if position not in range(1, len(self.__queue) + 1): - return self.__config.LENGTH_ERROR - else: - song = self.__queue[position-1] - self.__queue.remove(song) - - song_name = song.title if song.title else song.identifier - - return self.__config.SONG_REMOVED_SUCCESSFULLY.format(song_name) + return song def history(self) -> list: titles = [] diff --git a/Views/Embeds.py b/Views/Embeds.py index 2b3ed19..7b3036f 100644 --- a/Views/Embeds.py +++ b/Views/Embeds.py @@ -62,7 +62,7 @@ class Embeds: embedvc = Embed( title=title, description=f"[{info['title']}]({info['original_url']})", - color=self.__config.COLOURS['blue'] + color=self.__colors.BLUE ) embedvc.add_field(name=self.__config.SONGINFO_UPLOADER, @@ -92,6 +92,37 @@ class Embeds: return embedvc + def SONG_MOVED(self, song_name: str, pos1: int, pos2: int) -> Embed: + embed = Embed( + title=self.__config.SONG_PLAYER, + description=self.__config.SONG_MOVED_SUCCESSFULLY.format(song_name, pos1, pos2), + colour=self.__colors.BLUE + ) + return embed + + def ERROR_MOVING(self) -> Embed: + embed = Embed( + title=self.__config.UNKNOWN_ERROR, + description=self.__config.ERROR_MOVING, + colour=self.__colors.BLACK + ) + return embed + + def ERROR_EMBED(self, description: str) -> Embed: + embed = Embed( + description=description, + colour=self.__colors.BLACK + ) + return embed + + def WRONG_LENGTH_INPUT(self) -> Embed: + embed = Embed( + title=self.__config.BAD_COMMAND_TITLE, + description=self.__config.LENGTH_ERROR, + colour=self.__colors.BLACK + ) + return embed + def BAD_LOOP_USE(self) -> Embed: embed = Embed( title=self.__config.BAD_COMMAND_TITLE, @@ -209,7 +240,7 @@ class Embeds: def ERROR_NUMBER(self) -> Embed: embed = Embed( description=self.__config.ERROR_NUMBER, - colour=self.__colors.RED + colour=self.__colors.BLACK ) return embed @@ -221,6 +252,20 @@ class Embeds: ) return embed + def SONG_REMOVED(self, song_name: str) -> Embed: + embed = Embed( + description=self.__config.SONG_REMOVED_SUCCESSFULLY.format(song_name), + colour=self.__colors.BLUE + ) + return embed + + def PLAYLIST_RANGE_ERROR(self) -> Embed: + embed = Embed( + description=self.__config.LENGTH_ERROR, + colour=self.__colors.BLACK + ) + return embed + def CARA_COROA(self, result: str) -> Embed: embed = Embed( title='Cara Cora', @@ -233,7 +278,7 @@ class Embeds: embed = Embed( title='Choose something', description=f'Chosen: {thing}', - colour=self.__config.COLOURS['green'] + colour=self.__colors.GREEN ) return embed