Skip to content

core

opinionated multi-step workflows stitching the other packages together.

core download-songs

download → beets import → playlists refresh, in one pass.

core download-songs "<spotify-url>"                     # dry run by default
core download-songs "<spotify-url>" --apply
core download-songs path/to/urls.txt --apply
core download-songs --apply --only download --only import   # repeatable, runs in fixed order regardless

options:

  • --apply - do it for real (default: dry run)
  • --archive-path - crate root override (default archive_path)
  • -i, --input - staging drop for downloads (default <crate>/unorganized)
  • --only - run only this step (repeatable: download, import, playlists); default all three, in order
  • --format (default mp3), --bitrate (default 320k)
  • --verbose - forwarded to each step (maps to spotdl/yt-dlp's --debug for the download step)

dry run doesn't skip the steps - each one runs for real in its own no-op mode instead.

core sync

rescrape spotify + rebuild every (or named) playlist's .m3u8. the playlists --apply --rescrape flow, promoted to its own command.

core sync
core sync -p "<playlist-name-or-id>"       # repeatable
core sync --covers                          # also download each playlist's cover art

options:

  • -p, --playlist - sync a specific playlist by name or spotify id (repeatable; default: all owned)
  • --covers - download each playlist cover to <name>.jpg
  • --verbose - print every match decision
  • --playlists-path, --archive-path, --exports-dir - path overrides

no dry-run mode - a sync's whole point is writing the refreshed .m3u8s.

core process-unmatched

refresh playlists → download missing tracks → import → sync playlists, in one pass. ideal for processing unmatched tracks generated by playlist refresh and synchronizing playlists with the updated library.

core process-unmatched                                          # dry run by default
core process-unmatched --apply
core process-unmatched --archive-path <crate>
core process-unmatched --service spotify --exclude "_orc"
core process-unmatched --apply --format flac --bitrate 1000k

options:

  • --apply - do it for real (default: dry run)
  • --archive-path - crate root override (default: archive_path)
  • --playlists-path - playlists directory override
  • --exports-dir - exports directory override
  • --service - service to process (spotify or soundcloud, default: spotify)
  • --exclude - skip a specific playlist by name or id (repeatable)
  • --format (default mp3), --bitrate (default 320k)
  • --cookies-file - netscape format cookie file for spotify download
  • --pre-skip-existing - skip downloading existing files (default: true)
  • --retries (default 0) - number of download retries
  • --verbose - verbose output

workflow steps:

  1. refresh playlists: rescrapes spotify data and rebuilds local .m3u8s with --reindex to generate fresh unmatched.csv
  2. download: downloads tracks listed in the unmatched csv to <crate>/unorganized
  3. import: imports the downloaded files into the library crate via beets
  4. sync playlists: rebuilds local .m3u8s from the updated library (no rescrape)

each step runs in its own no-op mode during dry-run.