Refactor parsing genre

This commit is contained in:
Šarūnas Nejus 2026-01-24 22:36:56 +00:00
parent 99e972e2a7
commit 9be006a79d
No known key found for this signature in database
3 changed files with 42 additions and 19 deletions

View file

@ -16,7 +16,7 @@
from __future__ import annotations
from collections import Counter
from collections import defaultdict
from contextlib import suppress
from functools import cached_property
from itertools import product
@ -434,6 +434,23 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin):
original_day=day,
)
def _parse_genre(self, release: Release) -> str | None:
if self.config["genres"]:
genres = [
*release["release_group"][self.genres_field],
*release.get(self.genres_field, []),
]
count_by_genre: dict[str, int] = defaultdict(int)
for genre in genres:
count_by_genre[genre["name"]] += int(genre["count"])
return "; ".join(
g
for g, _ in sorted(count_by_genre.items(), key=lambda g: -g[1])
)
return None
def album_info(self, release: Release) -> beets.autotag.hooks.AlbumInfo:
"""Takes a MusicBrainz release result dictionary and returns a beets
AlbumInfo object containing the interesting data about that release.
@ -522,6 +539,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin):
data_source=self.data_source,
data_url=urljoin(BASE_URL, f"release/{release['id']}"),
barcode=release.get("barcode"),
genre=genre if (genre := self._parse_genre(release)) else None,
**self._parse_release_group(release["release_group"]),
)
info.va = info.artist_id == VARIOUS_ARTISTS_ID
@ -569,20 +587,6 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin):
else:
info.media = "Media"
if self.config["genres"]:
sources = [
release["release_group"][self.genres_field],
release.get(self.genres_field, []),
]
genres: Counter[str] = Counter()
for source in sources:
for genreitem in source:
genres[genreitem["name"]] += int(genreitem["count"])
info.genre = "; ".join(
genre
for genre, _count in sorted(genres.items(), key=lambda g: -g[1])
)
# We might find links to external sources (Discogs, Bandcamp, ...)
external_ids = self.config["external_ids"].get()
wanted_sources: set[UrlSource] = {

View file

@ -115,3 +115,14 @@ class ReleaseGroupFactory(_IdFactory):
secondary_types = factory.List([])
tags = factory.List([])
title = "Release Group"
class GenreFactory(factory.DictFactory):
id = factory.Faker("uuid4")
count = 1
disambiguation = ""
name = "Genre"
class TagFactory(GenreFactory):
name = "Tag"

View file

@ -60,6 +60,14 @@ def release_group_factory(**kwargs) -> mb.ReleaseGroup:
return factories.ReleaseGroupFactory.build(**kwargs)
def genre_factory(**kwargs) -> mb.Genre:
return factories.GenreFactory.build(**kwargs)
def tag_factory(**kwargs) -> mb.Tag:
return factories.TagFactory.build(**kwargs)
class MusicBrainzTestCase(BeetsTestCase):
def setUp(self):
super().setUp()
@ -85,8 +93,8 @@ class MusicBrainzTestCase(BeetsTestCase):
"artist_credit": [artist_credit_factory(artist__id_base=10)],
"date": "3001",
"media": [],
"genres": [{"count": 1, "name": "GENRE"}],
"tags": [{"count": 1, "name": "TAG"}],
"genres": [genre_factory()],
"tags": [tag_factory()],
"label_info": [
{
"catalog_number": "CATALOG NUMBER",
@ -520,14 +528,14 @@ class MBAlbumInfoTest(MusicBrainzTestCase):
config["musicbrainz"]["genres_tag"] = "genre"
release = self._make_release()
d = self.mb.album_info(release)
assert d.genre == "GENRE"
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"
assert d.genre == "Tag"
def test_no_genres(self):
config["musicbrainz"]["genres"] = False