def vibeviewer(): if request.method == "POST": spotifyObject = Spotify(auth=session["token"]) spotifyUser = spotifyObject.current_user() spotifyID = spotifyUser['id'] found_user = users.query.filter_by(username=spotifyID).first() if found_user: for mood in found_user.mood: if request.form["VibeName"] == mood.vibeName: for cluster in mood.clusters: db.session.delete(cluster) db.session.commit() for song in mood.songs: db.session.delete(song) db.session.commit() for genre in mood.genreRepresentation: db.session.delete(genre) db.session.commit() db.session.delete(mood) db.session.commit() break return redirect(url_for("user", usr="******")) else: spotifyObject = Spotify(auth=session["token"]) spotifyUser = spotifyObject.current_user() spotifyID = spotifyUser['id'] found_user = users.query.filter_by(username=spotifyID).first() return render_template("VibeViewer.html", values=found_user.mood)
def login(request): global sp, current_user access_token = "" token_info = sp_oauth.get_cached_token() if token_info: # print("Found cached token!") access_token = token_info['access_token'] else: url = request.url code = sp_oauth.parse_response_code(url) if code: # print("Found Spotify auth code in Request URL! Trying to get valid access token...") token_info = sp_oauth.get_access_token(code) access_token = token_info['access_token'] if access_token: # print("Access token available! Trying to get user information...") sp = Spotify(access_token, requests_timeout=1) results = sp.current_user() current_user = results['display_name'] flash("Ingelogd op Spotify als {}".format(results['display_name']), "success") return redirect(url_for('bigscreen')) else: return redirect(sp_oauth.get_authorize_url())
class SpotifyAuthenticator: def __init__(self): self.scopes = 'user-read-private user-read-email playlist-read-private playlist-read-collaborative ' \ 'user-top-read user-library-read' self.sp_oauth = None self.sp = None self._init_oauth( "0.0.0.0" ) # init with stand in redirect_uri so update_token_info can be called def _init_oauth(self, redirect_uri): self.sp_oauth = SpotifyOAuth( scope=self.scopes, client_id=os.getenv("SPOTIFY_CLIENT_ID"), client_secret=os.getenv("SPOTIFY_CLIENT_SECRET"), redirect_uri=redirect_uri) return self.sp_oauth.get_authorize_url() def initialize_auth(self, request): redirect_uri = request.build_absolute_uri('/') + 'login' return HttpResponseRedirect(self._init_oauth(redirect_uri)) def get_initial_token_info(self, initial_token): return self.sp_oauth.get_access_token(initial_token) def update_token_info(self, token_info): if self.sp_oauth.is_token_expired(token_info): return self.sp_oauth.refresh_access_token( token_info["refresh_token"]) return token_info def connect_user(self, token_info): self.sp = Spotify(token_info['access_token']) return self.sp.current_user()
def _cache_token_info(chat_id, token_info): client = Spotify(auth=token_info['access_token']) user_id = client.current_user()['id'] CACHE.set(chat_id, user_id, token_info) return user_id
def home(): webBackend = PlaylistCreation() #find or create new user spotifyObject = Spotify(auth=session["token"]) spotifyUser = spotifyObject.current_user() spotifyID = spotifyUser['id'] found_user = users.query.filter_by(username=spotifyID).first() if not found_user: newUser = users(username=spotifyID) db.session.add(newUser) db.session.commit() found_user = users.query.filter_by(username=spotifyID).first() loadPlaylists(spotifyID) recommendations = [["Create a Vibe Now to get Song Recomendations"]] if len(found_user.mood) > 0: recommendations = [] for x in range(0, 4): vibe = random.choice(found_user.mood) songsList = [] for y in range(0, 4): songsList.append(str(random.choice(vibe.songs))) recommendations.append([ webBackend.homepageRecs(session["token"], songsList), vibe.vibeName ]) return render_template("homepage.html", songs=recommendations)
def recomendations(self, token, tracksFullList, shuffleTime): # get user spotifyObject = Spotify(auth=token) spotifyUser = spotifyObject.current_user() username = spotifyUser['id'] tracks = [] tracksDict = {} songsAdded = 0 numSongsToAdd = int(int(shuffleTime) / 2) while songsAdded < numSongsToAdd: for i in range(0, 4): tracks.append(random.choice(tracksFullList)) recs = spotifyObject.recommendations(seed_tracks=tracks) tracks = [] for i in range (0, 4): track = random.choice(recs['tracks']) if track['id'] not in tracksDict.keys(): spotifyObject.add_to_queue(track['id']) tracksDict[track['id']] = "added" songsAdded = songsAdded + 1
def index(): access_token = "" token_info = sp_oauth.get_cached_token() if token_info: print("Found cached token!") access_token = token_info['access_token'] else: url = request.url code = sp_oauth.parse_response_code(url) if code: print( "Found Spotify auth code in Request URL! Trying to get valid access token..." ) token_info = sp_oauth.get_access_token(code) access_token = token_info['access_token'] if access_token: print("Access token available! Trying to get user information...") sp = Spotify(access_token) results = sp.current_user() return results else: return htmlForLoginButton()
def publicVibeViewer(): if request.method == "POST": spotifyObject = Spotify(auth=session["token"]) spotifyUser = spotifyObject.current_user() spotifyID = spotifyUser['id'] found_user = users.query.filter_by(username=spotifyID).first() if found_user: for mood in Mood.query.filter_by(public=True).all(): if request.form["VibeName"] == mood.vibeName: author = users.query.filter_by(id=mood.user_id).first() name = mood.vibeName + " by: " + str(author.username) mood.adds = mood.adds + 1 mood1 = Mood(name, adds=int(0), error=mood.error, public=False, user_id=found_user.id) db.session.add(mood1) db.session.commit() for cluster in mood.clusters: clusterString = str(cluster) addCluster = Clusters(cluster=clusterString, moodId=mood1.id) db.session.add(addCluster) db.session.commit() for song in mood.songs: songAdd = str(song) addSong = Songs(song=songAdd, moodId=mood1.id) db.session.add(addSong) db.session.commit() for genre in mood.genreRepresentation: genreAdd = str(genre) addGenre = Genres(genre=genreAdd, moodId=mood1.id) db.session.add(addGenre) db.session.commit() break return redirect(url_for("user", usr="******")) else: spotifyObject = Spotify(auth=session["token"]) spotifyUser = spotifyObject.current_user() spotifyID = spotifyUser['id'] #found_user = users.query.filter_by(username=spotifyID).first() return render_template("publicVibes.html", values=Mood.query.filter_by(public=True).all())
def get_user_id(spot: Spotify) -> str: """ Return user id of this Spotify connection :param spot: spotipy Spotify object to use its REST API :type spot: Spotify :return: str :rtype: str """ return spot.current_user()['id']
def test_adding_less_than_max_request(self): spotify = Spotify() spotify.current_user = unittest.mock.MagicMock({"id": "testUser"}) spotify.current_user_saved_albums_add = unittest.mock.MagicMock() dummy_albums = [ self._build_dummy_album("123"), self._build_dummy_album("456"), self._build_dummy_album("789"), ] add_albums_to_library(spotify, dummy_albums) spotify.current_user_saved_albums_add.assert_called_with(["123", "456", "789"])
def playlistCreation(): if request.method == "POST": playlistCreation = PlaylistCreation() vibe = request.form["VibeName"] moodFound = Mood.query.filter_by(id=vibe).first() clusters = moodFound.clusters clustersAsList = [] clustersAndError = [] for cluster in clusters: cluster = str(cluster) clusterList = playlistCreation.finalListDecoder(cluster) clustersAsList.append(clusterList) clustersAndError.append(clustersAsList) clustersAndError.append(float(moodFound.error)) spotifyObject = Spotify(auth=session["token"]) spotifyUser = spotifyObject.current_user() spotifyID = spotifyUser['id'] genreDictLoaded = moodFound.genreRepresentation playlistCreation.newBuildPlaylist( playlistName=request.form["oldPlaylist"], clustersAndError=clustersAndError, token=session["token"], newPlaylist=request.form["newPlaylist"], genreDict=genreDictLoaded) return redirect(url_for("user", usr="******")) else: spotifyObject = Spotify(auth=session["token"]) spotifyUser = spotifyObject.current_user() spotifyID = spotifyUser['id'] playlists = loadPlaylists(spotifyID) found_user = users.query.filter_by(username=spotifyID).first() return render_template( "playlistCreation.html", playlists=playlists, vibes=found_user.mood) #playlistCreation html page
def add_track_to_playlist(spot_client: spotipy.Spotify, track_id: str, playlist_id: str) -> None: try: spot_client.user_playlist_add_tracks( user=spot_client.current_user()['id'], playlist_id=playlist_id, tracks=[track_id]) except spotipy.client.SpotifyException as spot_except: print( f"Error adding track {track_id} to playlist {playlist_id}.\nMore info:\n{str(spot_except)}" )
def create_playlist(sp: spotipy.Spotify, tracks: list, playlist_name: str): """creates a playlist or tracks from tracks_uri on the users account of length amount""" print('...creating playlist') user_id = sp.current_user()["id"] playlist_id = sp.user_playlist_create(user_id, playlist_name)["id"] random.shuffle(tracks) tracks_uri = [] for track in tracks: tracks_uri.append(track) sp.user_playlist_add_tracks(user_id, playlist_id, tracks_uri) print('playlist, {}, has been generated.'.format(playlist_name)) return sp.playlist(playlist_id)["external_urls"]["spotify"]
def get_current_user(): """Retrieves information for the current user""" user_id = request.args.get('spotify_id') if user_id: db = Database(Config.DATABASE_PATH) token = db.get_user_token(user_id) spotify = Spotify(auth=token) user = spotify.current_user() return create_response(user) return jsonify({'Error': 'Invalid or missing spotify id'})
class SpotifyUser: """A Spotify User object that can create new playlists and add given tracks to it.""" def __init__(self, user_scopes): self.client = Spotify( auth_manager=SpotifyOAuth(client_id=sp_client_id, client_secret=sp_client_secret, redirect_uri=sp_redirect_uri, scope=user_scopes)) self.user_id = self.client.current_user()["id"] def create_playlist(self): """Creates a Spotify playlist and returns its id.""" playlist = self.client.user_playlist_create(self.user_id, "YouTube Music", public=False) print("\nPlaylist Created: YouTube Music") return playlist["id"] def get_track_ids(self, tracks_info): """Retrieves the spotify ID of all available tracks from the list of tracks provided.""" track_ids = [] for track in tracks_info: search_result = self.client.search(q="track:" + track["track"] + " artist:" + track["artist"], limit=1) # if the response in items exists, and it was not of length 0, add the id of that track to the list if len(search_result["tracks"]["items"]) > 0: track_ids.append(search_result["tracks"]["items"][0]["id"]) return track_ids def add_tracks(self, tracks_info, playlist_id): """Adds tracks from the provided list of tracks into a playlist of the current user, filtered by the playlist ID.""" ids = self.get_track_ids(tracks_info) self.client.user_playlist_add_tracks(self.user_id, playlist_id, ids) print( f"\nFrom your YouTube playlist, {len(ids)} out of {len(tracks_info)} " "tracks were successfully added to your Spotify 'YouTube Music' playlist." "\nDone.")
def loadPlaylists(self, token): #Authenticate with Spotify spotifyObject = Spotify(auth=token) spotifyUser = spotifyObject.current_user() username = spotifyUser['id'] count = int(0) playlistDict = {} response = spotifyObject.user_playlists(user=username, offset=count) #Stores all playlists into a Dictionary while count < response["total"]: response = spotifyObject.user_playlists(user=username, offset=count) count = count + 50 for x in range(0, len(response['items'])): playlistDict[response['items'][x]['name']] = response['items'][x]['id'] return playlistDict
def create_playlist(songs: List[Song], sp: spotipy.Spotify, full_url: bool) -> str: # Find the watsong playlist and use it if possible playlist = sp.user_playlist_create( sp.current_user()["id"], "Watsong Playlist", public=False, collaborative=True, description="A playlist created by watsong just for you", ) sp.playlist_add_items(playlist["id"], [song["uri"] for song in songs[:100]]) # Unsubscribe from the playlist immediately. The user can subscribe later by hitting the # Subscribe button. sp.current_user_unfollow_playlist(playlist["id"]) return (f'https://open.spotify.com/embed/playlist/{playlist["id"]}' if full_url else str(playlist["id"]))
def obtain_access_token(): """Post authorization code to 'https://accounts.spotify.com/api/token' and obtain access token """ # get dict from spotifyAPIService.obtainAccessToken(code) function access_data = request.get_json(force=True) auth_data = { 'grant_type': 'authorization_code', 'code': access_data['code'], 'redirect_uri': 'http://127.0.0.1:4200/host', 'client_secret': access_data['client_secret'], 'client_id': access_data['client_id'] } # do another post to get the token resp = requests.post(Config.SPOTIFY_TOKEN_URL, data=auth_data) # If successful if resp.status_code == 200: token = resp.json()['access_token'] spotify = Spotify(auth=token) user = spotify.current_user() db = Database(Config.DATABASE_PATH) existing_user = db.get_user(user['id']) # Check if user exists in local db if not existing_user: # if not, then add them to db w/ access token db.add_user(user['display_name'], user['id'], token) print('user added to db') else: # If they exist, update db with fresh token db.update_user_token(user['id'], token) print('updated user token') print(user['display_name'], 'is now logged into spotify') # return user info to front end return create_response({'token': token, 'id': user['id'], 'display_name': user['display_name']}) else: abort(resp.status_code)
def newCreateVibe(self, playlistName, token): # find playlist spotifyObject = Spotify(auth=token) spotifyUser = spotifyObject.current_user() username = spotifyUser['id'] # find playlist playlistID = playlistName #create genre dictionary genreDict = {} # get songs from playlist playlistSongs = spotifyObject.user_playlist_tracks(user=username, playlist_id=playlistID) numberOfSongs = int(playlistSongs['total']) totalAdded = int(0) songObjectsList = [] songID_List = [] while (numberOfSongs > totalAdded): playlistSongs = spotifyObject.user_playlist_tracks(user=username, playlist_id=playlistID, offset=totalAdded) for i in range(0, len(playlistSongs['items'])): try: songURI = playlistSongs['items'][i]['track']['uri'] songID = playlistSongs['items'][i]['track']['id'] songID_List.append(songID) songFeatures = spotifyObject.audio_features(songURI) genreDict = self.genreVibe(spotifyObject=spotifyObject, songId=songID, genreDict=genreDict) songObj = [songFeatures[0]['acousticness'], songFeatures[0]['danceability'], songFeatures[0]['energy'], songFeatures[0]['instrumentalness'], songFeatures[0]['liveness'], songFeatures[0]['speechiness'], round(songFeatures[0]['tempo'] / 180, 6), songFeatures[0]['valence']] songObjectsList.append(songObj) except: print("song was removed from spotify sorry") totalAdded = totalAdded + 100 centroidsAndError = self.KMeansVibe(data=songObjectsList) centroidsAndError_GenreDict = [centroidsAndError, genreDict, songID_List] return centroidsAndError_GenreDict
def login(): # If no current login, send user through Spotify OAuth process. # If current login, send user to his/her profile. if 'current_user' not in session: url = request.url oauth = get_spotify_oauth() code = oauth.parse_response_code(url) if code: token_info = oauth.get_access_token(code) access_token = token_info['access_token'] refresh_token = token_info['refresh_token'] expires_at = int(token_info['expires_at']) spotify = Spotify(access_token) spotify_user = spotify.current_user() user_id = spotify_user.get('id') user = get_user(user_id) # If user logging in w/ Spotify does not yet exist, create it if not user: user = create_user_from_spotify_user(spotify_user) track_new_user(user.id) else: track_user_login(user_id) # If user's image is from Facebook, token may have expired. # TODO: This needs to be smarter if 'fbcdn.net' in user.image_url: user = update_user_from_spotify_user(user, spotify_user) _update_session(user_id, access_token, refresh_token, expires_at) session.permanent = True # If user was going to a particular destination before logging in, # send them there after login. if 'next_url' in session: app.logger.info('Found next_url in session: %s', session['next_url']) next_url = session['next_url'].decode('base64', 'strict') app.logger.info('Decoded next_url in session, redirecting: %s', next_url) session.pop('next_url') return redirect(next_url) return redirect(url_for('profile'))
def test_adding_more_than_max_request(self): spotify = Spotify() spotify.current_user = unittest.mock.MagicMock({"id": "testUser"}) spotify.current_user_saved_albums_add = unittest.mock.MagicMock() dummy_albums = [] for _ in range(150): dummy_albums.append(self._build_dummy_album("123")) expected_chunks = [] for _ in range(3): chunk = [] for _ in range(50): chunk.append("123") expected_chunks.append(chunk) add_albums_to_library(spotify, dummy_albums) for i in range(3): spotify.current_user_saved_albums_add.assert_called_with(expected_chunks[i])
def callback(request): # redirects here after Spotify login token = 'http://localhost:8000/callback/?{}'.format( request.GET.urlencode()) sp_oauth = oauth2.SpotifyOAuth(os.getenv('SPOTIPY_CLIENT_ID'), os.getenv('SPOTIPY_CLIENT_SECRET'), os.getenv('SPOTIPY_REDIRECT_URI'), scope=os.getenv('SPOTIPY_SCOPE')) code = sp_oauth.parse_response_code(token) token_info = sp_oauth.get_access_token(code) if token_info: # store the Spotify token in the session request.session['spotipy_token'] = token_info sp = Spotify(auth=request.session['spotipy_token']['access_token']) request.session['user_id'] = sp.current_user()['id'] return redirect("http://localhost:8080/#/playlists")
def add_bot(): _clear_session() oauth = get_spotify_oauth(bot=True) code = oauth.parse_response_code(request.url) if code: token_info = oauth.get_access_token(code) access_token = token_info['access_token'] refresh_token = token_info['refresh_token'] expires_at = int(token_info['expires_at']) spotify = Spotify(access_token) spotify_user = spotify.current_user() bot_id = spotify_user['id'] app.logger.warn('Create/update bot %s: %s, %s, %s', bot_id, access_token, refresh_token, expires_at) create_or_update_bot(bot_id, access_token, refresh_token, expires_at) return 'Successfully added bot: %s' % (bot_id) return redirect(oauth.get_authorize_url())
def randomShuffle(self, token, playlistId, shuffleTime): # get user spotifyObject = Spotify(auth=token) spotifyUser = spotifyObject.current_user() username = spotifyUser['id'] tracks = [] songsAdded = 0 numSongsToAdd = int(int(shuffleTime) / 2) playlist = spotifyObject.user_playlist_tracks(user=username, playlist_id=playlistId) numberOfSongs = int(playlist['total']) if numberOfSongs < numSongsToAdd: numSongsToAdd = numberOfSongs while songsAdded < numSongsToAdd: for i in range (0, 5): offsetNum = random.randint(0, numberOfSongs-1) playlist = spotifyObject.user_playlist_tracks(user=username, playlist_id=playlistId, offset=offsetNum) song = random.choice(playlist['items']) if song['track']['id'] not in tracks: spotifyObject.add_to_queue(song['track']['id']) tracks.append(song['track']['id']) songsAdded = songsAdded + 1
#Find the index's of those times start_i = times.index(start) end_i = times.index(end) #Get the list of songs in the right order songs = songs[start_i:end_i:-1] #Close the webscraper driver.quit() #Setup spotify connection spotify = Spotify(app_token) spotify.token = user_token #Create playlist name = "Radio1 - " + usr_date_from.strftime( "%H:%M") + " - " + usr_date_till.strftime("%H:%M") usr_id = spotify.current_user().id playlist = spotify.playlist_create(usr_id, name) #For each song name make a request to find the correct id ids = [] for song in songs: song = song.split(" - ")[1] results = spotify.search(song, types=('track', ), limit=1) ids.append(results[0].items[0].id) #Add all the tracks to the playlist you created spotify.playlist_tracks_add(playlist.id, ids)
class AuthTestSpotipy(unittest.TestCase): """ These tests require user authentication - provide client credentials using the following environment variables :: 'SPOTIPY_CLIENT_USERNAME' 'SPOTIPY_CLIENT_ID' 'SPOTIPY_CLIENT_SECRET' 'SPOTIPY_REDIRECT_URI' """ playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx" playlist_new_id = "spotify:playlist:7GlxpQjjxRjmbb3RP2rDqI" four_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp", "spotify:track:7IHOIqZUUInxjVkko181PB", "4VrWlk8IQxevMvERoX08iC", "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"] two_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp", "spotify:track:7IHOIqZUUInxjVkko181PB"] other_tracks = ["spotify:track:2wySlB6vMzCbQrRnNGOYKa", "spotify:track:29xKs5BAHlmlX1u4gzQAbJ", "spotify:track:1PB7gRWcvefzu7t3LJLUlf"] album_ids = ["spotify:album:6kL09DaURb7rAoqqaA51KU", "spotify:album:6RTzC0rDbvagTSJLlY7AKl"] bad_id = 'BAD_ID' @classmethod def setUpClass(self): if sys.version_info >= (3, 2): # >= Python3.2 only warnings.filterwarnings( "ignore", category=ResourceWarning, # noqa message="unclosed.*<ssl.SSLSocket.*>") missing = list(filter(lambda var: not os.getenv(CCEV[var]), CCEV)) if missing: raise Exception( ('Please set the client credentials for the test application' ' using the following environment variables: {}').format( CCEV.values())) self.username = os.getenv(CCEV['client_username']) self.scope = ( 'playlist-modify-public ' 'user-library-read ' 'user-follow-read ' 'user-library-modify ' 'user-read-private ' 'user-top-read ' 'user-follow-modify ' 'user-read-recently-played ' 'ugc-image-upload' ) self.token = prompt_for_user_token(self.username, scope=self.scope) self.spotify = Spotify(auth=self.token) # Helper def get_or_create_spotify_playlist(self, playlist_name): playlists = self.spotify.user_playlists(self.username) while playlists: for item in playlists['items']: if item['name'] == playlist_name: return item playlists = self.spotify.next(playlists) return self.spotify.user_playlist_create( self.username, playlist_name) # Helper def get_as_base64(self, url): import base64 return base64.b64encode(requests.get(url).content).decode("utf-8") def test_track_bad_id(self): try: self.spotify.track(self.bad_id) self.assertTrue(False) except SpotifyException: self.assertTrue(True) def test_basic_user_profile(self): user = self.spotify.user(self.username) self.assertTrue(user['id'] == self.username.lower()) def test_current_user(self): user = self.spotify.current_user() self.assertTrue(user['id'] == self.username.lower()) def test_me(self): user = self.spotify.me() self.assertTrue(user['id'] == self.username.lower()) def test_user_playlists(self): playlists = self.spotify.user_playlists(self.username, limit=5) self.assertTrue('items' in playlists) self.assertTrue(len(playlists['items']) == 5) def test_user_playlist_tracks(self): playlists = self.spotify.user_playlists(self.username, limit=5) self.assertTrue('items' in playlists) for playlist in playlists['items']: user = playlist['owner']['id'] pid = playlist['id'] results = self.spotify.user_playlist_tracks(user, pid) self.assertTrue(len(results['items']) >= 0) def test_current_user_saved_albums(self): # List albums = self.spotify.current_user_saved_albums() self.assertTrue(len(albums['items']) > 1) # Add self.spotify.current_user_saved_albums_add(self.album_ids) # Contains self.assertTrue( self.spotify.current_user_saved_albums_contains( self.album_ids) == [ True, True]) # Remove self.spotify.current_user_saved_albums_delete(self.album_ids) albums = self.spotify.current_user_saved_albums() self.assertTrue(len(albums['items']) > 1) def test_current_user_playlists(self): playlists = self.spotify.current_user_playlists(limit=10) self.assertTrue('items' in playlists) self.assertTrue(len(playlists['items']) == 10) def test_user_playlist_follow(self): self.spotify.user_playlist_follow_playlist( 'plamere', '4erXB04MxwRAVqcUEpu30O') follows = self.spotify.user_playlist_is_following( 'plamere', '4erXB04MxwRAVqcUEpu30O', [ self.spotify.current_user()['id']]) self.assertTrue(len(follows) == 1, 'proper follows length') self.assertTrue(follows[0], 'is following') self.spotify.user_playlist_unfollow( 'plamere', '4erXB04MxwRAVqcUEpu30O') follows = self.spotify.user_playlist_is_following( 'plamere', '4erXB04MxwRAVqcUEpu30O', [ self.spotify.current_user()['id']]) self.assertTrue(len(follows) == 1, 'proper follows length') self.assertFalse(follows[0], 'is no longer following') def test_current_user_saved_tracks(self): tracks = self.spotify.current_user_saved_tracks() self.assertTrue(len(tracks['items']) > 0) def test_current_user_save_and_unsave_tracks(self): tracks = self.spotify.current_user_saved_tracks() total = tracks['total'] self.spotify.current_user_saved_tracks_add(self.four_tracks) tracks = self.spotify.current_user_saved_tracks() new_total = tracks['total'] self.assertTrue(new_total - total == len(self.four_tracks)) tracks = self.spotify.current_user_saved_tracks_delete( self.four_tracks) tracks = self.spotify.current_user_saved_tracks() new_total = tracks['total'] self.assertTrue(new_total == total) def test_categories(self): response = self.spotify.categories() self.assertTrue(len(response['categories']) > 0) def test_category_playlists(self): response = self.spotify.categories() for cat in response['categories']['items']: cat_id = cat['id'] response = self.spotify.category_playlists(category_id=cat_id) if len(response['playlists']["items"]) > 0: break self.assertTrue(True) def test_new_releases(self): response = self.spotify.new_releases() self.assertTrue(len(response['albums']) > 0) def test_featured_releases(self): response = self.spotify.featured_playlists() self.assertTrue(len(response['playlists']) > 0) def test_current_user_follows(self): response = self.spotify.current_user_followed_artists() artists = response['artists'] self.assertTrue(len(artists['items']) > 0) def test_current_user_top_tracks(self): response = self.spotify.current_user_top_tracks() items = response['items'] self.assertTrue(len(items) > 0) def test_current_user_top_artists(self): response = self.spotify.current_user_top_artists() items = response['items'] self.assertTrue(len(items) > 0) def test_current_user_recently_played(self): # No cursor res = self.spotify.current_user_recently_played() self.assertTrue(len(res['items']) <= 50) played_at = res['items'][0]['played_at'] # Using `before` gives tracks played before res = self.spotify.current_user_recently_played( before=res['cursors']['after']) self.assertTrue(len(res['items']) <= 50) self.assertTrue(res['items'][0]['played_at'] < played_at) played_at = res['items'][0]['played_at'] # Using `after` gives tracks played after res = self.spotify.current_user_recently_played( after=res['cursors']['before']) self.assertTrue(len(res['items']) <= 50) self.assertTrue(res['items'][0]['played_at'] > played_at) def test_user_playlist_ops(self): sp = self.spotify # create empty playlist playlist = self.get_or_create_spotify_playlist( 'spotipy-testing-playlist-1') playlist_id = playlist['id'] # remove all tracks from it sp.user_playlist_replace_tracks( self.username, playlist_id, []) playlist = sp.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 0) self.assertTrue(len(playlist['tracks']['items']) == 0) # add tracks to it sp.user_playlist_add_tracks( self.username, playlist_id, self.four_tracks) playlist = sp.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 4) self.assertTrue(len(playlist['tracks']['items']) == 4) # remove two tracks from it sp.user_playlist_remove_all_occurrences_of_tracks(self.username, playlist_id, self.two_tracks) playlist = sp.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 2) self.assertTrue(len(playlist['tracks']['items']) == 2) # replace with 3 other tracks sp.user_playlist_replace_tracks(self.username, playlist_id, self.other_tracks) playlist = sp.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 3) self.assertTrue(len(playlist['tracks']['items']) == 3) def test_playlist(self): # New playlist ID pl = self.spotify.playlist(self.playlist_new_id) self.assertTrue(pl["tracks"]["total"] > 0) # Old playlist ID pl = self.spotify.playlist(self.playlist) self.assertTrue(pl["tracks"]["total"] > 0) def test_playlist_tracks(self): # New playlist ID pl = self.spotify.playlist_tracks(self.playlist_new_id, limit=2) self.assertTrue(len(pl["items"]) == 2) self.assertTrue(pl["total"] > 0) # Old playlist ID pl = self.spotify.playlist_tracks(self.playlist, limit=2) self.assertTrue(len(pl["items"]) == 2) self.assertTrue(pl["total"] > 0) def test_playlist_upload_cover_image(self): pl1 = self.get_or_create_spotify_playlist('spotipy-testing-playlist-1') plid = pl1['uri'] old_b64 = pl1['images'][0]['url'] # Upload random dog image r = requests.get('https://dog.ceo/api/breeds/image/random') dog_base64 = self.get_as_base64(r.json()['message']) self.spotify.playlist_upload_cover_image(plid, dog_base64) # Image must be different pl1 = self.spotify.playlist(plid) new_b64 = self.get_as_base64(pl1['images'][0]['url']) self.assertTrue(old_b64 != new_b64) def test_playlist_cover_image(self): pl = self.get_or_create_spotify_playlist('spotipy-testing-playlist-1') plid = pl['uri'] res = self.spotify.playlist_cover_image(plid) self.assertTrue(len(res) > 0) first_image = res[0] self.assertTrue('width' in first_image) self.assertTrue('height' in first_image) self.assertTrue('url' in first_image) def test_user_follows_and_unfollows_artist(self): # Initially follows 1 artist res = self.spotify.current_user_followed_artists() self.assertTrue(res['artists']['total'] == 1) # Follow 2 more artists artists = ["6DPYiyq5kWVQS4RGwxzPC7", "0NbfKEOTQCcwd6o7wSDOHI"] self.spotify.user_follow_artists(artists) res = self.spotify.current_user_followed_artists() self.assertTrue(res['artists']['total'] == 3) # Unfollow these 2 artists self.spotify.user_unfollow_artists(artists) res = self.spotify.current_user_followed_artists() self.assertTrue(res['artists']['total'] == 1) def test_user_follows_and_unfollows_user(self): # TODO improve after implementing `me/following/contains` users = ["11111204", "xlqeojt6n7on0j7coh9go8ifd"] # Follow 2 more users self.spotify.user_follow_users(users) # Unfollow these 2 users self.spotify.user_unfollow_users(users) def test_deprecated_starred(self): pl = self.spotify.user_playlist(self.username) self.assertTrue(pl["tracks"] is None) self.assertTrue(pl["owner"] is None) def test_deprecated_user_playlist(self): # Test without user due to change from # https://developer.spotify.com/community/news/2018/06/12/changes-to-playlist-uris/ pl = self.spotify.user_playlist(None, self.playlist) self.assertTrue(pl["tracks"]["total"] > 0) def test_deprecated_user_playlis(self): # Test without user due to change from # https://developer.spotify.com/community/news/2018/06/12/changes-to-playlist-uris/ pl = self.spotify.user_playlist_tracks(None, self.playlist, limit=2) self.assertTrue(len(pl["items"]) == 2) self.assertTrue(pl["total"] > 0)
class AuthTestSpotipy(unittest.TestCase): """ These tests require user authentication - provide client credentials using the following environment variables :: 'SPOTIPY_CLIENT_USERNAME' 'SPOTIPY_CLIENT_ID' 'SPOTIPY_CLIENT_SECRET' 'SPOTIPY_REDIRECT_URI' """ playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx" four_tracks = [ "spotify:track:6RtPijgfPKROxEzTHNRiDp", "spotify:track:7IHOIqZUUInxjVkko181PB", "4VrWlk8IQxevMvERoX08iC", "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf" ] two_tracks = [ "spotify:track:6RtPijgfPKROxEzTHNRiDp", "spotify:track:7IHOIqZUUInxjVkko181PB" ] other_tracks = [ "spotify:track:2wySlB6vMzCbQrRnNGOYKa", "spotify:track:29xKs5BAHlmlX1u4gzQAbJ", "spotify:track:1PB7gRWcvefzu7t3LJLUlf" ] bad_id = 'BAD_ID' @classmethod def setUpClass(self): missing = list(filter(lambda var: not os.getenv(CCEV[var]), CCEV)) if missing: raise Exception( 'Please set the client credentials for the test application using the following environment variables: {}' .format(CCEV.values())) self.username = os.getenv(CCEV['client_username']) self.scope = ('playlist-modify-public ' 'user-library-read ' 'user-follow-read ' 'user-library-modify ' 'user-read-private ' 'user-top-read') self.token = prompt_for_user_token(self.username, scope=self.scope) self.spotify = Spotify(auth=self.token) def test_track_bad_id(self): try: track = self.spotify.track(self.bad_id) self.assertTrue(False) except SpotifyException: self.assertTrue(True) def test_basic_user_profile(self): user = self.spotify.user(self.username) self.assertTrue(user['id'] == self.username.lower()) def test_current_user(self): user = self.spotify.current_user() self.assertTrue(user['id'] == self.username.lower()) def test_me(self): user = self.spotify.me() self.assertTrue(user['id'] == self.username.lower()) def test_user_playlists(self): playlists = self.spotify.user_playlists(self.username, limit=5) self.assertTrue('items' in playlists) self.assertTrue(len(playlists['items']) == 5) def test_user_playlist_tracks(self): playlists = self.spotify.user_playlists(self.username, limit=5) self.assertTrue('items' in playlists) for playlist in playlists['items']: user = playlist['owner']['id'] pid = playlist['id'] results = self.spotify.user_playlist_tracks(user, pid) self.assertTrue(len(results['items']) >= 0) def user_playlist_tracks(self, user, playlist_id=None, fields=None, limit=100, offset=0): # known API issue currently causes this test to fail # the issue is that the API doesn't currently respect the # limit paramter self.assertTrue(len(playlists['items']) == 5) def test_current_user_saved_tracks(self): tracks = self.spotify.current_user_saved_tracks() self.assertTrue(len(tracks['items']) > 0) def test_current_user_saved_albums(self): albums = self.spotify.current_user_saved_albums() self.assertTrue(len(albums['items']) > 0) def test_current_user_playlists(self): playlists = self.spotify.current_user_playlists(limit=10) self.assertTrue('items' in playlists) self.assertTrue(len(playlists['items']) == 10) def test_user_playlist_follow(self): self.spotify.user_playlist_follow_playlist('plamere', '4erXB04MxwRAVqcUEpu30O') follows = self.spotify.user_playlist_is_following( 'plamere', '4erXB04MxwRAVqcUEpu30O', [self.spotify.current_user()['id']]) self.assertTrue(len(follows) == 1, 'proper follows length') self.assertTrue(follows[0], 'is following') self.spotify.user_playlist_unfollow('plamere', '4erXB04MxwRAVqcUEpu30O') follows = self.spotify.user_playlist_is_following( 'plamere', '4erXB04MxwRAVqcUEpu30O', [self.spotify.current_user()['id']]) self.assertTrue(len(follows) == 1, 'proper follows length') self.assertFalse(follows[0], 'is no longer following') def test_current_user_save_and_unsave_tracks(self): tracks = self.spotify.current_user_saved_tracks() total = tracks['total'] self.spotify.current_user_saved_tracks_add(self.four_tracks) tracks = self.spotify.current_user_saved_tracks() new_total = tracks['total'] self.assertTrue(new_total - total == len(self.four_tracks)) tracks = self.spotify.current_user_saved_tracks_delete( self.four_tracks) tracks = self.spotify.current_user_saved_tracks() new_total = tracks['total'] self.assertTrue(new_total == total) def test_categories(self): response = self.spotify.categories() self.assertTrue(len(response['categories']) > 0) def test_category_playlists(self): response = self.spotify.categories() for cat in response['categories']['items']: cat_id = cat['id'] response = self.spotify.category_playlists(category_id=cat_id) if len(response['playlists']["items"]) > 0: break self.assertTrue(True) def test_new_releases(self): response = self.spotify.new_releases() self.assertTrue(len(response['albums']) > 0) def test_featured_releases(self): response = self.spotify.featured_playlists() self.assertTrue(len(response['playlists']) > 0) def test_current_user_follows(self): response = self.spotify.current_user_followed_artists() artists = response['artists'] self.assertTrue(len(artists['items']) > 0) def test_current_user_top_tracks(self): response = self.spotify.current_user_top_tracks() items = response['items'] self.assertTrue(len(items) > 0) def test_current_user_top_artists(self): response = self.spotify.current_user_top_artists() items = response['items'] self.assertTrue(len(items) > 0) def get_or_create_spotify_playlist(self, playlist_name): playlists = self.spotify.user_playlists(self.username) while playlists: for item in playlists['items']: if item['name'] == playlist_name: return item['id'] playlists = self.spotify.next(playlists) playlist = self.spotify.user_playlist_create(self.username, playlist_name) playlist_id = playlist['uri'] return playlist_id def test_user_playlist_ops(self): # create empty playlist playlist_id = self.get_or_create_spotify_playlist( 'spotipy-testing-playlist-1') # remove all tracks from it self.spotify.user_playlist_replace_tracks(self.username, playlist_id, []) playlist = self.spotify.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 0) self.assertTrue(len(playlist['tracks']['items']) == 0) # add tracks to it self.spotify.user_playlist_add_tracks(self.username, playlist_id, self.four_tracks) playlist = self.spotify.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 4) self.assertTrue(len(playlist['tracks']['items']) == 4) # remove two tracks from it self.spotify.user_playlist_remove_all_occurrences_of_tracks( self.username, playlist_id, self.two_tracks) playlist = self.spotify.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 2) self.assertTrue(len(playlist['tracks']['items']) == 2) # replace with 3 other tracks self.spotify.user_playlist_replace_tracks(self.username, playlist_id, self.other_tracks) playlist = self.spotify.user_playlist(self.username, playlist_id) self.assertTrue(playlist['tracks']['total'] == 3) self.assertTrue(len(playlist['tracks']['items']) == 3)
class SpotifyCommunicator: def __init__(self, token_info): self.token_info = token_info self.sp = Spotify(token_info['access_token']) def get_user_info(self): return self.sp.current_user() def get_top_songs(self, time_range="medium_term", limit=20, offset=0): return self.sp.current_user_top_tracks(time_range=time_range, limit=limit, offset=offset) def get_recommendations_from_songs(self, songs, limit=20): uris = [] for song in songs: uris.append(uri_string(song['uri'])) return self.sp.recommendations(seed_tracks=uris, limit=limit) def get_recommendations(self, limit=50, **kwargs): return self.refresh_handler(get_recommendations_given_sp, sp=self.sp, limit=limit, **kwargs) def get_artist(self, **kwargs): return self.refresh_handler(get_artist_given_sp, sp=self.sp, **kwargs) def get_artists(self, **kwargs): return self.refresh_handler(get_artists_given_sp, sp=self.sp, **kwargs) def refresh_token(self): self.token_info = spotify_auth.update_token_info(self.token_info) self.sp = Spotify(self.token_info['access_token']) def refresh_handler(self, func, recurs=False, *args, **kwargs): try: return func(*args, **kwargs) except SpotifyException as e: if e.args[0] == 429: time.sleep(3) print('Caught too many requests error, trying again') res = self.refresh_handler(func, recurs=True, *args, **kwargs) print('Success after waiting') return res if not recurs: if e.args[0] == 401: self.refresh_token() if 'sp' in kwargs: kwargs['sp'] = self.sp res = self.refresh_handler(func, recurs=True, *args, **kwargs) print('Success on retry for token expired') return res else: raise ValueError('sp should be supplied in kwargs') else: raise Exception(f"Unknown exception occurred: {e}") else: print(f"Error on retry: {e}") return 'ERROR'
class SpotipyUtils: def __init__(self, client_id, client_secret, redirect_uri, scope): self._sp = Spotify( auth_manager=SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=scope)) def delete_all_tracks(self, playlist): """ Deletes all tracks in the given playlist """ tracks = self.retrieve_all_tracks_for_playlist(playlist) SpotipyUtils._list_of_uris_helper( playlist, tracks, self._sp.playlist_remove_all_occurrences_of_items) def add_all_tracks(self, playlist, tracks: List[Track]): """ Adds all the tracks to the given playlist """ SpotipyUtils._list_of_uris_helper(playlist, tracks, self._sp.playlist_add_items) def retrieve_all_tracks_for_playlist(self, playlist) -> List[Track]: """ Retrieves all tracks for the given playlist """ fields = 'next,' \ 'items(track(name,album(release_date,release_date_precision),artists(name),uri))' all_items = [] results = self._sp.playlist_items(playlist_id=playlist['id'], limit=50, fields=fields) while True: all_items.extend(results['items']) results = self._sp.next(results) if results is None: break return [SpotipyUtils.to_track(item) for item in all_items] def num_tracks_in_playlist(self, playlist) -> Optional[int]: """ Returns the number of tracks in this playlist """ playlist = self.search_playlist_in_current_user_library( playlist['name']) if playlist is None: return None return len(self.retrieve_all_tracks_for_playlist(playlist)) # TODO: have a class to represent playlist? def search_playlist_in_current_user_library(self, playlist_name: str): """ Searches for a playlist within the current user's library with the given name (case insensitive) (I don't think Spotify API offers the ability to search for a playlist within a user's library yet. See note section here: https://developer.spotify.com/documentation/web-api/reference/search/search/) """ batch_results = self._sp.current_user_playlists(limit=50) while True: for playlist in batch_results['items']: if playlist['name'].lower() == playlist_name.lower(): return playlist batch_results = self._sp.next(batch_results) if batch_results is None: break return None def create_temp_playlist(self): """ Creates a temp playlist (named "temp") in the user library. If temp already exists, delete all tracks """ playlist = self.search_playlist_in_current_user_library("temp") if playlist is None: user_id = self._sp.current_user()['id'] self._sp.user_playlist_create(user_id, "temp") return self.search_playlist_in_current_user_library("temp") @staticmethod def _list_of_uris_helper(playlist, tracks: List[Track], spotify_method): """ Helpers for functions that take in a list of Tracks """ playlist_id = playlist['id'] curr = 0 offset = 100 uris = [track.uri for track in tracks] while curr < len(tracks): spotify_method(playlist_id, uris[curr:curr + offset]) curr += offset @staticmethod def to_album_release_date(release_date: str, release_date_precision: str): if release_date_precision is None or release_date is None: return None pad_date = { 'day': lambda date: date, 'month': lambda date: f'{date}-01', 'year': lambda date: f'{date}-01-01' } return datetime.datetime.strptime( pad_date[release_date_precision](release_date), '%Y-%m-%d') @staticmethod def to_track(sp_result): sp_result = sp_result['track'] artist = sp_result['artists'][0]['name'] uri = sp_result['uri'] album_release_date = SpotipyUtils.to_album_release_date( release_date=sp_result['album']['release_date'], release_date_precision=sp_result['album'] ['release_date_precision']) return Track(album_release_date=album_release_date, artist=artist, uri=uri, name=sp_result['name'])
def spotify_playlist(token, service, url): #generate new spotify playlist; yield info to update progress bar apple = service == 'apple' tidal = service == 'tidal' if apple: import app.appcrawl try: #get dictionary of songs from Apple playlist indict = app.appcrawl.get_artists_tracks(url) except: yield "data:ERROR\n\n" #yield error, stop program, user imput wrong URL return None elif tidal: import app.tidapi try: indict = app.tidapi.tidal_to_dict(url) except: yield "data:ERROR\n\n" #yield error, stop program, user input wrong URL return None else: yield "data:ERROR\n\n" #yield error, stop program, something went wrong on my end return None yield "data: 10\n\n" spotifyObject = Spotify(auth = token) #use token to validate responses user = spotifyObject.current_user() userid = user['id'] idlist = [] name = indict['Name'] description = indict['Description'] headers = {'Authorization': 'Bearer {0}'.format(token)} headers['Content-Type'] = 'application/json' data = {'name': name, 'public': 'True', 'description': description} r = spotifyObject._internal_call('POST',"users/%s/playlists" % userid, data, None) #create playlist plid = r['id'] #playlist ID misses = [] yield "data: 15\n\n" displaypercent = 15 #approximately 15% done with program at this point exactpercent = 15.0 length = len(indict['Tracks']) for i in range(length // 100 + 1): #continuously call search function of API to find corresponding songs firstls = [] for item in indict['Tracks'][(100 * i): ((i + 1) * 100)]: #create proper string to search searchsec = "" artistname = item[(item.find('|Artist|:') + 10):item.find(' |URL|:')] trackname = item[(item.find('|Track|:') + 9):item.find('|Artist|:')] query = trackname + artistname query = query.replace(" "," ") retquery = artistname + ' - ' + trackname searchprim = spotifyObject.search(query, type = "track" , limit = 2) #search object addbool = False for thing in searchprim['tracks']['items']: #parse search object to find track for stuff in thing['artists']: if (artistname.lower() in stuff['name'].lower()) or (stuff['name'].lower() in artistname.lower()): firstls.append(thing['id']) addbool = True break if addbool: break if not addbool and (" & " in artistname or ("(" in trackname and ")" in trackname)): #try again but with different query secartist = artistname sectrack = trackname if " & " in artistname: secartist = artistname[:artistname.find(" & ")] if "(" in trackname and ")" in trackname: sectrack = removeParen(trackname) if "[" in trackname and "]" in trackname: sectrack = removeBrack(trackname) secquery = sectrack + secartist secquery = secquery.replace(" "," ") searchsec = spotifyObject.search(secquery, type = "track" , limit = 2) for thing in searchsec['tracks']['items']: #try again but with different query addbool = False for stuff in thing['artists']: if (secartist.lower() in stuff['name'].lower()) or (stuff['name'].lower() in secartist.lower()): firstls.append(thing['id']) addbool = True break if addbool: break if not addbool and apple: #try again but with different query, search using album name url = item[(item.find(' |URL|:') + 7):] albumpage = requests.get(url) albumhtml = BeautifulSoup(albumpage.text, 'html.parser') album = albumhtml.find(id = 'shoebox-ember-data-store').get_text() albdic = json.loads(album) albumname = albdic['data']['attributes']['name'] query = trackname + artistname + " " + albumname query = query.replace(" "," ") searchprim = spotifyObject.search(query, type = "track" , limit = 1) for thing in searchprim['tracks']['items']: addbool = False for stuff in thing['artists']: if (artistname.lower() in stuff['name'].lower()) or (stuff['name'].lower() in artistname.lower()): firstls.append(thing['id']) addbool = True break if addbool: break if not addbool and apple and (" & " in artistname or ("(" in trackname and ")" in trackname)): #try again but with different query, search using album name url = item[(item.find(' |URL|:') + 7):] albumpage = requests.get(url) albumhtml = BeautifulSoup(albumpage.text, 'html.parser') album = albumhtml.find(id = 'shoebox-ember-data-store').get_text() albdic = json.loads(album) albumname = albdic['data']['attributes']['name'] secquery = sectrack + secartist + " " + albumname secquery = secquery.replace(" "," ") searchsec = spotifyObject.search(secquery, type = "track" , limit = 1) for thing in searchsec['tracks']['items']: addbool = False for stuff in thing['artists']: if (secartist.lower() in stuff['name'].lower()) or (stuff['name'].lower() in secartist.lower()): firstls.append(thing['id']) addbool = True break if addbool: break if not addbool and tidal: #try again but with different query album = item[(item.find(' |URL|: ') + 7):] query = trackname + artistname + " " + album query = query.replace(" "," ") searchprim = spotifyObject.search(query, type = "track" , limit = 1) for thing in searchprim['tracks']['items']: addbool = False for stuff in thing['artists']: if (artistname.lower() in stuff['name'].lower()) or (stuff['name'].lower() in artistname.lower()): firstls.append(thing['id']) addbool = True break if addbool: break if not addbool and tidal and (" & " in artistname or ("(" in trackname and ")" in trackname)): #try again but with different query album = item[(item.find(' |URL|: ') + 7):] secquery = sectrack + secartist + " " + album secquery = secquery.replace(" "," ") searchsec = spotifyObject.search(secquery, type = "track" , limit = 1) for thing in searchsec['tracks']['items']: addbool = False for stuff in thing['artists']: if (secartist.lower() in stuff['name'].lower()) or (stuff['name'].lower() in secartist.lower()): firstls.append(thing['id']) addbool = True break if addbool: break if not addbool: #if no search attempts worked, add song to list of missed songs misses.append(retquery) exactpercent = ((65) / length) + exactpercent displaypercent = int(exactpercent) if displaypercent > 80: #about 80% done here displaypercent = 80 yield "data:" +str(displaypercent) + "\n\n" if firstls: #make list of lists, each sublist is up to 100 tracks (Spotify only allows 100 at a time) idlist.append(firstls) idlength = len(idlist) for item in idlist: #add songs to playlist spotifyObject.user_playlist_add_tracks(userid, plid, item) exactpercent = ((20) / idlength) + exactpercent displaypercent = int(exactpercent) if displaypercent > 100: displaypercent = 100 yield "data:" +str(displaypercent) + "\n\n" yield "data:100\n\n" urlstring = 'https://open.spotify.com/user/%s/playlist/%s' % (userid, str(plid)) #link to playlist yield "data:URL"+urlstring+"\n\n" for item in misses: yield "data:MISS"+item+"\n\n" yield "data:NAME"+name+"\n\n" yield "data:COMPLETE\n\n"