From cf7e7239dcdfd9cae31d959d1169ef835c9d38a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 19:45:52 +0000 Subject: [PATCH 1/4] Initial plan From 3b3cb5cddc5bc23ee9cfbda14e1c5baaeaab51b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 19:50:52 +0000 Subject: [PATCH 2/4] Update cog snippets in all doc files to use prog_name='scrobbledb' Co-authored-by: crossjam <208062+crossjam@users.noreply.github.com> --- docs/commands/albums.md | 6 +++--- docs/commands/artists.md | 8 ++++---- docs/commands/auth.md | 2 +- docs/commands/browse.md | 2 +- docs/commands/config.md | 8 ++++---- docs/commands/export.md | 2 +- docs/commands/import.md | 2 +- docs/commands/index.md | 2 +- docs/commands/ingest.md | 2 +- docs/commands/plays.md | 4 ++-- docs/commands/search.md | 2 +- docs/commands/sql.md | 26 +++++++++++++------------- docs/commands/stats.md | 8 ++++---- docs/commands/tracks.md | 8 ++++---- docs/commands/version.md | 2 +- 15 files changed, 42 insertions(+), 42 deletions(-) diff --git a/docs/commands/albums.md b/docs/commands/albums.md index 128bfa6..9d93b50 100644 --- a/docs/commands/albums.md +++ b/docs/commands/albums.md @@ -8,7 +8,7 @@ Album investigation commands. Search for albums and view detailed information ab from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["albums", "--help"]) +result = runner.invoke(cli, ["albums", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` @@ -34,7 +34,7 @@ Commands: Search for albums using fuzzy matching. Find albums by partial name when you don't remember exact titles. ``` @@ -72,7 +72,7 @@ Options: Display detailed information about a specific album and list its tracks with play statistics. ``` diff --git a/docs/commands/artists.md b/docs/commands/artists.md index 73af4b5..d066914 100644 --- a/docs/commands/artists.md +++ b/docs/commands/artists.md @@ -8,7 +8,7 @@ Artist investigation commands. Browse all artists, view top artists over differe from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["artists", "--help"]) +result = runner.invoke(cli, ["artists", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` @@ -35,7 +35,7 @@ Commands: List all artists in the database with play statistics. Supports sorting by play count, name, or recent activity. ``` @@ -78,7 +78,7 @@ Options: Show top artists with flexible time range support. Analyze listening patterns over different time periods with statistics including percentage of total plays and average plays per day. ``` @@ -121,7 +121,7 @@ Options: Display detailed information about a specific artist including top tracks and albums. ``` diff --git a/docs/commands/auth.md b/docs/commands/auth.md index 2bdc4d5..a2b4dba 100644 --- a/docs/commands/auth.md +++ b/docs/commands/auth.md @@ -8,7 +8,7 @@ Store credentials for Last.fm or Libre.fm. The command prompts for your username from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["auth", "--help"]) +result = runner.invoke(cli, ["auth", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` diff --git a/docs/commands/browse.md b/docs/commands/browse.md index d31b113..4fbce32 100644 --- a/docs/commands/browse.md +++ b/docs/commands/browse.md @@ -8,7 +8,7 @@ Launch an interactive Textual TUI to explore your library without typing search from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["browse", "--help"]) +result = runner.invoke(cli, ["browse", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` diff --git a/docs/commands/config.md b/docs/commands/config.md index 77c0c59..cb3bf4c 100644 --- a/docs/commands/config.md +++ b/docs/commands/config.md @@ -8,7 +8,7 @@ Initialize and manage the scrobbledb database, including optional FTS5 search se from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["config", "--help"]) +result = runner.invoke(cli, ["config", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` @@ -35,7 +35,7 @@ Commands: Create the data directory, initialize the database, and set up the FTS5 index unless `--no-index` is used. Use `--dry-run` to see what would be created without modifying disk. ``` @@ -60,7 +60,7 @@ Options: Drop and recreate the database, optionally skipping FTS5 with `--no-index`. Prompts for confirmation unless `--force`/`-f` is provided. ``` @@ -88,7 +88,7 @@ Options: Show the resolved data and config directories plus expected file paths. ``` diff --git a/docs/commands/export.md b/docs/commands/export.md index a3245be..3d56806 100644 --- a/docs/commands/export.md +++ b/docs/commands/export.md @@ -8,7 +8,7 @@ Run preset or custom queries against the database and write the results in JSONL from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["export", "--help"]) +result = runner.invoke(cli, ["export", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` diff --git a/docs/commands/import.md b/docs/commands/import.md index a155cba..fa64ef5 100644 --- a/docs/commands/import.md +++ b/docs/commands/import.md @@ -8,7 +8,7 @@ Load scrobbles from JSONL, CSV, or TSV files (or stdin) into the database. The c from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["import", "--help"]) +result = runner.invoke(cli, ["import", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` diff --git a/docs/commands/index.md b/docs/commands/index.md index 1b1114d..8dd9da0 100644 --- a/docs/commands/index.md +++ b/docs/commands/index.md @@ -8,7 +8,7 @@ Create or rebuild the FTS5 full-text search index. Use this after large imports from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["index", "--help"]) +result = runner.invoke(cli, ["index", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` diff --git a/docs/commands/ingest.md b/docs/commands/ingest.md index c706a6f..8d3e808 100644 --- a/docs/commands/ingest.md +++ b/docs/commands/ingest.md @@ -8,7 +8,7 @@ Fetch recent plays from Last.fm/Libre.fm using saved credentials and insert them from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["ingest", "--help"]) +result = runner.invoke(cli, ["ingest", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` diff --git a/docs/commands/plays.md b/docs/commands/plays.md index f32e2b6..7c6ec12 100644 --- a/docs/commands/plays.md +++ b/docs/commands/plays.md @@ -8,7 +8,7 @@ View and filter your listening history chronologically. The `plays` command grou from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["plays", "--help"]) +result = runner.invoke(cli, ["plays", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` @@ -32,7 +32,7 @@ Commands: List recent plays with filtering and pagination. Supports flexible date filtering using relative expressions like "7 days ago" or ISO 8601 dates. ``` diff --git a/docs/commands/search.md b/docs/commands/search.md index 5ab6da6..b4d0363 100644 --- a/docs/commands/search.md +++ b/docs/commands/search.md @@ -8,7 +8,7 @@ Full-text search across artists, albums, and track titles using the FTS5 index. from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["search", "--help"]) +result = runner.invoke(cli, ["search", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` diff --git a/docs/commands/sql.md b/docs/commands/sql.md index 17bf7e1..4052c6b 100644 --- a/docs/commands/sql.md +++ b/docs/commands/sql.md @@ -8,7 +8,7 @@ Read-only sqlite-utils commands against the scrobbledb database. Use these to in from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["sql", "--help"]) +result = runner.invoke(cli, ["sql", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` @@ -74,7 +74,7 @@ Commands: Execute SQL and return results as JSON. ``` @@ -114,7 +114,7 @@ Options: List database tables with optional counts and columns. ``` @@ -151,7 +151,7 @@ Options: Show the schema for the whole database or specific tables. ``` @@ -174,7 +174,7 @@ Options: List views in the database. ``` @@ -209,7 +209,7 @@ Options: Run full-text search against a table. ``` @@ -248,7 +248,7 @@ Options: Output a SQL dump of the schema and contents. ``` @@ -270,7 +270,7 @@ Options: Analyze columns in one or more tables. ``` @@ -299,7 +299,7 @@ Options: Execute SQL against an in-memory database created from CSV/TSV/JSON inputs. ``` @@ -348,7 +348,7 @@ Options: List installed sqlite-utils plugins. ``` @@ -369,7 +369,7 @@ Options: Show indexes for the whole database or specific tables. ``` @@ -403,7 +403,7 @@ Options: Output rows from a table with filtering options. ``` @@ -449,7 +449,7 @@ Options: Show triggers configured in the database. ``` diff --git a/docs/commands/stats.md b/docs/commands/stats.md index 7be7af7..5eba4ff 100644 --- a/docs/commands/stats.md +++ b/docs/commands/stats.md @@ -8,7 +8,7 @@ Summaries of your listening history. All subcommands default to the standard dat from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["stats", "--help"]) +result = runner.invoke(cli, ["stats", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` @@ -45,7 +45,7 @@ Commands: Totals for scrobbles, unique artists/albums/tracks, and the listen date range. ``` @@ -74,7 +74,7 @@ Options: Monthly play counts with optional relative or absolute date bounds and an optional limit on the number of months returned. ``` @@ -115,7 +115,7 @@ Options: Yearly play counts using the same filtering options as `monthly`. ``` diff --git a/docs/commands/tracks.md b/docs/commands/tracks.md index 115bd0f..1492af2 100644 --- a/docs/commands/tracks.md +++ b/docs/commands/tracks.md @@ -8,7 +8,7 @@ Track investigation commands. Search for tracks, view top tracks over time perio from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["tracks", "--help"]) +result = runner.invoke(cli, ["tracks", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` @@ -34,7 +34,7 @@ Commands: Search for tracks using fuzzy matching. Find tracks by partial title with optional artist and album filtering. ``` @@ -74,7 +74,7 @@ Options: Show top tracks with flexible time range support. Discover your most played tracks over various time periods with ranking and percentage statistics. ``` @@ -118,7 +118,7 @@ Options: Display detailed information about a specific track including play history and statistics. ``` diff --git a/docs/commands/version.md b/docs/commands/version.md index ae8a541..7eead45 100644 --- a/docs/commands/version.md +++ b/docs/commands/version.md @@ -8,7 +8,7 @@ Print the installed package version (also available via `-V/--version` on any co from click.testing import CliRunner from scrobbledb.cli import cli runner = CliRunner() -result = runner.invoke(cli, ["version", "--help"]) +result = runner.invoke(cli, ["version", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` From e33b809735bba5dfe4e641a85439f987429e8948 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 19:51:41 +0000 Subject: [PATCH 3/4] Regenerate docs with scrobbledb instead of cli Co-authored-by: crossjam <208062+crossjam@users.noreply.github.com> --- docs/commands/albums.md | 6 +++--- docs/commands/artists.md | 8 ++++---- docs/commands/auth.md | 2 +- docs/commands/browse.md | 2 +- docs/commands/config.md | 8 ++++---- docs/commands/export.md | 2 +- docs/commands/import.md | 2 +- docs/commands/index.md | 2 +- docs/commands/ingest.md | 2 +- docs/commands/plays.md | 4 ++-- docs/commands/search.md | 2 +- docs/commands/sql.md | 26 +++++++++++++------------- docs/commands/stats.md | 8 ++++---- docs/commands/tracks.md | 8 ++++---- docs/commands/version.md | 2 +- 15 files changed, 42 insertions(+), 42 deletions(-) diff --git a/docs/commands/albums.md b/docs/commands/albums.md index 9d93b50..c921140 100644 --- a/docs/commands/albums.md +++ b/docs/commands/albums.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["albums", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli albums [OPTIONS] COMMAND [ARGS]... +Usage: scrobbledb albums [OPTIONS] COMMAND [ARGS]... Album investigation commands. @@ -38,7 +38,7 @@ result = runner.invoke(cli, ["albums", "search", "--help"], prog_name='scrobbled cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli albums search [OPTIONS] QUERY +Usage: scrobbledb albums search [OPTIONS] QUERY Search for albums using fuzzy matching. @@ -76,7 +76,7 @@ result = runner.invoke(cli, ["albums", "show", "--help"], prog_name='scrobbledb' cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli albums show [OPTIONS] [ALBUM_TITLE] +Usage: scrobbledb albums show [OPTIONS] [ALBUM_TITLE] Display detailed information about a specific album and list its tracks. diff --git a/docs/commands/artists.md b/docs/commands/artists.md index d066914..d6e43e8 100644 --- a/docs/commands/artists.md +++ b/docs/commands/artists.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["artists", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli artists [OPTIONS] COMMAND [ARGS]... +Usage: scrobbledb artists [OPTIONS] COMMAND [ARGS]... Artist investigation commands. @@ -39,7 +39,7 @@ result = runner.invoke(cli, ["artists", "list", "--help"], prog_name='scrobbledb cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli artists list [OPTIONS] +Usage: scrobbledb artists list [OPTIONS] List all artists in the database with play statistics. @@ -82,7 +82,7 @@ result = runner.invoke(cli, ["artists", "top", "--help"], prog_name='scrobbledb' cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli artists top [OPTIONS] +Usage: scrobbledb artists top [OPTIONS] Show top artists with flexible time range support. @@ -125,7 +125,7 @@ result = runner.invoke(cli, ["artists", "show", "--help"], prog_name='scrobbledb cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli artists show [OPTIONS] [ARTIST_NAME] +Usage: scrobbledb artists show [OPTIONS] [ARTIST_NAME] Display detailed information about a specific artist. diff --git a/docs/commands/auth.md b/docs/commands/auth.md index a2b4dba..b0c8dee 100644 --- a/docs/commands/auth.md +++ b/docs/commands/auth.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["auth", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli auth [OPTIONS] +Usage: scrobbledb auth [OPTIONS] Save authentication credentials to a JSON file diff --git a/docs/commands/browse.md b/docs/commands/browse.md index 4fbce32..525d430 100644 --- a/docs/commands/browse.md +++ b/docs/commands/browse.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["browse", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli browse [OPTIONS] [DATABASE] +Usage: scrobbledb browse [OPTIONS] [DATABASE] Browse tracks in an interactive TUI. diff --git a/docs/commands/config.md b/docs/commands/config.md index cb3bf4c..bda2cd6 100644 --- a/docs/commands/config.md +++ b/docs/commands/config.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["config", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli config [OPTIONS] COMMAND [ARGS]... +Usage: scrobbledb config [OPTIONS] COMMAND [ARGS]... Configuration and database management commands. @@ -39,7 +39,7 @@ result = runner.invoke(cli, ["config", "init", "--help"], prog_name='scrobbledb' cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli config init [OPTIONS] +Usage: scrobbledb config init [OPTIONS] Initialize scrobbledb data directory and database. @@ -64,7 +64,7 @@ result = runner.invoke(cli, ["config", "reset", "--help"], prog_name='scrobbledb cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli config reset [OPTIONS] [DATABASE] +Usage: scrobbledb config reset [OPTIONS] [DATABASE] Reset the scrobbledb database. @@ -92,7 +92,7 @@ result = runner.invoke(cli, ["config", "location", "--help"], prog_name='scrobbl cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli config location [OPTIONS] +Usage: scrobbledb config location [OPTIONS] Display scrobbledb configuration and data directory locations. diff --git a/docs/commands/export.md b/docs/commands/export.md index 3d56806..f8848aa 100644 --- a/docs/commands/export.md +++ b/docs/commands/export.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["export", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli export [OPTIONS] [[plays|tracks|albums|artists]] +Usage: scrobbledb export [OPTIONS] [[plays|tracks|albums|artists]] Export scrobble data in various formats. diff --git a/docs/commands/import.md b/docs/commands/import.md index fa64ef5..c6aa8c5 100644 --- a/docs/commands/import.md +++ b/docs/commands/import.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["import", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli import [OPTIONS] [DATABASE] +Usage: scrobbledb import [OPTIONS] [DATABASE] Import scrobbles to the database from a file or stdin. diff --git a/docs/commands/index.md b/docs/commands/index.md index 8dd9da0..65958fb 100644 --- a/docs/commands/index.md +++ b/docs/commands/index.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["index", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli index [OPTIONS] [DATABASE] +Usage: scrobbledb index [OPTIONS] [DATABASE] Set up and rebuild FTS5 full-text search index. diff --git a/docs/commands/ingest.md b/docs/commands/ingest.md index 8d3e808..5e92da7 100644 --- a/docs/commands/ingest.md +++ b/docs/commands/ingest.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["ingest", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli ingest [OPTIONS] [DATABASE] +Usage: scrobbledb ingest [OPTIONS] [DATABASE] Ingest play history from last.fm/libre.fm to a SQLite database. diff --git a/docs/commands/plays.md b/docs/commands/plays.md index 7c6ec12..3f7a962 100644 --- a/docs/commands/plays.md +++ b/docs/commands/plays.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["plays", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli plays [OPTIONS] COMMAND [ARGS]... +Usage: scrobbledb plays [OPTIONS] COMMAND [ARGS]... Play history commands. @@ -36,7 +36,7 @@ result = runner.invoke(cli, ["plays", "list", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli plays list [OPTIONS] +Usage: scrobbledb plays list [OPTIONS] List recent plays with filtering and pagination. diff --git a/docs/commands/search.md b/docs/commands/search.md index b4d0363..34dd429 100644 --- a/docs/commands/search.md +++ b/docs/commands/search.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["search", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli search [OPTIONS] QUERY [DATABASE] +Usage: scrobbledb search [OPTIONS] QUERY [DATABASE] Search for tracks using full-text search. diff --git a/docs/commands/sql.md b/docs/commands/sql.md index 4052c6b..2f304d8 100644 --- a/docs/commands/sql.md +++ b/docs/commands/sql.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["sql", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql [OPTIONS] COMMAND [ARGS]... +Usage: scrobbledb sql [OPTIONS] COMMAND [ARGS]... SQLite database query and inspection commands. @@ -78,7 +78,7 @@ result = runner.invoke(cli, ["sql", "query", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql query [OPTIONS] SQL_QUERY +Usage: scrobbledb sql query [OPTIONS] SQL_QUERY Execute SQL query and return the results as JSON. @@ -118,7 +118,7 @@ result = runner.invoke(cli, ["sql", "tables", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql tables [OPTIONS] +Usage: scrobbledb sql tables [OPTIONS] List the tables in the database. @@ -155,7 +155,7 @@ result = runner.invoke(cli, ["sql", "schema", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql schema [OPTIONS] [TABLES]... +Usage: scrobbledb sql schema [OPTIONS] [TABLES]... Show full schema for this database or for specified tables. @@ -178,7 +178,7 @@ result = runner.invoke(cli, ["sql", "views", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql views [OPTIONS] +Usage: scrobbledb sql views [OPTIONS] List the views in the database. @@ -213,7 +213,7 @@ result = runner.invoke(cli, ["sql", "search", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql search [OPTIONS] DBTABLE Q +Usage: scrobbledb sql search [OPTIONS] DBTABLE Q Execute a full-text search against this table. @@ -252,7 +252,7 @@ result = runner.invoke(cli, ["sql", "dump", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql dump [OPTIONS] +Usage: scrobbledb sql dump [OPTIONS] Output a SQL dump of the schema and full contents of the database. @@ -274,7 +274,7 @@ result = runner.invoke(cli, ["sql", "analyze-tables", "--help"], prog_name='scro cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql analyze-tables [OPTIONS] [TABLES]... +Usage: scrobbledb sql analyze-tables [OPTIONS] [TABLES]... Analyze the columns in one or more tables. @@ -303,7 +303,7 @@ result = runner.invoke(cli, ["sql", "memory", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql memory [OPTIONS] [PATHS]... SQL_QUERY +Usage: scrobbledb sql memory [OPTIONS] [PATHS]... SQL_QUERY Execute SQL query against an in-memory database, optionally populated by imported data. @@ -352,7 +352,7 @@ result = runner.invoke(cli, ["sql", "plugins", "--help"], prog_name='scrobbledb' cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql plugins [OPTIONS] +Usage: scrobbledb sql plugins [OPTIONS] List installed sqlite-utils plugins. @@ -373,7 +373,7 @@ result = runner.invoke(cli, ["sql", "indexes", "--help"], prog_name='scrobbledb' cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql indexes [OPTIONS] [TABLES]... +Usage: scrobbledb sql indexes [OPTIONS] [TABLES]... Show indexes for the whole database or specific tables. @@ -407,7 +407,7 @@ result = runner.invoke(cli, ["sql", "rows", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql rows [OPTIONS] TABLE_NAME +Usage: scrobbledb sql rows [OPTIONS] TABLE_NAME Output all rows in the specified table. @@ -453,7 +453,7 @@ result = runner.invoke(cli, ["sql", "triggers", "--help"], prog_name='scrobbledb cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli sql triggers [OPTIONS] [TABLES]... +Usage: scrobbledb sql triggers [OPTIONS] [TABLES]... Show triggers configured in this database. diff --git a/docs/commands/stats.md b/docs/commands/stats.md index 5eba4ff..b049cae 100644 --- a/docs/commands/stats.md +++ b/docs/commands/stats.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["stats", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli stats [OPTIONS] COMMAND [ARGS]... +Usage: scrobbledb stats [OPTIONS] COMMAND [ARGS]... Descriptive statistics about your scrobbles. @@ -49,7 +49,7 @@ result = runner.invoke(cli, ["stats", "overview", "--help"], prog_name='scrobble cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli stats overview [OPTIONS] +Usage: scrobbledb stats overview [OPTIONS] Display overall scrobble statistics. @@ -78,7 +78,7 @@ result = runner.invoke(cli, ["stats", "monthly", "--help"], prog_name='scrobbled cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli stats monthly [OPTIONS] +Usage: scrobbledb stats monthly [OPTIONS] Display scrobble statistics rolled up by month. @@ -119,7 +119,7 @@ result = runner.invoke(cli, ["stats", "yearly", "--help"], prog_name='scrobbledb cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli stats yearly [OPTIONS] +Usage: scrobbledb stats yearly [OPTIONS] Display scrobble statistics rolled up by year. diff --git a/docs/commands/tracks.md b/docs/commands/tracks.md index 1492af2..1aa001f 100644 --- a/docs/commands/tracks.md +++ b/docs/commands/tracks.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["tracks", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli tracks [OPTIONS] COMMAND [ARGS]... +Usage: scrobbledb tracks [OPTIONS] COMMAND [ARGS]... Track investigation commands. @@ -38,7 +38,7 @@ result = runner.invoke(cli, ["tracks", "search", "--help"], prog_name='scrobbled cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli tracks search [OPTIONS] QUERY +Usage: scrobbledb tracks search [OPTIONS] QUERY Search for tracks using fuzzy matching. @@ -78,7 +78,7 @@ result = runner.invoke(cli, ["tracks", "top", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli tracks top [OPTIONS] +Usage: scrobbledb tracks top [OPTIONS] Show top tracks with flexible time range support. @@ -122,7 +122,7 @@ result = runner.invoke(cli, ["tracks", "show", "--help"], prog_name='scrobbledb' cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli tracks show [OPTIONS] [TRACK_TITLE] +Usage: scrobbledb tracks show [OPTIONS] [TRACK_TITLE] Display detailed information about a specific track. diff --git a/docs/commands/version.md b/docs/commands/version.md index 7eead45..e34f5e9 100644 --- a/docs/commands/version.md +++ b/docs/commands/version.md @@ -12,7 +12,7 @@ result = runner.invoke(cli, ["version", "--help"], prog_name='scrobbledb') cog.out("```\n" + result.output + "```") ]]] --> ``` -Usage: cli version [OPTIONS] +Usage: scrobbledb version [OPTIONS] Display the scrobbledb version. From 1a4e13f129049c65fe874df6a892dd1cc69b295c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 Jan 2026 22:57:47 +0000 Subject: [PATCH 4/4] Rewrite README.md with comprehensive overview and documentation Co-authored-by: crossjam <208062+crossjam@users.noreply.github.com> --- README.md | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 232 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1cd3127..842a423 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,239 @@ [![QA](https://github.com/crossjam/scrobbledb/actions/workflows/qa.yml/badge.svg)](https://github.com/crossjam/scrobbledb/actions/workflows/qa.yml) -A modernization of [Jacob Kaplan-Moss’s](https://github.com/jacobian/) -project -[lastfm-to-sqlite](https://github.com/jacobian/lastfm-to-sqlite). +**Save your listening history from Last.fm or Libre.fm to a local SQLite database.** -Uses the [pylast](https://github.com/pylast/pylast) module underneath -the covers. +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. -## Documentation +## About Last.fm and Scrobbling -See [docs/cli.md](docs/cli.md) for an overview of the -`scrobbledb` command line interface and links to per-command reference -pages in `docs/commands/`. +[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." +**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. + +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. + +## Why scrobbledb? + +- **Local backup**: Keep your listening history in a local database you control +- **Advanced queries**: Use SQL to analyze your music habits in ways the web interface doesn't support +- **Data portability**: Export your data in multiple formats (JSON, CSV, TSV) +- **Full-text search**: Find tracks, albums, and artists instantly with SQLite FTS5 +- **Interactive browsing**: Explore your library with a terminal UI +- **Privacy**: Your data stays on your machine + +## Origin + +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: + +- Modern Python tooling (uv, ruff, type hints) +- Domain-specific commands for exploring artists, albums, tracks, and plays +- Interactive terminal UI for browsing +- Full-text search capabilities +- Comprehensive data export options +- Enhanced statistics and filtering +- Rich terminal output with tables and progress bars + +Original concept and implementation by Jacob Kaplan-Moss. Current development by Brian M. Dennis. + +## Installation + +scrobbledb requires Python 3.11 or later and uses [uv](https://github.com/astral-sh/uv) for dependency management. + +```bash +# Clone the repository +git clone https://github.com/crossjam/scrobbledb.git +cd scrobbledb + +# Install dependencies +uv sync + +# Run scrobbledb +uv run scrobbledb --help +``` + +## Quick Start + +### 1. Save your Last.fm credentials + +```bash +uv run scrobbledb auth +``` + +This prompts for your Last.fm username, API key, shared secret, and password, then saves them in `~/.local/share/dev.pirateninja.scrobbledb/auth.json`. + +**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. + +### 2. Initialize the database + +```bash +uv run scrobbledb config init +``` + +This creates the SQLite database and sets up the full-text search index. + +### 3. Import your listening history + +```bash +uv run scrobbledb ingest +``` + +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. + +### 4. Explore your data + +```bash +# Search for tracks +uv run scrobbledb search "pink floyd" + +# View recent plays +uv run scrobbledb plays list --limit 50 + +# Browse interactively +uv run scrobbledb browse + +# See your top artists +uv run scrobbledb artists top --limit 20 + +# View statistics +uv run scrobbledb stats overview +``` + +## Command Overview + +scrobbledb provides a comprehensive set of commands for managing and exploring your music data: + +### Data Management + +- **`auth`** - Configure Last.fm/Libre.fm API credentials ([docs](docs/commands/auth.md)) +- **`config`** - Initialize database, reset data, or show configuration paths ([docs](docs/commands/config.md)) +- **`ingest`** - Fetch listening history from Last.fm/Libre.fm ([docs](docs/commands/ingest.md)) +- **`import`** - Import scrobbles from JSONL, CSV, or TSV files ([docs](docs/commands/import.md)) +- **`index`** - Create or rebuild the full-text search index ([docs](docs/commands/index.md)) +- **`export`** - Export data in various formats with presets or custom SQL ([docs](docs/commands/export.md)) + +### Data Exploration + +- **`search`** - Full-text search across artists, albums, and tracks ([docs](docs/commands/search.md)) +- **`browse`** - Interactive terminal UI for browsing tracks ([docs](docs/commands/browse.md)) +- **`plays`** - View and filter listening history chronologically ([docs](docs/commands/plays.md)) +- **`artists`** - Browse artists, view top artists, see detailed statistics ([docs](docs/commands/artists.md)) +- **`albums`** - Search albums and view album details with tracks ([docs](docs/commands/albums.md)) +- **`tracks`** - Search tracks, view top tracks, see play history ([docs](docs/commands/tracks.md)) +- **`stats`** - Generate listening statistics (overview, monthly, yearly) ([docs](docs/commands/stats.md)) + +### Advanced + +- **`sql`** - Direct access to sqlite-utils commands for power users ([docs](docs/commands/sql.md)) +- **`version`** - Display the installed version ([docs](docs/commands/version.md)) + +See the [CLI overview](docs/cli.md) for a complete command reference and detailed documentation for each command. + +## Database Schema + +scrobbledb stores your data in a normalized SQLite database: + +- **`artists`** - Artist information (id, name) +- **`albums`** - Album information (id, title, artist_id) +- **`tracks`** - Track information (id, title, album_id) +- **`plays`** - Play events (track_id, timestamp) +- **`tracks_fts`** - FTS5 full-text search index + +This schema enables efficient queries, comprehensive searches, and detailed analysis of your listening history. + +## Example Workflows + +### Backup your data weekly + +```bash +# Update with new scrobbles +uv run scrobbledb ingest --since-date "7 days ago" + +# Export to JSON backup +uv run scrobbledb export plays --format json --output backup-$(date +%Y%m%d).json +``` + +### Find your most-played tracks from a specific year + +```bash +uv run scrobbledb tracks top --since 2023-01-01 --until 2023-12-31 --limit 50 +``` + +### Analyze your listening patterns + +```bash +# Monthly breakdown +uv run scrobbledb stats monthly --year 2024 + +# Top artists in the last 30 days +uv run scrobbledb artists top --since "30 days ago" + +# All plays for a specific artist +uv run scrobbledb plays list --artist "Radiohead" --limit 1000 +``` + +### Export data for external analysis + +```bash +# Export to CSV for Excel/pandas +uv run scrobbledb export plays --format csv --output plays.csv + +# Custom SQL query +uv run scrobbledb export --sql "SELECT artist_name, COUNT(*) as plays FROM plays GROUP BY artist_name" --format csv +``` + +## Configuration + +scrobbledb follows the XDG Base Directory specification. By default, data is stored in: + +- **Linux/Unix**: `~/.local/share/dev.pirateninja.scrobbledb/` +- **macOS**: `~/Library/Application Support/dev.pirateninja.scrobbledb/` +- **Windows**: `%LOCALAPPDATA%\dev.pirateninja.scrobbledb\` + +You can override the database and auth file locations using command-line options: + +```bash +uv run scrobbledb --database /path/to/custom.db ingest --auth /path/to/auth.json +``` + +## Development + +scrobbledb uses modern Python development tools: + +- **uv** - Fast Python package manager +- **ruff** - Fast Python linter and formatter +- **pytest** - Testing framework +- **poe** - Task runner for common development tasks + +```bash +# Run tests +poe test + +# Lint code +poe lint + +# Type check +poe type + +# Run all quality checks +poe qa +``` + +See [AGENTS.md](AGENTS.md) for detailed development guidelines. + +## Contributing + +Contributions are welcome! Please feel free to submit issues or pull requests. + +## License + +scrobbledb is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for the full license text. + +Original lastfm-to-sqlite project by Jacob Kaplan-Moss, also licensed under Apache License 2.0. + +## Links + +- **Repository**: https://github.com/crossjam/scrobbledb +- **Original Project**: https://github.com/jacobian/lastfm-to-sqlite +- **Last.fm API**: https://www.last.fm/api +- **Libre.fm**: https://libre.fm/