def __init__(self): self.__youtube = Youtube() self.__spotify = Spotify() self.__editor = TagEditor() self.__last = LastFM() self.__apple = AppleMusic() self.__deezer = Deezer()
def getConfigArl(self): tempDz = Deezer() arl = None if (self.configFolder / '.arl').is_file(): with open(self.configFolder / '.arl', 'r') as f: arl = f.readline().rstrip("\n") if not tempDz.login_via_arl(arl): print("Saved ARL mistyped or expired, please enter a new one") return self.getArl(tempDz) else: return self.getArl(tempDz) return arl
def __init__(self): logger.debug("Initializing deemix library") self.db = Database() self.dz = Deezer() if config.deemix_path() == "": self.config_dir = localpaths.getConfigFolder() else: self.config_dir = Path(config.deemix_path()) self.dx_settings = LoadSettings(self.config_dir) logger.debug("deemix " + deemix.__version__) logger.debug(f"deemix config path: {self.config_dir}")
def main(): print('\nThis script will print out every album and song of a specific artist.') # initialize the main class deezer = Deezer() # taking the user input user_input = input('What artist do you want to see? > ').lower() # creating a generator object with all the artists found artists = deezer.search(user_input, 'artist') album_count = 1 track_count = 1 for artist in artists: # if the specific artis is found if artist.name.lower() == user_input: # print artist name print('\nArtist: %s\n' % (artist.name)) # for every album of the artist for album in artist.albums(): # print current count and album name print('Album: %s - %s\n' % (album_count, album.title)) # every new album increment this counter album_count += 1 # for every track of every album for track in album.tracks(): # print current track count and track title print('\tTrack: %s - %s' % (track_count, track.title)) # every new track increment this counter track_count +=1 # reset the track count every new album and print new line track_count = 1 print()
def get_playlist(query: int): try: api_result = Deezer().api.get_playlist(query) except deezer.errors.PermissionException: logger.warning(f" [!] Playlist ID {query} is private") return except deezer.errors.DataException: logger.warning(f" [!] Playlist ID {query} was not found") return except json.decoder.JSONDecodeError: logger.error(f" [!] Empty response from API while getting data for playlist ID {query}, retrying...") try: api_result = Deezer().api.get_playlist(query) except json.decoder.JSONDecodeError: logger.error(f" [!] API still sending empty response while getting data for playlist ID {query}") return return {'id': query, 'title': api_result['title'], 'link': f"https://deezer.com/playlist/{str(api_result['id'])}"}
def __init__(self): deezer_app_id = getenv("DEEZER_application_id") deezer_secret_key = getenv("DEEZER_secret_key") scope = "basic_access,manage_library" # login logging.info("Starting Deezer client") self.deezer_client = Deezer(access_token=deezer_authorize( deezer_app_id, deezer_secret_key, scope))
def login_deezer(self, deezer_object: Deezer): self.logger.debug("Attempting to authorize with Deezer") logged_in = deezer_object.login_via_arl( self.account_info_dict["DEEZER_ARL"]) if logged_in: self.logger.info("Authorized with Deezer") else: self.logger.info( "Unable to authorize with Deezer! This will likely cause lots of problems." )
def __init__(self): self.max_threads = 2 self.dz = Deezer() # Make our session threadsafe PlatformAPI.TOKEN = self.dz.gw.get_user_data()['checkForm'] self.dz.gw._get_token = self._get_token self.platform = self.get_platform() self.account_type = self.get_account_type() self.api = self.set_platform()
def get_playlist_tracks(query: dict): track_list = [] try: api_result = Deezer().api.get_playlist(query['id']) except deezer.errors.PermissionException: logger.warning(f" [!] Playlist ID {query} is private") return except deezer.errors.DataException: logger.warning(f" [!] Playlist ID {query} was not found") return except json.decoder.JSONDecodeError: logger.error(f" [!] Empty response from API while getting data for playlist ID {query['id']}") try: api_result = Deezer().api.get_playlist(query['id']) except json.decoder.JSONDecodeError: logger.error(f" [!] API still sending empty response while getting data for playlist ID {query['id']}") return for track in api_result['tracks']['data']: track_list.append({'id': track['id'], 'title': track['title'], 'artist_id': track['artist']['id'], 'artist_name': track['artist']['name']}) query['tracks'] = track_list return query
def __init__(self): self.api = api.PlatformAPI() self.artist_id: int = None self.artist: str = None self.choices: list = [] self.status_message: str = None self.queue_list = [] self.select_mode = False self.explicit_only = False self.search_results: str = None self.sort: str = "release_date" self.filter: str = None self.desc: bool = True self.db = db.Database() self.dz = Deezer()
def get_account_type(self): temp_dz = Deezer() temp_dz.login_via_arl(config.arl()) if temp_dz.get_session()['current_user'].get('can_stream_lossless'): logger.debug(f"Deezer account type is \"Hi-Fi\"") return "hifi" elif temp_dz.get_session()['current_user'].get('can_stream_hq'): logger.debug(f"Deezer account type is \"Premium\"") return "premium" else: logger.debug(f"Deezer account type is \"Free\"") return "free"
def login(arl, force=False, child=0): global first_connection if not app.isDeezerAvailable: emit('logged_in', {'status': LoginStatus.NOT_AVAILABLE, 'arl': arl, 'user': session['dz'].current_user}) return if child == None: child = 0 arl = arl.strip() emit('logging_in') if force: session['dz'] = Deezer() result = app.login(session['dz'], arl, int(child)) if force and result == LoginStatus.SUCCESS: result = LoginStatus.FORCED_SUCCESS emit('logged_in', {'status': result, 'arl': arl, 'user': session['dz'].current_user}) if first_connection and result in [LoginStatus.SUCCESS, LoginStatus.FORCED_SUCCESS]: first_connection = False app.restoreDownloadQueue(session['dz'], socket_interface) if result != 0: emit('familyAccounts', session['dz'].childs) emit('init_favorites', app.getUserFavorites(session['dz']))
def on_connect(): session['dz'] = Deezer() (settings, spotifyCredentials, defaultSettings) = app.getAllSettings() session['dz'].set_accept_language(settings.get('tagsLanguage')) emit('init_settings', (settings, spotifyCredentials, defaultSettings)) if first_connection: app.checkForUpdates() app.checkDeezerAvailability() emit('init_update',{ 'currentCommit': app.currentVersion, 'latestCommit': app.latestVersion, 'updateAvailable': app.updateAvailable, 'deemixVersion': deemix_version } ) if arl: login(arl) else: emit('init_autologin') queue, queueComplete, queueList, currentItem = app.initDownloadQueue() if len(queueList.keys()): emit('init_downloadQueue',{ 'queue': queue, 'queueComplete': queueComplete, 'queueList': queueList, 'currentItem': currentItem }) #emit('init_home', app.get_home(session['dz'])) #emit('init_charts', app.get_charts(session['dz'])) if app.updateAvailable: emit('updateAvailable') if not app.isDeezerAvailable: emit('deezerNotAvailable')
class MusicDownloader(object): def __init__(self): self.__youtube = Youtube() self.__spotify = Spotify() self.__editor = TagEditor() self.__last = LastFM() self.__apple = AppleMusic() self.__deezer = Deezer() def __downloadMusicFromYoutube(self, name, uri, dur): #finding song on youtube self.__youtube.get(name, dur) #downloading video from youtube if self.__youtube.download(url=self.__youtube.getResult(), path=uri, filename=uri): #converting video to mp3 file self.__youtube.convertVideoToMusic(uri=uri) return True else: return False def __getSongInfoFromSpotify(self, uri): try: return self.__spotify.getSongInfo(uri) except: return None def getNameFromYoutube(self, url): return self.__youtube.getNameFromYoutube(url) def getData(self, uri): try: return self.__spotify.getSongInfo(uri) except: return None def getLastFMTags(self, name): return self.__last.get(name) def getYoutubeMusicInfo(self, url): return self.__youtube.getNameFromYoutube(url) def downloadBySpotifyUri(self, uri, path): #get info info = self.__getSongInfoFromSpotify(uri) if info: fixed_name = f'{info["artist"][0]} - {info["name"]}' fixed_name = fixed_name.replace('.', '') fixed_name = fixed_name.replace(',', '') fixed_name = fixed_name.replace("'", '') fixed_name = fixed_name.replace("/", "") #finding and download from YouTube and tagging if self.__downloadMusicFromYoutube(fixed_name, info['uri'], info['duration_ms']): self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") print(path) if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') return True return False def downloadBySearchQuery(self, query, path=None): #get info info = self.__spotify.search(query=query) if not info: info = self.__last.get(query) if info: fixed_name = f'{info["artist"][0]} - {info["name"]}' fixed_name = fixed_name.replace('.', '') fixed_name = fixed_name.replace(',', '') fixed_name = fixed_name.replace("'", '') fixed_name = fixed_name.replace("/", "") #finding and download from YouTube and tagging self.__downloadMusicFromYoutube(fixed_name, info['uri'], info['duration_ms']) self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') return True, info else: return False, None def downloadBySpotifyUriFromFile(self, filename): try: with open(filename, 'r') as f: data = f.readlines() except FileNotFoundError: print(f'No such file or directory: "{filename}"') exit(2) #normalize try: data.remove('\n') except: pass links = [str(item).replace('\n', '') for item in data] for i, song in zip(range(len(links)), links): print(f'[{i+1}] - {song}') try: state = self.downloadBySpotifyUri(str(song).split(':')[-1]) if not state: notify.send(f'Failed to download', True) except: print('Something went wrong!') def downloadBySpotifyUriPlaylistMode(self, playlist_uri, path): user = Spotify.User() playlist = user.getPlaylistTracks(playlist_uri) for info, i in zip(playlist, range(len(playlist))): print(f'Downloading {i+1} of {len(playlist)}') fixed_name = f'{info["artist"][0]} - {info["name"]}' fixed_name = fixed_name.replace('.', '') fixed_name = fixed_name.replace(',', '') fixed_name = fixed_name.replace("'", '') fixed_name = fixed_name.replace("/", "") #finding and download from YouTube and tagging self.__downloadMusicFromYoutube(fixed_name, info['uri'], info['duration_ms']) self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') def downloadBySpotifyUriAlbumMode(self, album_uri, path): user = Spotify() playlist = user.getAlbum(album_uri) for info, i in zip(playlist['tracks'], range(len(playlist['tracks']))): print(f'Downloading {i+1} of {len(playlist["tracks"])}') fixed_name = f'{info["artist"][0]} - {info["name"]}' fixed_name = fixed_name.replace('.', '') fixed_name = fixed_name.replace(',', '') fixed_name = fixed_name.replace("'", '') fixed_name = fixed_name.replace("/", "") #finding and downloading from YouTube and tagging self.__downloadMusicFromYoutube(fixed_name, info['uri'], info['duration_ms']) self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') def downloadByDeezerUrl(self, url, path): link = str(str(url).split('/')[-1]).split('?')[0] #get info info = self.__deezer.getSongInfo(link) if info: fixed_name = f'{info["artist"][0]} - {info["name"]}' fixed_name = fixed_name.replace('.', '') fixed_name = fixed_name.replace(',', '') fixed_name = fixed_name.replace("'", '') fixed_name = fixed_name.replace("/", "") #finding and download from YouTube and tagging if self.__downloadMusicFromYoutube(fixed_name, info['uri'], info['duration_ms']): self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") print(path) if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') return True return False def downloadByDeezerUrlAlbumMode(self, album_url, path): link = str(str(album_url).split('/')[-1]).split('?')[0] #get info playlist = self.__deezer.getAlbum(link) for info, i in zip(playlist['tracks'], range(len(playlist['tracks']))): print(f'Downloading {i+1} of {len(playlist["tracks"])}') fixed_name = f'{info["artist"][0]} - {info["name"]}' fixed_name = fixed_name.replace('.', '') fixed_name = fixed_name.replace(',', '') fixed_name = fixed_name.replace("'", '') fixed_name = fixed_name.replace("/", "") #finding and downloading from YouTube and tagging self.__downloadMusicFromYoutube(fixed_name, info['uri'], info['duration_ms']) self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') def downloadByDeezerUrlPlaylistMode(self, playlist_url, path): link = str(str(playlist_url).split('/')[-1]).split('?')[0] #get info playlist = self.__deezer.getPlaylist(link) for info, i in zip(playlist['tracks'], range(len(playlist['tracks']))): print(f'Downloading {i+1} of {len(playlist["tracks"])}') fixed_name = f'{info["artist"][0]} - {info["name"]}' fixed_name = fixed_name.replace('.', '') fixed_name = fixed_name.replace(',', '') fixed_name = fixed_name.replace("'", '') fixed_name = fixed_name.replace("/", "") #finding and download from YouTube and tagging self.__downloadMusicFromYoutube(fixed_name, info['uri'], info['duration_ms']) self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') def downloadFromYoutubeMusic(self, url, info, path): print(info) uri = info['uri'] #downloading video from youtube if self.__youtube.download(url=url, path=uri, filename=uri): #converting video to mp3 file self.__youtube.convertVideoToMusic(uri=uri) self.__editor.setTags(data=info) cachepath = os.getcwd() + '/cache' fullpath = os.getcwd() + '/Downloads' if not os.path.exists(fullpath): os.makedirs(fullpath) name = f'{info["artist"][0]} - {info["name"]}' os.rename(f"{cachepath}/{info['uri']}/{info['uri']}.mp3", f"{fullpath}/{getCorrect(name)}.mp3") if path: os.rename(f"{fullpath}/{getCorrect(name)}.mp3", f"{path}/{getCorrect(name)}.mp3") #deleting cache try: shutil.rmtree(f"cache/{info['uri']}") except: pass notify.send(f'{info["artist"][0]} - {info["name"]}') return True, info else: return False, None def search(self, query): return self.__spotify.search(query=query)
class DeemixInterface: def __init__(self): logger.debug("Initializing deemix library") self.db = Database() self.dz = Deezer() if config.deemix_path() == "": self.config_dir = localpaths.getConfigFolder() else: self.config_dir = Path(config.deemix_path()) self.dx_settings = LoadSettings(self.config_dir) logger.debug("deemix " + deemix.__version__) logger.debug(f"deemix config path: {self.config_dir}") def download_url(self, url, bitrate, download_path, override_deemix=True): if override_deemix: deemix.generatePlaylistItem = self.generatePlaylistItem if download_path: self.dx_settings['downloadLocation'] = download_path logger.debug(f"deemix download path set to: {self.dx_settings['downloadLocation']}") links = [] for link in url: if ';' in link: for l in link.split(";"): links.append(l) else: links.append(link) for link in links: download_object = generateDownloadObject(self.dz, link, bitrate) if isinstance(download_object, list): for obj in download_object: Downloader(self.dz, obj, self.dx_settings).start() else: Downloader(self.dz, download_object, self.dx_settings).start() def deezer_acct_type(self): user_session = self.dz.get_session()['current_user'] if user_session.get('can_stream_lossless'): logger.debug("Deezer account connected and supports lossless") config.set('deezer_quality', 'lossless', validate=False) elif user_session.get('can_stream_hq'): logger.debug("Deezer account connected and supports high quality") config.set('deezer_quality', 'hq', validate=False) else: logger.warning("Deezer account connected but only supports 128k") config.set('deezer_quality', 'lq', validate=False) def verify_arl(self, arl): if not self.dz.login_via_arl(arl): print("FAILED") logger.debug(f"ARL Failed: {arl}") return False self.deezer_acct_type() print("OK") logger.debug("ARL is valid") return True def login(self): failed_logins = 0 logger.debug("Looking for ARL...") if config.arl(): logger.debug("ARL found in deemon config") print(":: Found ARL in deemon config, checking... ", end="") if self.verify_arl(config.arl()): return True else: logger.error("Unable to login using ARL found in deemon config") failed_logins += 1 else: logger.debug("ARL was not found in deemon config, checking if deemix has it...") if self.config_dir.is_dir(): if Path(self.config_dir / '.arl').is_file(): with open(self.config_dir / '.arl', 'r') as f: arl_from_file = f.readline().rstrip("\n") logger.debug("ARL found in deemix config") print(":: Found ARL in deemix .arl file, checking... ", end="") if self.verify_arl(arl_from_file): return True else: logger.error("Unable to login using ARL found in deemix config directory") failed_logins += 1 else: logger.debug(f"ARL not found in {self.config_dir}") else: logger.error(f"ARL directory {self.config_dir} was not found") if failed_logins > 1: notification = notifier.Notify() notification.expired_arl() else: logger.error("No ARL was found, aborting...") return False def generatePlaylistItem(self, dz, link_id, bitrate, playlistAPI=None, playlistTracksAPI=None): if not playlistAPI: if not str(link_id).isdecimal(): raise InvalidID(f"https://deezer.com/playlist/{link_id}") # Get essential playlist info try: playlistAPI = dz.api.get_playlist(link_id) except APIError: playlistAPI = None # Fallback to gw api if the playlist is private if not playlistAPI: try: userPlaylist = dz.gw.get_playlist_page(link_id) playlistAPI = map_user_playlist(userPlaylist['DATA']) except GWAPIError as e: raise GenerationError(f"https://deezer.com/playlist/{link_id}", str(e)) from e # Check if private playlist and owner if not playlistAPI.get('public', False) and playlistAPI['creator']['id'] != str(self.dz.current_user['id']): logger.warning("You can't download others private playlists.") raise NotYourPrivatePlaylist(f"https://deezer.com/playlist/{link_id}") if not playlistTracksAPI: playlistTracksAPI = dz.gw.get_playlist_tracks(link_id) playlistAPI['various_artist'] = dz.api.get_artist(5080) # Useful for save as compilation totalSize = len(playlistTracksAPI) playlistAPI['nb_tracks'] = totalSize collection = [] for pos, trackAPI in enumerate(playlistTracksAPI, start=1): # # BEGIN DEEMON PATCH # vals = {'track_id': trackAPI['SNG_ID'], 'playlist_id': playlistAPI['id']} sql = "SELECT * FROM 'playlist_tracks' WHERE track_id = :track_id AND playlist_id = :playlist_id" result = self.db.query(sql, vals).fetchone() if result: continue # # END DEEMON PATCH # trackAPI = map_track(trackAPI) if trackAPI['explicit_lyrics']: playlistAPI['explicit'] = True if 'track_token' in trackAPI: del trackAPI['track_token'] trackAPI['position'] = pos collection.append(trackAPI) if 'explicit' not in playlistAPI: playlistAPI['explicit'] = False return Collection({ 'type': 'playlist', 'id': link_id, 'bitrate': bitrate, 'title': playlistAPI['title'], 'artist': playlistAPI['creator']['name'], 'cover': playlistAPI['picture_small'][:-24] + '/75x75-000000-80-0-0.jpg', 'explicit': playlistAPI['explicit'], 'size': totalSize, 'collection': { 'tracks': collection, 'playlistAPI': playlistAPI } })
def logout(): if session['dz'].logged_in: session['dz'] = Deezer() emit('logged_out')
#!/usr/bin/env python3 from deezer import Deezer import sys if __name__ == '__main__': if len(sys.argv) > 1: dz = Deezer() releases = dz.gw.get_artist_discography_tabs(sys.argv[1], 100) for type in releases: for release in releases[type]: print(release['id'])
"Compare iTunes and cached versions of playlists to re-sync (fixes problems from program crash, also reverts user modifications)? [y/n] " ) == "y" else: fix_itunes = False make_m3u = input( "Make m3u files (stored in the playlists folder)? [y/n] ") == "y" verify_path_lengths = input( "Rename files too long to copy to Android? [y/n] ") == "y" copy_to_android = input( "Copy music and playlists to Android Music folder? (Won't waste time overwriting, make sure to enable USB debugging) [y/n] " ) == "y" account_manager = AccountManager(logger) account_manager.login_spotify() deezer_object = Deezer() account_manager.login_deezer(deezer_object) music_directory = str(Path.cwd().parents[0] / "music") youtube_tag_dict = collections.OrderedDict() youtube_manager = YoutubeManager(log_manager, logger, account_manager.spotipy, music_directory, youtube_tag_dict) playlist_manager = PlaylistManager(logger=logger, account_manager=account_manager) if get_user_playlists: playlist_manager.retrieve_spotify_playlists() if get_custom_playlists: playlist_manager.retrieve_custom_playlists()