Beispiel #1
0
def audiofeat():
    '''
    Audio feature route:
    This route brings user to Audio feature template
    '''
    if 'username' not in flask.session or not consistant_session(
            flask.session['username']):
        return flask.redirect(flask.url_for('logout'))

    if request.method == 'GET':
        # Check access tokens
        check_valid_access_tokens(flask.session['username'])
        return flask.render_template('audiofeat.html')
    else:
        flask.abort(404)
Beispiel #2
0
def search_artist(search):
    '''
    Search artist route:
    POST: Performs a search for artists with a provided string
    '''
    if 'username' not in flask.session:
        #session expired redirect to index page
        return flask.make_response(flask.jsonify({}), 401)

    # POST: Performs a search for artists with a string sent in request
    if flask.request.method == 'GET':
        search_artist_endpoint = SPOTIFY_API_URL + '/search'
        search_artist_params = {'q': search, 'limit': 50, 'type': 'artist'}
        # Implement function to check if the access token is expired. If the access token is expired here we need to update it and use the new one
        check_valid_access_tokens(flask.session['username'])
        query = get_db().cursor().execute(
            'SELECT access_token FROM users WHERE username=?',
            [flask.session['username']]).fetchall()
        headers = makeRequestEndpointHeaders(query[0]['access_token'])

        search_artist_response = requests.get(search_artist_endpoint,
                                              headers=headers,
                                              params=search_artist_params)
        search_artist_data = search_artist_response.json()

        if 'error' in search_artist_data:
            return flask.make_response(flask.jsonify({}), 500)

        artist_matches = []
        for artist in search_artist_data['artists']['items']:
            # print(artist['name'] +': ' + artist['id'])
            artist_matches.append({
                'name': artist['name'],
                'id': artist['id'],
                'images': artist['images']
            })

        return flask.make_response(flask.jsonify({'artists': artist_matches}),
                                   200)

    return flask.make_response(flask.jsonify({}), 405)
Beispiel #3
0
def related_artist(artist_id):
    '''
    Search artist route:
    GET: Performs a search for unpopular artists related to single artist 
    '''
    if 'username' not in flask.session:
        #session expired redirect to index page
        return flask.make_response(flask.jsonify({}), 401)

    # GET: Performs a search for unpopular artists related to single artist
    if flask.request.method == 'GET':
        related_artist_endpoint = SPOTIFY_API_URL + '/artists/{}/related-artists'
        follow_artist_endpoint = SPOTIFY_API_URL + '/me/following/contains'
        # Implement function to check if the access token is expired. If the access token is expired here we need to update it and use the new one
        check_valid_access_tokens(flask.session['username'])
        query = get_db().cursor().execute(
            'SELECT access_token FROM users WHERE username=?',
            [flask.session['username']]).fetchall()
        headers = makeRequestEndpointHeaders(query[0]['access_token'])

        related_artist_response = requests.get(
            related_artist_endpoint.format(artist_id), headers=headers)
        related_artist_data = related_artist_response.json()

        related_artist_dic = {}
        related_artist_list = []

        for artist in related_artist_data['artists']:
            related_artist_list.append(artist['id'])
            related_artist_dic[artist['id']] = {
                'name': artist['name'],
                'images': artist['images'],
                'popularity': artist['popularity'],
                'uri': artist['uri']
            }

        related_artist_list_copy = related_artist_list.copy()
        for artist in related_artist_list_copy:
            more_related_artist_response = requests.get(
                related_artist_endpoint.format(artist), headers=headers)
            more_related_artist_data = more_related_artist_response.json()

            for more_related_artist in more_related_artist_data['artists']:
                if related_artist_dic.get(more_related_artist['id']) == None:
                    related_artist_dic[more_related_artist['id']] = {
                        'name': more_related_artist['name'],
                        'images': more_related_artist['images'],
                        'popularity': more_related_artist['popularity'],
                        'uri': more_related_artist['uri']
                    }
                    related_artist_list.append(more_related_artist['id'])

        list_min = 0
        follow_artist_ids = related_artist_list[list_min:list_min + 50]
        while follow_artist_ids:
            comma_seperate_ids = ','.join(follow_artist_ids)
            follow_artist_response = requests.get(follow_artist_endpoint,
                                                  headers=headers,
                                                  params={
                                                      'ids':
                                                      comma_seperate_ids,
                                                      'type': 'artist'
                                                  })
            follow_artist_data = follow_artist_response.json()
            for idx, val in enumerate(follow_artist_data):
                related_artist_dic[follow_artist_ids[idx]]['follow'] = val
            list_min += 50
            follow_artist_ids = related_artist_list[list_min:list_min + 50]

        return flask.make_response(
            flask.jsonify({
                'related_artist_dic': related_artist_dic,
                'related_artist_list': related_artist_list
            }), 200)

    return flask.make_response(flask.jsonify({}), 405)
