Continued code reworking

This commit is contained in:
RemixDev 2020-08-14 22:28:26 +02:00
parent c611420bd9
commit 243cf3dfa6
4 changed files with 194 additions and 198 deletions

View File

@ -257,7 +257,36 @@ class Deezer:
return self.gw_api_call('deezer.pageArtist', {'art_id': art_id}) return self.gw_api_call('deezer.pageArtist', {'art_id': art_id})
def get_playlist_gw(self, playlist_id): def get_playlist_gw(self, playlist_id):
return self.gw_api_call('deezer.pagePlaylist', {'playlist_id': playlist_id, 'lang': 'en'}) 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'],
'description': playlistAPI['DESCRIPTION'],
'duration': playlistAPI['DURATION'],
'public': playlistAPI['STATUS'] == 1,
'is_loved_track': playlistAPI['TYPE'] == 4,
'collaborative': playlistAPI['STATUS'] == 2,
'nb_tracks': playlistAPI['NB_SONG'],
'fans': playlistAPI['NB_FAN'],
'link': "https://www.deezer.com/playlist/"+playlistAPI['PLAYLIST_ID'],
'share': "https://www.deezer.com/playlist/"+playlistAPI['PLAYLIST_ID'],
'picture': "https://api.deezer.com/playlist/"+playlistAPI['PLAYLIST_ID']+"/image",
'picture_small': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/56x56-000000-80-0-0.jpg",
'picture_medium': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/250x250-000000-80-0-0.jpg",
'picture_big': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/500x500-000000-80-0-0.jpg",
'picture_xl': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/1000x1000-000000-80-0-0.jpg",
'checksum': playlistAPI['CHECKSUM'],
'tracklist': "https://api.deezer.com/playlist/"+playlistAPI['PLAYLIST_ID']+"/tracks",
'creation_date': playlistAPI['DATE_ADD'],
'creator': {
'id': playlistAPI['PARENT_USER_ID'],
'name': playlistAPI['PARENT_USERNAME'],
'tracklist': "https://api.deezer.com/user/"+playlistAPI['PARENT_USER_ID']+"/flow",
'type': "user"
},
'type': "playlist"
}
def get_playlist_tracks_gw(self, playlist_id): def get_playlist_tracks_gw(self, playlist_id):
tracks_array = [] tracks_array = []

View File

