Commit graph

4348 commits

Author SHA1 Message Date
dunkla
0c2af3215c
Fix mypy incompatible return type in lastgenre 2026-02-22 14:19:17 +00:00
dunkla
d25c6204eb
Update lastgenre docstring and remove misleading comment (ref https://github.com/beetbox/beets/pull/6169#issuecomment-3716893013) 2026-02-22 14:19:17 +00:00
dunkla
d49f35a4d4
Use compact generator expression in Beatport (ref https://github.com/beetbox/beets/pull/6169#issuecomment-3716893013) 2026-02-22 14:19:17 +00:00
dunkla
9597075751
Simplify MusicBrainz genres assignment
Remove intermediate variable and assign directly to info.genres.
Addresses PR review comment.
2026-02-22 14:19:17 +00:00
dunkla
85903804ef
Implement automatic database-level genre migration
- Add Library._make_table() override to automatically migrate genres when database schema is updated
- Migration splits comma/semicolon/slash-separated genre strings into genres list
- Writes changes to both database and media files with progress reporting
- Remove lazy migration from correct_list_fields() - now handled at database level
- Remove migration-specific tests (migration is now automatic, not lazy)
- Update changelog to reflect automatic migration behavior

Related PR review comment changes:
- Replace _is_valid with _filter_valid method in lastgenre plugin
- Use unique_list and remove genre field from Beatport plugin
- Simplify LastGenre tests - remove separator logic
- Document separator deprecation in lastgenre plugin
- Add deprecation warning for genre parameter in Info.__init__()
2026-02-22 14:19:17 +00:00
dunkla
f2af5f8778
simplify check for fallback in beetsplug/lastgenre/__init__.py
Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2026-02-22 14:19:17 +00:00
dunkla
fe562f4009
simplify genre unpacking in beetsplug/lastgenre/__init__.py
Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2026-02-22 14:19:17 +00:00
dunkla
ee5dffaab5
simplify return logic in beetsplug/lastgenre/__init__.py
Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2026-02-22 14:19:17 +00:00
dunkla
8c28a962d3
better function description in beetsplug/lastgenre/__init__.py
Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2026-02-22 14:19:17 +00:00
Johann Fot
ee5f96be78
Add native support for multiple genres per album/track
Simplify multi-genre implementation based on maintainer feedback (PR #6169).

Changes:
- Remove multi_value_genres and genre_separator config options
- Replace complex sync_genre_fields() with ensure_first_value('genre', 'genres')
- Update all plugins (Beatport, MusicBrainz, LastGenre) to always write genres as lists
- Add automatic migration for comma/semicolon/slash-separated genre strings
- Add 'beet migrate genres' command for explicit batch migration with --pretend flag
- Update all tests to reflect simplified approach (44 tests passing)
- Update documentation

Implementation aligns with maintainer vision of always using multi-value genres
internally with automatic backward-compatible sync to the genre field via
ensure_first_value(), eliminating configuration complexity.

Migration strategy avoids problems from #5540:
- Automatic lazy migration on item access (no reimport/mbsync needed)
- Optional batch migration command for user control
- No endless rewrite loops due to proper field synchronization
2026-02-22 14:19:17 +00:00
Šarūnas Nejus
1930400ab8
Set default release/recording includes in MusicBrainzAPI 2026-02-22 02:09:25 +00:00
Šarūnas Nejus
c220d1f960
Fix mp3gain/aacgain paths on Windows
Fixes #2946
2026-02-21 16:52:26 +00:00
Šarūnas Nejus
37e18fbb46
Adapt code to fully typed confuse library 2026-02-16 12:45:05 +00:00
pbnoxious
144fd243ec
fix: wrong count in badfiles log message 2026-02-12 22:50:32 +01:00
w4grfw
57bd3189df Fix #6302: musicbrainz: crash when releases lack the "track" key. 2026-02-11 16:26:00 +01:00
Šarūnas Nejus
838681790c
Name these track/recording vars properly 2026-02-08 11:09:59 +00:00
Šarūnas Nejus
9f4c94f512
Provide missing kwargs to musicbrainz browse 2026-02-08 11:09:59 +00:00
Šarūnas Nejus
3b89d722ea
Fix mb search term formatting (#6354)
Fixes #6347

- Fixed MusicBrainz Lucene query formatting in
`MusicBrainzAPI.format_search_term()` (lowercase + trim + escape Lucene
special chars).
- Fixed `plugins.musicbrainz:extra_tags` support by mapping `alias` and
`tracks` into MusicBrainz search fields.
- Adjusted logging to make MusicBrainz API logs visible under the shared
`beets` logger (and removed an unused per-module logger in
`beetsplug.bpd`).
2026-02-08 07:20:11 +00:00
Šarūnas Nejus
df1573ce9d
Make MusicBrainzAPI logs visible 2026-02-07 22:36:43 +00:00
Šarūnas Nejus
aeee7b6da4
Musicbrainz: Fix support for alias, tracks extra tags 2026-02-07 22:26:52 +00:00
Šarūnas Nejus
1271b711f7
Format MusicBrainz search terms and escape Lucene special chars
Add a helper to lower/strip and escape Lucene query syntax.
Use it when building search queries and add unit tests.
2026-02-07 22:26:17 +00:00
Kirill A. Korinsky
1d8c378e9f
Disable Tekstowo by default as they block requests with the beets UA 2026-02-03 02:18:59 +01:00
Šarūnas Nejus
8f514eb6ab Replace/fix Release.type with Release.primary-type 2026-01-31 18:05:18 +00:00
Arne Beer
4d7b9cb14b fix(lastgenre): Canonicalize keep_existing fallback
Fixes a bug where existing tags were set to None, if they weren't whitelisted, but an whitelisted canonicalized parent existed up the tree.

In all other cases, the original genres are canonicalized and considered for the final genre, except in the keep_existing logic branch.
This PR fixes the issue and results in the expected behavior for this combination of options.

For the bug to trigger several conditions had to be met:

- Canonicalization is enabled and a whitelist is specified.
- `force` and `keep_existing` are set. Meaning, that Lastfm is queried for a genre, but the existing genres are still left around when none are found online.
- A release with a non-whitelisted genre exists, but that genre has a whitelisted genre parent up the tree.
- That very release has no genre on lastfm.

This is rather convoluted, but stay with me :D
What would happen is the following:

- `keep_genres` is set to the existing genres, as `force` and `keep_existing` is set.
- Genres for `track`/`album`/`artist` aren't found for this release, as they don't exist in lastfm.
- Then the `keep_existing` logic is entered.
  - The old logic only checks if the existing genres have an **exact** match for the whitelist. In contrast to all other code branches, we don't do the `_try_resolve_stage` in case there's no direct match, resulting in no match.
- We continue to the fallback logic, which returns the fallback (`None` in my case)

This patch results in one last try to resolve the existing genres when `keep_existing` is set, which includes canonicalization (if enabled).
2026-01-31 13:22:56 +01:00
Kirill A. Korinsky
78b6d537b6 Retries with 1, 2, 4, 8, 16, 32s backoff
At least it allows me to more or less use MusicBrainz
2026-01-30 00:46:13 +00:00
Šarūnas Nejus
95cef2de2b
Fix grouping for list fields and stabilize equal-chance order
- Handle list-valued fields when grouping for --field/--equal-chance to avoid
  "TypeError: unhashable type: 'list'" (e.g., artists).
- Sort items by the grouping key before building groups so equal-chance
  permutation preserves the same item set as `beet list`, only randomized.
2026-01-30 00:30:46 +00:00
Sebastian Mohr
6c52252672
Readded licence. Removed last legacy occurrences of artist and
replaced them with `field`. Removed unnecessary default parameters where
applicable.
2026-01-30 00:30:21 +00:00
Šarūnas Nejus
5ed0a72310
Add annotation for LibModel.length property 2026-01-30 00:30:21 +00:00
Sebastian Mohr
da9244d54d
Added an option to define the field to use for equal chance sampling 2026-01-30 00:30:21 +00:00
Šarūnas Nejus
2aa7575294
Replace random.Random with random module 2026-01-30 00:30:21 +00:00
Sebastian Mohr
3dd6f5a25b
Cached property for length & forgot sorted. 2026-01-30 00:30:21 +00:00
Sebastian Mohr
bcb22e6c85
Overall refactor of random plugin. Added length property to albums. 2026-01-30 00:30:21 +00:00
Sebastian Mohr
34e0de3e1f
Added typehints and some more tests. 2026-01-30 00:30:20 +00:00
Sebastian Mohr
1165758e1e
Moved functions from random.py into random plugin. Removed random.py 2026-01-30 00:29:27 +00:00
Šarūnas Nejus
146c462e97
Merge branch 'master' into handle-404-in-reimport 2026-01-23 02:08:45 +00:00
David Logie
8769f8f8f0 Gracefully handle 404s when importing from MusicBrainz.
A 404 error can be raised when fetching from MusicBrainz in the case of
re-importing an album that has since been deleted from MusicBrainz.
2026-01-22 12:20:04 +00:00
Rebecca Turner
958b36b298 fish: complete files in more places 2026-01-20 13:07:03 -08:00
Serene
39f65f6b11
Merge branch 'master' into embedart-clear-improvements 2026-01-20 08:43:30 +10:00
Henry
9b1bd5df7a Adjust type annotation, rebase. 2026-01-19 12:46:22 -08:00
Henry
ff95ce5d20 Remove utils, rework from_plugin method in ArtistState to from_config 2026-01-19 12:43:30 -08:00
Henry Oberholtzer
2cfd1df3c1 Split discogs.py into smaller and more workable modules. 2026-01-19 12:43:30 -08:00
Šarūnas Nejus
5523ca94a2 Document ArtistState 2026-01-19 12:43:30 -08:00
Šarūnas Nejus
b3183a73e0 Simplify building artist 2026-01-19 12:43:30 -08:00
Šarūnas Nejus
59e7c59172 Move building logic to dataclasses 2026-01-19 12:43:30 -08:00
Henry Oberholtzer
0e48c65171 Clarify variable in _process_clean_tracklist 2026-01-19 12:43:30 -08:00
Henry Oberholtzer
2d406a3ca5 Add comments, clean up types. 2026-01-19 12:43:30 -08:00
Henry
459fd39768 Fix behavior when ANV does not exist 2026-01-19 12:43:30 -08:00
Henry Oberholtzer
08a2c248b9 Fix handling of commas and semicolons in artist join 2026-01-19 12:43:30 -08:00
Henry
f0aef6e213 Cleanup for #6177, #6068 2026-01-19 12:43:27 -08:00
Henry
1d6e05709e Fix #6068 - Multivalue fields are now supported & tested. 2026-01-19 12:41:36 -08:00