Commit graph

12907 commits

Author SHA1 Message Date
Ben Stolovitz
2f98f11d57 fix local langdetect test failures
avoid linter error

avoid other linter error

fix format

changing deps (no lock!)

poetry lock?

lint & format

attempt 2 at poetry lock

crlf -> lf line endings

changelog!
2025-05-31 18:56:21 -04:00
Šarūnas Nejus
87701fd6f0
Move Distance to a dedicated module and refactor related tests (#5800)
This PR:

1. Reorganizes distance-related code by moving it from `hooks.py` and
`match.py` to a new dedicated `distance.py` module:
- The actual implementation logic and algorithms remain unchanged - code
is moved, not rewritten
- Distance class, string distance functions, and track/album distance
calculators are relocated intact
- Only imports and function references are updated to maintain
compatibility
- `current_metadata` function is replaced with equivalent
`get_most_common_tags` function for clarity

2. Refactors the distance testing code from unittest to pytest:
- Tests now use fixtures and parametrization while verifying the same
functionality
- The tested behaviors remain identical, just with improved test
structure
- Actually, `distance.py` coverage slightly increased since I included
an additional test

3. Adds a test for the `sanitize_pairs` function to complete config
utility test coverage

This is primarily a code organization improvement that follows better
separation of concerns, grouping related distance functionality in a
single module without changing how the distance calculations work. No
algorithm changes or behavior modifications were made to the core
distance calculation code - it was simply moved to a more appropriate
location.
2025-05-31 19:49:51 +01:00
Šarūnas Nejus
99f7e94b59
Add Distance and current_metadata to autotag.__init__ for backward compat 2025-05-31 19:17:44 +01:00
Šarūnas Nejus
cb246c28bc
Remove dead chartlyrics
This integration test failed because `chartlyrics.com` website is no
longer available, so I'm removing it.
2025-05-31 19:17:43 +01:00
Šarūnas Nejus
0da6192a4a
Test sanitize_pairs 2025-05-31 19:17:43 +01:00
Šarūnas Nejus
318a840af2
Rewrite distance tests 2025-05-31 19:17:43 +01:00
Šarūnas Nejus
adbd50b237
Move distance to a separate module 2025-05-31 19:17:43 +01:00
Šarūnas Nejus
01b6ea7898
Simplify and speed up plurality/album tags retrieval tests 2025-05-31 19:17:42 +01:00
Šarūnas Nejus
1c9aebd36c
match.current_metadata -> util.get_most_common_tags 2025-05-31 17:58:23 +01:00
Šarūnas Nejus
509cbdcbe4
Move sanitize_pairs/choices from plugins to util module 2025-05-31 17:55:41 +01:00
Ian McCowan
0f76312f31
Fix duplicate database change event send on Library.add (#5561)
## Description

Fixes #5560. Also a couple other incidental changes / improvements:
* Add `EventType` that holds the actual string literals used for event
sending. With type checking, this can prevent subtle bugs resulting from
misspelled event names.
* Fix `HiddenFileTest` by using `bytestring_path()`

## To Do

- [x] ~Documentation.~
- [x] Changelog.
- [x] Tests.

---------

Co-authored-by: J0J0 Todos <jojo@peek-a-boo.at>
Co-authored-by: J0J0 Todos <2733783+JOJ0@users.noreply.github.com>
2025-05-30 13:41:29 +00:00
Uncorrupt3318
dd2f203090
Feat: Add replace plugin (#5644)
Adds replace plugin. The plugin allows the user to replace the audio
file of a song, while keeping the tags and file name.

Some music servers keep track of favourite songs via paths and tags. Now
there won't be a need to 'refavourite'. Plus, this skips the
import/merge steps.
2025-05-27 00:17:52 +02:00
Ben Stolovitz
da5ec00aaf
[Test] Fix path tests on windows (#5803)
## Description

Fixes #5802.

Today, tests fail on most Windows machines because we hard-code `D:` as
the root drive, but most machines use `C:`. This change uses the same
normalization function in the test assertion to ensure the drives match.

## To Do

- [ ] ~~Documentation.~~
- [x] Changelog.
- [x] Tests. (this is a tests change)

## What changed?

* Updated tests to generate the drive name via normalization, instead of
hard-coding `D:`.
* Updated the `Item::destination()` method to document the
`relative_to_libdir` param.

## How tested?

* [x] Tests pass locally.
2025-05-26 19:24:57 +02:00
Šarūnas Nejus
60f24cdc74
Speed up a couple of tests (#5799)
Speed up tests by using `unittest.TestCase` for tests that don't require
directory setup

This PR improves test performance by switching several test classes from
`BeetsTestCase` to standard `unittest.TestCase` when they don't require
the directory setup and teardown overhead. The changes focus on test
classes that:

1. Only test utility functions
2. Don't need temporary directories
3. Don't interact with the filesystem

The PR removes unnecessary imports of `BeetsTestCase` and adds direct
imports of `unittest` where needed. This change reduces the test
execution time by avoiding the expensive setup/teardown steps for tests
that don't require them.
2025-05-26 14:32:36 +01:00
Šarūnas Nejus
5900282093
Use BeetsTestCase for lastgenre tests, re-use the defined config 2025-05-26 13:05:40 +01:00
Šarūnas Nejus
c9f98fca55
Use unittest.TestCase for tests that don't require the dir setup 2025-05-26 12:40:38 +01:00
Šarūnas Nejus
e439c04d89
Make mb_albumartistids available at the album level. (#4909)
As this is a field related to albums, it probably should be accessible
as `album.mb_albumartistids`.
2025-05-22 15:54:05 +01:00
David Logie
43b20f2850 Make mb_albumartistids available at the album level. 2025-05-22 15:49:27 +01:00
Sebastian Mohr
9584216209
Streamlined auto api referencing for documentation (#5795)
## Description

The current developer documentation feels somewhat cluttered due to
inline auto-generated API references for certain classes. To improve
readability and maintainability, this PR introduces a more streamlined
approach that aligns better with best practices observed in other PyData
ecosystem documentation.

Specifically, this PR:
- Adds a dedicated `api/` folder to the documentation structure.
- Moves all auto-generated references (classes, methods, etc.) to this
folder.
- Enables clean, concise linking to API elements from the narrative
documentation—without interrupting human-written content with large
autogenerated blocks.

This separation makes the documentation easier to navigate and maintain,
while still providing full API reference coverage where needed.

- [x] Documentation
- [x] Changelog
2025-05-22 11:35:40 +02:00
Šarūnas Nejus
5356e6e5ea
Replace outdated bitesized label link (#5790)
Meta: I was looking for possible contribution opportunities, so I
noticed this in the docs. I assume that the `bite-size` label is
outdated, as there aren't actually any issues with that label. Looks
like https://github.com/beetbox/beets/labels/good%20first%20issue is
currently used.

Note: Further below there's also mention of a `first timers only` label
– that link also yields no results and even gives a message about the
label being invalid. I wasn't sure if/how that should be replaced, so I
didn't touch it. Maybe the sentence I am changing should actually be
moved down and replace the one mentioning `first timers only`?
2025-05-21 11:19:04 +01:00
Manu
8e84268e06 Replace outdated bitesized label link 2025-05-21 11:13:50 +01:00
Benedikt
79c87e5886
Add fetchart typing v2 (#5716)
Adds typings to fetchart; a revised and modernized version of
https://github.com/beetbox/beets/pull/5213.

The former pull request became stale because I did more refactoring
there, in order to express properties of the `Candidate` (whether or not
it is validated) via the type system (motivated by the type state
pattern which is more common in Rust.
The result was a little contentious, since it became a little unclear
what the purpose of the `Candidate` class should even be at that point.

I think this was a case of combining too many things into a single PR.
Thus, this version does not perform any refactoring of that extent. It
does sprinkle in a few `assert`s to make thinks clear for the type
checker.
2025-05-20 11:07:22 +02:00
wisp3rwind
728076e97d fetchart: assert some invariants to satisfy mypy
Eventually, it would be nice to avoid this by more expressive typings.
For now, avoid such larger refactoring.
2025-05-20 10:06:11 +02:00
wisp3rwind
10d1c51a1d fetchart: consistently use lazy string formatting for debug logging 2025-05-20 09:23:34 +02:00
wisp3rwind
fd383ead51 ci: run with fetchart dependencies (Pillow)
at least in the with-coverage tests
2025-05-20 09:00:04 +02:00
wisp3rwind
abbabcf92e tests: skip tests that require ArtResizer.compare if it is broken
This is just a quick workaround to allow CI to pass. This didn't show up
in CI before because we didn't install ImageMagick.
2025-05-20 09:00:04 +02:00
wisp3rwind
ff22da0691 install imagemagick in CI environment 2025-05-20 09:00:04 +02:00
wisp3rwind
4fdfb393db update changelog 2025-05-20 08:59:49 +02:00
wisp3rwind
a6f2389aed typing: fetchart + tests 2025-05-20 08:57:30 +02:00
wisp3rwind
395aec96a3 fetchart: fixup #5244
by restoring config validation and making things more Pythonic
2025-05-20 08:57:30 +02:00
Šarūnas Nejus
f6f5518a7f
Discogs: allow fetching singletons by id, add configurable search_limit (#5791)
This PR adds two new features to the Discogs plugin:

1. A new `track_for_id` method that allows users to retrieve singleton
tracks directly by their Discogs ID
   - Builds on top of the existing `album_for_id` method
   - Searches through the album tracks to find the matching track ID

2. A configurable `search_limit` option to control the number of results
returned by the Discogs metadata search queries
   - Default value is set to 5
- Helps improve performance by limiting the number of results processed
   - Added proper documentation in the plugin docs

Fixes #4661
2025-05-19 13:43:17 +01:00
Šarūnas Nejus
e151b4b49b
Implement track_for_id to allow fetching singletons by discogs id 2025-05-19 09:43:56 +01:00
Šarūnas Nejus
d3ef627494
Expect plugins to return Iterables instead of Iterators 2025-05-19 09:43:54 +01:00
Šarūnas Nejus
d9b67acff5
discogs: simplify getting track from album 2025-05-19 09:43:03 +01:00
Šarūnas Nejus
9cc7ecaceb
discogs: cache TRACK_INDEX_RE 2025-05-19 09:43:03 +01:00
Šarūnas Nejus
8e5858254b
discogs: cache master release lookups 2025-05-19 09:43:03 +01:00
Šarūnas Nejus
12149b3e6d
discogs: remove duplicate error handling 2025-05-19 09:43:03 +01:00
Šarūnas Nejus
09862aeaea
discogs: Add types to public methods 2025-05-19 09:43:01 +01:00
Šarūnas Nejus
9242db04a5
discogs: add configurable search_limit 2025-05-19 09:42:06 +01:00
Šarūnas Nejus
3a663ad52e
Fix musicbrainz extra tags dict (#5789)
Fixes #5788

This PR fixes a regression that occurred when the MusicBrainz autotagger
was moved from core functionality into a standalone plugin. During this
transition, the handling of user-configured `extra_tags` was broken,
causing `beets` to die with `AttributeError` when this option was set.

Key changes in `musicbrainz` plugin

- Properly process values from `extra_tags` using the same logic as
before the migration.
- Centralize common bits from `candidates` and `item_candidates`
implementations under `_search_api` to move this class closer towards
`MetadataSourcePlugin` definition.
2025-05-19 09:23:23 +01:00
Šarūnas Nejus
e8e9369bc7
Remove unused extra_tags parameter 2025-05-19 09:18:06 +01:00
Šarūnas Nejus
2ec65ed8ca
Deduplicate candidate methods using _search_api method 2025-05-18 20:09:52 +01:00
Šarūnas Nejus
0102f3ce7d
Take into account va_likely param and remove redundant checks
- Instead of checking for empty `artist` query, use `va_likely`
  parameter to determine whether we should query for Various Artists or
  not.
- `album` / `title` is always a truthy string - no need to handle empty
  criteria case
- `tracks` list always has at least one track - no need to check for
  `len(items)`
2025-05-18 20:09:52 +01:00
Šarūnas Nejus
6487893315
Synchronise docs with the actual supported extra_tags 2025-05-18 20:09:51 +01:00
Šarūnas Nejus
be74936134
Handle extra_tags the way they used to be handled 2025-05-18 20:09:50 +01:00
Martin Atukunda
ab7b7a2e29
docs(plugin/web): update changelog 2025-05-18 20:59:29 +03:00
Martin Atukunda
7c799beda8
style(plugin/web): run djlint over html to clean it up a bit 2025-05-18 20:59:29 +03:00
Martin Atukunda
992d376d1b
feat(plugin/web): add artist and album to the item entry template 2025-05-18 20:59:29 +03:00
Šarūnas Nejus
e88aa8a450
feat: plugins/web: use media session api for notifications. (#5714)
The Media Session API provides a way to customize media notifications.
This PR has commits that, in summary, updates the metadata for the media
session whenever a new track (item) starts playing.

https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API
2025-05-18 17:21:18 +01:00
Martin Atukunda
a75d2b4aa6 Update beetsplug/web/static/beets.js
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-18 17:16:29 +01:00