Beispiel #1
0
def get_playlist_info(sp: spotipy.client.Spotify,
                      playlist_uri: str) -> Tuple[str, list, list, list]:
    """
    Extract track names and URIs from a playlist

    :param sp: spotify client object
    :param playlist_uri: playlist uri
    :return: playlist name, track names, artist names, song uris
    """

    # Initialize vars
    offset = 0
    tracks, uris, names, artists = [], [], [], []

    # Get playlist id and name from URI
    playlist_id = playlist_uri.split(':')[2]
    playlist_name = sp.playlist(playlist_id)['name']

    # Get all tracks in given playlist (max limit is 100 at a time --> use offset)
    while True:
        results = sp.playlist_items(playlist_id, offset=offset)
        tracks += results['items']
        if results['next'] is not None:
            offset += 100
        else:
            break

    # Get track metadata
    for track in tracks:
        names.append(track['track']['name'])
        artists.append(track['track']['artists'][0]['name'])
        uris.append(track['track']['uri'])

    return playlist_name, names, artists, uris
Beispiel #2
0
def get_playlist_tracks(spotify: spotipy.client.Spotify, playlist_id: str) -> list:
    """
    This function takes an authenticated Spotify client, and a playlist ID, and returns a list of song details of every song in the playlist
    Parameters required: Authenticated Spotify Client, and playlist ID or URL
    Return Data: List of song details in the playlist
    """
    # Get first 100 or lesser songs' details
    results = spotify.playlist_items(playlist_id)
    # Check if there are more songs for which details need to be obtained
    tracks = results["items"]
    while results["next"]:
        # Get next 100 songs' details, and append to the list of results already obtained
        results = spotify.next(results)
        tracks.extend(results["items"])
    # Create new list to hold track IDs
    track_id = {}
    # Extract each track detail from the extracted information, and append to track_id list
    track_id["IDs"] = []
    track_id["Name"] = []
    track_id["Artist"] = []
    track_id["Popularity"] = []
    for i in tracks:  # Looping through all tracks
        if i["track"]["id"] != None:
            track_id["IDs"].append(
                "spotify:track:" + i["track"]["id"]
            )  # Get ID of song
            track_id["Name"].append(i["track"]["name"])  # Get Name of song
            track_id["Artist"].append(
                i["track"]["artists"][0]["name"]
            )  # Get main Artist of song
            track_id["Popularity"].append(
                i["track"]["popularity"]
            )  # Get popularity of songs
    # Return all track IDs
    return track_id
Beispiel #3
0
def search_spotify(sp: spotipy.client.Spotify, artist: str, track: str):
    track_id = None
    artists = None
    name = None
    popularity = None

    results = sp.search(q=f"artist:{artist} track:{track} NOT Live",
                        type='track',
                        limit=1)

    if results['tracks']['total'] == 0:
        artist = clean_string(artist)
        results = sp.search(q=f"artist:{artist} track:{track} NOT Live",
                            type='track',
                            limit=1)
        if results['tracks']['total'] == 0:
            artist = artist.split(' ')
            if len(artist) > 1:
                artist = artist[0] + ' ' + artist[1]
                results = sp.search(
                    q=f"artist:{artist} track:{track} NOT Live",
                    type='track',
                    limit=1)

    if results['tracks']['total'] != 0:
        track_id = results['tracks']['items'][0]['id']
        artists = results['tracks']['items'][0]['artists']
        name = results['tracks']['items'][0]['name']
        popularity = results['tracks']['items'][0]['popularity']
    return track_id, artists, name, popularity
Beispiel #4
0
def current_playlist_tracks(sp: spotipy.client.Spotify, playlist_id: str):
    playlist_cont = []
    # Getting current songs in playlist to add to list for no duplicates
    results = sp.playlist_tracks(playlist_id=playlist_id)
    while len(playlist_cont) < results['total']:
        for tracks in results['items']:
            playlist_cont.append(tracks['track']['id'])
        results = sp.playlist_tracks(playlist_id=playlist_id,
                                     offset=len(playlist_cont))
    return playlist_cont
