More code reworking
This commit is contained in:
parent
243cf3dfa6
commit
7a536caf1c
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue