More code reworking
This commit is contained in:
		| @ -258,7 +258,6 @@ class Deezer: | ||||
|  | ||||
|     def get_playlist_gw(self, playlist_id): | ||||
|         playlistAPI = self.gw_api_call('deezer.pagePlaylist', {'playlist_id': playlist_id, 'lang': 'en'})['results']['DATA'] | ||||
|         print(json.dumps(playlistAPI)) | ||||
|         return { | ||||
|             'id': playlistAPI['PLAYLIST_ID'], | ||||
|             'title': playlistAPI['TITLE'], | ||||
|  | ||||
| @ -1,6 +1,12 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # Empty File | ||||
| from deemix.api.deezer import Deezer | ||||
| from deemix.app.settings import Settings | ||||
| from deemix.app.queuemanager import QueueManager | ||||
| from deemix.app.spotify import SpotifyHelper | ||||
|  | ||||
| class deemix: | ||||
|     def __init__(self): | ||||
|          | ||||
|         self.set = Settings() | ||||
|         self.dz = Deezer() | ||||
|         self.sp = SpotifyHelper() | ||||
|         self.qm = QueueManager() | ||||
|  | ||||
| @ -15,6 +15,7 @@ from deemix.api.deezer import APIError, USER_AGENT_HEADER | ||||
| from deemix.utils.misc import changeCase, uniqueArray | ||||
| from deemix.utils.pathtemplates import generateFilename, generateFilepath, settingsRegexAlbum, settingsRegexArtist, settingsRegexPlaylistFile | ||||
| from deemix.utils.taggers import tagID3, tagFLAC | ||||
| from deemix.app.queueitem import QISingle, QICollection, QIConvertable | ||||
| from mutagen.flac import FLACNoHeaderError | ||||
| import logging | ||||
|  | ||||
| @ -41,7 +42,7 @@ lastPercentage = 0 | ||||
|  | ||||
| def stream_track(dz, track, stream, trackAPI, queueItem, interface=None): | ||||
|     global downloadPercentage, lastPercentage | ||||
|     if 'cancel' in queueItem: | ||||
|     if queueItem.cancel: | ||||
|         raise downloadCancelled | ||||
|     try: | ||||
|         request = get(track['downloadUrl'], headers=dz.http_headers, stream=True, timeout=30) | ||||
| @ -55,7 +56,7 @@ def stream_track(dz, track, stream, trackAPI, queueItem, interface=None): | ||||
|     percentage = 0 | ||||
|     i = 0 | ||||
|     for chunk in request.iter_content(2048): | ||||
|         if 'cancel' in queueItem: | ||||
|         if queueItem.cancel: | ||||
|             raise downloadCancelled | ||||
|         if i % 3 == 0 and len(chunk) == 2048: | ||||
|             chunk = Blowfish.new(blowfish_key, Blowfish.MODE_CBC, b"\x00\x01\x02\x03\x04\x05\x06\x07").decrypt(chunk) | ||||
| @ -69,9 +70,9 @@ def stream_track(dz, track, stream, trackAPI, queueItem, interface=None): | ||||
|             downloadPercentage += chunkProgres | ||||
|         if round(downloadPercentage) != lastPercentage and round(downloadPercentage) % 2 == 0: | ||||
|             lastPercentage = round(downloadPercentage) | ||||
|             queueItem['progress'] = lastPercentage | ||||
|             queueItem.progress = lastPercentage | ||||
|             if interface: | ||||
|                 interface.send("updateQueue", {'uuid': queueItem['uuid'], 'progress': lastPercentage}) | ||||
|                 interface.send("updateQueue", {'uuid': queueItem.uuid, 'progress': lastPercentage}) | ||||
|         i += 1 | ||||
|  | ||||
|  | ||||
| @ -83,9 +84,9 @@ def trackCompletePercentage(trackAPI, queueItem, interface): | ||||
|         downloadPercentage += 1 / trackAPI['SIZE'] * 100 | ||||
|     if round(downloadPercentage) != lastPercentage and round(downloadPercentage) % 2 == 0: | ||||
|         lastPercentage = round(downloadPercentage) | ||||
|         queueItem['progress'] = lastPercentage | ||||
|         queueItem.progress = lastPercentage | ||||
|         if interface: | ||||
|             interface.send("updateQueue", {'uuid': queueItem['uuid'], 'progress': lastPercentage}) | ||||
|             interface.send("updateQueue", {'uuid': queueItem.uuid, 'progress': lastPercentage}) | ||||
|  | ||||
| def trackRemovePercentage(trackAPI, queueItem, interface): | ||||
|     global downloadPercentage, lastPercentage | ||||
| @ -95,9 +96,9 @@ def trackRemovePercentage(trackAPI, queueItem, interface): | ||||
|         downloadPercentage -= 1 / trackAPI['SIZE'] * 100 | ||||
|     if round(downloadPercentage) != lastPercentage and round(downloadPercentage) % 2 == 0: | ||||
|         lastPercentage = round(downloadPercentage) | ||||
|         queueItem['progress'] = lastPercentage | ||||
|         queueItem.progress = lastPercentage | ||||
|         if interface: | ||||
|             interface.send("updateQueue", {'uuid': queueItem['uuid'], 'progress': lastPercentage}) | ||||
|             interface.send("updateQueue", {'uuid': queueItem.uuid, 'progress': lastPercentage}) | ||||
|  | ||||
|  | ||||
| def downloadImage(url, path, overwrite="n"): | ||||
| @ -474,12 +475,45 @@ def getTrackData(dz, trackAPI_gw, settings, trackAPI=None, albumAPI_gw=None, alb | ||||
|     else: | ||||
|         track['title_feat'] = track['title'] | ||||
|  | ||||
|     if "_EXTRA_PLAYLIST" in trackAPI: | ||||
|         track['playlist'] = {} | ||||
|         if 'dzcdn.net' in trackAPI["_EXTRA_PLAYLIST"]['picture_small']: | ||||
|             track['playlist']['picUrl'] = trackAPI["_EXTRA_PLAYLIST"]['picture_small'][:-24] + "/{}x{}-{}".format( | ||||
|                 settings['embeddedArtworkSize'], settings['embeddedArtworkSize'], | ||||
|                 f'000000-{settings["jpegImageQuality"]}-0-0.jpg') | ||||
|         else: | ||||
|             track['playlist']['picUrl'] = trackAPI["_EXTRA_PLAYLIST"]['picture_xl'] | ||||
|         track['playlist']['title'] = trackAPI["_EXTRA_PLAYLIST"]['title'] | ||||
|         track['playlist']['mainArtist'] = { | ||||
|             'id': trackAPI["_EXTRA_PLAYLIST"]['various_artist']['id'], | ||||
|             'name': trackAPI["_EXTRA_PLAYLIST"]['various_artist']['name'], | ||||
|             'pic': trackAPI["_EXTRA_PLAYLIST"]['various_artist']['picture_small'][ | ||||
|                    trackAPI["_EXTRA_PLAYLIST"]['various_artist']['picture_small'].find('artist/') + 7:-24] | ||||
|         } | ||||
|         if settings['albumVariousArtists']: | ||||
|             track['playlist']['artist'] = {"Main": [trackAPI["_EXTRA_PLAYLIST"]['various_artist']['name'], ]} | ||||
|             track['playlist']['artists'] = [trackAPI["_EXTRA_PLAYLIST"]['various_artist']['name'], ] | ||||
|         else: | ||||
|             track['playlist']['artist'] = {"Main": []} | ||||
|             track['playlist']['artists'] = [] | ||||
|         track['playlist']['trackTotal'] = trackAPI["_EXTRA_PLAYLIST"]['nb_tracks'] | ||||
|         track['playlist']['recordType'] = "Compilation" | ||||
|         track['playlist']['barcode'] = "" | ||||
|         track['playlist']['label'] = "" | ||||
|         track['playlist']['explicit'] = trackAPI['_EXTRA_PLAYLIST']['explicit'] | ||||
|         track['playlist']['date'] = { | ||||
|             'day': trackAPI["_EXTRA_PLAYLIST"]["creation_date"][8:10], | ||||
|             'month': trackAPI["_EXTRA_PLAYLIST"]["creation_date"][5:7], | ||||
|             'year': trackAPI["_EXTRA_PLAYLIST"]["creation_date"][0:4] | ||||
|         } | ||||
|         track['playlist']['discTotal'] = "1" | ||||
|  | ||||
|     return track | ||||
|  | ||||
|  | ||||
| def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None, interface=None): | ||||
|     result = {} | ||||
|     if 'cancel' in queueItem: | ||||
|     if queueItem.cancel: | ||||
|         result['cancel'] = True | ||||
|         return result | ||||
|  | ||||
| @ -495,10 +529,10 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                 'artist': trackAPI['ART_NAME'] | ||||
|             } | ||||
|         logger.error(f"[{result['error']['data']['artist']} - {result['error']['data']['title']}] This track is not available on Deezer!") | ||||
|         queueItem['failed'] += 1 | ||||
|         queueItem['errors'].append(result['error']) | ||||
|         queueItem.failed += 1 | ||||
|         queueItem.errors.append(result['error']) | ||||
|         if interface: | ||||
|             interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|             interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                            'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|         return result | ||||
|     # Get the metadata | ||||
| @ -512,7 +546,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                              trackAPI=trackAPI['_EXTRA_TRACK'] if '_EXTRA_TRACK' in trackAPI else None, | ||||
|                              albumAPI=trackAPI['_EXTRA_ALBUM'] if '_EXTRA_ALBUM' in trackAPI else None | ||||
|                              ) | ||||
|     if 'cancel' in queueItem: | ||||
|     if queueItem.cancel: | ||||
|         result['cancel'] = True | ||||
|         return result | ||||
|     if track['MD5'] == '': | ||||
| @ -545,10 +579,10 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                         'artist': track['mainArtist']['name'] | ||||
|                     } | ||||
|                 } | ||||
|                 queueItem['failed'] += 1 | ||||
|                 queueItem['errors'].append(result['error']) | ||||
|                 queueItem.failed += 1 | ||||
|                 queueItem.errors.append(result['error']) | ||||
|                 if interface: | ||||
|                     interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|                     interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                                    'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|                 return result | ||||
|         else: | ||||
| @ -563,10 +597,10 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                     'artist': track['mainArtist']['name'] | ||||
|                 } | ||||
|             } | ||||
|             queueItem['failed'] += 1 | ||||
|             queueItem['errors'].append(result['error']) | ||||
|             queueItem.failed += 1 | ||||
|             queueItem.errors.append(result['error']) | ||||
|             if interface: | ||||
|                 interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|                 interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                                'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|             return result | ||||
|  | ||||
| @ -602,10 +636,10 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                         'artist': track['mainArtist']['name'] | ||||
|                     } | ||||
|                 } | ||||
|                 queueItem['failed'] += 1 | ||||
|                 queueItem['errors'].append(result['error']) | ||||
|                 queueItem.failed += 1 | ||||
|                 queueItem.errors.append(result['error']) | ||||
|                 if interface: | ||||
|                     interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|                     interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                                    'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|                 return result | ||||
|         else: | ||||
| @ -620,10 +654,10 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                     'artist': track['mainArtist']['name'] | ||||
|                 } | ||||
|             } | ||||
|             queueItem['failed'] += 1 | ||||
|             queueItem['errors'].append(result['error']) | ||||
|             queueItem.failed += 1 | ||||
|             queueItem.errors.append(result['error']) | ||||
|             if interface: | ||||
|                 interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|                 interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                                'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|             return result | ||||
|     elif selectedBitrate == -200: | ||||
| @ -638,45 +672,13 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                 'artist': track['mainArtist']['name'] | ||||
|             } | ||||
|         } | ||||
|         queueItem['failed'] += 1 | ||||
|         queueItem['errors'].append(result['error']) | ||||
|         queueItem.failed += 1 | ||||
|         queueItem.errors.append(result['error']) | ||||
|         if interface: | ||||
|             interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|             interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                            'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|         return result | ||||
|     track['selectedFormat'] = selectedBitrate | ||||
|     if "_EXTRA_PLAYLIST" in trackAPI: | ||||
|         track['playlist'] = {} | ||||
|         if 'dzcdn.net' in trackAPI["_EXTRA_PLAYLIST"]['picture_small']: | ||||
|             track['playlist']['picUrl'] = trackAPI["_EXTRA_PLAYLIST"]['picture_small'][:-24] + "/{}x{}-{}".format( | ||||
|                 settings['embeddedArtworkSize'], settings['embeddedArtworkSize'], | ||||
|                 f'000000-{settings["jpegImageQuality"]}-0-0.jpg') | ||||
|         else: | ||||
|             track['playlist']['picUrl'] = trackAPI["_EXTRA_PLAYLIST"]['picture_xl'] | ||||
|         track['playlist']['title'] = trackAPI["_EXTRA_PLAYLIST"]['title'] | ||||
|         track['playlist']['mainArtist'] = { | ||||
|             'id': trackAPI["_EXTRA_PLAYLIST"]['various_artist']['id'], | ||||
|             'name': trackAPI["_EXTRA_PLAYLIST"]['various_artist']['name'], | ||||
|             'pic': trackAPI["_EXTRA_PLAYLIST"]['various_artist']['picture_small'][ | ||||
|                    trackAPI["_EXTRA_PLAYLIST"]['various_artist']['picture_small'].find('artist/') + 7:-24] | ||||
|         } | ||||
|         if settings['albumVariousArtists']: | ||||
|             track['playlist']['artist'] = {"Main": [trackAPI["_EXTRA_PLAYLIST"]['various_artist']['name'], ]} | ||||
|             track['playlist']['artists'] = [trackAPI["_EXTRA_PLAYLIST"]['various_artist']['name'], ] | ||||
|         else: | ||||
|             track['playlist']['artist'] = {"Main": []} | ||||
|             track['playlist']['artists'] = [] | ||||
|         track['playlist']['trackTotal'] = trackAPI["_EXTRA_PLAYLIST"]['nb_tracks'] | ||||
|         track['playlist']['recordType'] = "Compilation" | ||||
|         track['playlist']['barcode'] = "" | ||||
|         track['playlist']['label'] = "" | ||||
|         track['playlist']['explicit'] = trackAPI['_EXTRA_PLAYLIST']['explicit'] | ||||
|         track['playlist']['date'] = { | ||||
|             'day': trackAPI["_EXTRA_PLAYLIST"]["creation_date"][8:10], | ||||
|             'month': trackAPI["_EXTRA_PLAYLIST"]["creation_date"][5:7], | ||||
|             'year': trackAPI["_EXTRA_PLAYLIST"]["creation_date"][0:4] | ||||
|         } | ||||
|         track['playlist']['discTotal'] = "1" | ||||
|     if settings['tags']['savePlaylistAsCompilation'] and "playlist" in track: | ||||
|         track['trackNumber'] = trackAPI["POSITION"] | ||||
|         track['discNumber'] = "1" | ||||
| @ -732,7 +734,7 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|     filename = generateFilename(track, trackAPI, settings) | ||||
|     (filepath, artistPath, coverPath, extrasPath) = generateFilepath(track, trackAPI, settings) | ||||
|  | ||||
|     if 'cancel' in queueItem: | ||||
|     if queueItem.cancel: | ||||
|         result['cancel'] = True | ||||
|         return result | ||||
|     # Download and cache coverart | ||||
| @ -865,10 +867,10 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                                 'artist': track['mainArtist']['name'] | ||||
|                             } | ||||
|                         } | ||||
|                         queueItem['failed'] += 1 | ||||
|                         queueItem['errors'].append(result['error']) | ||||
|                         queueItem.failed += 1 | ||||
|                         queueItem.errors.append(result['error']) | ||||
|                         if interface: | ||||
|                             interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|                             interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                                            'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|                         return 1 | ||||
|                 else: | ||||
| @ -883,10 +885,10 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|                             'artist': track['mainArtist']['name'] | ||||
|                         } | ||||
|                     } | ||||
|                     queueItem['failed'] += 1 | ||||
|                     queueItem['errors'].append(result['error']) | ||||
|                     queueItem.failed += 1 | ||||
|                     queueItem.errors.append(result['error']) | ||||
|                     if interface: | ||||
|                         interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|                         interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                                        'error': result['error']['message'], 'errid': result['error']['errid']}) | ||||
|                     return 1 | ||||
|             except Exception as e: | ||||
| @ -919,9 +921,9 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None | ||||
|         if 'searched' in track: | ||||
|             result['searched'] = f'{track["mainArtist"]["name"]} - {track["title"]}' | ||||
|     logger.info(f"[{track['mainArtist']['name']} - {track['title']}] Track download completed") | ||||
|     queueItem['downloaded'] += 1 | ||||
|     queueItem.downloaded += 1 | ||||
|     if interface: | ||||
|         interface.send("updateQueue", {'uuid': queueItem['uuid'], 'downloaded': True, 'downloadPath': writepath}) | ||||
|         interface.send("updateQueue", {'uuid': queueItem.uuid, 'downloaded': True, 'downloadPath': writepath}) | ||||
|     return result | ||||
|  | ||||
|  | ||||
| @ -939,61 +941,56 @@ def downloadTrackObj_wrap(dz, track, settings, bitrate, queueItem, interface): | ||||
|             } | ||||
|             } | ||||
|         } | ||||
|         queueItem['failed'] += 1 | ||||
|         queueItem['errors'].append(result['error']) | ||||
|         queueItem.failed += 1 | ||||
|         queueItem.errors.append(result['error']) | ||||
|         if interface: | ||||
|             interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|             interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                            'error': result['error']['message']}) | ||||
|     return result | ||||
|  | ||||
|  | ||||
| def download(dz, sp, queueItem, interface=None): | ||||
|     global downloadPercentage, lastPercentage | ||||
|     settings = queueItem['settings'] | ||||
|     bitrate = queueItem['bitrate'] | ||||
|     settings = queueItem.settings | ||||
|     bitrate = queueItem.bitrate | ||||
|     downloadPercentage = 0 | ||||
|     lastPercentage = 0 | ||||
|     if '_EXTRA' in queueItem: | ||||
|     if isinstance(queueItem, QIConvertable): | ||||
|         sp.convert_spotify_playlist(dz, queueItem, settings, interface=interface) | ||||
|     if 'single' in queueItem: | ||||
|     if isinstance(queueItem, QISingle): | ||||
|         try: | ||||
|             result = downloadTrackObj(dz, queueItem['single'], settings, bitrate, queueItem, interface=interface) | ||||
|             result = downloadTrackObj(dz, queueItem.single, settings, bitrate, queueItem, interface=interface) | ||||
|         except Exception as e: | ||||
|             logger.exception(str(e)) | ||||
|             result = {'error': { | ||||
|                 'message': str(e), | ||||
|                 'data': { | ||||
|                     'id': queueItem['single']['SNG_ID'], | ||||
|                     'title': queueItem['single']['SNG_TITLE'] + (queueItem['single']['VERSION'] if 'VERSION' in queueItem['single'] and queueItem['single']['VERSION'] and not queueItem['single']['VERSION'] in queueItem['single']['SNG_TITLE'] else ""), | ||||
|                     'mainArtist': {'name': queueItem['single']['ART_NAME']} | ||||
|                     'id': queueItem.single['SNG_ID'], | ||||
|                     'title': queueItem.single['SNG_TITLE'] + (queueItem.single['VERSION'] if 'VERSION' in queueItem.single and queueItem.single['VERSION'] and not queueItem.single['VERSION'] in queueItem.single['SNG_TITLE'] else ""), | ||||
|                     'mainArtist': {'name': queueItem.single['ART_NAME']} | ||||
|                 } | ||||
|             } | ||||
|             } | ||||
|             queueItem['failed'] += 1 | ||||
|             queueItem['errors'].append(result['error']) | ||||
|             queueItem.failed += 1 | ||||
|             queueItem.errors.append(result['error']) | ||||
|             if interface: | ||||
|                 interface.send("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], | ||||
|                 interface.send("updateQueue", {'uuid': queueItem.uuid, 'failed': True, 'data': result['error']['data'], | ||||
|                                                'error': result['error']['message']}) | ||||
|         download_path = after_download_single(result, settings, queueItem) | ||||
|     elif 'collection' in queueItem: | ||||
|         playlist = [None] * len(queueItem['collection']) | ||||
|         download_path = after_download_single(result, settings) | ||||
|     elif isinstance(queueItem, QICollection): | ||||
|         playlist = [None] * len(queueItem.collection) | ||||
|         with ThreadPoolExecutor(settings['queueConcurrency']) as executor: | ||||
|             for pos, track in enumerate(queueItem['collection'], start=0): | ||||
|             for pos, track in enumerate(queueItem.collection, start=0): | ||||
|                 playlist[pos] = executor.submit(downloadTrackObj_wrap, dz, track, settings, bitrate, queueItem, | ||||
|                                                 interface=interface) | ||||
|         download_path = after_download(playlist, settings, queueItem) | ||||
|     if interface: | ||||
|         if 'cancel' in queueItem: | ||||
|             interface.send('currentItemCancelled', queueItem['uuid']) | ||||
|             interface.send("removedFromQueue", queueItem['uuid']) | ||||
|         if queueItem.cancel: | ||||
|             interface.send('currentItemCancelled', queueItem.uuid) | ||||
|             interface.send("removedFromQueue", queueItem.uuid) | ||||
|         else: | ||||
|             interface.send("finishDownload", queueItem['uuid']) | ||||
|     return { | ||||
|         'dz': dz, | ||||
|         'sp': sp, | ||||
|         'interface': interface, | ||||
|         'download_path': download_path | ||||
|     } | ||||
|             interface.send("finishDownload", queueItem.uuid) | ||||
|     return download_path | ||||
|  | ||||
|  | ||||
| def after_download(tracks, settings, queueItem): | ||||
| @ -1049,7 +1046,7 @@ def after_download(tracks, settings, queueItem): | ||||
|     return extrasPath | ||||
|  | ||||
|  | ||||
| def after_download_single(track, settings, queueItem): | ||||
| def after_download_single(track, settings): | ||||
|     if 'cancel' in track: | ||||
|         return None | ||||
|     if 'extrasPath' not in track: | ||||
|  | ||||
| @ -101,7 +101,7 @@ class QueueManager: | ||||
|                 trackAPI['FILENAME_TEMPLATE'] = settings['albumTracknameTemplate'] | ||||
|                 collection.append(trackAPI) | ||||
|  | ||||
|             return return QICollection( | ||||
|             return QICollection( | ||||
|                 id, | ||||
|                 bitrate, | ||||
|                 albumAPI['title'], | ||||
| @ -128,7 +128,7 @@ class QueueManager: | ||||
|                     return QueueError(url, message) | ||||
|             if not playlistAPI['public'] and playlistAPI['creator']['id'] != str(dz.user['id']): | ||||
|                 logger.warn("You can't download others private playlists.") | ||||
|                 return return QueueError(url, "You can't download others private playlists.", "notYourPrivatePlaylist") | ||||
|                 return QueueError(url, "You can't download others private playlists.", "notYourPrivatePlaylist") | ||||
|  | ||||
|             playlistTracksAPI = dz.get_playlist_tracks_gw(id) | ||||
|             playlistAPI['various_artist'] = dz.get_artist(5080) | ||||
| @ -146,7 +146,7 @@ class QueueManager: | ||||
|             if not 'explicit' in playlistAPI: | ||||
|                 playlistAPI['explicit'] = False | ||||
|  | ||||
|             return return QICollection( | ||||
|             return QICollection( | ||||
|                 id, | ||||
|                 bitrate, | ||||
|                 playlistAPI['title'], | ||||
| @ -163,7 +163,7 @@ class QueueManager: | ||||
|                 artistAPI = dz.get_artist(id) | ||||
|             except APIError as e: | ||||
|                 e = json.loads(str(e)) | ||||
|                 return return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}") | ||||
|                 return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}") | ||||
|  | ||||
|             if interface: | ||||
|                 interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) | ||||
| @ -183,7 +183,7 @@ class QueueManager: | ||||
|                 artistAPI = dz.get_artist(id) | ||||
|             except APIError as e: | ||||
|                 e = json.loads(str(e)) | ||||
|                 return return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}") | ||||
|                 return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}") | ||||
|  | ||||
|             if interface: | ||||
|                 interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) | ||||
| @ -205,7 +205,7 @@ class QueueManager: | ||||
|                 artistAPI = dz.get_artist(id) | ||||
|             except APIError as e: | ||||
|                 e = json.loads(str(e)) | ||||
|                 return return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}") | ||||
|                 return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}") | ||||
|  | ||||
|             playlistAPI = { | ||||
|                 'id': str(artistAPI['id'])+"_top_track", | ||||
| @ -252,7 +252,7 @@ class QueueManager: | ||||
|             if not 'explicit' in playlistAPI: | ||||
|                 playlistAPI['explicit'] = False | ||||
|  | ||||
|             return return QICollection( | ||||
|             return QICollection( | ||||
|                 id, | ||||
|                 bitrate, | ||||
|                 playlistAPI['title'], | ||||
| @ -302,9 +302,8 @@ class QueueManager: | ||||
|                 return QueueError(url, "Spotify Features is not setted up correctly.", "spotifyDisabled") | ||||
|  | ||||
|             try: | ||||
|                 playlist = sp.adapt_spotify_playlist(dz, id, settings) | ||||
|                 playlist = sp.generate_playlist_queueitem(dz, id, settings) | ||||
|                 playlist['bitrate'] = bitrate | ||||
|                 playlist['uuid'] = f"{playlist['type']}_{id}_{bitrate}" | ||||
|                 return playlist | ||||
|             except SpotifyException as e: | ||||
|                 return QueueError(url, "Wrong URL: "+e.msg[e.msg.find('\n')+2:]) | ||||
|  | ||||
| @ -6,43 +6,45 @@ from os import mkdir | ||||
| import spotipy | ||||
| from spotipy.oauth2 import SpotifyClientCredentials | ||||
| from deemix.utils.localpaths import getConfigFolder | ||||
| from deemix.app.queueitem import QIConvertable | ||||
| from deemix.app.queueitem import QIConvertable, QICollection | ||||
|  | ||||
| emptyPlaylist = { | ||||
|     'collaborative': False, | ||||
|     'description': "", | ||||
|     'external_urls': {'spotify': None}, | ||||
|     'followers': {'total': 0, 'href': None}, | ||||
|     'id': None, | ||||
|     'images': [], | ||||
|     'name': "Something went wrong", | ||||
|     'owner': { | ||||
|         'display_name': "Error", | ||||
|         'id': None | ||||
|     }, | ||||
|     'public': True, | ||||
|     'tracks' : [], | ||||
|     'type': 'playlist', | ||||
|     'uri': None | ||||
| } | ||||
|  | ||||
| class SpotifyHelper: | ||||
|     def __init__(self, configFolder=None): | ||||
|         self.credentials = {} | ||||
|         self.spotifyEnabled = False | ||||
|         self.sp = None | ||||
|         if not configFolder: | ||||
|             self.configFolder = getConfigFolder() | ||||
|         else: | ||||
|             self.configFolder = configFolder | ||||
|         self.emptyPlaylist = { | ||||
|             'collaborative': False, | ||||
|             'description': "", | ||||
|             'external_urls': {'spotify': None}, | ||||
|             'followers': {'total': 0, 'href': None}, | ||||
|             'id': None, | ||||
|             'images': [], | ||||
|             'name': "Something went wrong", | ||||
|             'owner': { | ||||
|                 'display_name': "Error", | ||||
|                 'id': None | ||||
|             }, | ||||
|             'public': True, | ||||
|             'tracks' : [], | ||||
|             'type': 'playlist', | ||||
|             'uri': None | ||||
|         } | ||||
|         self.initCredentials() | ||||
|         self.configFolder = configFolder | ||||
|  | ||||
|     def initCredentials(self): | ||||
|         # Make sure config folder exsists | ||||
|         if not self.configFolder: | ||||
|             self.configFolder = getConfigFolder() | ||||
|         if not path.isdir(self.configFolder): | ||||
|             mkdir(self.configFolder) | ||||
|  | ||||
|         # Make sure authCredentials exsits | ||||
|         if not path.isfile(path.join(self.configFolder, 'authCredentials.json')): | ||||
|             with open(path.join(self.configFolder, 'authCredentials.json'), 'w') as f: | ||||
|                 json.dump({'clientId': "", 'clientSecret': ""}, f, indent=2) | ||||
|  | ||||
|         # Load spotify id and secret and check if they are usable | ||||
|         with open(path.join(self.configFolder, 'authCredentials.json'), 'r') as credentialsFile: | ||||
|             self.credentials = json.load(credentialsFile) | ||||
|         self.checkCredentials() | ||||
| @ -52,7 +54,9 @@ class SpotifyHelper: | ||||
|             spotifyEnabled = False | ||||
|         else: | ||||
|             try: | ||||
|                 self.createSpotifyConnection() | ||||
|                 client_credentials_manager = SpotifyClientCredentials(client_id=self.credentials['clientId'], | ||||
|                                                                       client_secret=self.credentials['clientSecret']) | ||||
|                 self.sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) | ||||
|                 self.sp.user_playlists('spotify') | ||||
|                 self.spotifyEnabled = True | ||||
|             except Exception as e: | ||||
| @ -63,18 +67,19 @@ class SpotifyHelper: | ||||
|         return self.credentials | ||||
|  | ||||
|     def setCredentials(self, spotifyCredentials): | ||||
|         # Remove extra spaces, just to be sure | ||||
|         spotifyCredentials['clientId'] = spotifyCredentials['clientId'].strip() | ||||
|         spotifyCredentials['clientSecret'] = spotifyCredentials['clientSecret'].strip() | ||||
|  | ||||
|         # Save them to disk | ||||
|         with open(path.join(self.configFolder, 'authCredentials.json'), 'w') as f: | ||||
|             json.dump(spotifyCredentials, f, indent=2) | ||||
|  | ||||
|         # Check if they are usable | ||||
|         self.credentials = spotifyCredentials | ||||
|         self.checkCredentials() | ||||
|  | ||||
|     def createSpotifyConnection(self): | ||||
|         client_credentials_manager = SpotifyClientCredentials(client_id=self.credentials['clientId'], | ||||
|                                                               client_secret=self.credentials['clientSecret']) | ||||
|         self.sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) | ||||
|  | ||||
|     # Converts spotify API playlist structure to deezer's playlist structure | ||||
|     def _convert_playlist_structure(self, spotify_obj): | ||||
|         if len(spotify_obj['images']): | ||||
|             url = spotify_obj['images'][0]['url'] | ||||
| @ -115,6 +120,7 @@ class SpotifyHelper: | ||||
|             deezer_obj['picture_xl'] = "https://e-cdns-images.dzcdn.net/images/cover/d41d8cd98f00b204e9800998ecf8427e/1000x1000-000000-80-0-0.jpg" | ||||
|         return deezer_obj | ||||
|  | ||||
|     # Returns deezer song_id from spotify track_id or track dict | ||||
|     def get_trackid_spotify(self, dz, track_id, fallbackSearch, spotifyTrack=None): | ||||
|         if not self.spotifyEnabled: | ||||
|             raise spotifyFeaturesNotEnabled | ||||
| @ -148,6 +154,7 @@ class SpotifyHelper: | ||||
|                 json.dump(cache, spotifyCache) | ||||
|         return dz_track | ||||
|  | ||||
|     # Returns deezer album_id from spotify album_id | ||||
|     def get_albumid_spotify(self, dz, album_id): | ||||
|         if not self.spotifyEnabled: | ||||
|             raise spotifyFeaturesNotEnabled | ||||
| @ -175,33 +182,24 @@ class SpotifyHelper: | ||||
|             json.dump(cache, spotifyCache) | ||||
|         return dz_album | ||||
|  | ||||
|     def adapt_spotify_playlist(self, dz, playlist_id, settings): | ||||
|  | ||||
|     def generate_playlist_queueitem(self, dz, playlist_id, settings): | ||||
|         if not self.spotifyEnabled: | ||||
|             raise spotifyFeaturesNotEnabled | ||||
|         spotify_playlist = self.sp.playlist(playlist_id) | ||||
|         result = { | ||||
|             'title': spotify_playlist['name'], | ||||
|             'artist': spotify_playlist['owner']['display_name'], | ||||
|             'size': spotify_playlist['tracks']['total'], | ||||
|             'downloaded': 0, | ||||
|             'failed': 0, | ||||
|             'progress': 0, | ||||
|             'errors': [], | ||||
|             'type': 'spotify_playlist', | ||||
|             'settings': settings or {}, | ||||
|             'id': playlist_id | ||||
|         } | ||||
|  | ||||
|         if len(spotify_playlist['images']): | ||||
|             result['cover'] = spotify_playlist['images'][0]['url'] | ||||
|             cover = spotify_playlist['images'][0]['url'] | ||||
|         else: | ||||
|             result[ | ||||
|                 'cover'] = "https://e-cdns-images.dzcdn.net/images/cover/d41d8cd98f00b204e9800998ecf8427e/75x75-000000-80-0-0.jpg" | ||||
|             cover = "https://e-cdns-images.dzcdn.net/images/cover/d41d8cd98f00b204e9800998ecf8427e/75x75-000000-80-0-0.jpg" | ||||
|  | ||||
|         playlistAPI = self._convert_playlist_structure(spotify_playlist) | ||||
|         playlistAPI['various_artist'] = dz.get_artist(5080) | ||||
|  | ||||
|         extra = {} | ||||
|         extra['unconverted'] = [] | ||||
|  | ||||
|         tracklistTmp = spotify_playlist['tracks']['items'] | ||||
|         result['collection'] = [] | ||||
|         result['_EXTRA'] = {} | ||||
|         result['_EXTRA']['unconverted'] = [] | ||||
|         while spotify_playlist['tracks']['next']: | ||||
|             spotify_playlist['tracks'] = self.sp.next(spotify_playlist['tracks']) | ||||
|             tracklistTmp += spotify_playlist['tracks']['items'] | ||||
| @ -209,13 +207,23 @@ class SpotifyHelper: | ||||
|             if item['track']: | ||||
|                 if item['track']['explicit']: | ||||
|                     playlistAPI['explicit'] = True | ||||
|                 result['_EXTRA']['unconverted'].append(item['track']) | ||||
|         totalSize = len(result['_EXTRA']['unconverted']) | ||||
|         result['size'] = totalSize | ||||
|                 extra['unconverted'].append(item['track']) | ||||
|  | ||||
|         totalSize = len(extra['unconverted']) | ||||
|         if not 'explicit' in playlistAPI: | ||||
|             playlistAPI['explicit'] = False | ||||
|         result['_EXTRA']['playlistAPI'] = playlistAPI | ||||
|         return result | ||||
|         extra['playlistAPI'] = playlistAPI | ||||
|         return QICollection( | ||||
|             playlist_id, | ||||
|             0, | ||||
|             spotify_playlist['name'], | ||||
|             spotify_playlist['owner']['display_name'], | ||||
|             cover, | ||||
|             totalSize, | ||||
|             'spotify_playlist', | ||||
|             settings, | ||||
|             extra, | ||||
|         ) | ||||
|  | ||||
|     def convert_spotify_playlist(self, dz, item, settings, interface=None): | ||||
|         convertPercentage = 0 | ||||
| @ -226,8 +234,9 @@ class SpotifyHelper: | ||||
|         else: | ||||
|             cache = {'tracks': {}, 'albums': {}} | ||||
|         if interface: | ||||
|             interface.send("startConversion", item['uuid']) | ||||
|         for pos, track in enumerate(item['_EXTRA']['unconverted'], start=1): | ||||
|             interface.send("startConversion", item.uuid) | ||||
|         collection = [] | ||||
|         for pos, track in enumerate(item.extra['unconverted'], start=1): | ||||
|             if str(track['id']) in cache['tracks']: | ||||
|                 trackID = cache['tracks'][str(track['id'])] | ||||
|             else: | ||||
| @ -248,20 +257,31 @@ class SpotifyHelper: | ||||
|                 } | ||||
|             else: | ||||
|                 deezerTrack = dz.get_track_gw(trackID) | ||||
|             deezerTrack['_EXTRA_PLAYLIST'] = item['_EXTRA']['playlistAPI'] | ||||
|             deezerTrack['_EXTRA_PLAYLIST'] = item.extra['playlistAPI'] | ||||
|             deezerTrack['POSITION'] = pos | ||||
|             deezerTrack['SIZE'] = item['size'] | ||||
|             deezerTrack['SIZE'] = item.size | ||||
|             deezerTrack['FILENAME_TEMPLATE'] = settings['playlistTracknameTemplate'] | ||||
|             item['collection'].append(deezerTrack) | ||||
|             collection.append(deezerTrack) | ||||
|  | ||||
|             convertPercentage = (pos / item['size']) * 100 | ||||
|             convertPercentage = (pos / item.size) * 100 | ||||
|             print(convertPercentage) | ||||
|             if round(convertPercentage) != lastPercentage and round(convertPercentage) % 2 == 0: | ||||
|                 lastPercentage = round(convertPercentage) | ||||
|                 if interface: | ||||
|                     interface.send("updateQueue", {'uuid': item['uuid'], 'conversion': lastPercentage}) | ||||
|                     interface.send("updateQueue", {'uuid': item.uuid, 'conversion': lastPercentage}) | ||||
|  | ||||
|         del item['_EXTRA'] | ||||
|         item = QICollection( | ||||
|             item.id, | ||||
|             item.bitrate, | ||||
|             item.title, | ||||
|             item.artist, | ||||
|             item.cover, | ||||
|             item.size, | ||||
|             item.type, | ||||
|             item.settings, | ||||
|             collection, | ||||
|         ) | ||||
|          | ||||
|         with open(path.join(self.configFolder, 'spotifyCache.json'), 'w') as spotifyCache: | ||||
|             json.dump(cache, spotifyCache) | ||||
|         if interface: | ||||
|  | ||||
| @ -218,11 +218,11 @@ def settingsRegexPlaylist(foldername, playlist, settings): | ||||
|     return antiDot(fixLongName(foldername)) | ||||
|  | ||||
| def settingsRegexPlaylistFile(foldername, queueItem, settings): | ||||
|     foldername = foldername.replace("%title%", fixName(queueItem['title'], settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%artist%", fixName(queueItem['artist'], settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%size%", str(queueItem['size'])) | ||||
|     foldername = foldername.replace("%type%", fixName(queueItem['type'], settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%id%", fixName(queueItem['id'], settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%bitrate%", bitrateLabels[int(queueItem['bitrate'])]) | ||||
|     foldername = foldername.replace("%title%", fixName(queueItem.title, settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%artist%", fixName(queueItem.artist, settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%size%", str(queueItem.size)) | ||||
|     foldername = foldername.replace("%type%", fixName(queueItem.type, settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%id%", fixName(queueItem.id, settings['illegalCharacterReplacer'])) | ||||
|     foldername = foldername.replace("%bitrate%", bitrateLabels[int(queueItem.bitrate)]) | ||||
|     foldername = foldername.replace('\\', pathSep).replace('/', pathSep).replace(pathSep, settings['illegalCharacterReplacer']) | ||||
|     return antiDot(fixLongName(foldername)) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 RemixDev
					RemixDev