mirror of
https://github.com/RafaelSolVargas/Vulkan.git
synced 2025-10-29 16:57:23 +00:00
Adding Deezer Module and Deezer Tests
This commit is contained in:
parent
c826af229c
commit
863b079a01
@ -75,10 +75,10 @@ class SearchMessages(Singleton):
|
||||
config = Configs()
|
||||
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.SPOTIFY_ERROR = 'Spotify could not process any songs with this input, verify your link or try again later.'
|
||||
self.GENERIC_TITLE = 'URL could not be processed'
|
||||
self.YOUTUBE_ERROR = 'Youtube could not process any songs with this input, verify your link or try again later.'
|
||||
self.INVALID_SPOTIFY_URL = 'Invalid Spotify URL, verify your link.'
|
||||
self.SPOTIFY_NOT_FOUND = 'Spotify could not process any songs with this input, verify your link or try again later.'
|
||||
self.YOUTUBE_NOT_FOUND = 'Youtube could not process any songs with this input, verify your link or try again later.'
|
||||
self.DEEZER_NOT_FOUND = 'Deezer could not process any songs with this input, verify your link or try again later.'
|
||||
|
||||
|
||||
class SpotifyMessages(Singleton):
|
||||
@ -86,3 +86,10 @@ class SpotifyMessages(Singleton):
|
||||
if not super().created:
|
||||
self.INVALID_SPOTIFY_URL = 'Invalid Spotify URL, verify your link.'
|
||||
self.GENERIC_TITLE = 'URL could not be processed'
|
||||
|
||||
|
||||
class DeezerMessages(Singleton):
|
||||
def __init__(self) -> None:
|
||||
if not super().created:
|
||||
self.INVALID_DEEZER_URL = 'Invalid Deezer URL, verify your link.'
|
||||
self.GENERIC_TITLE = 'URL could not be processed'
|
||||
|
||||
@ -49,6 +49,11 @@ class SpotifyError(VulkanError):
|
||||
super().__init__(message, title, *args)
|
||||
|
||||
|
||||
class DeezerError(VulkanError):
|
||||
def __init__(self, message='', title='', *args: object) -> None:
|
||||
super().__init__(message, title, *args)
|
||||
|
||||
|
||||
class UnknownError(VulkanError):
|
||||
def __init__(self, message='', title='', *args: object) -> None:
|
||||
super().__init__(message, title, *args)
|
||||
|
||||
72
Music/DeezerSearcher.py
Normal file
72
Music/DeezerSearcher.py
Normal file
@ -0,0 +1,72 @@
|
||||
import deezer
|
||||
from Exceptions.Exceptions import DeezerError
|
||||
from Config.Messages import DeezerMessages
|
||||
|
||||
|
||||
class DeezerSearcher:
|
||||
def __init__(self) -> None:
|
||||
self.__client = deezer.Client()
|
||||
self.__messages = DeezerMessages()
|
||||
self.__acceptedTypes = ['track', 'artist', 'playlist', 'album']
|
||||
|
||||
def search(self, url: str) -> None:
|
||||
if not self.__verifyValidUrl(url):
|
||||
raise DeezerError(self.__messages.INVALID_DEEZER_URL, self.__messages.GENERIC_TITLE)
|
||||
|
||||
urlType = url.split('/')[4].split('?')[0]
|
||||
code = int(url.split('/')[5].split('?')[0])
|
||||
|
||||
try:
|
||||
musics = []
|
||||
if urlType == 'album':
|
||||
musics = self.__get_album(code)
|
||||
elif urlType == 'playlist':
|
||||
musics = self.__get_playlist(code)
|
||||
elif urlType == 'track':
|
||||
musics = self.__get_track(code)
|
||||
elif urlType == 'artist':
|
||||
musics = self.__get_artist(code)
|
||||
|
||||
return musics
|
||||
except Exception as e:
|
||||
print(f'[DEEZER ERROR] -> {e}')
|
||||
raise DeezerError(self.__messages.INVALID_DEEZER_URL, self.__messages.GENERIC_TITLE)
|
||||
|
||||
def __get_album(self, code: int) -> list:
|
||||
album = self.__client.get_album(code)
|
||||
|
||||
return [track.title for track in album.tracks]
|
||||
|
||||
def __get_track(self, code: int) -> list:
|
||||
track = self.__client.get_track(code)
|
||||
|
||||
return [track.title]
|
||||
|
||||
def __get_playlist(self, code: int) -> list:
|
||||
playlist = self.__client.get_playlist(code)
|
||||
|
||||
return [track.title for track in playlist.tracks]
|
||||
|
||||
def __get_artist(self, code: int) -> list:
|
||||
artist = self.__client.get_artist(code)
|
||||
|
||||
topMusics = artist.get_top()
|
||||
|
||||
return [track.title for track in topMusics]
|
||||
|
||||
def __verifyValidUrl(self, url: str) -> bool:
|
||||
try:
|
||||
urlType = url.split('/')[4].split('?')[0]
|
||||
code = url.split('/')[5].split('?')[0]
|
||||
|
||||
code = int(code)
|
||||
|
||||
if urlType == '' or code == '':
|
||||
return False
|
||||
|
||||
if urlType not in self.__acceptedTypes:
|
||||
return False
|
||||
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
@ -65,6 +65,7 @@ class Downloader():
|
||||
with YoutubeDL(options) as ydl:
|
||||
try:
|
||||
extracted_info = ydl.extract_info(url, download=False)
|
||||
# Some links doesn't extract unless extract_flat key is passed as False in options
|
||||
if self.__failed_to_extract(extracted_info):
|
||||
extracted_info = self.__get_forced_extracted_info(url)
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
from Exceptions.Exceptions import InvalidInput, SpotifyError, YoutubeError
|
||||
from Exceptions.Exceptions import DeezerError, InvalidInput, SpotifyError, YoutubeError
|
||||
from Music.Downloader import Downloader
|
||||
from Music.Types import Provider
|
||||
from Music.Spotify import SpotifySearch
|
||||
from Music.DeezerSearcher import DeezerSearcher
|
||||
from Utils.Utils import Utils
|
||||
from Utils.UrlAnalyzer import URLAnalyzer
|
||||
from Config.Messages import SearchMessages
|
||||
@ -9,7 +10,8 @@ from Config.Messages import SearchMessages
|
||||
|
||||
class Searcher():
|
||||
def __init__(self) -> None:
|
||||
self.__Spotify = SpotifySearch()
|
||||
self.__spotify = SpotifySearch()
|
||||
self.__deezer = DeezerSearcher()
|
||||
self.__messages = SearchMessages()
|
||||
self.__down = Downloader()
|
||||
|
||||
@ -24,20 +26,35 @@ class Searcher():
|
||||
musics = await self.__down.extract_info(track)
|
||||
return musics
|
||||
except:
|
||||
raise YoutubeError(self.__messages.YOUTUBE_ERROR, self.__messages.GENERIC_TITLE)
|
||||
raise YoutubeError(self.__messages.YOUTUBE_NOT_FOUND, self.__messages.GENERIC_TITLE)
|
||||
|
||||
elif provider == Provider.Spotify:
|
||||
try:
|
||||
musics = self.__Spotify.search(track)
|
||||
musics = self.__spotify.search(track)
|
||||
if musics == None or len(musics) == 0:
|
||||
raise SpotifyError(self.__messages.SPOTIFY_ERROR, self.__messages.GENERIC_TITLE)
|
||||
raise SpotifyError(self.__messages.SPOTIFY_NOT_FOUND,
|
||||
self.__messages.GENERIC_TITLE)
|
||||
|
||||
return musics
|
||||
except SpotifyError as error:
|
||||
raise error # Redirect already processed error
|
||||
except Exception as e:
|
||||
print(f'[Spotify Error] -> {e}')
|
||||
raise SpotifyError(self.__messages.SPOTIFY_ERROR, self.__messages.GENERIC_TITLE)
|
||||
raise SpotifyError(self.__messages.SPOTIFY_NOT_FOUND, self.__messages.GENERIC_TITLE)
|
||||
|
||||
elif provider == Provider.Deezer:
|
||||
try:
|
||||
musics = self.__deezer.search(track)
|
||||
if musics == None or len(musics) == 0:
|
||||
raise DeezerError(self.__messages.DEEZER_NOT_FOUND,
|
||||
self.__messages.GENERIC_TITLE)
|
||||
|
||||
return musics
|
||||
except DeezerError as error:
|
||||
raise error # Redirect already processed error
|
||||
except Exception as e:
|
||||
print(f'[Deezer Error] -> {e}')
|
||||
raise DeezerError(self.__messages.DEEZER_NOT_FOUND, self.__messages.GENERIC_TITLE)
|
||||
|
||||
elif provider == Provider.Name:
|
||||
return [track]
|
||||
@ -52,7 +69,7 @@ class Searcher():
|
||||
if 'start_radio' or 'index' in trackAnalyzer.queryParams.keys():
|
||||
return trackAnalyzer.getCleanedUrl()
|
||||
|
||||
def __identify_source(self, track) -> Provider:
|
||||
def __identify_source(self, track: str) -> Provider:
|
||||
if not Utils.is_url(track):
|
||||
return Provider.Name
|
||||
|
||||
@ -62,4 +79,7 @@ class Searcher():
|
||||
if "https://open.spotify.com" in track:
|
||||
return Provider.Spotify
|
||||
|
||||
if "https://www.deezer.com" in track:
|
||||
return Provider.Deezer
|
||||
|
||||
return Provider.Unknown
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Provider(Enum):
|
||||
class Provider(str, Enum):
|
||||
Spotify = 'Spotify'
|
||||
Deezer = 'Deezer'
|
||||
YouTube = 'YouTube'
|
||||
Name = 'Track Name'
|
||||
Unknown = 'Unknown'
|
||||
|
||||
@ -19,3 +19,10 @@ class TestsConstants(Singleton):
|
||||
self.SPOTIFY_ALBUM_URL = 'https://open.spotify.com/album/71O60S5gIJSIAhdnrDIh3N'
|
||||
self.SPOTIFY_WRONG1_URL = 'https://open.spotify.com/wrongUrl'
|
||||
self.SPOTIFY_WRONG2_URL = 'https://open.spotify.com/track/WrongID'
|
||||
|
||||
self.DEEZER_TRACK_URL = 'https://www.deezer.com/br/track/33560861'
|
||||
self.DEEZER_ARTIST_URL = 'https://www.deezer.com/br/artist/180'
|
||||
self.DEEZER_PLAYLIST_URL = 'https://www.deezer.com/br/playlist/1001939451'
|
||||
self.DEEZER_ALBUM_URL = 'https://www.deezer.com/en/album/236107012'
|
||||
self.DEEZER_WRONG1_URL = 'xxxhttps://www.deezer.com/br/album/5'
|
||||
self.DEEZER_WRONG2_URL = 'https://www.deezer.com/en/album/23610701252'
|
||||
|
||||
66
Tests/VDeezerTests.py
Normal file
66
Tests/VDeezerTests.py
Normal file
@ -0,0 +1,66 @@
|
||||
from Tests.TestBase import VulkanTesterBase
|
||||
from Exceptions.Exceptions import DeezerError
|
||||
|
||||
|
||||
class VulkanDeezerTest(VulkanTesterBase):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
def test_deezerTrack(self) -> bool:
|
||||
musics = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.DEEZER_TRACK_URL))
|
||||
|
||||
if len(musics) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def test_deezerPlaylist(self) -> bool:
|
||||
musics = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.DEEZER_PLAYLIST_URL))
|
||||
|
||||
if len(musics) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def test_deezerArtist(self) -> bool:
|
||||
musics = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.DEEZER_ARTIST_URL))
|
||||
|
||||
if len(musics) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def test_deezerAlbum(self) -> bool:
|
||||
musics = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.DEEZER_ALBUM_URL))
|
||||
|
||||
if len(musics) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def test_deezerWrongUrlShouldThrowException(self) -> bool:
|
||||
try:
|
||||
musics = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.DEEZER_WRONG1_URL))
|
||||
|
||||
except DeezerError as e:
|
||||
print(f'Deezer Error -> {e.message}')
|
||||
return True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
def test_deezerWrongUrlTwoShouldThrowException(self) -> bool:
|
||||
try:
|
||||
musics = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.DEEZER_WRONG2_URL))
|
||||
|
||||
except DeezerError as e:
|
||||
print(f'Deezer Error -> {e.message}')
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
@ -58,15 +58,25 @@ class VulkanDownloaderTest(VulkanTesterBase):
|
||||
|
||||
def test_YoutubeMixPlaylist(self) -> None:
|
||||
# Search the link to determine names
|
||||
music = self._runner.run_coroutine(
|
||||
musics = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.YT_MIX_URL))
|
||||
|
||||
# Musics from Mix should download only the first music
|
||||
if len(music) == 1:
|
||||
return True
|
||||
else:
|
||||
if len(musics) != 1:
|
||||
return False
|
||||
|
||||
playlist = Playlist()
|
||||
song = Song(musics[0], playlist, '')
|
||||
playlist.add_song(song)
|
||||
|
||||
self._runner.run_coroutine(self._downloader.download_song(song))
|
||||
|
||||
if song.problematic:
|
||||
return False
|
||||
else:
|
||||
print(song.title)
|
||||
return True
|
||||
|
||||
def test_musicTitle(self):
|
||||
playlist = Playlist()
|
||||
song = Song(self._constants.MUSIC_TITLE_STRING, playlist, '')
|
||||
@ -81,11 +91,30 @@ class VulkanDownloaderTest(VulkanTesterBase):
|
||||
return True
|
||||
|
||||
def test_YoutubePersonalPlaylist(self) -> None:
|
||||
musics = self._runner.run_coroutine(
|
||||
musicsList = self._runner.run_coroutine(
|
||||
self._searcher.search(self._constants.YT_PERSONAL_PLAYLIST_URL))
|
||||
|
||||
if len(musics) > 0:
|
||||
print(musics)
|
||||
return True
|
||||
else:
|
||||
if len(musicsList) == 0:
|
||||
return False
|
||||
|
||||
# Create and store songs in list
|
||||
playlist = Playlist()
|
||||
songsList: List[Song] = []
|
||||
for info in musicsList:
|
||||
song = Song(identifier=info, playlist=playlist, requester='')
|
||||
playlist.add_song(song)
|
||||
songsList.append(song)
|
||||
|
||||
# Create a list of coroutines without waiting for them
|
||||
tasks: List[Task] = []
|
||||
for song in songsList:
|
||||
tasks.append(self._downloader.download_song(song))
|
||||
|
||||
# Send for runner to execute them concurrently
|
||||
self._runner.run_coroutines_list(tasks)
|
||||
|
||||
for song in songsList:
|
||||
if not song.problematic and song.title == None:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@ -1,8 +1,11 @@
|
||||
from Tests.VDownloaderTests import VulkanDownloaderTest
|
||||
from Tests.VSpotifyTests import VulkanSpotifyTest
|
||||
from Tests.VDeezerTests import VulkanDeezerTest
|
||||
|
||||
|
||||
tester = VulkanDownloaderTest()
|
||||
# tester.run()
|
||||
tester.run()
|
||||
tester = VulkanSpotifyTest()
|
||||
tester.run()
|
||||
tester = VulkanDeezerTest()
|
||||
tester.run()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user