Skip to main content

bcgenre

A beets plugin that fetches genre tags from Bandcamp release pages and merges them into your library’s genres field.

It is meant to complement lastgenre: Last.fm often misses artist-authored Bandcamp tags (and Bandcamp’s hyphenated forms like hip-hop / neo-soul). bcgenre reads those tags from the release page, normalizes them with lastgenre’s helpers, and filters them against a MusicBrainz genre whitelist.

Requirements

  • beets (includes the lastgenre package used for whitelist / aliases / canonicalization data)
  • beetcamp (bandcamp plugin) for Bandcamp HTML parsing and slug helpers
  • A Bandcamp URL in each item’s comments field (artist root or album URL), e.g. Visit https://artist.bandcamp.com

Install

Clone or copy this package so beets can see beetsplug/bcgenre:

beetsplug/
  bcgenre/
    __init__.py
    genres.py
    resolve.py
    README.md

Point pluginpath at the parent of that beetsplug directory (or at the beetsplug directory itself — both work with beets), then enable the plugin:

plugins: lastgenre bandcamp bcgenre
pluginpath: /path/to/parent   # directory that contains beetsplug/

Confirm it loads:

beet bcgenre -h

Configuration

Options live under bcgenre: and mirror lastgenre’s shared settings (they do not inherit from your lastgenre: block):

bcgenre:
    auto: no
    force: no
    keep_existing: no
    count: 1
    whitelist: yes          # yes = lastgenre's genres.txt; or a path to your own list
    aliases: yes            # yes = lastgenre's aliases.yaml; no = off; or an inline mapping
    canonical: no           # yes = add parent genres from lastgenre's genres-tree.yaml
    title_case: yes
    fallback:               # optional genre when Bandcamp yields nothing
    pretend: no
Option Meaning
force Modify items that already have genres
keep_existing When forcing, union Bandcamp genres with existing ones
count Max genres kept from Bandcamp after filtering (union with keep_existing can exceed this)
whitelist Genre allow-list; yes uses lastgenre’s bundled MusicBrainz list
aliases Spelling normalization (hip-hop → hip hop, etc.)
canonical Expand matched tags with parent genres from the genre tree
auto Run during import (off by default; prefer batch runs)
title_case Title-case written genres

File writes follow your global import.write setting (same as lastgenre).

Usage

# Preview changes (no DB / file writes)
beet bcgenre -p

# Apply (uses config force / keep_existing)
beet bcgenre

# Force + replace existing genres
beet bcgenre -f -K

# Force + union with existing genres
beet bcgenre -f -k

# Limit to a query (albums by default)
beet bcgenre -p albumartist:Aesop\ Rock
beet bcgenre -A artist:Aesop\ Rock    # items instead of albums

CLI flags match lastgenre: -p/--pretend, -f/-F (force), -k/-K (keep-existing), -a/-A (albums/items).

Output shows the same per-track genres: + / - diffs as lastgenre.

How URL resolution works

For each album, bcgenre:

  1. Reuses a cached bandcamp_album_url flex field if present
  2. Uses a deep /album/... (or /track/...) URL from comments when available
  3. Otherwise takes the Bandcamp root from comments and guesses /album/{slug}
  4. On miss, scrapes {root}/music and fuzzy-matches the album title (handles Bandcamp’s -2 slug collisions)

Resolved URLs are stored in bandcamp_album_url so re-runs avoid most network work.

Requests are paced at about 1 per second (not configurable), with backoff and abort on repeated HTTP 429 responses.

Tips

  • Prefer a pretend pass first: beet bcgenre -p -f -k
  • Albums without a Bandcamp URL in comments are skipped
  • Translated or heavily renamed titles may not match Bandcamp’s discography listing; set bandcamp_album_url manually or restore a closer title
  • lastgenre does not need to be enabled for bcgenre to use its data files, but enabling both is the usual setup

Metadata

Release files for beets-bcgenre 0.1.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 beets-bcgenre 0.1.0
File Size Uploaded
beets_bcgenre-0.1.0.tar.gz 11.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for beets-bcgenre 0.1.0
File Interpreter ABI Platform
beets_bcgenre-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 23.1 kB

Release files / beets_bcgenre-0.1.0.tar.gz

Download URL beets_bcgenre-0.1.0.tar.gz
Size 11.0 kB
Tags Source
SHA-256 checksum
How to use checksums
798c0799a62bb5ef07f79ac98f000f54eb0f51ee581d9b1c3e22898a8c0e1e42
BLAKE2b-256 checksum
How to use checksums
b8b544414335ef81ac4ee03f65c993cf37587adba9772c57218e21cfe57a095d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / beets_bcgenre-0.1.0-py3-none-any.whl

Download URL beets_bcgenre-0.1.0-py3-none-any.whl
Size 12.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef8b086b192891aff2679733fa46011ba9b27c666d2a858194a116375102d4c0
BLAKE2b-256 checksum
How to use checksums
2d0ae83f6c0642499fe1986cb3c701d307039b8d7c4bd1ca5941cc87376b6cb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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