pylast / pylast

A Python interface to Last.fm and Libre.fm
https://pypi.org/project/pylast/
Apache License 2.0
655 stars 108 forks source link

get_userplaycount() returning None #441

Open cliquing opened 7 months ago

cliquing commented 7 months ago

What did you do?

i am trying to create a detailed "nowplaying" command on my bot

What did you expect to happen?

i expected the user's artist & album plays on the nowplaying track would be easier to get after i figured out the track play count, but i have been struggling with this.

What actually happened?

image image

they just keep showing up as "None", im sure i have the wrong code though, and it may be a simple fix but I can't figure it out.

What versions are you using?

Please include code that reproduces the issue. the codes that are giving me the issue is in:

artist_play_count = now_playing.artist.get_userplaycount()
album_play_count = now_playing.get_album().get_userplaycount()

The best reproductions are self-contained scripts with minimal dependencies.

usernames = {}
@bot.command(name='s')
async def setlastfm(ctx, username):
    usernames[ctx.author.id] = username
    await ctx.send(embed=discord.Embed(description=f'<:check:1159989656994193439> {ctx.author.mention} - set {username} as your **last.fm**', color=16776958))

@bot.command(name='t')
async def track(ctx):
    user = ctx.author
    username = usernames.get(user.id)
    if username: 
        network = pylast.LastFMNetwork(api_key=LASTFM_API_KEY, api_secret=LASTFM_API_SECRET)
        user_lastfm = network.get_user(username)
        now_playing = user_lastfm.get_now_playing()

        if now_playing:
            artist_name = now_playing.artist.get_name()
            user_lastfm = network.get_user(username)

            track_title = now_playing.get_name()
            track_play_count = now_playing.get_userplaycount()
            artist_name = now_playing.artist.get_name()
            artist_play_count = now_playing.artist.get_userplaycount()

            album_name = now_playing.get_album().title
            album_play_count = now_playing.get_album().get_userplaycount()

            album_cover_image = now_playing.get_album().get_cover_image(pylast.SIZE_EXTRA_LARGE)               

            track_url = f'https://www.last.fm/music/{artist_name.replace(" ", "+")}/_/{track_title.replace(" ", "+")}'
            artist_url = f'https://www.last.fm/music/{artist_name.replace(" ", "+")}'
            album_url = f'https://www.last.fm/music/{album_name.replace(" ", "+")}'
            user_url = f'https://www.last.fm/user/{username.replace(" ", "+")}'
            total_play_count = user_lastfm.get_playcount()

            embed = discord.Embed(title=f"last.fm - {username} | {total_play_count} total plays ", color=16776958,
                description=f"**artist plays**: {artist_play_count}\n**album plays**: {album_play_count} ")
            embed.set_author(name=user.name, icon_url=user.avatar, url=user_url)
            embed.add_field(name=f'playing', value=f'[{track_title}]({track_url})\n**{track_play_count} plays**')
            embed.add_field(name=f'album', value=f'[{album_name}]({album_url})\n{album_play_count} plays')
            embed.add_field(name=f'artist', value=f'[{artist_name}]({artist_url})\n{artist_play_count} plays')
            embed.set_thumbnail(url=album_cover_image)
            await ctx.send(embed=embed)
        else:
            await ctx.send("You are not currently playing anything.")
    else:
        await ctx.send(embed=discord.Embed(description=f'<:whitealert:1146101911297208471> {ctx.author.mention} - {user.name} has not **set** their __Last.fm__ profile yet. Use `{ctx.prefix}set`', color=16776958))
cliquing commented 7 months ago

@hugovk could you help me out with this? i have been trying on this for hours. basically what i want is to get the amount of scrobbles the user doing the command has on the artist & album. the code for getting the "track_play_count" is correct, but the artist_play_count = now_playing.artist.get_userplaycount() album_play_count = now_playing.get_album().get_userplaycount()

is where the issue is, they just keep coming back as None even though its not.

hugovk commented 7 months ago

Can you print out what now_playing.artist is?

And what now_playing.get_album() is?

cliquing commented 7 months ago

Can you print out what now_playing.artist is?

And what now_playing.get_album() is?

i just tested it right now, here are the results: image this is what was printed out: image now_playing.artist: Quelly Woo now_playing.get_album(): Quelly Woo - Wicked

cliquing commented 7 months ago

Can you print out what now_playing.artist is? And what now_playing.get_album() is?

i just tested it right now, here are the results: image this is what was printed out: image now_playing.artist: Quelly Woo now_playing.get_album(): Quelly Woo - Wicked

as you can see, the only thing thats actually working correctly for me is the track plays.

