diff --git a/beets/metadata_plugins.py b/beets/metadata_plugins.py index 1be2d5821..952985980 100644 --- a/beets/metadata_plugins.py +++ b/beets/metadata_plugins.py @@ -39,7 +39,10 @@ def candidates(items, *args, **kwargs) -> Iterable[AlbumInfo]: """Return matching album candidates from all metadata source plugins.""" for plugin in find_metadata_source_plugins(): for info in plugin.candidates(items, *args, **kwargs): - send("albuminfo_received", info=info, items=items) + send( + "albuminfo_received", + info=plugin.before_album_info_emitted(items, info), + ) yield info @@ -60,7 +63,10 @@ def album_for_id( """ for plugin in find_metadata_source_plugins(): if info := plugin.album_for_id(album_id=_id): - send("albuminfo_received", info=info, items=items) + send( + "albuminfo_received", + info=plugin.before_album_info_emitted(items, info), + ) return info return None @@ -132,6 +138,18 @@ class MetadataSourcePlugin(BeetsPlugin, metaclass=abc.ABCMeta): found.""" raise NotImplementedError + def before_album_info_emitted( + self, + items: Iterable[Item], + album_info: AlbumInfo, + ) -> AlbumInfo: + """Called after an :py:class:`AlbumInfo` object has been found for a set + of :py:class:`Item` objects but before the ``albuminfo_received`` + :py:type:`plugins.EventType` has been sent. The returned instance will + be the payload of the event. + """ + return album_info + @abc.abstractmethod def track_for_id(self, track_id: str) -> TrackInfo | None: """Return a :py:class:`TrackInfo` object or None if no matching release was diff --git a/beetsplug/mbpseudo.py b/beetsplug/mbpseudo.py index 557c762ab..0a4e304f2 100644 --- a/beetsplug/mbpseudo.py +++ b/beetsplug/mbpseudo.py @@ -100,9 +100,6 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): pass self.register_listener("pluginload", self._on_plugins_loaded) - self.register_listener( - "albuminfo_received", self._on_album_info_received - ) self.register_listener("album_matched", self._adjust_final_album_match) # noinspection PyMethodMayBeStatic @@ -116,12 +113,13 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): " the mbpseudo plugin" ) - def _on_album_info_received( + @override + def before_album_info_emitted( self, - info: AlbumInfo, items: Iterable[Item], + album_info: AlbumInfo, ): - if isinstance(info, PseudoAlbumInfo): + if isinstance(album_info, PseudoAlbumInfo): for item in items: # particularly relevant for reimport but could also happen during import if "mb_albumid" in item: @@ -131,10 +129,12 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): self._log.debug( "Using {0} release for distance calculations for album {1}", - info.determine_best_ref(list(items)), - info.album_id, + album_info.determine_best_ref(list(items)), + album_info.album_id, ) + return album_info + @override def candidates( self, diff --git a/docs/changelog.rst b/docs/changelog.rst index aad3181d6..f3ca6a78d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -57,8 +57,9 @@ Bug fixes: For plugin developers: -- The plugin event ``albuminfo_received`` now has a second argument ``items`` - with the files that were used in the corresponding search. +- Metadata plugins can now implement a ``before_album_info_emitted`` method to + modify ``AlbumInfo`` objects before they are emitted as part of the + ``albuminfo_received`` event. - 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. diff --git a/docs/dev/plugins/events.rst b/docs/dev/plugins/events.rst index 67a3f8edc..aaab9ccd7 100644 --- a/docs/dev/plugins/events.rst +++ b/docs/dev/plugins/events.rst @@ -175,7 +175,7 @@ registration process in this case: or adjustments (e.g., ``mbsync``). ``albuminfo_received`` - :Parameters: ``info`` (|AlbumInfo|), ``items`` (iterable of |Item|) + :Parameters: ``info`` (|AlbumInfo|) :Description: Like ``trackinfo_received`` but for album-level metadata. ``album_matched`` diff --git a/test/plugins/test_mbpseudo.py b/test/plugins/test_mbpseudo.py index 717aa032c..316d2e3c7 100644 --- a/test/plugins/test_mbpseudo.py +++ b/test/plugins/test_mbpseudo.py @@ -141,7 +141,7 @@ class TestMBPseudoPlugin(PluginMixin): item["title"] = "百花繚乱" # if items don't have mb_*, they are not modified - mbpseudo_plugin._on_album_info_received(pseudo_info, [item]) + mbpseudo_plugin.before_album_info_emitted([item], pseudo_info) assert pseudo_info.album == item.title pseudo_info.use_pseudo_as_ref() @@ -153,7 +153,7 @@ class TestMBPseudoPlugin(PluginMixin): assert item.get("mb_trackid") == "mb_tid" # if items have mb_*, they are deleted - mbpseudo_plugin._on_album_info_received(pseudo_info, [item]) + mbpseudo_plugin.before_album_info_emitted([item], pseudo_info) assert pseudo_info.album == item.title assert item.get("mb_albumid") == "" assert item.get("mb_trackid") == ""