Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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())
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
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())
Ejemplo n.º 9
0
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"])
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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"]
Ejemplo n.º 14
0
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'})
Ejemplo n.º 15
0
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.")
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
0
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"]))
Ejemplo n.º 18
0
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)
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
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])
Ejemplo n.º 22
0
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")
Ejemplo n.º 23
0
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())
Ejemplo n.º 24
0
    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
Ejemplo n.º 25
0
        #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)
Ejemplo n.º 26
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"
    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)
Ejemplo n.º 27
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)
Ejemplo n.º 28
0
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'
Ejemplo n.º 29
0
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'])
Ejemplo n.º 30
0
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"