Commit graph

13088 commits

Author SHA1 Message Date
J0J0 Todos
edd366e766 lastgenre: Fix album not falling back to artist stage
which was the usual behaviour in lastgenre ever since and it should be
kept that way. Also refactor "if track" to use a similar notation for
overall code readability.
2025-04-09 22:52:07 +02:00
J0J0 Todos
2b276e07f1 lastgenre: Log unconfigured fallback 2025-04-09 22:52:07 +02:00
J0J0 Todos
e20cf7f20b lastgenre: Rework combine, stringify, count reduction
- Rename method from _combine_genres() to _combine_resolve_and_log() to
  make clear that it not only combines new and old genres but also
  resolves them (which in this plugin's wording means "do the magic" of
  canonicalizationm, whitelist checking and reducing to a configured
  genre count).

- Clarify in _resolve docstring that a possible outcome might be all
  genres being removed.

- Add an additional log message telling which existing genres are taken
  into account BEFORE "the magic happens".

- Rename _to_delimited_genre_string() to _format_and_stringify()

- Move count reduction logic to _resolve_genres()

- Fix and rename a test
2025-04-09 22:52:07 +02:00
J0J0 Todos
3291aa03e7 lastgenre: Describe in docstring what _resolve_genres does 2025-04-09 22:52:07 +02:00
J0J0 Todos
15f4b2ac29 lastgenre: Place to_delim. func near _get_genre
and the other helpers.
2025-04-09 22:52:07 +02:00
J0J0 Todos
eba3dc15fd lastgenre: Final label only if required in _get_genre() 2025-04-09 22:52:07 +02:00
J0J0 Todos
94f78ae70f lastgenre: Prevent returning empty genre list
As reported in #5649 when new last.fm genres were found, they still might
get kicked out by the whitelist check in _resolve_genres(). This might
lead to _combine_genres() returning an empty list.

The desired outcome though is that since still nothing worthwhile was
found, the next stage should be entered - which in this case is,
returning with the configured fallback genre (or the default fallback
None).

