{"id":17974707,"url":"https://github.com/meeb/bandcampsync","last_synced_at":"2026-01-16T23:26:10.890Z","repository":{"id":195273193,"uuid":"647107004","full_name":"meeb/bandcampsync","owner":"meeb","description":"Downloads your Bandcamp purchases automatically","archived":false,"fork":false,"pushed_at":"2026-01-15T04:48:42.000Z","size":324,"stargazers_count":283,"open_issues_count":4,"forks_count":19,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-15T11:44:46.851Z","etag":null,"topics":["bandcamp","bandcampsync","music","selfhosted"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meeb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["meeb"]}},"created_at":"2023-05-30T04:37:08.000Z","updated_at":"2026-01-15T09:05:26.000Z","dependencies_parsed_at":"2023-10-26T06:29:26.931Z","dependency_job_id":"569ac8b6-6f65-4942-92da-d7028606b34d","html_url":"https://github.com/meeb/bandcampsync","commit_stats":null,"previous_names":["meeb/bandcampsync"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/meeb/bandcampsync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fbandcampsync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fbandcampsync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fbandcampsync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fbandcampsync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meeb","download_url":"https://codeload.github.com/meeb/bandcampsync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fbandcampsync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28487586,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T22:54:02.790Z","status":"ssl_error","status_checked_at":"2026-01-16T22:50:10.344Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bandcamp","bandcampsync","music","selfhosted"],"created_at":"2024-10-29T17:15:11.793Z","updated_at":"2026-01-16T23:26:10.877Z","avatar_url":"https://github.com/meeb.png","language":"Python","funding_links":["https://github.com/sponsors/meeb"],"categories":[],"sub_categories":[],"readme":"# BandcampSync\n\nBandcampSync is a Python module and command line script (also packed in\na Docker container) which synchronises media purchased on a Bandcamp\n(https://bandcamp.com/) account with a local directory.\n\nYou may use this to download media you have purchased from Bandcamp to a\nlocal media server, such as Plex or Jellyfin.\n\nMost media items purchased on Bandcamp have high quality download options\navailable and BandcampSync defaults to `flac`.\n\nWhen called, `bandcampsync` will:\n\n1. Authenticate to bandcamp.com as you using your exported session cookies\n2. Scan your local media directory for existing downloaded items\n3. Index a list of all of your purchased items in your Bandcamp collection\n4. Download the archive of missing items not downloaded already from your collection\n5. Unzip the archive and move the contents to the local media directory\n\nThe media directory will have the following format:\n\n```\n/media/\n/media/Artist Name\n/media/Artist Name/Album Name\n/media/Artist Name/Album Name/bandcamp_item_id.txt (if no ignores file provided)\n/media/Artist Name/Album Name/cover.jpg\n/media/Artist Name/Album Name/Track Name.flac\n```\n\nThe directory format of `artist_name`/`item_title` is not editable.\n\n`bandcamp_item_id.txt` is a special file created in each item directory and\nit contains the Bandcamp item ID as an integer. This file is used by BandcampSync\nto track which media items have already been downloaded, when an ignores file is\nnot being used. You can rename the artist or album directories, but do not delete\nthe `bandcamp_item_id.txt` file or the media item will be redownloaded the next\ntime `bandcampsync` is run.\n\nThe `bandcamp_item_id.txt` file method of tracking what items are synchronised\nalso means you can also use media managers such as Lidarr to rename artist,\nalbum and track names automatically without issues.\n\n\n## Installation\n\n`bandcampsync` is pure Python and only has a dependancy on the `requests` and\n`beautifulsoup4` libraries. You can install `bandcampsync` via pip:\n\n```bash\n$ pip install bandcampsync\n```\n\nAny modern version of Python3 will be compatible.\n\nAlternatively, there's a batteries included Docker image available if you prefer.\n\n\n## Docker\n\nThe Docker image contains the `bandcampsync` Python module as well as a helper\nscript that runs the `bandcampsync` on a timer. Configuration variables are also\nmoved to environment variables\n\nYou can pull and run the image with the following commands:\n\n```bash\n# Pull image\n$ docker pull ghcr.io/meeb/bandcampsync:latest\n# Start the container using your user ID and group ID\n$ docker run \\\n  -d \\\n  --name bandcampsync \\\n  -e TZ=Europe/London \\\n  -e PUID=1000 \\\n  -e PGID=1000 \\\n  -e RUN_DAILY_AT=3 \\\n  -v /some/directory/bandcampsync-config:/config \\\n  -v /some/directory/bandcampsync-media:/downloads \\\n  ghcr.io/meeb/bandcampsync:latest\n\n```\n\nOr an example Docker Compose entry:\n\n```bash\nversion: '3.7'\nservices:\n  bandcampsync:\n    image: ghcr.io/meeb/bandcampsync:latest\n    container_name: bandcampsync\n    restart: unless-stopped\n    volumes:\n      - /some/directory/bandcampsync-config:/config\n      - /some/directory/bandcampsync-media:/downloads\n    environment:\n      - TZ=Europe/London\n      - PUID=1000\n      - PGID=1000\n      - RUN_DAILY_AT=3\n```\n\nIn the above example you would save your cookies data into a file called\n`cookies.txt` and save it at `/some/directory/bandcampsync-config/cookies.txt`.\nBandcampSync will look for this location when it starts up.\n\nIn the `config` directory you will find an `ignores.txt` file. You may edit the\nfile to specify which items not to download. The downloader automatically\nappends ids of the downloaded items during each run. The format is one bandcamp\nid per line (same as `bandcamp_item_id.txt` files), optionally followed by a\ncomment that starts with `#`. For example:\n\n```\n1546934218  # Chrome Sparks / Sparks EP\n1418240212  # Chrome Sparks / Goddess EP\n```\n\nThe `RUN_DAILY_AT` environment variable is the hour the `bandcampsync` script\nwill run at. In this example, 3am local time. After running the container will\nsleep until the following 3am. It will run daily. There is also a randomised\ndelay added to the hour to not dogpile bandcamp.com with requests on the hour \nso the script won't run exactly on the hour.\n\n`RUN_DAILY_AT` should be a number between 0 and 23 (specifying an hour).\n\n`PUID` and `PGID` are the user and group IDs to attempt run the download as.\nThis sets the UID and GID of the files that are downloaded.\n\n`TEMP_DIR` variable can be set to a directory in the container. If set the\ndirectory is used as the temporary download location.\n\n`IGNORE` can be set to ignore bands, same as the `--ignore` CLI argument.\n\n`NOTIFY_URL` can be set to a URL to send an HTTP GET request to when new\nitems have been loaded, same as the `--notify-url` CLI argument.\n\n`MAX_RETRIES` can be set to the maximum number of download retry attempts, defaults to `3`.\n\n`RETRY_WAIT` can be set to the number of seconds to wait between download retries, defaults to `5`.\n\n`CONCURRENCY` can be set to the number of concurrent downloads, defaults to `1`.\n\n\n## Configuration\n\nBandcampSync requires minimial configuration. First, it requires your session\ncookies from an authenticated Bandcamp account. The easiest way to get this is\nto go to https://bandcamp.com/ in your browser and log in with your account.\n\nNext, open the developer tools in your browser (F12 button on most browsers, or\nselect \"developer tools\" from the options menu).\n\nReload the index page and find the index page request in your network requests\ntab of your browser. Go to the \"Request Headers\" section then select and copy\nthe string after the `Cookie` header. The string should look something like this:\n\n```\nclient_id=00B1F3C8EB48E181A185CCD041E40C0E8F; session=1%0893C88%570EE405455%%8DEC37B5BC393983DB983DD%%BDFD46C3B8A0%%580DA466D5CD; identity=1%HhehuehUFEUiuebn%%2ADB72300DAE573%BEEF389A1B526EA35AC38019FA0A6F%11B4BD5FBC18B83F720; js_logged_in=1; logout=%7B%22username%22%3A%22someuser%22%7D; download_encoding=401; BACKENDID3=some-sever-name\n```\n\nSave this string to a file called `cookies.txt`.\n\n![Getting your session cookues](https://github.com/meeb/bandcampsync/blob/main/docs/cookies.jpg?raw=true)\n\nYou need to save your session ID from cookies manually because Bandcamp has\na captcha on the login form so BandcampSync can't log in with your username\nand password for you.\n\nIMPORTANT NOTE: Keep the `cookies.txt` file safe! Anyone with access to this file\ncan log into your Bandcamp account, impersonate you, potentially make purchases\nand generally have total access to your Bandcamp account!\n\nYou can also use Netscape formatted cookie export files if you have exported your\ncookies using a cookie exporter plugin or similar tool.\n\n\n## CLI usage\n\nOnce you have the Python `bandcampsync` module installed you can call it with the\n`bandcampsync` command:\n\n```bash\n$ bandcampsync --cookies cookies.txt --directory /path/to/music\n```\n\nor in shorthand:\n\n```bash\n$ bandcampsync -c cookies.txt -d /path/to/music\n```\n\nYou can use `-t` or `--temp-dir` to set the temporary download directory used.\nYou can use `-i` or `--ignore` to bypass artists that have data issues that\nyour OS can not handle.\n\nSee `-h` or `--help` for the full list of command line options.\n\n```bash\n$ bandcampsync --cookies cookies.txt --directory /path/to/music --ignore \"badband\"\n```\n\n`--ignore` supports multiple strings space seperated strings, for example\n`--ignore \"band1 band2 band3\"`.\n\n\nYou can use `-I` or `--ignore-file` to specify the path to a file containing\nbandcamp ids of each item to skip (see above).\n\nIf you do, the items downloaded will be appended to the file, so that the next\ntime you run the script those items will not be re-downloaded.\nThis means you can use media managers such as Lidarr to rename artist, album\nand track names automatically, rename the directory, or even move the items out\nof the download directory without issues.\n\n\nYou can notify an an external HTTP server when new items have been loaded with `-n` or\n`--notify-url`.\n\nYou can set the maximum number of download retry attempts with `--max-retries` (defaults to `3`) and the number of seconds to wait between retries with `--retry-wait` (defaults to `5`).\n\nYou can set the number of concurrent downloads with `-j` or `--concurrency` (defaults to `1`).\n\n```bash\n$ bandcampsync ... --notify-url \"http://some.service.local/some-uri\"\n```\n\nYou can use this to call a \"refresh\" hook on media servers (for example rescan a Plex\nor Jellyfin library). The `--notify-url` parameter, if set, simply makes an HTTP GET\nrequest to the specified URL and confirms it returns a `2XX` response.\n\nFor advanced notify URLs you can use the following `--notify-url` format:\n\n`method url headers body`\n\n`method` must be one of `GET` or `POST`. `url` is any URL. `headers` are a comma\nseparated list of `key=value` pairs and `body` is an body string to send if the `method`\nis `POST`. You can use `-` for header and body values to leave them unset. Some examples:\n\n`GET http://some.service.local/some-uri - -`\n\n`GET http://some.service.local/some-uri header1=abc,header2 -`\n\n`POST http://some.service.local/some-uri auth-header=abc somedata`\n\n\n## Formats\n\nBy default, BandcampSync will download your music in the `flac` format. You can specify\nanother format with the `--format` argument. Common Bandcamp download formats are:\n\n| Name            | Description                                                     |\n| --------------- | --------------------------------------------------------------- |\n| `mp3-v0`        | Variable bitrate MP3. Small file sizes. OK quality.             |\n| `mp3-320`       | High quality MP3. Medium file sizes. Good quality.              |\n| `flac`          | Lossless audio. Large file sizes. Original Quality.             |\n| `aac-hi`        | Apple variable bitrate format. Small file sizes. OK quality.    |\n| `aiff-lossless` | Uncompressed audio format. Biggest file size. Original quality. |\n| `vorbis`        | Open source lossy format. Small file sizes. OK quality.         |\n| `alac`          | Apple lossless format. Large file sizes. Original quality.      |\n| `wav`           | Uncompressed audio format. Biggest file size. Original quality. |\n\n\n# Contributing\n\nAll properly formatted and sensible pull requests, issues and comments are welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeeb%2Fbandcampsync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeeb%2Fbandcampsync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeeb%2Fbandcampsync/lists"}