Introduce album_info_received event with items

This commit is contained in:
asardaes 2025-12-30 13:31:22 +01:00
parent 2f659934f2
commit 9a2dd2459f
9 changed files with 36 additions and 12 deletions

View file

@ -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)

View file

@ -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:

View file

@ -70,6 +70,7 @@ EventType = Literal[
"album_imported",
"album_removed",
"albuminfo_received",
"album_info_received",
"album_matched",
"before_choose_candidate",
"before_item_moved",

View file

@ -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

View file

@ -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(

View file

@ -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`

View file

@ -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``)

View file

@ -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

View file

@ -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",)),
],
)