## Description
Adds the new `mbpseudo` plugin, that proactively searches for pseudo-releases during import and
adds them as candidates. Since it also depends on MusicBrainz, there are
some special considerations for the default logic (which is now a plugin
as well). However, at the very least it expects a list of desired [names
of scripts](https://en.wikipedia.org/wiki/ISO_15924) in the
configuration, for example:
```yaml
mbpseudo:
scripts:
- Latn
```
It will use that to search for pseudo-releases that match some of the
desired scripts, but will only do so if the input tracks match against
an official release that is not in one of the desired scripts.
## Standalone Usage
This would be the recommended approach, which involves disabling the
`musicbrainz` plugin. The `mbpseudo` plugin will manually delegate the
initial search to it. Since the data source of official releases will
still match MusicBrainz, weights are still relevant:
```yaml
mbpseudo:
source_weight: 0.0
scripts:
- Latn
musicbrainz:
source_weight: 0.1
```
A setup like that would ensure that the pseudo-releases have slightly
more preference when choosing the final proposal.
## Combined Usage
I initially thought it would be important to coexist with the
`musicbrainz` plugin when it's enabled, and reuse as much of its data as
possible to avoid redundant calls to the MusicBrainz API. I have the
impression this is not really important in the end, and maybe things
could be simplified if we decide that both plugins shouldn't coexist.
As it is right now, using both plugins at the same time would still
work, but it'll only avoid redundancy if `musicbrainz` emits its
candidates before `mbpseudo`, ~which is why I modified the
plugin-loading logic slightly to guarantee ordering. I'm not sure if you
think this could be an issue, but I think the `musicbrainz` plugin is
also used by other plugins and I can imagine it's good to guarantee the
order that is declared in the configuration?~
If the above is fulfilled, the `mbpseudo` plugin will use listeners to
intercept data emitted by the `musicbrainz` plugin and check if any of
them have pseudo-releases that might be desirable.
Spotify has deprecated many of its APIs that we are still using, wasting
calls and time on these API calls; also results in frequent rate limits.
This PR introduces a dedicated `AudioFeaturesUnavailableError` and
tracks audio feature availability with an `audio_features_available`
flag. If the audio-features endpoint returns an HTTP 403 error, raise a
new error, log a warning once, and disable further audio-features
requests for the session.
The plugin now skips attempting audio-features lookups when disabled
(avoiding repeated failed calls and rate-limit issues).
Also, update the changelog to document the behavior.
## To Do
- [x] Changelog. (Add an entry to `docs/changelog.rst` to the bottom of
one of the lists near the top of the document.)
Add a dedicated AudioFeaturesUnavailableError and track audio-features
availability with an audio_features_available flag. If the audio-features
endpoint returns HTTP 403, raise the new error, log a warning once, and
disable further audio-features requests for the session. The plugin now
skips attempting audio-features lookups when disabled (avoiding repeated
failed calls and potential rate-limit issues).
Also update changelog to document the behavior.
- Use self.config instead of global config, which was interfering whith
other plugin tests (test_importsource) when run alongside (eg in CI)
- Rename test
## Description
Updates the docs chapter "Handling Paths" describing how to modernise
old code and intentionally includes historical details. Examples should
further guide contributors while refactoring.
Also moved the guide from the contribution guide into the dev docs.
Fixes#5575Fixes#5822Fixes#6082Fixes#6026
### Python 3.13 compatibility
- Updated `librosa` dependency from `^0.10.2.post1` to `>=0.11` where a
bug with `numpy` types is fixed.
- Updated transitive `audioread` dependency which now pulls in
`standard-aifc`, `standard-sunau`, and `audioop-lts` packages for Python
3.13 and above.
### Python 3.14 compatibility
- Python 3.14 introduced stricter requirements for input type in low
level `fnctl.ioctl` function which we used to detect the terminal width.
I replaced it with high-level, cross-platform
`shutil.get_terminal_size()`.
- I'm not adding official support yet, as I faced many issues trying to
install `librosa` dependencies on Python 3.14. It should work fine for
people that do not use `autobpm`, and it may even work for those that do
- if they have the right set of system dependencies available. We can
revise this once we drop Python 3.9 in a couple of days.
## Description
This small PR allows ftintitle to process even if the artist/s in the
artist and albumartist fields are the same.
This fixes the problem with a lot of singles like [Porter Robinsons song
Shelter](https://musicbrainz.org/release/ccc261b9-e4cc-4965-81b8-7c92a5d28601)
and even [Rihanas's album
Umbrella](https://musicbrainz.org/release/60f8f1f5-485b-4637-8574-23f2bb98531f)
Without this fix the songs would end up with the feat. artist in the
artists folder-name and not the feat. in the songs filename.
Without:
`Rihanna feat. JAY‐Z\(2007) Umbrella\01 - Umbrella (radio edit).flac`
`Porter Robinson feat. Madeon\(2016) Shelter\01 - Shelter.flac`
With:
`Rihanna\(2007) Umbrella\01 - Umbrella (radio edit) feat. JAY‐Z.flac`
`Porter Robinson\(2016) Shelter\01 - Shelter feat. Madeon.flac`
I left the current way ftintitle works as the default so stuff doesn't
randomly change for users, but maybe it should is changed as the PR that
changed the ftintitle's behavour is only ~2 month old
https://github.com/beetbox/beets/pull/5943
Thoughts?
I'm also not super happy with the args name
`skip_if_artist_and_album_artists_is_the_same` so any suggestion what it
could be instead is more than welcome 😅
## To Do
<!--
- If you believe one of below checkpoints is not required for the change
you
are submitting, cross it out and check the box nonetheless to let us
know.
For example: - [x] ~Changelog~
- Regarding the changelog, often it makes sense to add your entry only
once
reviewing is finished. That way you might prevent conflicts from other
PR's in
that file, as well as keep the chance high your description fits with
the
latest revision of your feature/fix.
- Regarding documentation, bugfixes often don't require additions to the
docs.
- Please remove the descriptive sentences in braces from the enumeration
below,
which helps to unclutter your PR description.
-->
- [x] Documentation. (If you've added a new command-line flag, for
example, find the appropriate page under `docs/` to describe it.)
- [x] Changelog. (Add an entry to `docs/changelog.rst` to the bottom of
one of the lists near the top of the document.)
- [x] Tests. (Very much encouraged but not strictly required.)
This PR adds support for nexttrack keypress in the web plugin.
It uses feature detection for the Media Session API, and then
instantiates a metadata object for the session, and adds the specific
action handler for the nexttrack keypress.