Beispiel #5
0
def clear_playlist(sp: spotipy.client.Spotify, playlist_id: str):
    playlist_cont = current_playlist_tracks()
    with open(
            f'playlist_cont_{dt.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}.txt',
            'w') as f:
        for track_id in playlist_cont:
            f.write(f"{track_id}\n")
            sp.user_playlist_remove_all_occurrences_of_tracks(
                user=username, playlist_id=playlist_id, tracks=[track_id])

    return 0
Beispiel #6
0
    def download(self, sp: spotipy.client.Spotify, playlist_id: str) -> None:
        page_size = 100
        offset = 0
        fields = ','.join([
            'items.track.name',
            'items.track.artists.name',
            'items.added_by.id',
            'items.added_at',
        ])
        while True:
            rsp = sp.playlist_items(
                playlist_id,
                limit=page_size,
                offset=offset,
                fields=fields,
                additional_types=['track']
            )
            if not rsp['items']:
                break

            self.__items += [
                PlaylistItem(s['track']['name'], s['added_at'], s['added_by']['id'], s['track']['artists']) 
                for s in rsp['items'] if s['track']
            ]
            offset += page_size
Beispiel #7
0
def get_audio_features(sp: spotipy.client.Spotify, track_uri: str):
    track_uri = sp._get_id("track", track_uri)

    os.makedirs("audio_features", exist_ok=True)
    filename = f"audio_features/{track_uri}"
    try:
        with open(filename, "r") as f:
            contents = f.read()
            data = json.loads(contents)
    except FileNotFoundError:
        features = sp.audio_features([track_uri])
        data = features[0]
        with open(filename, "w") as f:
            contents = json.dumps(data, indent=4)
            f.write(contents)
    return data
Beispiel #8
0
def prep_songs(song_ids: list, spotify: spotipy.client.Spotify) -> pd.DataFrame:
    """
    Songs passed with IDs cannot directly be used in the model. This function preps the song for the ML model
    Parameters Required: List of song ids (from client), authenticated spotify client
    Return Data: Pandas DataFrame of song details, for which classes can now be predicted
    """
    prep_set = []
    curr_number = 0
    tracks = []
    # Get all details of every song passed
    # Can only do 50 at a time, else throws an error of too many ids passed
    while curr_number <= len(song_ids):
        # Checking if it is empty
        if song_ids[curr_number : curr_number + 50]:
            tracks.extend(
                spotify.tracks(song_ids[curr_number : curr_number + 50])["tracks"]
            )
            curr_number += 50
        else:
            break
    # Getting audio features of all songs passed
    features = get_audio_features(spotify, song_ids)
    # Combining obtained data into single dictionary
    for i in range(len(features)):
        temp_song = features[i]
        temp_song["Popularity"] = tracks[i]["popularity"]
        temp_song["Name"] = tracks[i]["name"]
        temp_song["Artist"] = tracks[i]["artists"][0]["name"]
        # Adding dictionary to list containing all processed songs
        prep_set.append(temp_song)
    # Converting list of dictionaries to a pandas dataframe
    pred_data = pd.DataFrame(prep_set)
    # Returning Dataframe
    return pred_data
Beispiel #9
0
def get_tracks_artist_info(sp: spotipy.client.Spotify,
                           pl_uri: str) -> List[List[Dict]]:
    artists_info = list()
    # Start retrieving tracks from the beginning of the playlist
    offset = 0
    pl_length = get_pl_length(sp, pl_uri)

    # Playlist track retrieval only fetches 100 tracks at a time, hence\
    # the loop to keep retrieving until we reach the end of the playlist
    while offset != pl_length:
        # Get the next batch of tracks
        pl_tracks = sp.playlist_tracks(pl_uri,
                                       offset=offset,
                                       fields="items.track")

        # Get the list with the info about the artists of each track from the\
        # latest batch and append it to the running list
        [
            artists_info.append(pl_item["track"]["artists"])
            for pl_item in pl_tracks["items"]
        ]

        # Update the offset
        offset += len(pl_tracks["items"])

    return artists_info
