Added support for spotify playlists

This commit is contained in:
RemixDev 2020-04-15 11:13:55 +02:00
parent 73e67bd0f8
commit 52a4e3e0c5
4 changed files with 107 additions and 6 deletions

View File

@ -13,7 +13,6 @@ Run `python server.py` to start just the server<br>
Finish porting all features: Finish porting all features:
- logging - logging
- finish the gui - finish the gui
- spotify playlist support
- ? - ?
Settings not yet implemented: Settings not yet implemented:

View File

@ -377,6 +377,21 @@ def downloadTrackObj(dz, trackAPI, settings, bitrate, queueItem, extraTrack=None
if 'cancel' in queueItem: if 'cancel' in queueItem:
result['cancel'] = True result['cancel'] = True
return result return result
if trackAPI['SNG_ID'] == 0:
result['error'] = {
'message': "Track not available on Deezer!",
}
if 'SNG_TITLE' in trackAPI:
result['error']['data'] = {
'id': trackAPI['SNG_ID'],
'title': trackAPI['SNG_TITLE'],
'mainArtist': {'name': trackAPI['ART_NAME']}
}
if socket:
queueItem['failed'] += 1
socket.emit("updateQueue", {'uuid': queueItem['uuid'], 'failed': True, 'data': result['error']['data'], 'error': "Track not available on Deezer!"})
return result
# Get the metadata # Get the metadata
if extraTrack: if extraTrack:
track = extraTrack track = extraTrack
@ -662,6 +677,8 @@ def after_download(tracks, settings, queueItem):
if 'cancel' in result: if 'cancel' in result:
return None return None
if 'error' in result: if 'error' in result:
if not 'data' in result['error']:
result['error']['data'] = {'id': 0, 'title': 'Unknown', 'mainArtist': {'name': 'Unknown'}}
errors += f"{result['error']['data']['id']} | {result['error']['data']['mainArtist']['name']} - {result['error']['data']['title']} | {result['error']['message']}\r\n" errors += f"{result['error']['data']['id']} | {result['error']['data']['mainArtist']['name']} - {result['error']['data']['title']} | {result['error']['message']}\r\n"
if 'searched' in result: if 'searched' in result:
searched += result['searched']+"\r\n" searched += result['searched']+"\r\n"

View File

@ -1,5 +1,5 @@
from deemix.utils.misc import getIDFromLink, getTypeFromLink, getBitrateInt from deemix.utils.misc import getIDFromLink, getTypeFromLink, getBitrateInt
from deemix.utils.spotifyHelper import get_trackid_spotify, get_albumid_spotify from deemix.utils.spotifyHelper import get_trackid_spotify, get_albumid_spotify, convert_spotify_playlist
from concurrent.futures import ProcessPoolExecutor from concurrent.futures import ProcessPoolExecutor
from deemix.app.downloader import download from deemix.app.downloader import download
@ -146,6 +146,14 @@ def generateQueueItem(dz, url, settings, bitrate=None, albumAPI=None, socket=Non
else: else:
print("Album not found on deezer!") print("Album not found on deezer!")
result['error'] = "Album not found on deezer!" result['error'] = "Album not found on deezer!"
elif type == "spotifyplaylist":
if socket:
socket.emit("toast", {'msg': f"Converting spotify tracks to deezer tracks", 'icon': 'loading', 'dismiss': False, 'id': 'spotifyplaylist_'+str(id)})
result = convert_spotify_playlist(dz, id, settings)
result['bitrate'] = bitrate
result['uuid'] = f"{result['type']}_{id}_{bitrate}"
if socket:
socket.emit("toast", {'msg': f"Spotify playlist converted", 'icon': 'done', 'dismiss': True, 'id': 'spotifyplaylist_'+str(id)})
else: else:
print("URL not supported yet") print("URL not supported yet")
result['error'] = "URL not supported yet" result['error'] = "URL not supported yet"

View File

@ -37,11 +37,44 @@ if spotifyEnabled:
client_credentials_manager = SpotifyClientCredentials(client_id=credentials['clientId'], client_secret=credentials['clientSecret']) client_credentials_manager = SpotifyClientCredentials(client_id=credentials['clientId'], client_secret=credentials['clientSecret'])
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
def get_trackid_spotify(dz, track_id, fallbackSearch): def _convert_playlist_structure(spotify_obj):
if len(spotify_obj['images']):
url = spotify_obj['images'][0]['url']
else:
url = "https://e-cdns-images.dzcdn.net/images/cover/d41d8cd98f00b204e9800998ecf8427e/75x75-000000-80-0-0.jpg"
deezer_obj = {
'checksum': spotify_obj['snapshot_id'],
'collaborative': spotify_obj['collaborative'],
'creation_date': "???-??-??",
'creator': {'id': spotify_obj['owner']['id'], 'name': spotify_obj['owner']['display_name'], 'tracklist': spotify_obj['owner']['href'], 'type': "user"},
'description': spotify_obj['description'],
'duration': 0,
'fans': spotify_obj['followers']['total'],
'id': spotify_obj['id'],
'is_loved_track': False,
'link': spotify_obj['external_urls']['spotify'],
'nb_tracks': spotify_obj['tracks']['total'],
'picture': url,
'picture_big': url,
'picture_medium': url,
'picture_small': url,
'picture_xl': url,
'public': spotify_obj['public'],
'share': spotify_obj['external_urls']['spotify'],
'title': spotify_obj['name'],
'tracklist': spotify_obj['tracks']['href'],
'type': "playlist"
}
return deezer_obj
def get_trackid_spotify(dz, track_id, fallbackSearch, spotifyTrack=None):
global spotifyEnabled global spotifyEnabled
if not spotifyEnabled: if not spotifyEnabled:
return "Not Enabled" return "Not Enabled"
spotify_track = sp.track(track_id) if not spotifyTrack:
spotify_track = sp.track(track_id)
else:
spotify_track = spotifyTrack
dz_track = 0 dz_track = 0
if 'external_ids' in spotify_track and 'isrc' in spotify_track['external_ids']: if 'external_ids' in spotify_track and 'isrc' in spotify_track['external_ids']:
try: try:
@ -71,9 +104,53 @@ def get_albumid_spotify(dz, album_id):
dz_album = 0 dz_album = 0
return dz_album return dz_album
def convert_spotify_playlist(dz, playlist_id): def convert_spotify_playlist(dz, playlist_id, settings):
global spotifyEnabled global spotifyEnabled
if not spotifyEnabled: if not spotifyEnabled:
return "Not Enabled" return "Not Enabled"
spotify_playlist = sp.playlist(playlist_id) spotify_playlist = sp.playlist(playlist_id)
print(spotify_playlist) result = {
'title': spotify_playlist['name'],
'artist': spotify_playlist['owner']['display_name'],
'size': spotify_playlist['tracks']['total'],
'downloaded': 0,
'failed': 0,
'progress': 0,
'type': 'spotify_playlist',
'settings': settings or {},
'id': playlist_id
}
if len(spotify_playlist['images']):
result['cover'] = spotify_playlist['images'][0]['url']
else:
result['cover'] = "https://e-cdns-images.dzcdn.net/images/cover/d41d8cd98f00b204e9800998ecf8427e/75x75-000000-80-0-0.jpg"
playlistAPI = _convert_playlist_structure(spotify_playlist)
tracklist = spotify_playlist['tracks']['items']
result['collection'] = []
while spotify_playlist['tracks']['next']:
spotify_playlist['tracks'] = sp.next(spotify_playlist['tracks'])
tracklist += spotify_playlist['tracks']['items']
totalSize = len(tracklist)
for pos, track in enumerate(tracklist, start=1):
trackID = get_trackid_spotify(dz, 0, settings['fallbackSearch'], track['track'])
if trackID == 0:
deezerTrack = {
'SNG_ID': 0,
'SNG_TITLE': track['track']['name'],
'DURATION': 0,
'MD5_ORIGIN': 0,
'MEDIA_VERSION': 0,
'FILESIZE': 0,
'ALB_TITLE': track['track']['album']['name'],
'ALB_PICTURE': "",
'ART_ID': 0,
'ART_NAME': track['track']['artists'][0]['name']
}
else:
deezerTrack = dz.get_track_gw(trackID)
deezerTrack['_EXTRA_PLAYLIST'] = playlistAPI
deezerTrack['POSITION'] = pos
deezerTrack['SIZE'] = totalSize
deezerTrack['FILENAME_TEMPLATE'] = settings['playlistTracknameTemplate']
result['collection'].append(deezerTrack)
return result