From 839219a7b7f13bc2917362a6d9db65446b615aa8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 5 Oct 2026 20:31:32 +0800 Subject: [PATCH 1/2] fix(metadata): restore multi-genre parsing for Qobuz albums `from_qobuz` was changed in #942 to read only `genre.name`, which drops `genres_list` and collapses multi-genre albums to a single tag. For the "Rumours" fixture this turned ["Pop", "Rock"] into ["Rock"], breaking `test_album_metadata_qobuz` and degrading the genre tag for every Qobuz album whose primary genre has a parent. Prefer `genres_list` (the hierarchy, e.g. "Pop/Rock" -> ["Pop", "Rock"]) and fall back to `genre.name` only when `genres_list` is a flat, localised list, so the #618 fix is preserved. `genre.name` missing no longer raises TypeError. Fixes the only failing test on `dev`. --- streamrip/metadata/album.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/streamrip/metadata/album.py b/streamrip/metadata/album.py index 01b48ed2..fa15bb70 100644 --- a/streamrip/metadata/album.py +++ b/streamrip/metadata/album.py @@ -84,7 +84,16 @@ def format_folder_path(self, formatter: str) -> str: def from_qobuz(cls, resp: dict) -> AlbumMetadata: album = resp.get("title", "Unknown Album") tracktotal = resp.get("tracks_count", 1) - genre = [safe_get(resp, "genre", "name")] or resp.get("genre") or [] + # `genres_list` is the genre hierarchy returned by Qobuz, e.g. + # ["Pop/Rock", "Pop/Rock→Rock"], which expands to ["Pop", "Rock"]. + # For some accounts it is a flat, localised list of leaf names instead, + # in which case `genre.name` carries the canonical genre (see #618). + raw_genres = [g for g in (resp.get("genres_list") or []) if isinstance(g, str)] + if any("/" in g or "\u2192" in g for g in raw_genres): + genre = raw_genres + else: + genre_name = safe_get(resp, "genre", "name") + genre = [genre_name] if genre_name else raw_genres genres = list(set(genre_clean.findall("/".join(genre)))) date = resp.get("release_date_original") or resp.get("release_date") year = date[:4] if date is not None else "Unknown" From 86c378e1fa5543e1b628352bee4366c1d79b56e1 Mon Sep 17 00:00:00 2001 From: Hiiiirth <1540340002@qq.com> Date: Mon, 5 Oct 2026 23:40:10 +0800 Subject: [PATCH 2/2] test(metadata): cover Qobuz albums with no genre fields `from_qobuz` raised TypeError when neither `genre` nor `genres_list` was present: `[safe_get(resp, "genre", "name")]` evaluates to `[None]`, which is truthy, so the `or` fallback never ran and `"/".join([None])` failed. The new test asserts such a response degrades to an empty genre list instead of crashing. --- tests/test_meta.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_meta.py b/tests/test_meta.py index 01032baa..2c04e236 100644 --- a/tests/test_meta.py +++ b/tests/test_meta.py @@ -61,3 +61,12 @@ def test_track_metadata_qobuz(): assert t.tracknumber == 9 assert t.discnumber == 1 assert t.composer == "John Darnielle" + + +def test_album_metadata_qobuz_without_genre(): + """An album response without `genre`/`genres_list` must not raise.""" + resp = { + k: v for k, v in qobuz_album_resp.items() if k not in ("genre", "genres_list") + } + m = AlbumMetadata.from_qobuz(resp) + assert m.genre == []