@ -1,21 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""
queueItem base structure
title
artist
cover
size
downloaded
failed
errors
progress
type
id
bitrate
uuid: type+id+bitrate
"""
class QueueItem: class QueueItem:
def __init__(self, id=None, bitrate=None, title=None, artist=None, cover=None, size=None, type=None, settings=None, queueItemList=None): def __init__(self, id=None, bitrate=None, title=None, artist=None, cover=None, size=None, type=None, settings=None, queueItemList=None):
if queueItemList: if queueItemList:
@ -41,9 +25,10 @@ class QueueItem:
self.errors = [] self.errors = []
self.progress = 0 self.progress = 0
self.uuid = f"{self.type}_{self.id}_{self.bitrate}" self.uuid = f"{self.type}_{self.id}_{self.bitrate}"
self.cancel = False
def toDict(self): def toDict(self):
queueItem = { return {
'title': self.title, 'title': self.title,
'artist': self.artist, 'artist': self.artist,
'cover': self.cover, 'cover': self.cover,
@ -57,7 +42,6 @@ class QueueItem:
'bitrate': self.bitrate, 'bitrate': self.bitrate,
'uuid': self.uuid 'uuid': self.uuid
} }
return queueItem
def getResettedItem(self): def getResettedItem(self):
item = self.toDict() item = self.toDict()
@ -102,3 +86,17 @@ class QICollection(QueueItem):
queueItem = super().toDict() queueItem = super().toDict()
queueItem['collection'] = self.collection queueItem['collection'] = self.collection
return queueItem return queueItem
class QIConvertable(QueueItem):
def __init__(self, id=None, bitrate=None, title=None, artist=None, cover=None, size=None, type=None, settings=None, extra=None, queueItemList=None):
if queueItemList:
super().__init__(queueItemList=queueItemList)
self.extra = queueItemList['_EXTRA']
else:
super().__init__(id, bitrate, title, artist, cover, size, type, settings)
self.extra = extra
def toDict(self):
queueItem = super().toDict()
queueItem['_EXTRA'] = self.extra
return queueItem

View File

@ -26,7 +26,7 @@ class QueueManager:
if type == None or id == None: if type == None or id == None:
logger.warn("URL not recognized") logger.warn("URL not recognized")
return queueError(url, "URL not recognized", "invalidURL") return QueueError(url, "URL not recognized", "invalidURL")
elif type == "track": elif type == "track":
if id.startswith("isrc"): if id.startswith("isrc"):
@ -38,7 +38,7 @@ class QueueManager:
except APIError as e: except APIError as e:
e = json.loads(str(e)) e = json.loads(str(e))
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 ''}")
try: try:
trackAPI = dz.get_track_gw(id) trackAPI = dz.get_track_gw(id)
except APIError as e: except APIError as e:
@ -46,7 +46,7 @@ class QueueManager:
message = "Wrong URL" message = "Wrong URL"
if "DATA_ERROR" in e: if "DATA_ERROR" in e:
message += f": {e['DATA_ERROR']}" message += f": {e['DATA_ERROR']}"
return queueError(url, message) return QueueError(url, message)
if albumAPI: if albumAPI:
trackAPI['_EXTRA_ALBUM'] = albumAPI trackAPI['_EXTRA_ALBUM'] = albumAPI
if settings['createSingleFolder']: if settings['createSingleFolder']:
@ -74,7 +74,7 @@ class QueueManager:
albumAPI = dz.get_album(id) albumAPI = dz.get_album(id)
except APIError as e: except APIError as e:
e = json.loads(str(e)) e = json.loads(str(e))
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 id.startswith('upc'): if id.startswith('upc'):
id = albumAPI['id'] id = albumAPI['id']
albumAPI_gw = dz.get_album_gw(id) albumAPI_gw = dz.get_album_gw(id)
@ -119,45 +119,16 @@ class QueueManager:
playlistAPI = dz.get_playlist(id) playlistAPI = dz.get_playlist(id)
except: except:
try: try:
playlistAPI = dz.get_playlist_gw(id)['results']['DATA'] playlistAPI = dz.get_playlist_gw(id)
except APIError as e: except APIError as e:
e = json.loads(str(e)) e = json.loads(str(e))
message = "Wrong URL" message = "Wrong URL"
if "DATA_ERROR" in e: if "DATA_ERROR" in e:
message += f": {e['DATA_ERROR']}" message += f": {e['DATA_ERROR']}"
return queueError(url, message) return QueueError(url, message)
newPlaylist = {
'id': playlistAPI['PLAYLIST_ID'],
'title': playlistAPI['TITLE'],
'description': playlistAPI['DESCRIPTION'],
'duration': playlistAPI['DURATION'],
'public': False,
'is_loved_track': False,
'collaborative': False,
'nb_tracks': playlistAPI['NB_SONG'],
'fans': playlistAPI['NB_FAN'],
'link': "https://www.deezer.com/playlist/"+playlistAPI['PLAYLIST_ID'],
'share': None,
'picture': "https://api.deezer.com/playlist/"+playlistAPI['PLAYLIST_ID']+"/image",
'picture_small': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/56x56-000000-80-0-0.jpg",
'picture_medium': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/250x250-000000-80-0-0.jpg",
'picture_big': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/500x500-000000-80-0-0.jpg",
'picture_xl': "https://cdns-images.dzcdn.net/images/"+playlistAPI['PICTURE_TYPE']+"/"+playlistAPI['PLAYLIST_PICTURE']+"/1000x1000-000000-80-0-0.jpg",
'checksum': playlistAPI['CHECKSUM'],
'tracklist': "https://api.deezer.com/playlist/"+playlistAPI['PLAYLIST_ID']+"/tracks",
'creation_date': playlistAPI['DATE_ADD'],
'creator': {
'id': playlistAPI['PARENT_USER_ID'],
'name': playlistAPI['PARENT_USERNAME'],
'tracklist': "https://api.deezer.com/user/"+playlistAPI['PARENT_USER_ID']+"/flow",
'type': "user"
},
'type': "playlist"
}
playlistAPI = newPlaylist
if not playlistAPI['public'] and playlistAPI['creator']['id'] != str(dz.user['id']): if not playlistAPI['public'] and playlistAPI['creator']['id'] != str(dz.user['id']):
logger.warn("You can't download others private playlists.") logger.warn("You can't download others private playlists.")
return return queueError(url, "You can't download others private playlists.", "notYourPrivatePlaylist") return return QueueError(url, "You can't download others private playlists.", "notYourPrivatePlaylist")
playlistTracksAPI = dz.get_playlist_tracks_gw(id) playlistTracksAPI = dz.get_playlist_tracks_gw(id)
playlistAPI['various_artist'] = dz.get_artist(5080) playlistAPI['various_artist'] = dz.get_artist(5080)
@ -192,7 +163,7 @@ class QueueManager:
artistAPI = dz.get_artist(id) artistAPI = dz.get_artist(id)
except APIError as e: except APIError as e:
e = json.loads(str(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 return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}")
if interface: if interface:
interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']})
@ -212,7 +183,7 @@ class QueueManager:
artistAPI = dz.get_artist(id) artistAPI = dz.get_artist(id)
except APIError as e: except APIError as e:
e = json.loads(str(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 return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}")
if interface: if interface:
interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']}) interface.send("startAddingArtist", {'name': artistAPI['name'], 'id': artistAPI['id']})
@ -234,7 +205,7 @@ class QueueManager:
artistAPI = dz.get_artist(id) artistAPI = dz.get_artist(id)
except APIError as e: except APIError as e:
e = json.loads(str(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 return QueueError(url, f"Wrong URL: {e['type']+': ' if 'type' in e else ''}{e['message'] if 'message' in e else ''}")
playlistAPI = { playlistAPI = {
'id': str(artistAPI['id'])+"_top_track", 'id': str(artistAPI['id'])+"_top_track",
@ -296,39 +267,39 @@ class QueueManager:
elif type == "spotifytrack": elif type == "spotifytrack":
if not sp.spotifyEnabled: if not sp.spotifyEnabled:
logger.warn("Spotify Features is not setted up correctly.") logger.warn("Spotify Features is not setted up correctly.")
return queueError(url, "Spotify Features is not setted up correctly.", "spotifyDisabled") return QueueError(url, "Spotify Features is not setted up correctly.", "spotifyDisabled")
try: try:
track_id = sp.get_trackid_spotify(dz, id, settings['fallbackSearch']) track_id = sp.get_trackid_spotify(dz, id, settings['fallbackSearch'])
except SpotifyException as e: except SpotifyException as e:
return queueError(url, "Wrong URL: "+e.msg[e.msg.find('\n')+2:]) return QueueError(url, "Wrong URL: "+e.msg[e.msg.find('\n')+2:])
if track_id != 0: if track_id != 0:
return generateQueueItem(dz, sp, f'https://www.deezer.com/track/{track_id}', settings, bitrate) return generateQueueItem(dz, sp, f'https://www.deezer.com/track/{track_id}', settings, bitrate)
else: else:
logger.warn("Track not found on deezer!") logger.warn("Track not found on deezer!")
return queueError(url, "Track not found on deezer!", "trackNotOnDeezer") return QueueError(url, "Track not found on deezer!", "trackNotOnDeezer")
elif type == "spotifyalbum": elif type == "spotifyalbum":
if not sp.spotifyEnabled: if not sp.spotifyEnabled:
logger.warn("Spotify Features is not setted up correctly.") logger.warn("Spotify Features is not setted up correctly.")
return queueError(url, "Spotify Features is not setted up correctly.", "spotifyDisabled") return QueueError(url, "Spotify Features is not setted up correctly.", "spotifyDisabled")
try: try:
album_id = sp.get_albumid_spotify(dz, id) album_id = sp.get_albumid_spotify(dz, id)
except SpotifyException as e: except SpotifyException as e:
return queueError(url, "Wrong URL: "+e.msg[e.msg.find('\n')+2:]) return QueueError(url, "Wrong URL: "+e.msg[e.msg.find('\n')+2:])
if album_id != 0: if album_id != 0:
return generateQueueItem(dz, sp, f'https://www.deezer.com/album/{album_id}', settings, bitrate) return generateQueueItem(dz, sp, f'https://www.deezer.com/album/{album_id}', settings, bitrate)
else: else:
logger.warn("Album not found on deezer!") logger.warn("Album not found on deezer!")
return queueError(url, "Album not found on deezer!", "albumNotOnDeezer") return QueueError(url, "Album not found on deezer!", "albumNotOnDeezer")
elif type == "spotifyplaylist": elif type == "spotifyplaylist":
if not sp.spotifyEnabled: if not sp.spotifyEnabled:
logger.warn("Spotify Features is not setted up correctly.") logger.warn("Spotify Features is not setted up correctly.")
return queueError(url, "Spotify Features is not setted up correctly.", "spotifyDisabled") return QueueError(url, "Spotify Features is not setted up correctly.", "spotifyDisabled")
try: try:
playlist = sp.adapt_spotify_playlist(dz, id, settings) playlist = sp.adapt_spotify_playlist(dz, id, settings)
@ -336,156 +307,153 @@ class QueueManager:
playlist['uuid'] = f"{playlist['type']}_{id}_{bitrate}" playlist['uuid'] = f"{playlist['type']}_{id}_{bitrate}"
return playlist return playlist
except SpotifyException as e: except SpotifyException as e:
return queueError(url, "Wrong URL: "+e.msg[e.msg.find('\n')+2:]) return QueueError(url, "Wrong URL: "+e.msg[e.msg.find('\n')+2:])
else: else:
logger.warn("URL not supported yet") logger.warn("URL not supported yet")
return queueError(url, "URL not supported yet", "unsupportedURL") return QueueError(url, "URL not supported yet", "unsupportedURL")
def addToQueue(self, dz, sp, url, settings, bitrate=None, interface=None):
def addToQueue(dz, sp, url, settings, bitrate=None, interface=None): if not dz.logged_in:
global currentItem, queueList, queue if interface:
if not dz.logged_in: interface.send("loginNeededToDownload")
return "Not logged in" return False
if type(url) is list: def parseLink(link):
queueItem = []
for link in url:
link = link.strip() link = link.strip()
if link == "": if link == "":
continue return False
logger.info("Generating queue item for: "+link) logger.info("Generating queue item for: "+link)
item = generateQueueItem(dz, sp, link, settings, bitrate, interface=interface) return self.generateQueueItem(dz, sp, link, settings, bitrate, interface=interface)
if type(item) is list: if type(url) is list:
queueItem += item queueItem = []
else: for link in url:
queueItem.append(item) item = parseLink(link)
else: if not item:
url = url.strip() continue
if url == "": elif type(item) is list:
return False queueItem += item
logger.info("Generating queue item for: "+url) else:
queueItem = generateQueueItem(dz, sp, url, settings, bitrate, interface=interface) queueItem.append(item)
if type(queueItem) is list: if not len(queueItem):
for x in queueItem: return False
if 'error' in x:
logger.error(f"[{x['link']}] {x['error']}")
continue
if x['uuid'] in list(queueList.keys()):
logger.warn(f"[{x['uuid']}] Already in queue, will not be added again.")
continue
if interface:
interface.send("addedToQueue", slimQueueItem(x))
queue.append(x['uuid'])
queueList[x['uuid']] = x
logger.info(f"[{x['uuid']}] Added to queue.")
else:
if 'error' in queueItem:
logger.error(f"[{queueItem['link']}] {queueItem['error']}")
if interface:
interface.send("queueError", queueItem)
return False
if queueItem['uuid'] in list(queueList.keys()):
logger.warn(f"[{queueItem['uuid']}] Already in queue, will not be added again.")
if interface:
interface.send("alreadyInQueue", {'uuid': queueItem['uuid'], 'title': queueItem['title']})
return False
if interface:
interface.send("addedToQueue", slimQueueItem(queueItem))
logger.info(f"[{queueItem['uuid']}] Added to queue.")
queue.append(queueItem['uuid'])
queueList[queueItem['uuid']] = queueItem
nextItem(dz, sp, interface)
return True
def nextItem(dz, sp, interface=None):
global currentItem, queueList, queue
if currentItem != "":
return None
else:
if len(queue) > 0:
currentItem = queue.pop(0)
else: else:
queueItem = parseLink(url)
if not queueItem:
return False
if type(queueItem) is list:
ogLen = len(self.queue)
for x in queueItem:
if isinstance(x, QueueError):
logger.error(f"[{x.link}] {x.message}")
continue
if x.uuid in list(self.queueList.keys()):
logger.warn(f"[{x.uuid}] Already in queue, will not be added again.")
continue
self.queue.append(x.uuid)
self.queueList[x.uuid] = x
logger.info(f"[{x.uuid}] Added to queue.")
if ogLen <= len(self.queue):
return False
else:
if isinstance(queueItem, QueueError):
logger.error(f"[{x.link}] {x.message}")
if interface:
interface.send("queueError", queueItem.toDict())
return False
if queueItem.uuid in list(self.queueList.keys()):
logger.warn(f"[{queueItem.uuid}] Already in queue, will not be added again.")
if interface:
interface.send("alreadyInQueue", {'uuid': queueItem.uuid, 'title': queueItem.title})
return False
if interface:
interface.send("addedToQueue", queueItem.getSlimmedItem())
logger.info(f"[{queueItem.uuid}] Added to queue.")
self.queue.append(queueItem.uuid)
self.queueList[queueItem.uuid] = queueItem
self.nextItem(dz, sp, interface)
return True
def nextItem(self, dz, sp, interface=None):
if self.currentItem != "":
return None return None
else:
if len(self.queue) > 0:
self.currentItem = self.queue.pop(0)
else:
return None
if interface:
interface.send("startDownload", self.currentItem)
logger.info(f"[{self.currentItem}] Started downloading.")
download(dz, sp, self.queueList[self.currentItem], interface)
self.afterDownload(dz, sp, interface)
def afterDownload(self, dz, sp, interface):
if self.queueList[self.currentItem].cancel:
del self.queueList[self.currentItem]
else:
self.queueComplete.append(self.currentItem)
logger.info(f"[{self.currentItem}] Finished downloading.")
self.currentItem = ""
self.nextItem(dz, sp, interface)
def getQueue(self):
return (self.queue, self.queueComplete, self.queueList, self.currentItem)
# TODO: Convert dicts to QueueItem Objects when restoring
def restoreQueue(self, queue, queueComplete, queueList, dz, sp, interface):
self.queueComplete = queueComplete
self.queueList = queueList
self.queue = queue
nextItem(dz, sp, interface)
def removeFromQueue(self, uuid, interface=None):
if uuid == self.currentItem:
if interface:
interface.send("cancellingCurrentItem", uuid)
self.queueList[uuid].cancel = True
elif uuid in self.queue:
self.queue.remove(uuid)
del self.queueList[uuid]
if interface:
interface.send("removedFromQueue", uuid)
elif uuid in self.queueComplete:
self.queueComplete.remove(uuid)
del self.queueList[uuid]
if interface:
interface.send("removedFromQueue", uuid)
def cancelAllDownloads(self, interface=None):
self.queue = []
self.queueComplete = []
if self.currentItem != "":
if interface:
interface.send("cancellingCurrentItem", self.currentItem)
self.queueList[self.currentItem].cancel = True
for uuid in list(self.queueList.keys()):
if uuid != self.currentItem:
del self.queueList[uuid]
if interface: if interface:
interface.send("startDownload", currentItem) interface.send("removedAllDownloads", self.currentItem)
logger.info(f"[{currentItem}] Started downloading.")
result = download(dz, sp, queueList[currentItem], interface)
callbackQueueDone(result)
def callbackQueueDone(result): def removeFinishedDownloads(self, interface=None):
global currentItem, queueList, queueComplete for uuid in self.queueComplete:
if 'cancel' in queueList[currentItem]: del self.queueList[self.uuid]
del queueList[currentItem] self.queueComplete = []
else:
queueComplete.append(currentItem)
logger.info(f"[{currentItem}] Finished downloading.")
currentItem = ""
nextItem(result['dz'], result['sp'], result['interface'])
def getQueue():
global currentItem, queueList, queue, queueComplete
return (queue, queueComplete, queueList, currentItem)
def restoreQueue(pqueue, pqueueComplete, pqueueList, dz, interface):
global currentItem, queueList, queue, queueComplete
queueComplete = pqueueComplete
queueList = pqueueList
queue = pqueue
nextItem(dz, interface)
def removeFromQueue(uuid, interface=None):
global currentItem, queueList, queue, queueComplete
if uuid == currentItem:
if interface: if interface:
interface.send("cancellingCurrentItem", currentItem) interface.send("removedFinishedDownloads")
queueList[uuid]['cancel'] = True
elif uuid in queue:
queue.remove(uuid)
del queueList[uuid]
if interface:
interface.send("removedFromQueue", uuid)
elif uuid in queueComplete:
queueComplete.remove(uuid)
del queueList[uuid]
if interface:
interface.send("removedFromQueue", uuid)
class QueueError:
def cancelAllDownloads(interface=None):
global currentItem, queueList, queue, queueComplete
queue = []
queueComplete = []
if currentItem != "":
if interface:
interface.send("cancellingCurrentItem", currentItem)
queueList[currentItem]['cancel'] = True
for uuid in list(queueList.keys()):
if uuid != currentItem:
del queueList[uuid]
if interface:
interface.send("removedAllDownloads", currentItem)
def removeFinishedDownloads(interface=None):
global queueList, queueComplete
for uuid in queueComplete:
del queueList[uuid]
queueComplete = []
if interface:
interface.send("removedFinishedDownloads")
class queueError:
def __init__(self, link, message, errid=None): def __init__(self, link, message, errid=None):
self.link = link self.link = link
self.message = message self.message = message
self.errid = errid self.errid = errid
def toList(self): def toDict(self):
error = { return {
'link' 'link': self.link,
'error': self.message,
'errid': self.errid
} }

View File

@ -6,6 +6,7 @@ from os import mkdir
import spotipy import spotipy
from spotipy.oauth2 import SpotifyClientCredentials from spotipy.oauth2 import SpotifyClientCredentials
from deemix.utils.localpaths import getConfigFolder from deemix.utils.localpaths import getConfigFolder
from deemix.app.queueitem import QIConvertable
class SpotifyHelper: class SpotifyHelper: