Skip to main content

bandcamp-plex-sync

bandcamp-plex-sync helps keep a purchased Bandcamp collection in sync with a local Plex music library.

It can:

  • Fetch your Bandcamp fan collection.
  • Incrementally scan a Plex-style local music tree such as /nas/music.
  • Cache scanned tags in SQLite so unchanged audio files are not reopened each run.
  • Report albums/tracks that appear to be missing locally.
  • Download missing purchased FLAC files from Bandcamp.
  • Extract Bandcamp album ZIPs into Plex-friendly Artist/Album/ directories.

The tool is intentionally conservative: it never deletes existing music and it dry-runs downloads unless you pass --yes.

Requirements

  • Linux/macOS with Python 3.11+
  • uv installed
  • A browser where you are logged in to Bandcamp
  • A local Plex music directory, defaulting to /nas/music

Bandcamp purchased FLAC downloads require authentication. The tool reads Bandcamp cookies from your browser with browser-cookie3; no Bandcamp password is stored by this tool.

Installation

Install the published command with uv:

uv tool install bandcamp-plex-sync
bandcamp-plex-sync --help

To run from a source checkout:

git clone git@github.com:feoh/bandcamp-plex-sync.git
cd bandcamp-plex-sync
uv sync
uv run bandcamp-plex-sync --help

The checkout also retains a development wrapper with inline uv dependency metadata:

./bin/bandcamp-plex-sync --help

Quick start

Fetch your Bandcamp collection, incrementally scan the local library, and download missing purchased music in one command:

bandcamp-plex-sync sync --user YOUR_BANDCAMP_USERNAME --yes

After the first run, the saved report supplies the username, so repeat runs are:

bandcamp-plex-sync sync --yes

By default, files are written under /nas/music.

Commands

sync

Every invocation fetches the current Bandcamp collection, incrementally scans the destination music library, compares the two, and writes fresh reports. It downloads missing purchased items when --yes is provided; without --yes, it is a dry run.

Outputs are stored under ~/.cache/bandcamp-plex-sync/:

bandcamp-collection.json   # fetched Bandcamp collection metadata
local-scan.json            # scanned local audio metadata and incremental scan stats
music-scan.sqlite3         # persistent file signatures and cached tag metadata
sync-report.json           # machine-readable comparison and download progress
sync-report.md             # human-readable report
missing-urls.txt           # Bandcamp item pages for missing items
missing.csv                # spreadsheet-friendly missing item list

The local tree is still walked to detect additions, changes, and deletions, but unchanged audio tags come from music-scan.sqlite3 rather than being reread from every music file. Only new or changed files require metadata parsing after the initial scan.

FLAC is the default:

bandcamp-plex-sync sync --download-format flac --yes

Safety/testing options:

# Dry run; shows what would download
bandcamp-plex-sync sync

# Test with one item
bandcamp-plex-sync sync --limit 1 --yes

# Write somewhere other than /nas/music
bandcamp-plex-sync sync --destination ./downloads --yes

# Keep Bandcamp ZIP archives after extraction
bandcamp-plex-sync sync --keep-archives --yes

# Replace existing files
bandcamp-plex-sync sync --overwrite --yes

Downloaded album ZIPs are extracted into:

/nas/music/Artist/Album/

Single-track FLAC downloads are written similarly:

/nas/music/Artist/Track Title/Artist - Track Title.flac

After every successfully downloaded or verified item, sync immediately moves that item from missing to completed in sync-report.json, records its file paths, and updates the Markdown, URL, and CSV reports. Interrupted runs therefore resume with only unfinished items. The next invocation starts with another fresh, incremental comparison, so files downloaded earlier are recognized locally before Bandcamp download pages are opened.

auth-check

Verify that one of the supported browser profiles is logged in to the account that owns the requested collection and that Bandcamp exposes protected download URLs:

bandcamp-plex-sync auth-check USER

This is a diagnostic check only. It does not create a persistent login or store browser cookies.

Incremental scanning

The first sync run reads tags from every audio file and records the file size, nanosecond modification/change times, device, and inode in ~/.cache/bandcamp-plex-sync/music-scan.sqlite3. Later runs still walk the filesystem to detect additions, modifications, renames, and deletions, but reuse cached tags for unchanged files instead of opening and parsing every audio file.

# Put the checkpoint database somewhere else
bandcamp-plex-sync sync --checkpoint-db /path/to/music-checkpoints.sqlite3 --yes

# Ignore cached signatures and refresh every track's metadata
bandcamp-plex-sync sync --rescan-all --yes

Authentication and browser cookies

sync uses browser authentication by default because Bandcamp's purchased-download pages are protected. Authentication is command-scoped; no login session is persisted between invocations.

Use auth-check USER to diagnose authentication independently before running sync.

Every discovered profile in each supported browser is checked, rather than only the browser's default profile. The tool verifies that the selected session owns the requested Bandcamp collection before accepting its cookies; this prevents an anonymous or wrong-profile session from silently producing empty download URLs.

Supported browser cookie stores are tried in this order:

  1. Firefox
  2. LibreWolf
  3. Chrome
  4. Chromium
  5. Brave
  6. Vivaldi
  7. Edge
  8. Opera

If cookies fail to load:

  • Make sure you are logged in to Bandcamp in one of those browsers.
  • Close the browser if its cookie database is locked.
  • Try running the command from the same desktop user account as the browser.
  • Confirm the collection username is owned by the logged-in Bandcamp account.

Bandcamp subscription collection entries are not individually downloadable. Their album and track releases appear as separate downloadable collection items.

Matching behavior

sync compares normalized artist, album, and track metadata. It uses local audio tags when present and falls back to Plex-style paths:

Artist/Album/Track.ext

The report distinguishes:

  • matched: confident local match
  • possible: fuzzy match worth reviewing
  • missing: no good local match found

You can tune fuzzy matching with:

bandcamp-plex-sync sync --threshold 0.90 --yes

Higher thresholds produce fewer possible matches.

Privacy and safety

  • The tool does not store your Bandcamp password.
  • Authenticated Bandcamp redownload URLs are saved in bandcamp-collection.json and sync-report.json; treat these files as private.
  • Existing music is skipped by default.
  • The local SQLite checkpoint database contains file paths and music tags, but no Bandcamp credentials or browser cookies.
  • Nothing is downloaded unless sync --yes is used.
  • Nothing is deleted from your Plex library.

Development

uv sync
uv run python -m compileall -q src tests
uv run pre-commit run --all-files
uv run mypy src/bandcamp_plex_sync
uv run python -m unittest discover -s tests -v
uv build

License

MIT

Metadata

Release files for bandcamp-plex-sync 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bandcamp-plex-sync 1.0.0
File Size Uploaded Provenance
bandcamp_plex_sync-1.0.0.tar.gz 66.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bandcamp-plex-sync 1.0.0
File Interpreter ABI Platform
bandcamp_plex_sync-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 84.8 kB

Release files / bandcamp_plex_sync-1.0.0.tar.gz

Download URL bandcamp_plex_sync-1.0.0.tar.gz
Size 66.0 kB
Tags Source
SHA-256 checksum
How to use checksums
5022aa7916915e4ad16b5992e76fb448d52b41dc591fb607ceea1df03a373585
BLAKE2b-256 checksum
How to use checksums
aa765c877665f0d47597794d4feb00a870a62de40114cbf8ec8260b122d27488
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.

Transparency log

Release files / bandcamp_plex_sync-1.0.0-py3-none-any.whl

Download URL bandcamp_plex_sync-1.0.0-py3-none-any.whl
Size 18.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1c624b9313f0f02065b48b873215f457f8e20692560c2dc3671d6b5792213b0a
BLAKE2b-256 checksum
How to use checksums
e19eec9788e09b9fdead5b09053cbfdfd29679e82aff25d085d6c20d3245353c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.

Transparency log

Security for bandcamp-plex-sync 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for bandcamp_plex_sync-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page