# Get play counts
track_play_count = now_playing.get_userplaycount()
artist_play_count = now_playing.artist.get_userplaycount()
album_play_count = now_playing.get_album().get_userplaycount()

this is how it looks in my code now, artist_play_count and album_play_count are printing as None. what can i do to fix this to get the correct play counts?

hugovk commented 7 months ago

It looks like this info might be missing from the Last.fm API. The three endpoints:

If you click the example URLs (XML) and replace YOUR_API_KEY with your value, and replace the artist, album, and/or track with your values, you can see if there's any userplaycount present.

If not, then the data just isn't available from Last.fm, or there's a problem with the API, and you'll need to report it to them at https://support.last.fm/c/support/api/47.

cliquing commented 7 months ago

it seems none of these have userplaycount even the track one? which is weird because i was able to get the correct track plays to show. image

and i do know its possible to see the amount of album plays and artist plays because there was a bot that had it. do you have any other suggestions of how i can get this working?

hugovk commented 7 months ago

I suggest reporting it to Last.fm and see what they say.

cliquing commented 7 months ago

I suggest reporting it to Last.fm and see what they say.

will do, im still researching some other bots and features they have. the bleed bot has commands called "whoknows" or "wk" commands, it basically looks up stats for users in a server. this includes track, artist and album plays and the info is accurate, is this already existing in pylast or something similar to it maybe i can use instead? screenshots attached below: i just want to be aware of what im capable to do with pylast, im not sure if im going to have to create some codes on my own which i know would take me a long time since im not too experienced with coding as a beginner.

track: IMG_6156

artist: IMG_6155

album: IMG_6157

cliquing commented 7 months ago

I suggest reporting it to Last.fm and see what they say.

wait but the site you directed me to says this username (Optional) : The username for the context of the request. If supplied, the user's playcount for this album is included in the response. in the params. suggesting it is possible to see album playcount? but how?

hugovk commented 6 months ago

Ah, right, if we add a username like &username=bbc6music to the end of the URLs in https://github.com/pylast/pylast/issues/441#issuecomment-1841733393 we do get userplaycount:

<stats>
<listeners>1623190</listeners>
<playcount>25614479</playcount>
<userplaycount>28</userplaycount>
</stats>

With pylast, you can set a username setting up the network object:

network = pylast.LastFMNetwork(api_key=LASTFM_API_KEY, api_secret=LASTFM_API_SECRET, username= username)

Also, you may need to set a username on the artist or album objects.

For example, instead of:

artist_play_count = now_playing.artist.get_userplaycount()

Check if there's a username set on the artist object:

artist = now_playing.artist
print(f"{artist=}")
artist_play_count = artist.get_userplaycount()

And you can set it like this:

artist = now_playing.artist
artist.username = username
print(f"{artist=}")
artist_play_count = artist.get_userplaycount()

Does that help?

It might be an idea to allow passing a username to get_userplaycount(), but would you like to try the above first?

engeir commented 5 months ago

artist = now_playing.artist artist.username = username print(f"{artist=}") artist_play_count = artist.get_userplaycount()

I faced the same issue, and with the snippet above I was able to get what seems to be the correct playcount for artists.

submeg commented 3 weeks ago

And you can set it like this:

artist = now_playing.artist
artist.username = username
print(f"{artist=}")
artist_play_count = artist.get_userplaycount()

So I have tried to do this, and I only see None as the value.

my code -


network = pylast.LastFMNetwork(
        api_key=API_KEY,
        api_secret=API_SECRET,
        username=username,
        password_hash=password_hash,
    )

artist = network.get_artist("Yellowcard")

artist_name = artist.get_name()
playcount = artist.get_userplaycount()

print("playcount of " + artist_name + " " + str(playcount))
hugovk commented 3 weeks ago

It might be an idea to allow passing a username to get_userplaycount()

Does this help?

submeg commented 3 weeks ago

It might be an idea to allow passing a username to get_userplaycount()

Does this help?

When I tried this -

username = "Submeg"
user = network.get_user(username)

playcount = artist.get_userplaycount(user)

it gives this error - TypeError: get_userplaycount() takes 1 positional argument but 2 were given

submeg commented 3 weeks ago

It might be an idea to allow passing a username to get_userplaycount()

Does this help?

When I tried this -

username = "Submeg"
user = network.get_user(username)

playcount = artist.get_userplaycount(user)

it gives this error - TypeError: get_userplaycount() takes 1 positional argument but 2 were given

Should have read closer -

artist.username = username
artist_play_count = artist.get_userplaycount()

print("playcount of " + artist_name + " " + str(artist_play_count))
submeg commented 3 weeks ago

How does this line work?

artist.username = username

Is this setting an attribute of the artist object to find the username in the artist's listeners?