More code reworking

This commit is contained in:
RemixDev 2020-08-15 15:49:45 +02:00
parent 243cf3dfa6
commit 7a536caf1c
6 changed files with 199 additions and 178 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -6,19 +6,9 @@ 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
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 = {
emptyPlaylist = {
'collaborative': False,
'description': "",
'external_urls': {'spotify': None},
@ -35,14 +25,26 @@ class SpotifyHelper:
'type': 'playlist',
'uri': None
}
self.initCredentials()
def initCredentials(self):
class SpotifyHelper:
def __init__(self, configFolder=None):
self.credentials = {}
self.spotifyEnabled = False
self.sp = None
self.configFolder = configFolder
# 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})
item = QICollection(
item.id,
item.bitrate,
item.title,
item.artist,
item.cover,
item.size,
item.type,
item.settings,
collection,
)
del item['_EXTRA']
with open(path.join(self.configFolder, 'spotifyCache.json'), 'w') as spotifyCache:
json.dump(cache, spotifyCache)
if interface:

View File

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