Skip to main content

Use origin files to enrich beets importer search criteria

Project description

beets-originquery-ng

The published package name is beets-originquery-ng. The beets plugin name is originquery.

originquery is a beets plugin that reads supplemental metadata from an origin file in each import directory and injects that data into the importer before candidate lookup.

This is most useful when audio files only have minimal tags, but the release directory also contains richer metadata such as edition year, catalog number, label, media, or release notes.

What it does

During beet import, the plugin can:

  • read a text, JSON, YAML, or YML origin file from the album directory
  • map fields from that file onto beets item fields before lookup
  • surface the tagged-vs-origin values during candidate selection
  • detect conflicts between tagged and origin data
  • optionally remove a conflicting albumartist before beets derives search terms
  • optionally scan the origin file for provider URLs such as Discogs or Bandcamp

Installation

Install beets and then install this plugin:

pip install "beets>=2.5.1"
pip install beets-originquery-ng

Supported Python versions: 3.10 through 3.13.

Minimal configuration:

plugins:
  - musicbrainz
  - originquery

musicbrainz:
  extra_tags: [year, catalognum, media, label, albumdisambig]

originquery:
  origin_file: origin.yaml
  tag_patterns:
    artist: $.Artist
    album: $.Name
    year: $['Edition year']
    label: $['Record label']
    catalognum: $['Catalog number']
    media: $.Media
    albumdisambig: $.Edition

If you use Discogs, enable it in beets:

plugins:
  - musicbrainz
  - discogs
  - originquery

Configuration

originquery looks for an origin file in the source directory for each album task. When you import a parent directory, it resolves against the album subdirectory, not the top-level import root. The filename may be a glob:

originquery:
  origin_file: origin-*.yaml

If multiple files match, the first alphanumerically sorted match is used.

Supported options:

originquery:
  origin_file: origin.yaml
  origin_type: yaml
  use_origin_on_conflict: no
  preserve_media_with_catalognum: no
  remove_conflicting_albumartist: no
  tag_patterns:
    artist: $.Artist
    album: $.Name
    year: $['Edition year']
    label: $['Record label']
    catalognum: $['Catalog number']
    media: $.Media
    albumdisambig: $.Edition
    tags: $.Tags

Options:

  • origin_file: filename or glob, relative to the album directory
  • origin_type: text, json, yaml, or yml; when omitted, the file extension is used
  • use_origin_on_conflict: when yes, origin values win if conflict fields do not match
  • preserve_media_with_catalognum: when no, the plugin removes media if both media and catalognum are present
  • remove_conflicting_albumartist: when yes, a unanimous tagged albumartist that disagrees with origin artist is cleared before search

Import fields

The following tag_patterns keys are understood as beets fields:

  • artist
  • album
  • media
  • year
  • country
  • label
  • barcode
  • catalognum
  • albumdisambig

Any additional keys are treated as display-only fields and are shown in the import summary, but they are not mapped onto beets search fields.

File formats

Text origin files


For `text` origin files, each pattern must be a regular expression with exactly
one capture group:

    originquery:
      origin_file: origin.txt
      origin_type: text
      tag_patterns:
        media: 'media=(.+)'
        year: 'year=(\d{4})'
        label: 'label=(.+)'
        catalognum: 'catalognum=(.+)'

JSON origin files

For json origin files, each pattern may be either a JSONPath expression or an ordered list of JSONPath expressions for fallback lookup:

originquery:
  origin_file: origin.json
  tag_patterns:
    artist: $.Artist
    album: $.Name
    year: $['Edition year']
    label: $['Record label']
    catalognum: $['Catalog number']
    country:
      - $['Country']
      - $['Release country']

YAML / YML origin files


YAML files use the same JSONPath-based `tag_patterns` as JSON, including
fallback lists:

    originquery:
      origin_file: origin.yml
      tag_patterns:
        artist: $.Artist
        album: $.Name
        year:
          - $['Edition year']
          - $['Original year']
        label:
          - $['Record label']
          - $['Original release label']
        catalognum:
          - $['Catalog number']
          - $['Original catalog number']

Conflicts
---------

The plugin treats the following fields as conflict-sensitive:

- `artist`
- `barcode`
- `catalognum`
- `media`

When one of those fields differs between existing tags and origin data, the
plugin reports a conflict during import.

Default behavior:

- tagged data wins
- origin data is still displayed for inspection

To make origin data win instead:

    originquery:
      use_origin_on_conflict: yes

Albumartist cleanup
-------------------

beets derives the likely album artist from the imported items before lookup. If
all tracks agree on `albumartist`, that value can override `artist` in the
derived search terms.

When your files have a wrong `albumartist` but the origin file has the correct
`artist`, enable:

    originquery:
      remove_conflicting_albumartist: yes

If the tagged `albumartist` is unanimous and differs from the origin artist, it
is cleared before search.

Media handling
--------------

By default, `originquery` removes the `media` field when both `media` and
`catalognum` are present:

    originquery:
      preserve_media_with_catalognum: no

If you want to keep `media`:

    originquery:
      preserve_media_with_catalognum: yes

URL extraction
--------------

The plugin can scan the raw origin file for provider URLs and show them during
import. Supported providers:

- `discogs`
- `bandcamp`

Enable extraction in the provider configuration:

    discogs:
      extract_urls_from_origin: yes

    bandcamp:
      extract_urls_from_origin: yes

This feature displays matched URLs. It does not convert them into lookup IDs.

Development
-----------

Local checks:

    uv sync --group dev
    uv run ruff check .
    uv run ty check
    uv run pytest

The repository also includes a local importer bench for sample albums:

    ./.bench/setup.sh
    ./.bench/reset-state.sh
    ./.bench/import-album.sh '2018-For Emma, Forever Ago (Reissue)'

The default development toolchain uses `ruff`, `ty`, and `pytest`.

Release process
---------------

Releases are created from Git tags in GitHub Actions and published to PyPI.

1. Update `project.version` in `pyproject.toml`.
2. Merge the version bump to `master`.
3. Push a tag in the form `vX.Y.Z` that matches `project.version`.

The release workflow then:

- validates the tag against `pyproject.toml`
- reruns lint, type-check, tests, and packaging checks
- builds `sdist` and `wheel`
- publishes `beets-originquery-ng` to PyPI
- creates a GitHub Release with auto-generated notes and attached artifacts

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

beets_originquery_ng-2.3.0.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

beets_originquery_ng-2.3.0-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file beets_originquery_ng-2.3.0.tar.gz.

File metadata

  • Download URL: beets_originquery_ng-2.3.0.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for beets_originquery_ng-2.3.0.tar.gz
Algorithm Hash digest
SHA256 27ff562ec31c6a09d535bf58d159a86288e7e073329a27c50a2ee2c2e0c51734
MD5 8783179c1638ff2df41933426cd25754
BLAKE2b-256 4ceb061d1c22dad6681e49c38e6bf156d327ae60711c16616a7a76c38ce753dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for beets_originquery_ng-2.3.0.tar.gz:

Publisher: release.yml on libussa/beets-originquery-ng

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file beets_originquery_ng-2.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for beets_originquery_ng-2.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c7981b0facc5645a4b314f211dfe6ed9f3be9315dc3da7ca1a39387b72df0ba1
MD5 c43cc4b7a02e13b04bc67ee90c2fc360
BLAKE2b-256 832e3417035258441c09180603a6b24bfc0bc9ff8fece5724129e040c3983518

See more details on using hashes here.

Provenance

The following attestation bundles were made for beets_originquery_ng-2.3.0-py3-none-any.whl:

Publisher: release.yml on libussa/beets-originquery-ng

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page