Beispiel #4
0
def audio_feat_playlist():
    '''
    Audio Feat playlist route:
    GET: Retrives all users saved songs and audio features of each track 
    POST: Create playlist of given tracks 
    '''
    if 'username' not in flask.session:
        # Session expired redirect to index page
        return flask.make_response(flask.jsonify({}), 401)

    # GET: Retrives all users saved songs and audio features of each track
    if flask.request.method == 'GET':
        genre_dic = {}
        genre_list = []
        saved_tracks_dic = {}
        saved_tracks_list = []
        saved_artist_dic = {}
        saved_artist_no_duplicates = []
        audio_features_endpoint = SPOTIFY_API_URL + '/audio-features'
        saved_tracks_endpoint = SPOTIFY_API_URL + '/me/tracks?limit=50'
        artists_endpoint = SPOTIFY_API_URL + '/artists'

        # Implement function to check if the access token is expired. If the access token is expired here we need to update it and use the new one
        check_valid_access_tokens(flask.session['username'])
        query = get_db().cursor().execute(
            'SELECT access_token FROM users WHERE username=?',
            [flask.session['username']]).fetchall()
        headers = makeRequestEndpointHeaders(query[0]['access_token'])

        artist_ids_dic = {'ids': ''}
        artist_ids_count = 0
        saved_tracks_ids = {'ids': ''}
        saved_tracks_ids_count = 0

        while (True):
            saved_tracks_response = requests.get(saved_tracks_endpoint,
                                                 headers=headers)
            saved_tracks_data = saved_tracks_response.json()

            if 'error' in saved_tracks_data:
                print(saved_tracks_data)
                return flask.make_response(flask.jsonify({}), 500)

            for track_obj in saved_tracks_data['items']:
                saved_tracks_list.append(track_obj['track']['id'])
                saved_tracks_ids['ids'] = saved_tracks_ids['ids'] + track_obj[
                    'track']['id'] + ','
                artist_id = track_obj['track']['artists'][0]['id']
                # Get all artist's names for a single track
                track_artists = []
                for artist_obj in track_obj['track']['artists']:
                    track_artists.append(artist_obj['name'])
                # Create map of track ids to genre/bpm/valence/danceability/energy/track name/track artists
                saved_tracks_dic[track_obj['track']['id']] = {
                    'name': track_obj['track']['name'],
                    'artists': track_artists,
                    'genres': [],
                    'bpm': 0,
                    'valence': 0,
                    'danceability': 0,
                    'energy': 0
                }
                # Create map of artists to list of tracks and list of unique artist id strings with 50 ids that are used in a query string later
                if saved_artist_dic.get(artist_id) == None:
                    saved_artist_dic[artist_id] = []
                    # Add artist id strings once we have a string of 50 unique ids
                    if artist_ids_count == 50:
                        saved_artist_no_duplicates.append(artist_ids_dic)
                        artist_ids_dic = {'ids': ''}
                        artist_ids_count = 0
                    artist_ids_count += 1
                    artist_ids_dic[
                        'ids'] = artist_ids_dic['ids'] + artist_id + ','
                saved_artist_dic[artist_id].append(track_obj['track']['id'])

                saved_tracks_ids_count += 1
            # Add remaing unique artist id strings
            if artist_ids_count > 0:
                saved_artist_no_duplicates.append(artist_ids_dic)
                artist_ids_dic = {'ids': ''}
                artist_ids_count = 0

            if saved_tracks_ids_count == 100:
                # Trim ending comma
                saved_tracks_ids['ids'] = saved_tracks_ids['ids'][:-1]

                audio_response = requests.get(audio_features_endpoint,
                                              headers=headers,
                                              params=saved_tracks_ids)
                audio_response_data = audio_response.json()

                if 'error' in audio_response_data:
                    print(audio_response_data)
                    return flask.make_response(flask.jsonify({}), 500)

                # Add BPM to tracks
                for track in audio_response_data['audio_features']:
                    # Handle if no audio features for a track. This usually occues if the song was recently released and Spotify hasn't gathered audio data yet
                    # Fixes TypeError: 'NoneType' object is not subscriptable: Was getting this because Drakes new album I saved didn't have audio data yet
                    if track == None:
                        continue
                    saved_tracks_dic[track['id']]['bpm'] = track['tempo']
                    saved_tracks_dic[track['id']]['valence'] = track['valence']
                    saved_tracks_dic[
                        track['id']]['danceability'] = track['danceability']
                    saved_tracks_dic[track['id']]['energy'] = track['energy']
                saved_tracks_ids = {'ids': ''}
                saved_tracks_ids_count = 0

            if saved_tracks_data['next'] == None:
                break

            saved_tracks_endpoint = saved_tracks_data['next']

        if saved_tracks_ids_count > 0:
            # Trim ending comma
            saved_tracks_ids['ids'] = saved_tracks_ids['ids'][:-1]
            audio_response = requests.get(audio_features_endpoint,
                                          headers=headers,
                                          params=saved_tracks_ids)
            audio_response_data = audio_response.json()

            if 'error' in audio_response_data:
                print(audio_response_data)
                return flask.make_response(flask.jsonify({}), 500)
            # Add BPM to reamaining tracks
            for track in audio_response_data['audio_features']:
                # Handle if no audio features for a track. This usually occues if the song was recently released and Spotify hasn't gathered audio data yet
                if track == None:
                    continue

                saved_tracks_dic[track['id']]['bpm'] = track['tempo']
                saved_tracks_dic[track['id']]['valence'] = track['valence']
                saved_tracks_dic[
                    track['id']]['danceability'] = track['danceability']
                saved_tracks_dic[track['id']]['energy'] = track['energy']
            saved_tracks_ids = {'ids': ''}
            saved_tracks_ids_count = 0

        # Get list of genres of users saved songs
        for obj in saved_artist_no_duplicates:
            # Trim ending comma
            obj['ids'] = obj['ids'][:-1]
            artists_response = requests.get(artists_endpoint,
                                            headers=headers,
                                            params=obj)
            artists_response_data = artists_response.json()

            if 'error' in artists_response_data:
                print(artists_response_data)
                return flask.make_response(flask.jsonify({}), 500)

            for artist in artists_response_data['artists']:
                for track in saved_artist_dic[artist['id']]:
                    saved_tracks_dic[track]['genres'] = artist['genres']
                    for genre in artist['genres']:
                        if genre_dic.get(genre) == None:
                            genre_dic[genre] = True
                            genre_list.append(genre)

        genre_list.sort()
        return flask.make_response(
            flask.jsonify({
                'saved_tracks_dic': saved_tracks_dic,
                'saved_tracks_list': saved_tracks_list,
                'genre_list': genre_list,
                'genre_dic': genre_dic
            }), 200)

    # POST: Create playlist of given tracks
    elif flask.request.method == 'POST':
        content = flask.request.json

        # Implement function to check if the access token is expired. If the access token is expired here we need to update it and use the new one
        check_valid_access_tokens(flask.session['username'])
        query = get_db().cursor().execute(
            'SELECT access_token FROM users WHERE username=?',
            [flask.session['username']]).fetchall()
        headers = makeRequestEndpointHeaders(query[0]['access_token'])

        response = requests.get(SPOTIFY_API_URL + '/me', headers=headers)
        data = response.json()

        body = {'name': content['name']}
        headers['Content-type'] = 'application/json'
        response = requests.post(SPOTIFY_API_URL +
                                 '/users/{}/playlists'.format(data['id']),
                                 headers=headers,
                                 data=json.dumps(body))
        data = response.json()

        if 'error' in data:
            print(data)
            return flask.make_response(flask.jsonify({}), 500)

        created_playlist_id = data['id']
        body = []
        for track_id in content['tracks']:
            if len(body) == 100:
                response = requests.post(
                    SPOTIFY_API_URL +
                    '/playlists/{}/tracks'.format(created_playlist_id),
                    headers=headers,
                    data=json.dumps(body))
                body = []
            body.append('spotify:track:' + track_id)

        if len(body) > 0:
            response = requests.post(
                SPOTIFY_API_URL +
                '/playlists/{}/tracks'.format(created_playlist_id),
                headers=headers,
                data=json.dumps(body))
            body = []

        return flask.make_response(flask.jsonify({}), 201)

    return flask.make_response(flask.jsonify({}), 405)