Last.fm play count importer
Moving a music library to Navidrome brings the files but not the history. Last.fm usually has years of play counts, and Navidrome has its own. Copying the numbers directly would double-count anything already scrobbled; doing nothing loses the history.
This script imports the difference. It fetches the full scrobble history from Last.fm, fetches the Navidrome library, and matches tracks on normalised artist, album, and title — falling back to artist and title when the album does not match. For every matched track it submits only the gap between the Last.fm count and the current Navidrome count, as Subsonic scrobbles carrying the original Last.fm timestamps.
Navidrome ends up with both an accurate play count and a plausible “last played” date, and re-running the script is safe: counts are topped up, never inflated.
Practicalities
Tracks that cannot be matched are written to unmatched.tsv, sorted by play count, so the gaps are visible instead of silently dropped. A --dry-run flag prints what would be sent without touching the server. --limit N tops up only the first N tracks, which is useful for checking the matching rules on a small sample before committing a whole library.
Dependencies are declared inline and run with uv, so there is no virtual environment to manage. Credentials live in a .env file: Last.fm username and API key, Navidrome URL and login.
Built with
- Python
- uv
- Last.fm API
- Subsonic API
- Navidrome