diff --git a/beetsplug/musicbrainz.py b/beetsplug/musicbrainz.py index 3b49107ad6..2b9d5e9c26 100644 --- a/beetsplug/musicbrainz.py +++ b/beetsplug/musicbrainz.py @@ -90,6 +90,7 @@ def get_message(self): "isrcs", "url-rels", "release-rels", + "genres", "tags", } & set(musicbrainzngs.VALID_INCLUDES["release"]) @@ -370,6 +371,10 @@ def _merge_pseudo_and_actual_album( class MusicBrainzPlugin(MetadataSourcePlugin): + @cached_property + def genres_field(self) -> str: + return f"{self.config['genres_tag'].as_choice(['genre', 'tag'])}-list" + def __init__(self): """Set up the python-musicbrainz-ngs module according to settings from the beets configuration. This should be called at startup. @@ -382,6 +387,7 @@ def __init__(self): "ratelimit": 1, "ratelimit_interval": 1, "genres": False, + "genres_tag": "genre", "external_ids": { "discogs": False, "bandcamp": False, @@ -723,8 +729,8 @@ def album_info(self, release: JSONDict) -> beets.autotag.hooks.AlbumInfo: if self.config["genres"]: sources = [ - release["release-group"].get("tag-list", []), - release.get("tag-list", []), + release["release-group"].get(self.genres_field, []), + release.get(self.genres_field, []), ] genres: Counter[str] = Counter() for source in sources: diff --git a/docs/changelog.rst b/docs/changelog.rst index e6821327e2..1225f4f9f7 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,8 @@ been dropped. New features: - :doc:`plugins/ftintitle`: Added argument for custom feat. words in ftintitle. +- :doc:`plugins/musicbrainz`: Allow selecting tags or genres to populate the + genres tag. - :doc:`plugins/ftintitle`: Added argument to skip the processing of artist and album artist are the same in ftintitle. - :doc:`plugins/play`: Added `$playlist` marker to precisely edit the playlist diff --git a/docs/plugins/musicbrainz.rst b/docs/plugins/musicbrainz.rst index 00c553d8b8..7fe436c2c1 100644 --- a/docs/plugins/musicbrainz.rst +++ b/docs/plugins/musicbrainz.rst @@ -32,6 +32,7 @@ Default ratelimit_interval: 1.0 extra_tags: [] genres: no + genres_tag: genre external_ids: discogs: no bandcamp: no @@ -136,6 +137,12 @@ Default ``beatport_album_id``, ``deezer_album_id``, ``tidal_album_id``). On re-imports existing data will be overwritten. +.. conf:: genres_tag + :default: genre + + Either ``genre`` or ``tag``. Specify ``genre`` to use just musicbrainz genre and + ``tag`` to use all user-supplied musicbrainz tags. + .. include:: ./shared_metadata_source_config.rst .. _building search indexes: https://musicbrainz.org/doc/Development/Search_server_setup diff --git a/test/plugins/test_musicbrainz.py b/test/plugins/test_musicbrainz.py index 844b2ad4ef..9e271a4817 100644 --- a/test/plugins/test_musicbrainz.py +++ b/test/plugins/test_musicbrainz.py @@ -65,6 +65,8 @@ def _make_release( ], "date": "3001", "medium-list": [], + "genre-list": [{"count": 1, "name": "GENRE"}], + "tag-list": [{"count": 1, "name": "TAG"}], "label-info-list": [ { "catalog-number": "CATALOG NUMBER", @@ -515,6 +517,26 @@ def test_data_source(self): d = self.mb.album_info(release) assert d.data_source == "MusicBrainz" + def test_genres(self): + config["musicbrainz"]["genres"] = True + config["musicbrainz"]["genres_tag"] = "genre" + release = self._make_release() + d = self.mb.album_info(release) + assert d.genre == "GENRE" + + def test_tags(self): + config["musicbrainz"]["genres"] = True + config["musicbrainz"]["genres_tag"] = "tag" + release = self._make_release() + d = self.mb.album_info(release) + assert d.genre == "TAG" + + def test_no_genres(self): + config["musicbrainz"]["genres"] = False + release = self._make_release() + d = self.mb.album_info(release) + assert d.genre is None + def test_ignored_media(self): config["match"]["ignored_media"] = ["IGNORED1", "IGNORED2"] tracks = [