From 9a2dd2459f03fac58ac68e835109cd6cd72c09e5 Mon Sep 17 00:00:00 2001 From: asardaes Date: Tue, 30 Dec 2025 13:31:22 +0100 Subject: [PATCH] Introduce album_info_received event with items --- beets/autotag/match.py | 4 ++-- beets/metadata_plugins.py | 11 +++++++---- beets/plugins.py | 1 + beetsplug/mbsync.py | 4 +++- beetsplug/missing.py | 4 +++- docs/changelog.rst | 9 +++++++++ docs/dev/plugins/events.rst | 9 ++++++++- test/test_importer.py | 2 +- test/test_metadata_plugins.py | 4 ++-- 9 files changed, 36 insertions(+), 12 deletions(-) diff --git a/beets/autotag/match.py b/beets/autotag/match.py index 374ea3c13..42be5b503 100644 --- a/beets/autotag/match.py +++ b/beets/autotag/match.py @@ -120,7 +120,7 @@ def match_by_id(items: Iterable[Item]) -> AlbumInfo | None: return None # If all album IDs are equal, look up the album. log.debug("Searching for discovered album ID: {}", first) - return metadata_plugins.album_for_id(first) + return metadata_plugins.album_for_id(first, items) def _recommendation( @@ -275,7 +275,7 @@ def tag_album( if search_ids: for search_id in search_ids: log.debug("Searching for album ID: {}", search_id) - if info := metadata_plugins.album_for_id(search_id): + if info := metadata_plugins.album_for_id(search_id, items): _add_candidate(items, candidates, info) if opt_candidate := candidates.get(info.album_id): plugins.send("album_matched", match=opt_candidate) diff --git a/beets/metadata_plugins.py b/beets/metadata_plugins.py index 7c08d72a3..be56cad0e 100644 --- a/beets/metadata_plugins.py +++ b/beets/metadata_plugins.py @@ -21,12 +21,13 @@ from beets import config, logging from beets.util import cached_classproperty from beets.util.id_extractors import extract_release_id -from .plugins import BeetsPlugin, find_plugins, notify_info_yielded +from .plugins import BeetsPlugin, find_plugins, notify_info_yielded, send if TYPE_CHECKING: from collections.abc import Callable, Iterable, Iterator, Sequence - from .autotag.hooks import AlbumInfo, Item, TrackInfo + from .autotag.hooks import AlbumInfo, TrackInfo + from .library.models import Item Ret = TypeVar("Ret") @@ -95,8 +96,10 @@ def tracks_for_ids(*args, **kwargs) -> Iterator[TrackInfo]: yield from () -def album_for_id(_id: str) -> AlbumInfo | None: - return next(albums_for_ids([_id]), None) +def album_for_id(_id: str, items: Iterable[Item]) -> AlbumInfo | None: + album_info = next(albums_for_ids([_id]), None) + send("album_info_received", items=items, album_info=album_info) + return album_info def track_for_id(_id: str) -> TrackInfo | None: diff --git a/beets/plugins.py b/beets/plugins.py index 01d9d3327..61bbae123 100644 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -70,6 +70,7 @@ EventType = Literal[ "album_imported", "album_removed", "albuminfo_received", + "album_info_received", "album_matched", "before_choose_candidate", "before_item_moved", diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index 45f34e865..2292aebb0 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -102,7 +102,9 @@ class MBSyncPlugin(BeetsPlugin): continue if not ( - album_info := metadata_plugins.album_for_id(album.mb_albumid) + album_info := metadata_plugins.album_for_id( + album.mb_albumid, album.items() + ) ): self._log.info( "Release ID {0.mb_albumid} not found for album {0}", album diff --git a/beetsplug/missing.py b/beetsplug/missing.py index d2aae14e9..46bbda370 100644 --- a/beetsplug/missing.py +++ b/beetsplug/missing.py @@ -230,7 +230,9 @@ class MissingPlugin(MusicBrainzAPIMixin, BeetsPlugin): item_mbids = {x.mb_trackid for x in album.items()} # fetch missing items # TODO: Implement caching that without breaking other stuff - if album_info := metadata_plugins.album_for_id(album.mb_albumid): + if album_info := metadata_plugins.album_for_id( + album.mb_albumid, album.items() + ): for track_info in album_info.tracks: if track_info.track_id not in item_mbids: self._log.debug( diff --git a/docs/changelog.rst b/docs/changelog.rst index 5488e264f..360e8416f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,12 @@ New features: Bug fixes: +For plugin developers: + +- The ``albuminfo_received`` event has been deprecated in favor of the new + ``album_info_received`` event, which includes information about the ``Item`` + set being imported. + For packagers: Other changes: @@ -133,6 +139,9 @@ For plugin developers: - A new plugin event, ``album_matched``, is sent when an album that is being imported has been matched to its metadata and the corresponding distance has been calculated. +- The ``albuminfo_received`` event has been deprecated in favor of the new + ``album_info_received`` event, which includes information about the ``Item`` + set being imported. - Added a reusable requests handler which can be used by plugins to make HTTP requests with built-in retry and backoff logic. It uses beets user-agent and configures timeouts. See :class:`~beetsplug._utils.requests.RequestHandler` diff --git a/docs/dev/plugins/events.rst b/docs/dev/plugins/events.rst index aaab9ccd7..b856c2fab 100644 --- a/docs/dev/plugins/events.rst +++ b/docs/dev/plugins/events.rst @@ -176,7 +176,14 @@ registration process in this case: ``albuminfo_received`` :Parameters: ``info`` (|AlbumInfo|) - :Description: Like ``trackinfo_received`` but for album-level metadata. + :Description: Deprecated. Like ``trackinfo_received`` but for album-level + metadata. + +``album_info_received`` + :Parameters: ``items`` (``Sequence`` of |Item|), ``album_info`` + (|AlbumInfo|) + :Description: After searching based on the given ``items``, the specified + ``album_info`` was received. ``album_matched`` :Parameters: ``match`` (``AlbumMatch``) diff --git a/test/test_importer.py b/test/test_importer.py index 6ae7d562b..171ee17d1 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -1528,7 +1528,7 @@ class ImportPretendTest(IOMixin, AutotagImportTestCase): assert self.__run(importer) == [f"No files imported from {empty_path}"] -def mocked_get_album_by_id(id_): +def mocked_get_album_by_id(id_, _): """Return album candidate for the given id. The two albums differ only in the release title and artist name, so that diff --git a/test/test_metadata_plugins.py b/test/test_metadata_plugins.py index 684784191..c3618ba3e 100644 --- a/test/test_metadata_plugins.py +++ b/test/test_metadata_plugins.py @@ -53,7 +53,7 @@ class TestMetadataPluginsException(PluginMixin): ("tracks_for_ids", "tracks_for_ids", (["some_id"],)), # Currently, singular methods call plural ones internally and log # errors from there - ("album_for_id", "albums_for_ids", ("some_id",)), + ("album_for_id", "albums_for_ids", ("some_id", [])), ("track_for_id", "tracks_for_ids", ("some_id",)), ], ) @@ -72,7 +72,7 @@ class TestMetadataPluginsException(PluginMixin): [ ("candidates", ()), ("item_candidates", ()), - ("album_for_id", ("some_id",)), + ("album_for_id", ("some_id", [])), ("track_for_id", ("some_id",)), ], )