Introduce Source class to encapsulate metadata extraction logic,
replacing scattered `get_most_common_tags` calls throughout codebase.
- Add Source class in importer.tasks with artist, name, and metadata
- Simplify `distance()` to accept Source.data instead of items list
- Update display functions to use Source objects
- Cache Source creation with @cached_property on ImportTask
This centralizes metadata handling and reduces coupling between
autotag and library modules.
Add a MetaflacBackend that computes ReplayGain for FLAC files with metaflac --add-replay-gain and reads the values back with --show-tag. Only FLAC is supported. Includes docs, a changelog entry, and tests.
The relative-date regex used character classes [+|-] and [y|m|w|d],
which mistakenly treat | as a literal member rather than alternation.
As a result a value like added:2000|2001 (as a user might type expecting
| to mean "or") captured | as the relative-date unit and crashed with
an uncaught KeyError in Period.parse instead of raising the documented
InvalidQueryArgumentValueError.
Remove the stray | from both character classes so malformed date strings
fall through to the normal invalid-date error path.
Co-Authored-By: Claude <noreply@anthropic.com>
### Description
`extract_release_id` now accepts the native Spotify URI format
(`spotify:album:<id>`, `spotify:track:<id>`) in addition to the already
supported `open.spotify.com` URLs and bare IDs.
Co-authored-by: Marina Pena Malschitzky Crespo <marinacrespo@estudante.ufscar.br>
- Fixes some inconsistencies in spelling in the data files we ship with
the plugin as well as adds some new genres to both files that seem to
be returned often by last.fm.
- For some changes the default aliases feature helps to streamline
inconsistencies that come from last.fm already.
- The default aliases file that ships with beets
- Tests fixes that prove that most of the alias normalization patterns
work as they are supposed to.
Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
InQuery inherited FieldQuery.__hash__, which hashes the pattern directly.
A list pattern raises `unhashable type: 'list'`, which broke the
smartplaylist `splupdate` command whenever a `playlist:` query was configured.
Sorting by a field whose declared type is nullable (its null value is
`None`, e.g. `NullInteger`/`NullFloat`) raised `TypeError: '<' not
supported between instances of ...` when the field was present on some
objects but missing on others, because `FieldSort.sort` compared `None`
against real values.
Group missing values together in the sort key so they are never compared
against present ones: they are ordered first when sorting ascending and
last when descending, matching SQLite's default ordering of NULLs used by
the fast `FixedFieldSort` path.
Fixes#3461.
Co-Authored-By: Claude <noreply@anthropic.com>