2020-04-10 14:12:21 +00:00
|
|
|
from deemix.utils.misc import getIDFromLink, getTypeFromLink, getBitrateInt
|
|
|
|
from deemix.utils.spotifyHelper import get_trackid_spotify, get_albumid_spotify
|
|
|
|
from concurrent.futures import ProcessPoolExecutor
|
|
|
|
from deemix.app.downloader import download
|
|
|
|
|
|
|
|
queue = []
|
|
|
|
queueList = {}
|
2020-04-14 14:48:13 +00:00
|
|
|
queueComplete = []
|
2020-04-10 14:12:21 +00:00
|
|
|
currentItem = ""
|
|
|
|
|
|
|
|
"""
|
|
|
|
queueItem base structure
|
|
|
|
title
|
|
|
|
artist
|
|
|
|
cover
|
|
|
|
size
|
|
|
|
downloaded
|
|
|
|
failed
|
|
|
|
progress
|
|
|
|
type
|
|
|
|
id
|
|
|
|
bitrate
|
|
|
|
uuid: type+id+bitrate
|
|
|
|
if its a single track
|
|
|
|
single
|
|
|
|
if its an album/playlist
|
|
|
|
collection
|
|
|
|
"""
|
|
|
|
|
2020-04-11 10:51:22 +00:00
|
|
|
def generateQueueItem(dz, url, settings, bitrate=None, albumAPI=None, socket=None):
|
2020-04-10 14:12:21 +00:00
|
|
|
forcedBitrate = getBitrateInt(bitrate)
|
|
|
|
bitrate = forcedBitrate if forcedBitrate else settings['maxBitrate']
|
|
|
|
type = getTypeFromLink(url)
|
|
|
|
id = getIDFromLink(url, type)
|
|
|
|
result = {}
|
|
|
|
if type == None or id == None:
|
|
|
|
print("URL not recognized")
|
|
|
|
result['error'] = "URL not recognized"
|
|
|
|
elif type == "track":
|
|
|
|
trackAPI = dz.get_track_gw(id)
|
|
|
|
if albumAPI:
|
|
|
|
trackAPI['_EXTRA_ALBUM'] = albumAPI
|
|
|
|
trackAPI['FILENAME_TEMPLATE'] = settings['tracknameTemplate']
|
|
|
|
trackAPI['SINGLE_TRACK'] = True
|
|
|
|
|
|
|
|
result['title'] = trackAPI['SNG_TITLE']
|
|
|
|
if 'VERSION' in trackAPI and trackAPI['VERSION']:
|
|
|
|
result['title'] += " " + trackAPI['VERSION']
|
|
|
|
result['artist'] = trackAPI['ART_NAME']
|
2020-04-10 16:00:42 +00:00
|
|
|
result['cover'] = f"https://e-cdns-images.dzcdn.net/images/cover/{trackAPI['ALB_PICTURE']}/75x75-000000-80-0-0.jpg"
|
2020-04-10 14:12:21 +00:00
|
|
|
result['size'] = 1
|
|
|
|
result['downloaded'] = 0
|
|
|
|
result['failed'] = 0
|
|
|
|
result['progress'] = 0
|
|
|
|
result['type'] = 'track'
|
|
|
|
result['id'] = id
|
|
|
|
result['bitrate'] = bitrate
|
2020-04-10 16:00:42 +00:00
|
|
|
result['uuid'] = f"{result['type']}_{id}_{bitrate}"
|
2020-04-10 14:12:21 +00:00
|
|
|
result['settings'] = settings or {}
|
|
|
|
result['single'] = trackAPI
|
|
|
|
|
|
|
|
elif type == "album":
|
|
|
|
albumAPI = dz.get_album(id)
|
|
|
|
albumAPI_gw = dz.get_album_gw(id)
|
|
|
|
albumAPI['nb_disk'] = albumAPI_gw['NUMBER_DISK']
|
|
|
|
albumAPI['copyright'] = albumAPI_gw['COPYRIGHT']
|
|
|
|
if albumAPI['nb_tracks'] == 1:
|
|
|
|
return generateQueueItem(dz, f"https://www.deezer.com/track/{albumAPI['tracks']['data'][0]['id']}", settings, bitrate, albumAPI)
|
|
|
|
tracksArray = dz.get_album_tracks_gw(id)
|
|
|
|
|
|
|
|
result['title'] = albumAPI['title']
|
|
|
|
result['artist'] = albumAPI['artist']['name']
|
2020-04-10 16:00:42 +00:00
|
|
|
result['cover'] = albumAPI['cover_small'][:-24]+'/75x75-000000-80-0-0.jpg'
|
2020-04-10 14:12:21 +00:00
|
|
|
result['size'] = albumAPI['nb_tracks']
|
|
|
|
result['downloaded'] = 0
|
|
|
|
result['failed'] = 0
|
|
|
|
result['progress'] = 0
|
|
|
|
result['type'] = 'album'
|
|
|
|
result['id'] = id
|
|
|
|
result['bitrate'] = bitrate
|
2020-04-10 16:00:42 +00:00
|
|
|
result['uuid'] = f"{result['type']}_{id}_{bitrate}"
|
2020-04-10 14:12:21 +00:00
|
|
|
result['settings'] = settings or {}
|
2020-04-10 22:21:30 +00:00
|
|
|
totalSize = len(tracksArray)
|
2020-04-10 14:12:21 +00:00
|
|
|
result['collection'] = []
|
|
|
|
for pos, trackAPI in enumerate(tracksArray, start=1):
|
|
|
|
trackAPI['_EXTRA_ALBUM'] = albumAPI
|
|
|
|
trackAPI['POSITION'] = pos
|
2020-04-10 22:21:30 +00:00
|
|
|
trackAPI['SIZE'] = totalSize
|
2020-04-10 14:12:21 +00:00
|
|
|
trackAPI['FILENAME_TEMPLATE'] = settings['albumTracknameTemplate']
|
|
|
|
result['collection'].append(trackAPI)
|
|
|
|
|
|
|
|
elif type == "playlist":
|
|
|
|
playlistAPI = dz.get_playlist(id)
|
|
|
|
playlistTracksAPI = dz.get_playlist_tracks_gw(id)
|
|
|
|
|
|
|
|
result['title'] = playlistAPI['title']
|
|
|
|
result['artist'] = playlistAPI['creator']['name']
|
2020-04-10 16:00:42 +00:00
|
|
|
result['cover'] = playlistAPI['picture_small'][:-24]+'/75x75-000000-80-0-0.jpg'
|
2020-04-10 14:12:21 +00:00
|
|
|
result['size'] = playlistAPI['nb_tracks']
|
|
|
|
result['downloaded'] = 0
|
|
|
|
result['failed'] = 0
|
|
|
|
result['progress'] = 0
|
|
|
|
result['type'] = 'playlist'
|
|
|
|
result['id'] = id
|
|
|
|
result['bitrate'] = bitrate
|
2020-04-10 16:00:42 +00:00
|
|
|
result['uuid'] = f"{result['type']}_{id}_{bitrate}"
|
2020-04-10 14:12:21 +00:00
|
|
|
result['settings'] = settings or {}
|
2020-04-10 22:21:30 +00:00
|
|
|
totalSize = len(playlistTracksAPI)
|
2020-04-10 14:12:21 +00:00
|
|
|
result['collection'] = []
|
|
|
|
for pos, trackAPI in enumerate(playlistTracksAPI, start=1):
|
|
|
|
trackAPI['_EXTRA_PLAYLIST'] = playlistAPI
|
|
|
|
trackAPI['POSITION'] = pos
|
2020-04-10 22:21:30 +00:00
|
|
|
trackAPI['SIZE'] = totalSize
|
2020-04-10 14:12:21 +00:00
|
|
|
trackAPI['FILENAME_TEMPLATE'] = settings['playlistTracknameTemplate']
|
|
|
|
result['collection'].append(trackAPI)
|
|
|
|
|
|
|
|
elif type == "artist":
|
2020-04-11 10:51:22 +00:00
|
|
|
artistAPI = dz.get_artist(id)
|
|
|
|
if socket:
|
|
|
|
socket.emit("toast", {'msg': f"Adding {artistAPI['name']} albums to queue", 'icon': 'loading', 'dismiss': False, 'id': 'artist_'+str(artistAPI['id'])})
|
|
|
|
artistAPITracks = dz.get_artist_albums(id)
|
2020-04-10 14:12:21 +00:00
|
|
|
albumList = []
|
2020-04-11 10:51:22 +00:00
|
|
|
for album in artistAPITracks['data']:
|
2020-04-10 14:12:21 +00:00
|
|
|
albumList.append(generateQueueItem(dz, album['link'], settings, bitrate))
|
2020-04-11 10:51:22 +00:00
|
|
|
if socket:
|
2020-04-13 17:58:11 +00:00
|
|
|
socket.emit("toast", {'msg': f"Added {artistAPI['name']} albums to queue", 'icon': 'done', 'dismiss': True, 'id': 'artist_'+str(artistAPI['id'])})
|
2020-04-10 14:12:21 +00:00
|
|
|
return albumList
|
|
|
|
elif type == "spotifytrack":
|
|
|
|
track_id = get_trackid_spotify(dz, id, settings['fallbackSearch'])
|
|
|
|
result = {}
|
|
|
|
if track_id == "Not Enabled":
|
|
|
|
print("Spotify Features is not setted up correctly.")
|
|
|
|
result['error'] = "Spotify Features is not setted up correctly."
|
|
|
|
elif track_id != 0:
|
|
|
|
return generateQueueItem(dz, f'https://www.deezer.com/track/{track_id}', settings, bitrate)
|
|
|
|
else:
|
|
|
|
print("Track not found on deezer!")
|
|
|
|
result['error'] = "Track not found on deezer!"
|
|
|
|
elif type == "spotifyalbum":
|
|
|
|
album_id = get_albumid_spotify(dz, id)
|
|
|
|
if album_id == "Not Enabled":
|
|
|
|
print("Spotify Features is not setted up correctly.")
|
|
|
|
result['error'] = "Spotify Features is not setted up correctly."
|
|
|
|
elif album_id != 0:
|
2020-04-14 14:48:13 +00:00
|
|
|
return generateQueueItem(dz, f'https://www.deezer.com/album/{album_id}', settings, bitrate)
|
2020-04-10 14:12:21 +00:00
|
|
|
else:
|
|
|
|
print("Album not found on deezer!")
|
|
|
|
result['error'] = "Album not found on deezer!"
|
|
|
|
else:
|
|
|
|
print("URL not supported yet")
|
|
|
|
result['error'] = "URL not supported yet"
|
|
|
|
return result
|
|
|
|
|
|
|
|
def addToQueue(dz, url, settings, bitrate=None, socket=None):
|
2020-04-14 14:48:13 +00:00
|
|
|
global currentItem, queueList, queue
|
2020-04-12 19:22:06 +00:00
|
|
|
if not dz.logged_in:
|
|
|
|
return "Not logged in"
|
2020-04-11 10:51:22 +00:00
|
|
|
queueItem = generateQueueItem(dz, url, settings, bitrate, socket=socket)
|
2020-04-10 14:12:21 +00:00
|
|
|
if type(queueItem) is list:
|
|
|
|
for x in queueItem:
|
2020-04-10 21:21:09 +00:00
|
|
|
if 'error' in x:
|
2020-04-11 10:51:22 +00:00
|
|
|
continue
|
2020-04-10 21:21:09 +00:00
|
|
|
if x['uuid'] in list(queueList.keys()):
|
|
|
|
print("Already in queue!")
|
2020-04-11 10:51:22 +00:00
|
|
|
continue
|
2020-04-10 14:12:21 +00:00
|
|
|
if socket:
|
|
|
|
socket.emit("addedToQueue", x)
|
|
|
|
queue.append(x['uuid'])
|
|
|
|
queueList[x['uuid']] = x
|
|
|
|
else:
|
2020-04-10 21:21:09 +00:00
|
|
|
if 'error' in queueItem:
|
|
|
|
if socket:
|
2020-04-14 14:48:13 +00:00
|
|
|
socket.emit("toast", {'msg': queueItem['error'], 'icon': 'error'})
|
2020-04-12 19:22:06 +00:00
|
|
|
return False
|
2020-04-10 21:21:09 +00:00
|
|
|
if queueItem['uuid'] in list(queueList.keys()):
|
|
|
|
print("Already in queue!")
|
|
|
|
if socket:
|
2020-04-14 14:48:13 +00:00
|
|
|
socket.emit("toast", {'msg': f"{queueItem['title']} is already in queue!", 'icon': 'playlist_add_check'})
|
2020-04-12 19:22:06 +00:00
|
|
|
return False
|
2020-04-10 14:12:21 +00:00
|
|
|
if socket:
|
|
|
|
socket.emit("addedToQueue", queueItem)
|
2020-04-14 14:48:13 +00:00
|
|
|
socket.emit("toast", {'msg': f"{queueItem['title']} added to queue", 'icon': 'playlist_add'})
|
2020-04-10 14:12:21 +00:00
|
|
|
queue.append(queueItem['uuid'])
|
|
|
|
queueList[queueItem['uuid']] = queueItem
|
|
|
|
nextItem(dz, socket)
|
2020-04-12 19:22:06 +00:00
|
|
|
return True
|
2020-04-10 14:12:21 +00:00
|
|
|
|
|
|
|
def nextItem(dz, socket=None):
|
2020-04-14 14:48:13 +00:00
|
|
|
global currentItem, queueList, queue
|
2020-04-10 14:12:21 +00:00
|
|
|
if currentItem != "":
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
if len(queue)>0:
|
|
|
|
currentItem = queue.pop(0)
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
if socket:
|
2020-04-10 21:04:05 +00:00
|
|
|
socket.emit("startDownload", currentItem)
|
2020-04-10 14:12:21 +00:00
|
|
|
result = download(dz, queueList[currentItem], socket)
|
|
|
|
callbackQueueDone(result)
|
|
|
|
|
|
|
|
def callbackQueueDone(result):
|
2020-04-14 14:48:13 +00:00
|
|
|
global currentItem, queueList, queueComplete
|
|
|
|
if 'cancel' in queueList[currentItem]:
|
|
|
|
del queueList[currentItem]
|
|
|
|
else:
|
|
|
|
queueComplete.append(currentItem)
|
2020-04-10 14:12:21 +00:00
|
|
|
currentItem = ""
|
|
|
|
nextItem(result['dz'], result['socket'])
|
2020-04-11 13:43:59 +00:00
|
|
|
|
2020-04-11 14:24:53 +00:00
|
|
|
def getQueue():
|
2020-04-14 14:48:13 +00:00
|
|
|
global currentItem, queueList, queue, queueComplete
|
|
|
|
return (queue, queueComplete, queueList, currentItem)
|
2020-04-11 14:24:53 +00:00
|
|
|
|
2020-04-11 13:43:59 +00:00
|
|
|
def removeFromQueue(uuid, socket=None):
|
2020-04-14 14:48:13 +00:00
|
|
|
global currentItem, queueList, queue, queueComplete
|
2020-04-11 13:43:59 +00:00
|
|
|
if uuid == currentItem:
|
2020-04-14 17:14:17 +00:00
|
|
|
if socket:
|
|
|
|
socket.emit('toast', {'msg': "Cancelling current item.", 'icon':'loading', 'dismiss': False, 'id':'cancelling_'+uuid})
|
2020-04-11 13:43:59 +00:00
|
|
|
queueList[uuid]['cancel'] = True
|
|
|
|
elif uuid in queue:
|
|
|
|
queue.remove(uuid)
|
|
|
|
del queueList[uuid]
|
|
|
|
if socket:
|
|
|
|
socket.emit("removedFromQueue", uuid)
|
2020-04-14 14:48:13 +00:00
|
|
|
elif uuid in queueComplete:
|
|
|
|
queueComplete.remove(uuid)
|
|
|
|
del queueList[uuid]
|
|
|
|
if socket:
|
|
|
|
socket.emit("removedFromQueue", uuid)
|
2020-04-11 14:24:53 +00:00
|
|
|
|
|
|
|
def cancelAllDownloads(socket=None):
|
2020-04-14 14:48:13 +00:00
|
|
|
global currentItem, queueList, queue, queueComplete
|
2020-04-11 14:24:53 +00:00
|
|
|
queue = []
|
2020-04-14 14:48:13 +00:00
|
|
|
queueComplete = []
|
2020-04-11 14:24:53 +00:00
|
|
|
if currentItem != "":
|
2020-04-14 17:14:17 +00:00
|
|
|
if socket:
|
|
|
|
socket.emit('toast', {'msg': "Cancelling current item.", 'icon':'loading', 'dismiss': False, 'id':'cancelling_'+currentItem})
|
2020-04-11 14:24:53 +00:00
|
|
|
queueList[currentItem]['cancel'] = True
|
|
|
|
for uuid in list(queueList.keys()):
|
|
|
|
if uuid != currentItem:
|
|
|
|
del queueList[uuid]
|
|
|
|
if socket:
|
2020-04-14 17:14:17 +00:00
|
|
|
socket.emit("removedAllDownloads", currentItem)
|
2020-04-14 14:48:13 +00:00
|
|
|
|
|
|
|
def removeFinishedDownloads(socket=None):
|
|
|
|
global queueList, queueComplete
|
|
|
|
for uuid in queueComplete:
|
|
|
|
del queueList[uuid]
|
|
|
|
queueComplete = []
|
|
|
|
if socket:
|
|
|
|
socket.emit("removedFinishedDownloads")
|