Beispiel #10
0
def get_track_info(sp: spotipy.client.Spotify, track_uri: str):
    track_uri = sp._get_id("track", track_uri)

    filename = f"track_info/{track_uri}"
    with open(filename, "r") as f:
        contents = f.read()
        track = json.loads(contents)
        return track
Beispiel #11
0
def save_track_info(sp: spotipy.client.Spotify, track):
    track_uri = sp._get_id("track", track["uri"])

    os.makedirs("track_info", exist_ok=True)
    filename = f"track_info/{track_uri}"
    with open(filename, "w") as f:
        contents = json.dumps(track, indent=4)
        f.write(contents)
def failure_command_signal(client: spotipy.client.Spotify):
    current_volume = client.current_playback()['device']['volume_percent']
    client.volume(int(current_volume * 1 / 2))
    time.sleep(0.5)
    client.volume(int(current_volume * 1 / 5))
    time.sleep(0.5)
    client.volume(current_volume)
Beispiel #13
0
def get_audio_features(spotify: spotipy.client.Spotify, track_ids: list) -> list:
    """
    This function gets the following features of a spotify song, hundred songs at a time:
    ["acousticness", "danceability", "durationms", "energy", "instrumentalness", "key", "liveness", "loudness", "mode", "speechiness"\
        , "tempo", "timesignature", "valence"]
    Getting more than 100 songs will result in a bad request error
    Parameters Required: Authenticated Spotify Client, and list of song IDs
    Return Data: List of dictionary containing song features
    """
    # Getting features
    featurelst = []
    count = 0
    while count <= len(track_ids):
        # Get 100 songs' features at a time. Getting any more will result in bad result error
        featurelst.extend(spotify.audio_features(track_ids[count : count + 100]))
        count = count + 100
    return featurelst
Beispiel #14
0
def get_features_for_playlist(sp: spotipy.client.Spotify,
                              uri: str) -> pd.DataFrame:
    """
    Extract features from each track in a playlist

    :param sp: spotify client object
    :param uri: playlist uri
    :return: playlist with audio features of each song
    """
    # Get all track metadata from given playlist
    playlist_name, names, artists, uris = get_playlist_info(sp, uri)

    # Set column names and empty dataframe
    column_names = [
        'name', 'artist', 'track_URI', 'acousticness', 'danceability',
        'energy', 'instrumentalness', 'liveness', 'loudness', 'speechiness',
        'tempo', 'valence', 'playlist'
    ]
    df = pd.DataFrame(columns=column_names)

    # Iterate through each track to get audio features and save data into dataframe
    for name, artist, track_uri in zip(names, artists, uris):

        # Access audio features for given track URI via spotipy
        audio_features = sp.audio_features(track_uri)

        # Get relevant audio features
        feature_subset = [
            audio_features[0][col] for col in column_names
            if col not in ["name", "artist", "track_URI", "playlist"]
        ]

        # Compose a row of the dataframe by flattening the list of audio features
        row = [name, artist, track_uri, *feature_subset, playlist_name]
        df.loc[len(df.index)] = row

    return df
Beispiel #15
0
def _get_playlist_from_spotify(
        spotify: spotipy.client.Spotify,
        spotify_playlist_id: SpotifyPlaylistId) -> PlayList:
    return spotify.playlist(spotify_playlist_id)
Beispiel #16
0
def get_pl_length(sp: spotipy.client.Spotify, pl_uri: str) -> int:
    return sp.playlist_tracks(pl_uri, offset=0, fields="total")["total"]
Beispiel #17
0
def add_track(sp: spotipy.client.Spotify, username: str, playlist_id: str,
              track_id: list):
    sp.user_playlist_add_tracks(user=username,
                                playlist_id=playlist_id,
                                tracks=track_id)
    return 0
def successful_command_signal(client: spotipy.client.Spotify):
    current_volume = client.current_playback()['device']['volume_percent']
    client.volume(int(current_volume * 3 / 4))
    time.sleep(0.6)
    client.volume(current_volume)