|
2 | 2 |
|
3 | 3 | [](https://github.com/crossjam/scrobbledb/actions/workflows/qa.yml) |
4 | 4 |
|
5 | | -A modernization of [Jacob Kaplan-Moss’s](https://github.com/jacobian/) |
6 | | -project |
7 | | -[lastfm-to-sqlite](https://github.com/jacobian/lastfm-to-sqlite). |
| 5 | +**Save your listening history from Last.fm or Libre.fm to a local SQLite database.** |
8 | 6 |
|
9 | | -Uses the [pylast](https://github.com/pylast/pylast) module underneath |
10 | | -the covers. |
| 7 | +scrobbledb is a Python command-line tool that downloads your scrobble data (listening history) from Last.fm or Libre.fm and stores it in a SQLite database for local analysis, backup, and exploration. Built with modern Python tooling, it offers rich terminal output, full-text search, interactive browsing, and comprehensive data export capabilities. |
11 | 8 |
|
12 | | -## Documentation |
| 9 | +## About Last.fm and Scrobbling |
13 | 10 |
|
14 | | -See [docs/cli.md](docs/cli.md) for an overview of the |
15 | | -`scrobbledb` command line interface and links to per-command reference |
16 | | -pages in `docs/commands/`. |
| 11 | +[Last.fm](https://www.last.fm/) is a music discovery and tracking service that records what you listen to across different platforms and devices. This process of recording your listening history is called "scrobbling." |
17 | 12 |
|
| 13 | +**Scrobbling** automatically logs each track you play—including the artist, album, track name, and timestamp—creating a detailed history of your music consumption over time. Last.fm aggregates this data to generate statistics, recommendations, and insights about your listening habits. |
| 14 | + |
| 15 | +The **Last.fm API** provides programmatic access to this scrobble data, allowing applications like scrobbledb to retrieve and analyze your complete listening history. [Libre.fm](https://libre.fm/) is an open-source alternative that offers compatible scrobbling services. |
| 16 | + |
| 17 | +## Why scrobbledb? |
| 18 | + |
| 19 | +- **Local backup**: Keep your listening history in a local database you control |
| 20 | +- **Advanced queries**: Use SQL to analyze your music habits in ways the web interface doesn't support |
| 21 | +- **Data portability**: Export your data in multiple formats (JSON, CSV, TSV) |
| 22 | +- **Full-text search**: Find tracks, albums, and artists instantly with SQLite FTS5 |
| 23 | +- **Interactive browsing**: Explore your library with a terminal UI |
| 24 | +- **Privacy**: Your data stays on your machine |
| 25 | + |
| 26 | +## Origin |
| 27 | + |
| 28 | +scrobbledb is a modernization of [Jacob Kaplan-Moss's](https://github.com/jacobian/) [lastfm-to-sqlite](https://github.com/jacobian/lastfm-to-sqlite) project. This version has been significantly expanded with: |
| 29 | + |
| 30 | +- Modern Python tooling (uv, ruff, type hints) |
| 31 | +- Domain-specific commands for exploring artists, albums, tracks, and plays |
| 32 | +- Interactive terminal UI for browsing |
| 33 | +- Full-text search capabilities |
| 34 | +- Comprehensive data export options |
| 35 | +- Enhanced statistics and filtering |
| 36 | +- Rich terminal output with tables and progress bars |
| 37 | + |
| 38 | +Original concept and implementation by Jacob Kaplan-Moss. Current development by Brian M. Dennis. |
| 39 | + |
| 40 | +## Installation |
| 41 | + |
| 42 | +scrobbledb requires Python 3.11 or later and uses [uv](https://github.com/astral-sh/uv) for dependency management. |
| 43 | + |
| 44 | +```bash |
| 45 | +# Clone the repository |
| 46 | +git clone https://github.com/crossjam/scrobbledb.git |
| 47 | +cd scrobbledb |
| 48 | + |
| 49 | +# Install dependencies |
| 50 | +uv sync |
| 51 | + |
| 52 | +# Run scrobbledb |
| 53 | +uv run scrobbledb --help |
| 54 | +``` |
| 55 | + |
| 56 | +## Quick Start |
| 57 | + |
| 58 | +### 1. Save your Last.fm credentials |
| 59 | + |
| 60 | +```bash |
| 61 | +uv run scrobbledb auth |
| 62 | +``` |
| 63 | + |
| 64 | +This prompts for your Last.fm username, API key, shared secret, and password, then saves them in `~/.local/share/dev.pirateninja.scrobbledb/auth.json`. |
| 65 | + |
| 66 | +**Getting API credentials**: Visit [Last.fm API](https://www.last.fm/api/account/create) to create an API account and obtain your API key and shared secret. |
| 67 | + |
| 68 | +### 2. Initialize the database |
| 69 | + |
| 70 | +```bash |
| 71 | +uv run scrobbledb config init |
| 72 | +``` |
| 73 | + |
| 74 | +This creates the SQLite database and sets up the full-text search index. |
| 75 | + |
| 76 | +### 3. Import your listening history |
| 77 | + |
| 78 | +```bash |
| 79 | +uv run scrobbledb ingest |
| 80 | +``` |
| 81 | + |
| 82 | +This fetches your complete scrobble history from Last.fm and stores it locally. Depending on how many scrobbles you have, this may take several minutes. |
| 83 | + |
| 84 | +### 4. Explore your data |
| 85 | + |
| 86 | +```bash |
| 87 | +# Search for tracks |
| 88 | +uv run scrobbledb search "pink floyd" |
| 89 | + |
| 90 | +# View recent plays |
| 91 | +uv run scrobbledb plays list --limit 50 |
| 92 | + |
| 93 | +# Browse interactively |
| 94 | +uv run scrobbledb browse |
| 95 | + |
| 96 | +# See your top artists |
| 97 | +uv run scrobbledb artists top --limit 20 |
| 98 | + |
| 99 | +# View statistics |
| 100 | +uv run scrobbledb stats overview |
| 101 | +``` |
| 102 | + |
| 103 | +## Command Overview |
| 104 | + |
| 105 | +scrobbledb provides a comprehensive set of commands for managing and exploring your music data: |
| 106 | + |
| 107 | +### Data Management |
| 108 | + |
| 109 | +- **`auth`** - Configure Last.fm/Libre.fm API credentials ([docs](docs/commands/auth.md)) |
| 110 | +- **`config`** - Initialize database, reset data, or show configuration paths ([docs](docs/commands/config.md)) |
| 111 | +- **`ingest`** - Fetch listening history from Last.fm/Libre.fm ([docs](docs/commands/ingest.md)) |
| 112 | +- **`import`** - Import scrobbles from JSONL, CSV, or TSV files ([docs](docs/commands/import.md)) |
| 113 | +- **`index`** - Create or rebuild the full-text search index ([docs](docs/commands/index.md)) |
| 114 | +- **`export`** - Export data in various formats with presets or custom SQL ([docs](docs/commands/export.md)) |
| 115 | + |
| 116 | +### Data Exploration |
| 117 | + |
| 118 | +- **`search`** - Full-text search across artists, albums, and tracks ([docs](docs/commands/search.md)) |
| 119 | +- **`browse`** - Interactive terminal UI for browsing tracks ([docs](docs/commands/browse.md)) |
| 120 | +- **`plays`** - View and filter listening history chronologically ([docs](docs/commands/plays.md)) |
| 121 | +- **`artists`** - Browse artists, view top artists, see detailed statistics ([docs](docs/commands/artists.md)) |
| 122 | +- **`albums`** - Search albums and view album details with tracks ([docs](docs/commands/albums.md)) |
| 123 | +- **`tracks`** - Search tracks, view top tracks, see play history ([docs](docs/commands/tracks.md)) |
| 124 | +- **`stats`** - Generate listening statistics (overview, monthly, yearly) ([docs](docs/commands/stats.md)) |
| 125 | + |
| 126 | +### Advanced |
| 127 | + |
| 128 | +- **`sql`** - Direct access to sqlite-utils commands for power users ([docs](docs/commands/sql.md)) |
| 129 | +- **`version`** - Display the installed version ([docs](docs/commands/version.md)) |
| 130 | + |
| 131 | +See the [CLI overview](docs/cli.md) for a complete command reference and detailed documentation for each command. |
| 132 | + |
| 133 | +## Database Schema |
| 134 | + |
| 135 | +scrobbledb stores your data in a normalized SQLite database: |
| 136 | + |
| 137 | +- **`artists`** - Artist information (id, name) |
| 138 | +- **`albums`** - Album information (id, title, artist_id) |
| 139 | +- **`tracks`** - Track information (id, title, album_id) |
| 140 | +- **`plays`** - Play events (track_id, timestamp) |
| 141 | +- **`tracks_fts`** - FTS5 full-text search index |
| 142 | + |
| 143 | +This schema enables efficient queries, comprehensive searches, and detailed analysis of your listening history. |
| 144 | + |
| 145 | +## Example Workflows |
| 146 | + |
| 147 | +### Backup your data weekly |
| 148 | + |
| 149 | +```bash |
| 150 | +# Update with new scrobbles |
| 151 | +uv run scrobbledb ingest --since-date "7 days ago" |
| 152 | + |
| 153 | +# Export to JSON backup |
| 154 | +uv run scrobbledb export plays --format json --output backup-$(date +%Y%m%d).json |
| 155 | +``` |
| 156 | + |
| 157 | +### Find your most-played tracks from a specific year |
| 158 | + |
| 159 | +```bash |
| 160 | +uv run scrobbledb tracks top --since 2023-01-01 --until 2023-12-31 --limit 50 |
| 161 | +``` |
| 162 | + |
| 163 | +### Analyze your listening patterns |
| 164 | + |
| 165 | +```bash |
| 166 | +# Monthly breakdown |
| 167 | +uv run scrobbledb stats monthly --year 2024 |
| 168 | + |
| 169 | +# Top artists in the last 30 days |
| 170 | +uv run scrobbledb artists top --since "30 days ago" |
| 171 | + |
| 172 | +# All plays for a specific artist |
| 173 | +uv run scrobbledb plays list --artist "Radiohead" --limit 1000 |
| 174 | +``` |
| 175 | + |
| 176 | +### Export data for external analysis |
| 177 | + |
| 178 | +```bash |
| 179 | +# Export to CSV for Excel/pandas |
| 180 | +uv run scrobbledb export plays --format csv --output plays.csv |
| 181 | + |
| 182 | +# Custom SQL query |
| 183 | +uv run scrobbledb export --sql "SELECT artist_name, COUNT(*) as plays FROM plays GROUP BY artist_name" --format csv |
| 184 | +``` |
| 185 | + |
| 186 | +## Configuration |
| 187 | + |
| 188 | +scrobbledb follows the XDG Base Directory specification. By default, data is stored in: |
| 189 | + |
| 190 | +- **Linux/Unix**: `~/.local/share/dev.pirateninja.scrobbledb/` |
| 191 | +- **macOS**: `~/Library/Application Support/dev.pirateninja.scrobbledb/` |
| 192 | +- **Windows**: `%LOCALAPPDATA%\dev.pirateninja.scrobbledb\` |
| 193 | + |
| 194 | +You can override the database and auth file locations using command-line options: |
| 195 | + |
| 196 | +```bash |
| 197 | +uv run scrobbledb --database /path/to/custom.db ingest --auth /path/to/auth.json |
| 198 | +``` |
| 199 | + |
| 200 | +## Development |
| 201 | + |
| 202 | +scrobbledb uses modern Python development tools: |
| 203 | + |
| 204 | +- **uv** - Fast Python package manager |
| 205 | +- **ruff** - Fast Python linter and formatter |
| 206 | +- **pytest** - Testing framework |
| 207 | +- **poe** - Task runner for common development tasks |
| 208 | + |
| 209 | +```bash |
| 210 | +# Run tests |
| 211 | +poe test |
| 212 | + |
| 213 | +# Lint code |
| 214 | +poe lint |
| 215 | + |
| 216 | +# Type check |
| 217 | +poe type |
| 218 | + |
| 219 | +# Run all quality checks |
| 220 | +poe qa |
| 221 | +``` |
| 222 | + |
| 223 | +See [AGENTS.md](AGENTS.md) for detailed development guidelines. |
| 224 | + |
| 225 | +## Contributing |
| 226 | + |
| 227 | +Contributions are welcome! Please feel free to submit issues or pull requests. |
| 228 | + |
| 229 | +## License |
| 230 | + |
| 231 | +scrobbledb is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for the full license text. |
| 232 | + |
| 233 | +Original lastfm-to-sqlite project by Jacob Kaplan-Moss, also licensed under Apache License 2.0. |
| 234 | + |
| 235 | +## Links |
| 236 | + |
| 237 | +- **Repository**: https://github.com/crossjam/scrobbledb |
| 238 | +- **Original Project**: https://github.com/jacobian/lastfm-to-sqlite |
| 239 | +- **Last.fm API**: https://www.last.fm/api |
| 240 | +- **Libre.fm**: https://libre.fm/ |
0 commit comments