mental32 / spotify.py

🌐 API wrapper for Spotify 🎶
https://spotifypy.readthedocs.io/en/latest/
MIT License
150 stars 38 forks source link

Playlist attribute `tracks` is always None #53

Closed iangu48 closed 4 years ago

iangu48 commented 4 years ago

I'm new to this so forgive me in advance

I'm following the Flask example, and whenever I try to access the tracks attribute of Playlist, it gives me None. I'm also not able to use the remove() method of Playlist, and it throws me ValueError: list.remove(x): x not in list since tracks is None

def start():
    currentUser: spotify.User = SPOTIFY_USERS[flask.session['spotify_user_id']]
    if currentUser.id in listeningSessions:
        return flask.redirect(flask.url_for('.queue'))
    try:
        currentUser.currently_playing()['item']
    except KeyError:
        flask.flash("Playback device not found.. Please open your Spotify app and begin playing (any random song)",
                    category='error')
        return flask.redirect(flask.url_for('.index'))  # todo handle error
    playlists = currentUser.get_playlists()
    playlist: spotify.Playlist = None
    for p in playlists:
        print(p.name, p.name == 'Spo2fi Queue')  # Spo2fi Queue True
        if p.name == 'Spo2fi Queue':
            playlist = p
            break

    print(playlist.tracks)  # None
    if not playlist:
        playlist = currentUser.create_playlist('Spo2fi Queue', collaborative=True, public=False)

    print(playlist.tracks)  # None

    try:
        if currentUser.currently_playing()['is_playing']:
            playlist.replace_tracks(currentUser.currently_playing()['item'])
    except KeyError:
        usersTopTracks = currentUser.top_tracks(limit=1, time_range='medium_term')
        print(usersTopTracks)
        playlist.replace_tracks(usersTopTracks[0])
    print(playlist.tracks)  # None

    joinId = ''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(4))
    while joinId in parties:
        joinId = ''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(4))
    listeningSessions[currentUser.id] = ListeningSession(currentUser, [], playlist, joinId)
    parties[joinId] = currentUser.id
    print(playlist.tracks)  # None

    print(currentUser.currently_playing())  # works
    flask.session['party'] = listeningSessions[currentUser.id].joinId
    print(flask.session['party'])  # works

    try:
        currentUser.get_player().play(playlist)
        currentUser.get_player().shuffle(False)
    except spotify.errors.NotFound:
        flask.flash("Playback device not found.. Please open your Spotify app and begin playing (any random song)",
                    category='error')
        return flask.redirect(flask.url_for('.index'))  # todo handle error
    print(playlist.tracks)  # None
    return flask.redirect(flask.url_for('.queue'))
mental32 commented 4 years ago

That's a bit of a dead field that went left over, I'll remove it in the next major bump. at the moment get your tracks from Playlist.get_all_tracks() or get_tracks() instead.

mental32 commented 4 years ago

@iangu48 Let me know if you have any more issues or questions, I'm going to keep this thread open for a couple days :D

iangu48 commented 4 years ago

Thanks for the clarification How would I remove a specific track in a playlist? playlist.remove_tracks(track) removes all occurrences of the track in the playlist I'm been trying playlist.remove_tracks({track.uri: [index]}), but I can't get it to work either.

spotify.errors.HTTPException: Bad Request (status code: 400): JSON body contains an invalid track uri: {'spotify:track:2YorpKjHKhDBD0QOuucIrA': [1]}

Here's my code

def removeTrack():
    try:
        print(flask.session['party'])
        ownerId = parties[flask.session['party']]
        party = listeningSessions[ownerId]
        print(party)
    except KeyError:
        return "no session currently found"
    else:
        currentUser = SPOTIFY_USERS[flask.session['spotify_user_id']]
        track = SPOTIFY_CLIENT.get_track(flask.request.args['track'])
        party.playlist.remove_tracks({track.uri: [int(flask.request.args['trackIndex'])]})
        return flask.redirect(flask.url_for('.queue'))
mental32 commented 4 years ago

That's a good point, I forgot to add support for that.

I'm going to release a new minor in the next hour or so addressing this. The api would look like this:

playlist.remove_tracks(track_a, track_b, (track_c, [0, 3]))

where all occurrences of tracks A and B get uniformly removed and only Cs at index's 0 and 3 get removed.

iangu48 commented 4 years ago

Looking forward to that, thanks again for your help :)

mental32 commented 4 years ago

@iangu48 Sorry took longer than expected to get around to it!

It's in as of 0.9.0 and I'm happy to publish to pypi tomorrow or whenever you confirm the changes are working.

iangu48 commented 4 years ago

Changes seem to be working. Thanks for your work!

mental32 commented 4 years ago

No problem :D