Commit graph

13528 commits

Author SHA1 Message Date
Šarūnas Nejus
d613981efe
Replace capture_output with io.getoutput 2026-02-10 00:53:20 +00:00
Šarūnas Nejus
fea789bb59
Replace control_stdin with io.addinput 2026-02-10 00:53:20 +00:00
Šarūnas Nejus
6a65f13776
Replace custom stdio mocks with pytest io fixture
Create a centralised pytest fixture to provide controllable stdin and
captured stdout in all tests. Simplify DummyIO/DummyIn and remove the
custom DummyOut implementation and make use of pytest builtin fixtures.

Create a centralised pytest fixture to provide controllable stdin and
captured stdout that can be applied to any tests, regardless whether
they are based on pytest or unittest.

* `io` fixture can be used as a fixture in pytest-based tests
* `IOMixin` can be used to attach `io` attribute to any test class,
  including `unittest.TestCase`
2026-02-10 00:53:20 +00:00
Šarūnas Nejus
1c87da2c05
Fix test failures 2026-02-10 00:53:20 +00:00
Šarūnas Nejus
a4249af700
Patch sys.stdin and sys.stdout in tests 2026-02-10 00:53:20 +00:00
Šarūnas Nejus
6dbee2437e
Fix fetching large MusicBrainz releases (#6357)
Fixes #6355 

- Fix `plugins/musicbrainz` handling of very large MusicBrainz releases
by passing the missing `limit` and `includes` kwargs to
`mb_api.browse_recordings`.
2026-02-08 21:18:16 +00: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
bf6c0a1bdf
Disable Tekstowo by default as they block requests with the beets UA (#6344) 2026-02-08 01:29:30 +00:00
Šarūnas Nejus
8f81e1d913
Update ownership 2026-02-07 22:41:17 +00:00
Šarūnas Nejus
df1573ce9d
Make MusicBrainzAPI logs visible 2026-02-07 22:36:43 +00:00
Šarūnas Nejus
84b22fddd5
Order mbcollection, mbpseudo, mbsubmit after musicbrainz plugin in docs 2026-02-07 22:28:00 +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
snejus
cdfb813910 Increment version to 2.6.1 2026-02-02 02:29:04 +00:00
Šarūnas Nejus
d65e37cba0
Fix dependencies (#6333)
Fixes #6332 

- Promotes `packaging` from a release-only dependency to a required
runtime dependency by moving it into `pyproject.toml`'s main
dependencies.

- Updates `poetry.lock` to pick up patched versions of vulnerable
libraries, notably `brotli` (`1.1.0` → `1.2.0`), `urllib3` (`2.5.0` →
`2.6.3`), `werkzeug` (`3.1.3` → `3.1.5`), and `filelock` (`3.20.2` →
`3.20.3`).

<img width="442" height="169" alt="image"
src="https://github.com/user-attachments/assets/fe70475e-0163-4d45-b1e4-362008669c00"
/>
2026-02-02 02:27:06 +00:00
Šarūnas Nejus
9d7d3ae7b0
Update vulnerable dependencies 2026-02-02 02:18:51 +00:00
Šarūnas Nejus
b6230a84fc
Make packaging a required dependency 2026-02-02 02:16:36 +00:00
snejus
680473b9e5 Increment version to 2.6.0 2026-02-01 14:42:50 +00:00
Šarūnas Nejus
b2335b984d
Fix crash in task.imported_items (#6326)
Fixes #6291

I think it does not hurt if the imported_items() method returned an
empty list instead of an throwing an exception if there is nothing in
it!
2026-01-31 23:54:07 +00:00
J0J0 Todos
d2600c354c Fix crash in task.imported_items 2026-01-31 23:48:43 +00:00
Šarūnas Nejus
f9cf15732c
Safely handle metadata plugin exceptions. (#5965)
When a metadata plugin raises an exception during the auto-tagger
process, the entire operation crashes. This behavior is not desirable,
since metadata lookups can legitimately fail for various reasons (e.g.,
temporary API downtime, network issues, or offline usage).

This PR introduces a safeguard by adding general exception handling
around metadata plugin calls. Instead of causing the whole process to
fail, exceptions from individual plugins are now caught and logged. This
ensures that the auto-tagger continues to function with the remaining
available metadata sources. I used a proxy pattern here as this
seems like an elegant solution to me.

This replaces the efforts from #5910
2026-01-31 23:47:56 +00:00
Šarūnas Nejus
2196bd89de Simplify tests 2026-01-31 23:42:09 +00:00
Šarūnas Nejus
cb6ad89ce6 Use a decorator-based approach 2026-01-31 23:42:09 +00:00
Sebastian Mohr
8e0b3f1323 Moved config check into find_metadata_source_plugins func. 2026-01-31 23:42:09 +00:00
Sebastian Mohr
5cbdab40d2 Renamed variable to use protected names. 2026-01-31 23:42:09 +00:00
Sebastian Mohr
cfba015998 Fixed cache clear issue. 2026-01-31 23:42:09 +00:00
Sebastian Mohr
4511a37699 Added default config and simplified proxy class. 2026-01-31 23:42:09 +00:00
Sebastian Mohr
3388882c21 Added a proxy to catch and handle exceptions in metadataplugins during
the autotag process.
2026-01-31 23:42:09 +00:00
Šarūnas Nejus
0cde654ffe
musicbrainz: fix release type (#6299)
- Update the MusicBrainz integration to read the release group's
canonical `'primary-type'` field instead of the legacy `'type'` field
when deriving `info.albumtype`.

Noticed that `albumtype` was missing from the metadata when I did some
imports in my library.
2026-01-31 18:11:21 +00:00
Šarūnas Nejus
8f514eb6ab Replace/fix Release.type with Release.primary-type 2026-01-31 18:05:18 +00:00
Šarūnas Nejus
ea7a0ce370
Extend git blame ignore revs (#6310)
Found a couple of additional historical commits that added noise to git
blame and which should be ignored.
2026-01-31 18:04:52 +00:00
Šarūnas Nejus
5b48701ba1 Add missing commits to git blame ignore revs 2026-01-31 17:59:45 +00:00
J0J0 Todos
a327c28470
fix(lastgenre): Canonicalize keep_existing fallback (#6303) 2026-01-31 13:27:35 +01: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
Šarūnas Nejus
aaf046e6bd
Add support for creating indices on arbitrary database tables (#5926)
Creating indexes turned out to be relatively straightforward!
While we can’t remove them yet, that doesn’t seem necessary for now.
Interestingly, much of the infrastructure for database additions was
already in place.

- This PR introduces a new type, `Index`, which can be used to create an
index on any defined table. 🎉
- The `items` table now automatically registers an index on `album_id`

Closes #5809
2026-01-30 21:42:49 +00:00
Šarūnas Nejus
cde73cc433
Add changelog note 2026-01-30 01:18:11 +00:00
Šarūnas Nejus
a17857213b
Fix lints 2026-01-30 01:06:31 +00:00
Šarūnas Nejus
fc54f809a1
Merge branch 'master' into indices 2026-01-30 01:03:18 +00:00
Šarūnas Nejus
e768f978b6
Simplify creating indices 2026-01-30 00:55:13 +00:00
Šarūnas Nejus
838a94d931
Retries with 1, 2, 4, 8, 16, 32s backoff (#6322)
At least it allows me to more or less use MusicBrainz, and makes issues
from #6312 almost not noticible
2026-01-30 00:50:57 +00:00
Kirill A. Korinsky
48c954edf6 Nuked tests 2026-01-30 00:46:13 +00:00
Kirill A. Korinsky
47b1644110 Attemt to rework tests 2026-01-30 00:46:13 +00: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
c1484169dc
Refactored beets/random.py and moved into beetsplug/random.py (#5924)
The `beets/random.py` module was only used by the random plugin, so I
moved its functions into `beetsplug/random.py` to keep core modules
cleaner.


Changes:
- Moved beets/random.py functions into beetsplug/random.py
- Added typehints for better readability and tooling support
- Added additional tests for improved coverage
- General tidy up and refactor, keeping the core functionality unchanged
2026-01-30 00:36:51 +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
ee7dc3c4e7
Enhanced documentation of random plugin. 2026-01-30 00:30:45 +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