diff --git a/Controllers/HistoryController.py b/Controllers/HistoryController.py index ffccf83..1765476 100644 --- a/Controllers/HistoryController.py +++ b/Controllers/HistoryController.py @@ -2,7 +2,7 @@ from discord.ext.commands import Context from discord import Client from Controllers.AbstractController import AbstractController from Controllers.ControllerResponse import ControllerResponse -from Utils.Utils import format_time +from Utils.Utils import Utils class HistoryController(AbstractController): @@ -18,7 +18,7 @@ class HistoryController(AbstractController): else: text = f'\nšŸ“œ History Length: {len(history)} | Max: {self.config.MAX_SONGS_HISTORY}\n' for pos, song in enumerate(history, start=1): - text += f"**`{pos}` - ** {song.title} - `{format_time(song.duration)}`\n" + text += f"**`{pos}` - ** {song.title} - `{Utils.format_time(song.duration)}`\n" embed = self.embeds.HISTORY(text) return ControllerResponse(self.ctx, embed) diff --git a/Controllers/QueueController.py b/Controllers/QueueController.py index 231ea63..dc8d15f 100644 --- a/Controllers/QueueController.py +++ b/Controllers/QueueController.py @@ -3,7 +3,7 @@ from discord import Client from Controllers.AbstractController import AbstractController from Controllers.ControllerResponse import ControllerResponse from Music.Downloader import Downloader -from Utils.Utils import format_time +from Utils.Utils import Utils class QueueController(AbstractController): @@ -29,15 +29,15 @@ class QueueController(AbstractController): else: title = self.config.QUEUE_TITLE - total_time = format_time(sum([int(song.duration if song.duration else 0) - for song in songs_preload])) + total_time = Utils.format_time(sum([int(song.duration if song.duration else 0) + for song in songs_preload])) total_songs = len(self.player.playlist) text = f'šŸ“œ Queue length: {total_songs} | āŒ› Duration: `{total_time}` downloaded \n\n' for pos, song in enumerate(songs_preload, start=1): song_name = song.title if song.title else self.config.SONG_DOWNLOADING - text += f"**`{pos}` - ** {song_name} - `{format_time(song.duration)}`\n" + text += f"**`{pos}` - ** {song_name} - `{Utils.format_time(song.duration)}`\n" embed = self.embeds.QUEUE(title, text) return ControllerResponse(self.ctx, embed) diff --git a/Exceptions/Exceptions.py b/Exceptions/Exceptions.py index 80af102..beb7efa 100644 --- a/Exceptions/Exceptions.py +++ b/Exceptions/Exceptions.py @@ -29,6 +29,11 @@ class MusicUnavailable(Error): super().__init__(message, title, *args) +class YoutubeError(Error): + def __init__(self, message='', title='', *args: object) -> None: + super().__init__(message, title, *args) + + class BadCommandUsage(Error): def __init__(self, message='', title='', *args: object) -> None: super().__init__(message, title, *args) diff --git a/Music/Downloader.py b/Music/Downloader.py index d96986d..4df1824 100644 --- a/Music/Downloader.py +++ b/Music/Downloader.py @@ -1,12 +1,10 @@ import asyncio from typing import List - -from numpy import extract from Config.Config import Configs from yt_dlp import YoutubeDL from concurrent.futures import ThreadPoolExecutor from Music.Song import Song -from Utils.Utils import is_url, run_async +from Utils.Utils import Utils, run_async class Downloader(): @@ -39,10 +37,10 @@ class Downloader(): self.__playlist_keys = ['entries'] def finish_one_song(self, song: Song) -> Song: - if song.identifier == None: + if song.identifier is None: return None - if is_url(song.identifier): + if Utils.is_url(song.identifier): song_info = self.__download_url(song.identifier) else: song_info = self.__download_title(song.identifier) @@ -56,7 +54,7 @@ class Downloader(): @run_async def extract_info(self, url: str) -> List[dict]: - if is_url(url): # If Url + if Utils.is_url(url): # If Url options = Downloader.__YDL_OPTIONS_EXTRACT with YoutubeDL(options) as ydl: try: @@ -78,7 +76,7 @@ class Downloader(): return [] except Exception as e: print(f'DEVELOPER NOTE -> Error Extracting Music: {e}') - raise + raise e else: return [] @@ -109,10 +107,11 @@ class Downloader(): return None def __download_func(song: Song) -> None: - if is_url(song.identifier): + if Utils.is_url(song.identifier): song_info = self.__download_url(song.identifier) else: song_info = self.__download_title(song.identifier) + song.finish_down(song_info) # Creating a loop task to download each song diff --git a/Music/Searcher.py b/Music/Searcher.py index 2482acb..f9dd92e 100644 --- a/Music/Searcher.py +++ b/Music/Searcher.py @@ -1,4 +1,4 @@ -from Exceptions.Exceptions import InvalidInput, SpotifyError +from Exceptions.Exceptions import InvalidInput, SpotifyError, YoutubeError from Music.Downloader import Downloader from Music.Types import Provider from Music.Spotify import SpotifySearch @@ -18,8 +18,11 @@ class Searcher(): raise InvalidInput(self.__messages.UNKNOWN_INPUT, self.__messages.UNKNOWN_INPUT_TITLE) elif provider == Provider.YouTube: - musics = await self.__down.extract_info(track) - return musics + try: + musics = await self.__down.extract_info(track) + return musics + except: + raise YoutubeError(self.__messages.YOUTUBE_ERROR, self.__messages.GENERIC_TITLE) elif provider == Provider.Spotify: try: diff --git a/Music/Song.py b/Music/Song.py index d8af059..95b7676 100644 --- a/Music/Song.py +++ b/Music/Song.py @@ -10,6 +10,10 @@ class Song(ISong): self.__playlist: IPlaylist = playlist def finish_down(self, info: dict) -> None: + if info is None: + self.destroy() + return None + self.__usefull_keys = ['duration', 'title', 'webpage_url', 'channel', 'id', 'uploader', diff --git a/Utils/Utils.py b/Utils/Utils.py index f287cdc..83add6e 100644 --- a/Utils/Utils.py +++ b/Utils/Utils.py @@ -32,44 +32,6 @@ class Utils: return False -def is_connected(ctx): - try: - voice_channel = ctx.guild.voice_client.channel - - if not ctx.guild.voice_client.is_connected(): - return None - else: - return voice_channel - except: - return None - - -def format_time(duration) -> str: - if not duration: - return "00:00" - - hours = duration // 60 // 60 - minutes = duration // 60 % 60 - seconds = duration % 60 - - return "{}{}{:02d}:{:02d}".format( - hours if hours else "", - ":" if hours else "", - minutes, - seconds - ) - - -def is_url(string) -> bool: - regex = re.compile( - "http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+") - - if re.search(regex, string): - return True - else: - return False - - class Timer: def __init__(self, callback): self.__callback = callback diff --git a/config/Messages.py b/config/Messages.py index d401fc6..4e8c921 100644 --- a/config/Messages.py +++ b/config/Messages.py @@ -79,3 +79,4 @@ class SearchMessages(Singleton): self.UNKNOWN_INPUT_TITLE = 'Nothing Found' self.SPOTIFY_ERROR = 'Spotify could not process any songs with this input, verify your link or try again later.' self.GENERIC_TITLE = 'Input could not be processed' + self.YOUTUBE_ERROR = 'Youtube could not process any songs with this input, verify your link or try again later.'