Adding Deezer Module and Deezer Tests

This commit is contained in:
Rafael Vargas 2022-07-10 16:08:22 -03:00
parent c826af229c
commit 863b079a01
11 changed files with 232 additions and 21 deletions

View File

@ -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'

View File

@ -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
View 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

View File

@ -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)

View File

@ -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

View File

@ -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'

View File

@ -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
View 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

View File

@ -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

Binary file not shown.

View File

@ -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()