The any() check makes sure this is the case and moving out the
string conversion from _combine_genres() makes this code slightly more
readable.
2025-04-09 22:52:07 +02:00
Sebastian Mohr
559b87ee56 Updated changelog.
Also edited my previous changelog entry to streamline
typehint entries a bit.
2025-04-08 18:29:54 +02:00
Sebastian Mohr
753bdd9106 Added typehints for _instance, _classes and for class attributes. 2025-04-08 18:15:08 +02:00
Sebastian Mohr
024e13bc1a
Merge branch 'master' into typehints-plugins 2025-04-08 15:45:15 +02:00
Šarūnas Nejus
1cec93e695
(docs) Fix Broken link for Arch Linux package (#5688) 2025-04-08 14:38:45 +01:00
racehd
0f2b8b794a Fix Broken link for Arch Linux package 2025-04-08 15:33:43 +02:00
Benedikt
6895a946e5
Fix typing_extensions requirement inconsistency (#5700)
Typing Extensions is an optional requirement for `python>3.10`, thus
TypeVarTuple and Unpack need another import in higher python versions as
`typing_extensions` is not available

see https://docs.python.org/3.10/library/typing.html for supported types

close #5695
2025-04-08 15:20:30 +02:00
Sebastian Mohr
58ab2c696a Removed typevar from typing_extensions as it is available in typing since
like python 3.3
2025-04-02 17:25:53 +02:00
Sebastian Mohr
e6ce818913 Added some more typehints where missing. 2025-04-02 16:28:41 +02:00
Sebastian Mohr
19b3330fc8 Fixed circular import of distance by consistently importing if whenever
it is needed.
2025-04-02 16:07:00 +02:00
Sebastian Mohr
0cc0db313a Added typehints to the plugins file. 2025-04-02 15:57:16 +02:00
Sebastian Mohr
bcae6429a4 typing extensions is an optional requirement for py>3.10, therefore
TypeVarTuple and Unpack need additional handling see
https://docs.python.org/3.9/library/typing.html

see #5695
2025-04-02 14:43:38 +02:00
Šarūnas Nejus
030fd1fcf5
Update README.rst (#5691)
Fixes #5669

SCREENSHOT ATTACHED-

![image](https://github.com/user-attachments/assets/76bc254c-0ce6-4b56-9705-ff39a0b67502)
2025-03-27 04:22:26 +00:00
Unnati
ecbb0edd15
Update README.rst 2025-03-27 09:23:09 +05:30
Unnati
656dcf1a9d
Merge branch 'master' into Unnati-techie-updated-broken-img-readme 2025-03-27 09:13:46 +05:30
Šarūnas Nejus
19ee164560
Update python in CI (#5544)
Bump python version in the CI to current versions.

This is the same as #5503 that for some reason got closed when the merge
of the `drop-py38` branch happened
2025-03-27 02:23:53 +00:00
Unnati
a48683bb62
Update README.rst 2025-03-26 20:32:39 +05:30
Fabio Alessandro Locati
4b04d0e7c8
Update python to current supported versions. 2025-03-24 22:12:58 +01:00
Bob Cotton
670a3bcd17
Add beets-id3extract to community plugins (#5660)
Add link to community plugin beets-id3extract
2025-03-12 07:14:38 +00:00
Allen
b7521f9a0b
fix: plugins/listenbrainz: Fix UnboundLocalError in cases where 'mbid' is not defined (#5651)
Fix ocurrence of `UnboundLocalError` in plugins/listenbrainz >
`get_tracks_from_listens()` when `mbid` is not available.
Removed a print statment.
Fix link to config.yaml.
Fix link to Listenbrainz "get the token" documentation.

Co-authored-by: Šarūnas Nejus <snejus@protonmail.com>
2025-03-12 07:08:53 +00:00
Jack Wilsdon
1f93867401
Fix IMBackend#compare on ImageMagick 7.1.1-44 (#5650) 2025-02-28 09:09:41 +00:00
Jack Wilsdon
5c1817c780 Fix IMBackend#compare on ImageMagick 7.1.1-44 2025-02-27 01:03:16 +00:00
Pierre Ayoub
5c8f1c1ee5
Fix convert plugin attempting to process a non-media file (#5261)
## Description

My library is managed using Beets for organization and
[git-annex](https://git-annex.branchable.com/) as storage backend.
Therefore when using this system, while my library files always exists
on my filesystem, some files may be empty (without content). In this
case, when I'm running the `convert` plugin, I don't wants it to process
files which are empty (same apply for any Beets plugin). Hence, I added
a check that the file is readable as a `MediaFile` before doing any
process.

Before this fix, trying to encode an empty file would have lead to an
error while leaving `convert` doing its side-effects **and** `convert`
would also copy empty files to destination for files that doesn't need
to be re-encoded.

In my case, this is empty files, but the problem can be anything else
(depending on the storage backend) and/or corrupted files. Conclusion, I
think **checking that the file is readable is always recommended before
proceeding to heavy operation** like this.
2025-02-20 16:23:14 +00:00
Šarūnas Nejus
fe28957358
Lyrics: Resurrect translations and refactor ReST and command line handling (#5485)
🎵 The Refactoring Blues 🎵 by [Claude](https://claude.ai)

Verse 1:
Got those lyrics plugin blues
Cleaning up some messy code
Moving classes, fixing views
Making changes down the road

Chorus:
We're refactoring tonight
Making the codebase clean and bright
Translation's got a brand new home
And ReST files found their own

Verse 2:
Added Microsoft Translate
Keeping tokens safe and sound
Config options up-to-date
Better structure all around

Bridge:
Path operations simplified
Groups of artists, neat and tied
Error handling's looking fine
Comments clear along each line

Verse 3:
RestFiles in their own class now
Cleaning imports, showing how
Better typing makes it clear
What should go and what stays here

Final Chorus:
We're refactoring tonight
Making the codebase clean and bright
Translation's got a brand new home
And our code can stand alone!

—  inspired by _the diff_

---

### Technical Changes

- Replaced deprecated and broken Bing translations by Microsoft
Translator API
  - Isolated all functionality in the `Translator` class.
  - Updated translation settings configuration.
  - Added support for synced lyrics from LRCLib.
- Added support for preserving existing translations to help users to
manage their characters quota.
  - Added error handling and logging
  - Added tests

- Created RestFiles class for ReST document handling
  - Simplified path operations using pathlib
  - Added tests

- Improved command line options handling

#### Caching of translations
The plugin will not re-translate lyrics if translations already exist,
see

```fish
$ beet -v lyrics albumartist::Sel karta -f
...
lyrics: LyricsPlugin: Fetching lyrics for Sel - Saulės Miestas
lyrics: LRCLib: Fetching JSON from https://lrclib.net/api/get
lyrics: LyricsPlugin: 🟢 Found lyrics: 32275 | 1996 / Neįvertinta Karta: Sel - Saulės Miestas
lyrics: Translator: Posting data to https://api.cognitive.microsofttranslator.com/translate
lyrics: Translator: 🟢 Translated lyrics to EN

$ beet -v lyrics albumartist::Sel karta -f
...
lyrics: LyricsPlugin: Fetching lyrics for Sel - Saulės Miestas
lyrics: LRCLib: Fetching JSON from https://lrclib.net/api/get
lyrics: LyricsPlugin: 🟢 Found lyrics: 32275 | 1996 / Neįvertinta Karta: Sel - Saulės Miestas
lyrics: Translator: 🔵 Translations already exist
```
2025-02-20 04:19:08 +00:00
Šarūnas Nejus
4da72cb5f8
Ignore _typing.py coverage 2025-02-20 03:47:04 +00:00
Šarūnas Nejus
b713d72612
translations: use a more distinctive separator
I found that the translator would sometimes replace the pipe character
with another symbol (maybe it got confused thinking the character is
part of the text?).

Added spaces around the pipe to make it more clear that it's definitely
the separator.
2025-02-20 03:47:04 +00:00
Šarūnas Nejus
43032f7bc7
translations: make sure we do not re-translate 2025-02-20 03:47:04 +00:00
Šarūnas Nejus
7893766e4c
Improve flags structure and add tests 2025-02-20 03:47:04 +00:00
Šarūnas Nejus
c95156adcd
Refactor writing rest files 2025-02-20 03:47:04 +00:00
Šarūnas Nejus
d7201062a8
Resurrect translation functionality 2025-02-20 03:47:04 +00:00
Šarūnas Nejus
c315487bd2
Importer typehints and small importer refactor (#5611)
## Description

Hello y'all. 

One of the dev from the [beets-flask
app](https://github.com/pSpitzner/beets-flask) here. We are extending
the `ImportSession` in our application to get the interactive imports
working in our application. Overall that was not a too pleasant
experience as a ton of typehints are missing in that area of the beets
code. This PR wants to fix this ;)

### Changes

Moved importer state logic into a dataclass. Is clearer and more
isolated now in my opinion, we are not using it but I found it quite
confusing when looking at it.

Added a ton of typehints to the `importer.py` file. Predominantly the
`ImportSession`, `ImportTask` (and derivatives) and pipeline stage
decorators are now (hopefully) completely typed. Additionally I fixed
some typhint issues in the `util.__init__.py` file, mainly related to
the `PathLike` type.

If you have some strong opinions about any of the changes feel free to
revert or edit the PR.

Best,
Sebastian

P.S: I noticed that beets does not use Abstract Base Classes is there
any reason for that or is it just of historic nature? I think some Base
Classes could be adapted to use an ABC metaclass quite easily.
2025-02-18 09:37:29 +00:00
Sebastian Mohr
918fd863f3
Merge branch 'master' into importer-typehints-and-refactor 2025-02-17 23:02:00 +01:00
J0J0 Todos
1c5aaf5532
smartplaylist: change encoding of additional field (#5563)
## Description

URL-encode additional item `fields` within generated EXTM3U playlists
instead of JSON-encoding them.
This is because JSON-encoding additional fields/attributes made it
difficult to parse the `EXTINF` line but using URL-encoding for these
values makes parsing easy (because URL-encoded values cannot contain
commas, quotation marks and spaces; see
[here](https://github.com/mgoltzsche/beets-webm3u/blob/v0.6.4/beetsplug/webm3u/playlist.py#L102)
and
[here](https://github.com/mgoltzsche/beets-webm3u/blob/v0.6.4/beetsplug/webm3u/playlist.py#L122)).

[I introduced the generation of additional EXTM3U item fields earlier
this year](https://github.com/beetbox/beets/pull/5121) and I want to
correct that now.
2025-02-17 21:49:53 +01:00
J0J0 Todos
f01707b477
Merge branch 'master' into smartplaylist-attr-url-encoding 2025-02-17 21:40:51 +01:00
Sebastian Mohr
115b502353
Merge branch 'master' into importer-typehints-and-refactor 2025-02-17 21:33:57 +01:00
Šarūnas Nejus
044818a8dd
Fix musicbrainz genres fetching (#5609)
- genres are now called tags
- tags needs to be in "mb fetch includes"
- release-group has them
- release has them
- and recording as well but we don't use them
- not sure what this outdated check was doing, it looked at "recordings"
in the valid list even though genre fetching is only included in the
`album_info` code and not `track_info` 🤷
- see musicbrainz.VALID_INCLUDES for reference
2025-02-17 20:31:24 +00:00
J0J0 Todos
2286511ebe
Merge branch 'master' into smartplaylist-attr-url-encoding 2025-02-17 21:16:09 +01:00
J0J0 Todos
795545c1fa
Merge branch 'master' into fixmbgenre 2025-02-17 21:12:46 +01:00
Sebastian Mohr
9683a5b956 See https://github.com/beetbox/beets/pull/5611#discussion_r1957433785 2025-02-17 16:30:42 +01:00
Sebastian Mohr
cf1b4d8913 See https://github.com/beetbox/beets/pull/5611#discussion_r1958356845.
Revert normpath additions
2025-02-17 16:25:41 +01:00
Sebastian Mohr
87b022e48c See https://github.com/beetbox/beets/pull/5611#discussion_r1957443692 2025-02-17 16:09:18 +01:00
Sebastian Mohr
bdabafeefd See https://github.com/beetbox/beets/pull/5611#discussion_r1957443316 2025-02-17 15:48:11 +01:00
Šarūnas Nejus
4e7b054f48
Populate bug issue template automatically (#5612)
Update documentation to use specific GitHub issue templates instead of
generic issue links. This helps users provide better structured feedback
when reporting bugs or requesting features.

This was noted in
https://github.com/beetbox/beets/issues/5610#issuecomment-2628985640
2025-02-17 00:29:26 +00:00
Šarūnas Nejus
5a9c769f5c
Link to specific bug report/feature request templates in docs 2025-02-16 23:41:00 +00:00