Last.fm
You can fetch all your Scrobbles (listens) from one or more Last.fm accounts. You can then view: recent Scrobbles; the most popular Artists, Tracks and Albums (for different time periods); number of Scrobbles per year; all Scrobbles for a single day; etc.
Set-up
In the Django admin, create a new Account in the Last.fm app. Enter your Last.fm username, your full name, and a Last.fm API key from http://www.last.fm/api/account/create
Now you can download your scrobbles. See Management commands.
Models
The models available in ditto.lastfm.models are:
AccountRepresenting a Last.fm account with an API key.
ScrobbleA single listen to a particular
Trackby anArtistat a certain time (post_time), optionally on anAlbum.TrackA track by an
Artist. Itsscrobblesproperty is a set ofScrobbles; all the times it has been listened to. Tracks have no direct relationship toAlbums.ArtistA music artist. Its
scrobblesproperty is a set ofScrobbles; all the timesTracks by this artist have been listened to.AlbumAn album by an
Artist. Itsscrobblesproperty is a set ofScrobbles; all the timesTrackson this album have been listened to.
When the Last.fm API provides it, we store an mbid (MusicBrainz Identifier)
for each Track, Artist and Album.
The URL slug is used to differentiate one entity from another at Last.fm. While we store these as original_slug Ditto uses a lowercase version, slug, so that matching newly-fetched entities to existing ones is more reliable. (And because there’s no case-insensitive searching of unicode strings in SQLite.)
Track s and Albums s aren’t directly related; their only connection is
through Scrobble s. This is because the data doesn’t seem reliable enough
to useful construct this relationship. Each Album has a tracks property
that returns a QuerySet of Track s associated with it:
album = Album.objects.get(slug='bang+bang+rock+&+roll')
for track in album.tracks:
print(track.name)
Similarly, to get the Album s on which a particular Track appears, use its albums property:
track = Track.objects.get(slug='emily+kane')
for album in track.albums:
print(album.name)
See ditto.lastfm.models for more useful properties and methods.
Managers
The default manager for each of Track, Album and Artist has a with_scrobble_counts() method. This gives each returned object a scrobble_count property which is an aggregated count of the number of times that thing has been scrobbled. These results are also filterable by Account, minimum and maximum scrobble time, and (for Track and Album) by Artist.
By default, the manager behaves as expected, eg:
# A QuerySet of all Track objects:
tracks = Track.objects.all()
# A QuerySet of all Track objects by Art Brut:
artist = Artist.objects.get(slug='art+brut')
tracks = Track.objects.filter(artist=artist)
The default ordering is by name.
To add number of scrobbles, and sort with the most-scrobbled tracks first:
tracks = Track.objects.with_scrobble_counts().order_by('-scrobble_count')
artist = Artist.objects.get(slug='art+brut')
tracks = Track.objects.with_scrobble_counts(artist=artist).order_by('-scrobble_count')
Here, each Track will have a scrobble_count property, an integer.
Some more examples (d1 and d2 are both datetime.datetime s):
# All Artists scrobbled since d1:
artists = Artist.objects.with_scrobble_counts(min_post_time=d1)
# All Albums scrobbled between d1 and d2,:
albums = Album.objects.with_scrobble_counts(min_post_time=d1,
max_post_time=d2)
# All Tracks scrobbled by this account since d1:
account = Account.objects.get(username='gyford')
tracks = Track.objects.with_scrobble_counts(min_post_time=d1,
account=account)
# All Tracks by this artist scrobbled by this account, between d1 and d2:
artist = Artist.objects.get(slug='art+brut')
tracks = Track.objects.with_scrobble_counts(artist=artist,
account=account,
min_post_time=d1,
max_post_time=d2)
Management commands
There is only one Last.fm management command.
Fetch Scrobbles
Fetches Scrobbles for one or all Accounts.
To fetch ALL Scrobbles for all Accounts (this could take a long time):
$ ./manage.py fetch_lastfm_scrobbles --days=all
To fetch Scrobbles for all Accounts from the past 3 days:
$ ./manage.py fetch_lastfm_scrobbles --days=3
Both options can be restricted to only fetch for a single Account by adding the Last.fm username. e.g.:
$ ./manage.py fetch_lastfm_scrobbles --account=gyford --days=3
It’s safe to re-fetch the same data. Duplicates will only occur if an Artist/Track/Album’s URL slug has changed. A change of case won’t cause duplicates, but anything more will.
Subsequent fetches will update any other changed data, such as altered Artist names, new or different MBIDs, etc.