Commit graph

12907 commits

Author SHA1 Message Date
Šarūnas Nejus
4260162d44
Remove all Python 2 references 2025-07-08 11:37:34 +01:00
Šarūnas Nejus
7cada1c9f8
Remove no-op decargs 2025-07-08 11:37:33 +01:00
Sebastian Mohr
e6016c125b Added changelog entry. 2025-07-08 11:38:12 +02:00
Sebastian Mohr
9cd1a50785 Added git blame ignore 2025-07-08 11:38:12 +02:00
Sebastian Mohr
98377ab5f6 Split library file into different files inside library folder. 2025-07-08 11:38:12 +02:00
Šarūnas Nejus
3d364e4666
Only consider release collections in mbcollection plugin (#5856)
Currently, `mbcollection` takes the first collection it finds (if the
user does not explicitely indicates one in the configuration).

The problem is that the user may have collections of types that we are
not interested in (e.g. recording collections, artist collections,
etc.).

Since the `get_collections` response returns the collections types, we
can only keep the `release` collections.
2025-07-07 16:31:05 +01:00
Nicolas Mémeint
eb497eee1a Only consider release collections in mbcollection plugin 2025-07-07 13:25:25 +02:00
Šarūnas Nejus
f461651797
Minor improvements to deezer plugin typing. (#5814)
Added some more typehints to deezer plugin.

I know, it is properly not used much and we don't even have test for the
deezer plugin but I want to make this a bit more maintainable, mainly to
prepare for https://github.com/beetbox/beets/pull/5787 and make
migration a bit easier.
2025-07-07 12:14:20 +01:00
Sebastian Mohr
50604b0510 Fixed linting issue after rebase. 2025-07-07 11:40:51 +02:00
Sebastian Mohr
04a3dd2169 Adjusted typehint for search api. Removed optional none from filter. 2025-07-07 11:37:02 +02:00
Sebastian Mohr
1f15598294 Moved constants back to top. 2025-07-07 11:37:02 +02:00
Sebastian Mohr
6ab0f8d3a7 Removed old docstring. 2025-07-07 11:37:02 +02:00
Sebastian Mohr
085b89b70b Minor improvements to deezer plugin typing. 2025-07-07 11:37:02 +02:00
Sebastian Mohr
59ecfd9a49 Moved fetch_data and _get_track function. 2025-07-07 11:36:38 +02:00
Martin Atukunda
a64acf8aa2
Merge branch 'master' into feature/add-artist-to-item-entry-template 2025-07-07 09:35:15 +03:00
J0J0 Todos
a01e603492
Support m3u8 ending in playlist plugin (#5829)
m3u8 files are technically supported in the playlist plugin, only the
difference in the file ending prevented usage of such files.
2025-07-07 08:13:16 +02:00
J0J0 Todos
cf557fb41b playlist: Use pathlib.Path and add types for is_m3u_file()
Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2025-07-07 08:05:47 +02:00
J0J0 Todos
257991c73d playlist: Changelog for #5829 2025-07-07 08:05:45 +02:00
J0J0 Todos
dcd3a9f7f4 playlist: Support m3u8 ending in playlist plugin 2025-07-07 07:58:59 +02:00
Martin Atukunda
b96f7a5068
move changelog note to the Unreleased section 2025-07-07 08:34:12 +03:00
Šarūnas Nejus
0de27cbfb3
Merge branch 'master' into feature/add-artist-to-item-entry-template 2025-07-06 16:43:37 +01:00
Šarūnas Nejus
d5f87264e9
Rewrite and speed up query tests (#5813)
Previously:

```sh
Poe => pytest -p no:cov test/test_query.py --durations=10
=============================================================================== test session starts ===============================================================================
platform linux -- Python 3.9.20, pytest-8.3.5, pluggy-1.5.0
cachedir: /tmp/pytest_cache
rootdir: /home/sarunas/repo/beets
configfile: setup.cfg
plugins: anyio-4.9.0, xdist-3.6.1, requests-mock-1.12.1, flask-1.3.0
collected 133 items                                                                                                                                                               

test/test_query.py .....................................................................................................................................                 [133/133]

============================================================================== slowest 10 durations ===============================================================================
0.13s call     test/test_query.py::NotQueryTest::test_type_none
0.12s call     test/test_query.py::NotQueryTest::test_fast_vs_slow
0.11s call     test/test_query.py::GetTest::test_singleton_0
0.11s call     test/test_query.py::NotQueryTest::test_type_substring
0.11s call     test/test_query.py::RelatedQueriesTest::test_filter_items_by_common_field
0.11s call     test/test_query.py::RelatedQueriesTest::test_get_items_filter_by_album_field
0.11s call     test/test_query.py::NotQueryTest::test_type_boolean
0.11s call     test/test_query.py::NotQueryTest::test_type_or
0.11s call     test/test_query.py::NotQueryTest::test_type_numeric
0.11s call     test/test_query.py::NotQueryTest::test_type_true
=============================================================================== 133 passed in 9.94s ===============================================================================
```

Now:
```sh
Poe => pytest -p no:cov test/test_query.py --durations=10
=============================================================================== test session starts ================================================================================
platform linux -- Python 3.9.20, pytest-8.3.5, pluggy-1.5.0
cachedir: /tmp/pytest_cache
rootdir: /home/sarunas/repo/beets
configfile: setup.cfg
plugins: anyio-4.9.0, xdist-3.6.1, requests-mock-1.12.1, flask-1.3.0
collected 129 items                                                                                                                                                                

test/test_query.py .................................................................................................................................                      [129/129]

=============================================================================== slowest 10 durations ===============================================================================
0.10s setup    test/test_query.py::TestRelatedQueries::test_related_query[match-album-with-item-field-query]
0.09s setup    test/test_query.py::TestGet::test_get_query[''-['first', 'second', 'third']]
0.09s setup    test/test_query.py::TestPathQuery::test_explicit[exact-match]
0.09s setup    test/test_query.py::TestQuery::test_value_type[parse-true]
0.08s setup    test/test_query.py::TestDefaultSearchFields::test_search[album-match-album]
0.02s call     test/test_query.py::TestGet::test_query_logic[SubstringQuery('album', 'ba', fast=True)-{'third'}]
0.02s call     test/test_query.py::TestGet::test_query_logic[NoneQuery('rg_track_gain', True)-set()]
0.02s call     test/test_query.py::TestGet::test_query_logic[NumericQuery('year', '2001..2002', fast=True)-{'third'}]
0.02s call     test/test_query.py::TestGet::test_query_logic[RegexpQuery('artist', re.compile('^t'), fast=True)-{'first'}]
0.02s call     test/test_query.py::TestGet::test_query_logic[OrQuery([BooleanQuery('comp', 1, fast=True), NumericQuery('year', '2002', fast=True)])-{'third'}]
=============================================================================== 129 passed in 2.53s ================================================================================
```
2025-07-06 16:24:46 +01:00
Šarūnas Nejus
443ed578dc
Standardize abstract methods for coverage 2025-07-06 16:15:30 +01:00
Šarūnas Nejus
09b22949c0
Refactor test_query
And rewrite test_query.py
2025-07-06 16:15:30 +01:00
Šarūnas Nejus
2c6f314f4f
Replace assertNegationProperties 2025-07-06 16:15:29 +01:00
Šarūnas Nejus
2b306de0fe
Replace assertInResult and assertNotInResult 2025-07-06 16:15:29 +01:00
Šarūnas Nejus
7165b04a22
Move queries and types to respective modules (#5775)
This PR moves query and type definitions away from `library.py` to
`dbcore` to improve modularity and organization.

**Key Changes:**

*   **Query and Type Relocation:**
* `PathQuery` and `SingletonQuery` moved from `beets.library` to
`beets.dbcore.query`.
* `DateType`, `PathType` (and its variants `NullPathType`),
`MusicalKey`, and `DurationType` moved from `beets.library` to
`beets.dbcore.types`.
* The `BLOB_TYPE` definition was moved from `beets.library` to
`beets.dbcore.query` and then referenced in `beets.dbcore.types`.
* The `human_seconds_short` utility function was moved from `beets.ui`
to `beets.util` due to circular dependency.
*   **Test Modernization:**
* The `PathQueryTest` class in `test/test_query.py` has been rewritten
to use `pytest.mark.parametrize` for more concise and readable test
cases.
* **Import Updates:** All internal references to these moved classes and
functions have been updated across the codebase.
2025-07-06 16:14:46 +01:00
Šarūnas Nejus
9d088ab69f
Move human formatting functions under beets.util.units 2025-07-06 16:09:50 +01:00
Šarūnas Nejus
8937978d5f
Refactor PathQuery and add docs 2025-07-06 16:09:50 +01:00
Šarūnas Nejus
45f92ac641
Remove case_sensitive from PathQuery.__init__
The case_sensitive parameter was only used in tests, which now use
monkeypatch to control the behavior of util.case_sensitive() instead.
This simplifies the PathQuery initialization logic while maintaining
test coverage.
2025-07-06 16:09:50 +01:00
Šarūnas Nejus
a38918380d
Rewrite path query tests using pytest.mark.parametrize
And remove `force_implicit_query_detection` attribute from `PathQuery`
class.
2025-07-06 16:09:49 +01:00
Šarūnas Nejus
b40ce836d5
Add NullPathType and types to PathType 2025-07-06 16:09:49 +01:00
Šarūnas Nejus
1a045c9166
Copy paste query, types from library to dbcore 2025-07-06 16:03:46 +01:00
Martin Atukunda
54e76368d0
Avoid rendering extraneous separators
handling cases where the artist or album data might be missing to avoid
rendering extraneous separators. Suggested by Copilot.
2025-07-06 12:22:02 +03:00
Martin Atukunda
8ea7346575
Merge branch 'master' into feature/add-artist-to-item-entry-template 2025-07-06 12:14:48 +03:00
J0J0 Todos
2a896d48b9
Add --remove option to duplicates plugin (#5832)
The duplicates plugin currently only supports deleting files entirely,
sometimes it's desired to only fix the library and keep files in place.
This PR adds this possibility.
2025-07-06 08:56:45 +02:00
J0J0 Todos
7c22cd635c duplicates: Add changelog for --remove option 2025-07-05 07:24:26 +02:00
J0J0 Todos
47eee070ba duplicates: remove or delete options mutually exclusive
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-05 07:22:33 +02:00
J0J0 Todos
549847bfd8 duplicates: Add docs for --remove option 2025-07-05 07:22:28 +02:00
J0J0 Todos
537a71ff82 duplicates: Add --remove option to duplicates plugin
Removes from library but keeps files.
2025-07-05 07:17:59 +02:00
Noor
ac96b9b64e
Preserve line breaks for example cases in substitution plugin docs (#5846)
## Description

Adds line block markup to example substitutions in the plugin
documentation, so that each case is shown on a separate line:

> The replacement can be an expression utilising the matched regex,
allowing us to create more general rules. Say for example, we want to
sort all albums by multiple artists into the directory of the first
artist. We can thus capture everything before the first ,, `` &`` or ``
and``, and use this capture group in the output, discarding the rest of
the string.
> 
> ```yaml
> substitute:
>  ^(.*?)(,| &| and).*: \1
> ```
>
> This would handle all the below cases in a single rule:
>
>> Bob Dylan and The Band -> Bob Dylan
>> Neil Young & Crazy Horse -> Neil Young
>> James Yorkston, Nina Persson & The Second Hand Orchestra -> James
Yorkston
2025-07-02 18:40:37 +00:00
dhruvravii
dd6cb538ac
Fix: Spotify plugin unable to recognize Chinese and Japanese albums. (#5705)
Fixes an issue where each spotify query was converted to ascii before sending. Adds a 
new config option to enable legacy behaviour.

A file called japanese_track_request.json was made to mimic the Spotify
API response since I don't have the credentials. Entries in that will
need to be modified with the actual entries.

Co-authored-by: Sebastian Mohr <sebastian@mohrenclan.de>
Co-authored-by: Sebastian Mohr <39738318+semohr@users.noreply.github.com>
Co-authored-by: J0J0 Todos <2733783+JOJ0@users.noreply.github.com>
2025-07-01 11:08:54 +02:00
Šarūnas Nejus
a005941a56
Fix pipx install action (#5841)
## Fix pipx-install-action Windows compatibility issue

Replace `BrandonLWhite/pipx-install-action@v1.0.3` with
`threeal/pipx-install-action@v1.0.0` in CI workflow due to Windows
compatibility issues.

**Changes:**
- Switch to alternative pipx-install-action that works on Windows
- Add explicit package specification for poethepoet and poetry
- Resolves GitHub issue:
https://github.com/BrandonLWhite/pipx-install-action/issues/62

**Edit**: received a reply from `pipx-install-action` maintainer with a
fix: simply remove the breaking cache from GitHub Actions: this worked
fine.

Thus I reverted the commit which introduced another action on Windows.
The only change that this PR makes is `pipx-install-action` version
upgrade.
2025-06-29 15:06:53 +01:00
Šarūnas Nejus
9926a1ac3c
Revert "Try using threeal/pipx-install-action@v1.0.0 for CI tests"
This reverts commit ab9b2e0b69.
2025-06-29 13:43:48 +01:00
Šarūnas Nejus
ab9b2e0b69
Try using threeal/pipx-install-action@v1.0.0 for CI tests
I have reported the issue with BrandonLWhite/pipx-install-action@v1.0.3
failing on Windows here:
https://github.com/BrandonLWhite/pipx-install-action/issues/62
2025-06-24 12:08:33 +01:00
Šarūnas Nejus
d5bd24bb64
Update pipx-install-action to fix caching errors 2025-06-24 12:08:33 +01:00
Šarūnas Nejus
8fd20b9b67
Fix the MusicBrainz search not taking into account the album/recording aliases (#5821)
When searching on MusicBrainz, beets does not add the `alias` field that
allows for searching on the entity aliases.

As per [the MusicBrainz Indexed Search
Syntax](https://musicbrainz.org/doc/Indexed_Search_Syntax#Search_Fields_9):
> alias | (part of) any alias attached to the release group (diacritics
are ignored)
> [...]
> release | (part of) the title of any of the releases in the release
group

By adding the `alias` field assigned with the entity title, the search
returns better results for titles that can be aliased.

The problem can be reproduced with the following album:
https://musicbrainz.org/release-group/b5b4eed2-e871-4268-80bb-7625ee0c6cd0:
- Currently, beets searches using the following query: [`release:(rude
lose dance \- single) tracks:(1)
artist:(minami)`](https://musicbrainz.org/search?query=release%3A%28rude+lose+dance+%5C-+single%29+tracks%3A%281%29+artist%3A%28minami%29&type=release_group&limit=25&method=advanced)
- We can see that the correct album cannot be found (even after 5
pages!)
- With this PR, beets now searches using the following query:
[`release:(rude lose dance \- single) alias:(rude lose dance \- single)
tracks:(1)
artist:(minami)`](https://musicbrainz.org/search?query=release%3A%28rude+lose+dance+%5C-+single%29+alias%3A%28rude+lose+dance+%5C-+single%29+tracks%3A%281%29+artist%3A%28minami%29&type=release_group&limit=25&method=advanced)
  - We can see that the correct album is now found in 1st position!

Tests had to be updated due to the addition of the `alias` criteria.
2025-06-15 21:54:45 +01:00
Nicolas Mémeint
4893cee5e5 Fix the MusicBrainz search not taking into account the album/recording aliases 2025-06-15 21:33:20 +01:00
Sebastian Mohr
66864fcc27
Minor improvements to spotify plugin typing. (#5815)
## Description

Added some more typehints to the spotify plugin. Also added a method to
get the tokenfile and changed to logic for the handle_response to use
`requests.request`.

This is done mainly to prepare for
https://github.com/beetbox/beets/pull/5787, see also
https://github.com/beetbox/beets/pull/5814
2025-06-11 15:19:46 +02:00
Šarūnas Nejus
0a458966ae
[Inner loop] Require langdetect when running tests (#5801)
Fixes #5797.

Today, local tests (`poe test`) will fail to run if `langdetect` is not
installed. This change makes `langdetect` required for test runs.

Although this is easy to resolve with `poetry install --all-extras`, the
code intends to work without that; it's a worthwhile fix.
2025-06-01 00:12:21 +01:00