From e0842c44dbe92c5fcc6221f767d0bff7d8016491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0ar=C5=ABnas=20Nejus?= Date: Tue, 13 Jan 2026 00:43:23 +0000 Subject: [PATCH] Normalize dashes to underscores in musicbrainz data fields --- beetsplug/_utils/musicbrainz.py | 49 +- beetsplug/mbpseudo.py | 10 +- beetsplug/musicbrainz.py | 88 +-- test/plugins/test_mbpseudo.py | 6 +- test/plugins/test_musicbrainz.py | 88 +-- test/plugins/utils/test_musicbrainz.py | 77 ++- test/rsrc/mbpseudo/official_release.json | 814 +++++++++++------------ test/rsrc/mbpseudo/pseudo_release.json | 256 +++---- 8 files changed, 723 insertions(+), 665 deletions(-) diff --git a/beetsplug/_utils/musicbrainz.py b/beetsplug/_utils/musicbrainz.py index 2fc821df9..ee94316e7 100644 --- a/beetsplug/_utils/musicbrainz.py +++ b/beetsplug/_utils/musicbrainz.py @@ -169,7 +169,7 @@ class MusicBrainzAPI(RequestHandler): if includes: kwargs["inc"] = "+".join(includes) - return self._group_relations( + return self._normalize_data( self.get_json(f"{self.api_root}/{resource}", params=kwargs) ) @@ -240,29 +240,39 @@ class MusicBrainzAPI(RequestHandler): @singledispatchmethod @classmethod - def _group_relations(cls, data: Any) -> Any: - """Normalize MusicBrainz 'relations' into type-keyed fields recursively. + def _normalize_data(cls, data: Any) -> Any: + """Normalize MusicBrainz relation structures into easier-to-use shapes. - This helper rewrites payloads that use a generic 'relations' list into - a structure that is easier to consume downstream. When a mapping - contains 'relations', those entries are regrouped by their 'target-type' - and stored under keys like '-relations'. The original - 'relations' key is removed to avoid ambiguous access patterns. - - The transformation is applied recursively so that nested objects and - sequences are normalized consistently, while non-container values are - left unchanged. + This default handler is a no-op that returns non-container values + unchanged. Specialized handlers for sequences and mappings perform the + actual transformations described below. """ return data - @_group_relations.register(list) + @_normalize_data.register(list) @classmethod def _(cls, data: list[Any]) -> list[Any]: - return [cls._group_relations(i) for i in data] + """Apply normalization to each element of a sequence recursively. - @_group_relations.register(dict) + Sequences received from the MusicBrainz API may contain nested mappings + that require transformation. This handler maps the normalization step + over the sequence and preserves order. + """ + return [cls._normalize_data(i) for i in data] + + @_normalize_data.register(dict) @classmethod def _(cls, data: JSONDict) -> JSONDict: + """Transform mappings by regrouping relationships and normalizing keys. + + When a mapping contains a generic 'relations' list, entries are grouped + by their 'target-type' and placed under keys like + '_relations' with the 'target-type' field removed from each + entry. All other mapping keys have hyphens converted to underscores and + their values are normalized recursively to ensure a consistent shape + throughout the payload. + """ + output_data = {} for k, v in list(data.items()): if k == "relations": get_target_type = operator.methodcaller("get", "target-type") @@ -273,13 +283,12 @@ class MusicBrainzAPI(RequestHandler): {k: v for k, v in item.items() if k != "target-type"} for item in group ] - data[f"{target_type}-relations"] = cls._group_relations( - relations + output_data[f"{target_type}_relations"] = ( + cls._normalize_data(relations) ) - data.pop("relations") else: - data[k] = cls._group_relations(v) - return data + output_data[k.replace("-", "_")] = cls._normalize_data(v) + return output_data class MusicBrainzAPIMixin: diff --git a/beetsplug/mbpseudo.py b/beetsplug/mbpseudo.py index d084d1531..9e4be4bad 100644 --- a/beetsplug/mbpseudo.py +++ b/beetsplug/mbpseudo.py @@ -168,7 +168,7 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): return [ pr_id - for rel in data.get("release-relations", []) + for rel in data.get("release_relations", []) if (pr_id := self._wanted_pseudo_release_id(album_id, rel)) is not None ] @@ -176,7 +176,7 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): def _has_desired_script(self, release: JSONDict) -> bool: if len(self._scripts) == 0: return False - elif script := release.get("text-representation", {}).get("script"): + elif script := release.get("text_representation", {}).get("script"): return script in self._scripts else: return False @@ -216,9 +216,9 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): if len(config["import"]["languages"].as_str_seq()) > 0: return - lang = raw_pseudo_release.get("text-representation", {}).get("language") - artist_credits = raw_pseudo_release.get("release-group", {}).get( - "artist-credit", [] + lang = raw_pseudo_release.get("text_representation", {}).get("language") + artist_credits = raw_pseudo_release.get("release_group", {}).get( + "artist_credit", [] ) aliases = [ artist_credit.get("artist", {}).get("aliases", []) diff --git a/beetsplug/musicbrainz.py b/beetsplug/musicbrainz.py index aac20e9ac..1dc2ddfaa 100644 --- a/beetsplug/musicbrainz.py +++ b/beetsplug/musicbrainz.py @@ -160,9 +160,9 @@ def _multi_artist_credit( # Artist sort name. if alias: - artist_sort_parts.append(alias["sort-name"]) - elif "sort-name" in el["artist"]: - artist_sort_parts.append(el["artist"]["sort-name"]) + artist_sort_parts.append(alias["sort_name"]) + elif "sort_name" in el["artist"]: + artist_sort_parts.append(el["artist"]["sort_name"]) else: artist_sort_parts.append(cur_artist_name) @@ -245,10 +245,10 @@ def _preferred_release_event( ].as_str_seq() for country in preferred_countries: - for event in release.get("release-events", {}): + for event in release.get("release_events", {}): try: if area := event.get("area"): - if country in area["iso-3166-1-codes"]: + if country in area["iso_3166_1_codes"]: return country, event["date"] except KeyError: pass @@ -381,28 +381,28 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): data_url=track_url(recording["id"]), ) - if recording.get("artist-credit"): + if recording.get("artist_credit"): # Get the artist names. ( info.artist, info.artist_sort, info.artist_credit, - ) = _flatten_artist_credit(recording["artist-credit"]) + ) = _flatten_artist_credit(recording["artist_credit"]) ( info.artists, info.artists_sort, info.artists_credit, ) = _multi_artist_credit( - recording["artist-credit"], include_join_phrase=False + recording["artist_credit"], include_join_phrase=False ) - info.artists_ids = _artist_ids(recording["artist-credit"]) + info.artists_ids = _artist_ids(recording["artist_credit"]) info.artist_id = info.artists_ids[0] - if recording.get("artist-relations"): + if recording.get("artist_relations"): info.remixer = _get_related_artist_names( - recording["artist-relations"], relation_type="remixer" + recording["artist_relations"], relation_type="remixer" ) if recording.get("length"): @@ -416,7 +416,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): lyricist = [] composer = [] composer_sort = [] - for work_relation in recording.get("work-relations", ()): + for work_relation in recording.get("work_relations", ()): if work_relation["type"] != "performance": continue info.work = work_relation["work"]["title"] @@ -425,7 +425,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): info.work_disambig = work_relation["work"]["disambiguation"] for artist_relation in work_relation["work"].get( - "artist-relations", () + "artist_relations", () ): if "type" in artist_relation: type = artist_relation["type"] @@ -434,7 +434,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): elif type == "composer": composer.append(artist_relation["artist"]["name"]) composer_sort.append( - artist_relation["artist"]["sort-name"] + artist_relation["artist"]["sort_name"] ) if lyricist: info.lyricist = ", ".join(lyricist) @@ -443,7 +443,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): info.composer_sort = ", ".join(composer_sort) arranger = [] - for artist_relation in recording.get("artist-relations", ()): + for artist_relation in recording.get("artist_relations", ()): if "type" in artist_relation: type = artist_relation["type"] if type == "arranger": @@ -464,7 +464,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): """ # Get artist name using join phrases. artist_name, artist_sort_name, artist_credit_name = ( - _flatten_artist_credit(release["artist-credit"]) + _flatten_artist_credit(release["artist_credit"]) ) ( @@ -472,7 +472,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): artists_sort_names, artists_credit_names, ) = _multi_artist_credit( - release["artist-credit"], include_join_phrase=False + release["artist_credit"], include_join_phrase=False ) ntracks = sum(len(m["tracks"]) for m in release["media"]) @@ -508,10 +508,10 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): all_tracks = medium["tracks"] if ( - "data-tracks" in medium + "data_tracks" in medium and not config["match"]["ignore_data_tracks"] ): - all_tracks += medium["data-tracks"] + all_tracks += medium["data_tracks"] track_count = len(all_tracks) if "pregap" in medium: @@ -548,30 +548,30 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): # Prefer track data, where present, over recording data. if track.get("title"): ti.title = track["title"] - if track.get("artist-credit"): + if track.get("artist_credit"): # Get the artist names. ( ti.artist, ti.artist_sort, ti.artist_credit, - ) = _flatten_artist_credit(track["artist-credit"]) + ) = _flatten_artist_credit(track["artist_credit"]) ( ti.artists, ti.artists_sort, ti.artists_credit, ) = _multi_artist_credit( - track["artist-credit"], include_join_phrase=False + track["artist_credit"], include_join_phrase=False ) - ti.artists_ids = _artist_ids(track["artist-credit"]) + ti.artists_ids = _artist_ids(track["artist_credit"]) ti.artist_id = ti.artists_ids[0] if track.get("length"): ti.length = int(track["length"]) / (1000.0) track_infos.append(ti) - album_artist_ids = _artist_ids(release["artist-credit"]) + album_artist_ids = _artist_ids(release["artist_credit"]) info = beets.autotag.hooks.AlbumInfo( album=release["title"], album_id=release["id"], @@ -593,38 +593,38 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): if info.va: info.artist = config["va_name"].as_str() info.asin = release.get("asin") - info.releasegroup_id = release["release-group"]["id"] + info.releasegroup_id = release["release_group"]["id"] info.albumstatus = release.get("status") - if release["release-group"].get("title"): - info.release_group_title = release["release-group"].get("title") + if release["release_group"].get("title"): + info.release_group_title = release["release_group"].get("title") # Get the disambiguation strings at the release and release group level. - if release["release-group"].get("disambiguation"): - info.releasegroupdisambig = release["release-group"].get( + if release["release_group"].get("disambiguation"): + info.releasegroupdisambig = release["release_group"].get( "disambiguation" ) if release.get("disambiguation"): info.albumdisambig = release.get("disambiguation") - if reltype := release["release-group"].get("primary-type"): + if reltype := release["release_group"].get("primary_type"): info.albumtype = reltype.lower() # Set the new-style "primary" and "secondary" release types. albumtypes = [] - if "primary-type" in release["release-group"]: - rel_primarytype = release["release-group"]["primary-type"] + if "primary_type" in release["release_group"]: + rel_primarytype = release["release_group"]["primary_type"] if rel_primarytype: albumtypes.append(rel_primarytype.lower()) - if "secondary-types" in release["release-group"]: - if release["release-group"]["secondary-types"]: - for sec_type in release["release-group"]["secondary-types"]: + if "secondary_types" in release["release_group"]: + if release["release_group"]["secondary_types"]: + for sec_type in release["release_group"]["secondary_types"]: albumtypes.append(sec_type.lower()) info.albumtypes = albumtypes # Release events. info.country, release_date = _preferred_release_event(release) - release_group_date = release["release-group"].get("first-release-date") + release_group_date = release["release_group"].get("first_release_date") if not release_date: # Fall back if release-specific date is not available. release_date = release_group_date @@ -634,17 +634,17 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): _set_date_str(info, release_group_date, True) # Label name. - if release.get("label-info"): - label_info = release["label-info"][0] + if release.get("label_info"): + label_info = release["label_info"][0] if label_info.get("label"): label = label_info["label"]["name"] if label != "[no label]": info.label = label - info.catalognum = label_info.get("catalog-number") + info.catalognum = label_info.get("catalog_number") # Text representation data. - if release.get("text-representation"): - rep = release["text-representation"] + if release.get("text_representation"): + rep = release["text_representation"] info.script = rep.get("script") info.language = rep.get("language") @@ -659,7 +659,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): if self.config["genres"]: sources = [ - release["release-group"].get(self.genres_field, []), + release["release_group"].get(self.genres_field, []), release.get(self.genres_field, []), ] genres: Counter[str] = Counter() @@ -676,7 +676,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): wanted_sources = { site for site, wanted in external_ids.items() if wanted } - if wanted_sources and (url_rels := release.get("url-relations")): + if wanted_sources and (url_rels := release.get("url_relations")): urls = {} for source, url in product(wanted_sources, url_rels): @@ -800,7 +800,7 @@ class MusicBrainzPlugin(MusicBrainzAPIMixin, MetadataSourcePlugin): actual_res = None if res.get("status") == "Pseudo-Release" and ( - relations := res.get("release-relations") + relations := res.get("release_relations") ): for rel in relations: if ( diff --git a/test/plugins/test_mbpseudo.py b/test/plugins/test_mbpseudo.py index 2fb6321b3..ff0838aad 100644 --- a/test/plugins/test_mbpseudo.py +++ b/test/plugins/test_mbpseudo.py @@ -163,7 +163,7 @@ class TestMBPseudoPlugin(TestMBPseudoMixin): official_release: JSONDict, json_key: str, ): - del official_release["release-relations"][0][json_key] + del official_release["release_relations"][0][json_key] album_info = mbpseudo_plugin.album_info(official_release) assert not isinstance(album_info, PseudoAlbumInfo) @@ -174,8 +174,8 @@ class TestMBPseudoPlugin(TestMBPseudoMixin): mbpseudo_plugin: MusicBrainzPseudoReleasePlugin, official_release: JSONDict, ): - official_release["release-relations"][0]["release"][ - "text-representation" + official_release["release_relations"][0]["release"][ + "text_representation" ]["script"] = "Null" album_info = mbpseudo_plugin.album_info(official_release) diff --git a/test/plugins/test_musicbrainz.py b/test/plugins/test_musicbrainz.py index 069f1fb99..49039f2ba 100644 --- a/test/plugins/test_musicbrainz.py +++ b/test/plugins/test_musicbrainz.py @@ -51,18 +51,18 @@ class MBAlbumInfoTest(MusicBrainzTestCase): "id": "ALBUM ID", "asin": "ALBUM ASIN", "disambiguation": "R_DISAMBIGUATION", - "release-group": { - "primary-type": "Album", - "first-release-date": date_str, + "release_group": { + "primary_type": "Album", + "first_release_date": date_str, "id": "RELEASE GROUP ID", "disambiguation": "RG_DISAMBIGUATION", }, - "artist-credit": [ + "artist_credit": [ { "artist": { "name": "ARTIST NAME", "id": "ARTIST ID", - "sort-name": "ARTIST SORT NAME", + "sort_name": "ARTIST SORT NAME", }, "name": "ARTIST CREDIT", } @@ -71,30 +71,30 @@ class MBAlbumInfoTest(MusicBrainzTestCase): "media": [], "genres": [{"count": 1, "name": "GENRE"}], "tags": [{"count": 1, "name": "TAG"}], - "label-info": [ + "label_info": [ { - "catalog-number": "CATALOG NUMBER", + "catalog_number": "CATALOG NUMBER", "label": {"name": "LABEL NAME"}, } ], - "text-representation": { + "text_representation": { "script": "SCRIPT", "language": "LANGUAGE", }, "country": "COUNTRY", "status": "STATUS", "barcode": "BARCODE", - "release-events": [{"area": None, "date": "2021-03-26"}], + "release_events": [{"area": None, "date": "2021-03-26"}], } if multi_artist_credit: - release["artist-credit"][0]["joinphrase"] = " & " - release["artist-credit"].append( + release["artist_credit"][0]["joinphrase"] = " & " + release["artist_credit"].append( { "artist": { "name": "ARTIST 2 NAME", "id": "ARTIST 2 ID", - "sort-name": "ARTIST 2 SORT NAME", + "sort_name": "ARTIST 2 SORT NAME", }, "name": "ARTIST MULTI CREDIT", } @@ -117,25 +117,25 @@ class MBAlbumInfoTest(MusicBrainzTestCase): if track_artist: # Similarly, track artists can differ from recording # artists. - track["artist-credit"] = [ + track["artist_credit"] = [ { "artist": { "name": "TRACK ARTIST NAME", "id": "TRACK ARTIST ID", - "sort-name": "TRACK ARTIST SORT NAME", + "sort_name": "TRACK ARTIST SORT NAME", }, "name": "TRACK ARTIST CREDIT", } ] if multi_artist_credit: - track["artist-credit"][0]["joinphrase"] = " & " - track["artist-credit"].append( + track["artist_credit"][0]["joinphrase"] = " & " + track["artist_credit"].append( { "artist": { "name": "TRACK ARTIST 2 NAME", "id": "TRACK ARTIST 2 ID", - "sort-name": "TRACK ARTIST 2 SORT NAME", + "sort_name": "TRACK ARTIST 2 SORT NAME", }, "name": "TRACK ARTIST 2 CREDIT", } @@ -157,7 +157,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): { "position": "1", "tracks": track_list, - "data-tracks": data_track_list, + "data_tracks": data_track_list, "format": medium_format, "title": "MEDIUM TITLE", } @@ -182,39 +182,39 @@ class MBAlbumInfoTest(MusicBrainzTestCase): if duration is not None: track["length"] = duration if artist: - track["artist-credit"] = [ + track["artist_credit"] = [ { "artist": { "name": "RECORDING ARTIST NAME", "id": "RECORDING ARTIST ID", - "sort-name": "RECORDING ARTIST SORT NAME", + "sort_name": "RECORDING ARTIST SORT NAME", }, "name": "RECORDING ARTIST CREDIT", } ] if multi_artist_credit: - track["artist-credit"][0]["joinphrase"] = " & " - track["artist-credit"].append( + track["artist_credit"][0]["joinphrase"] = " & " + track["artist_credit"].append( { "artist": { "name": "RECORDING ARTIST 2 NAME", "id": "RECORDING ARTIST 2 ID", - "sort-name": "RECORDING ARTIST 2 SORT NAME", + "sort_name": "RECORDING ARTIST 2 SORT NAME", }, "name": "RECORDING ARTIST 2 CREDIT", } ) if remixer: - track["artist-relations"] = [ + track["artist_relations"] = [ { "type": "remixer", - "type-id": "RELATION TYPE ID", + "type_id": "RELATION TYPE ID", "direction": "RECORDING RELATION DIRECTION", "artist": { "id": "RECORDING REMIXER ARTIST ID", "type": "RECORDING REMIXER ARTIST TYPE", "name": "RECORDING REMIXER ARTIST NAME", - "sort-name": "RECORDING REMIXER ARTIST SORT NAME", + "sort_name": "RECORDING REMIXER ARTIST SORT NAME", }, } ] @@ -354,7 +354,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): def test_detect_various_artists(self): release = self._make_release(None) - release["artist-credit"][0]["artist"]["id"] = ( + release["artist_credit"][0]["artist"]["id"] = ( musicbrainz.VARIOUS_ARTISTS_ID ) d = self.mb.album_info(release) @@ -429,7 +429,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): def test_missing_language(self): release = self._make_release(None) - del release["text-representation"]["language"] + del release["text_representation"]["language"] d = self.mb.album_info(release) assert d.language is None @@ -697,7 +697,7 @@ class ArtistFlatteningTest(unittest.TestCase): return { "artist": { "name": f"NAME{suffix}", - "sort-name": f"SORT{suffix}", + "sort_name": f"SORT{suffix}", }, "name": f"CREDIT{suffix}", } @@ -706,7 +706,7 @@ class ArtistFlatteningTest(unittest.TestCase): alias = { "name": f"ALIAS{suffix}", "locale": locale, - "sort-name": f"ALIASSORT{suffix}", + "sort_name": f"ALIASSORT{suffix}", } if primary: alias["primary"] = "primary" @@ -810,7 +810,7 @@ class MBLibraryTest(MusicBrainzTestCase): "position": 5, } ], - "artist-credit": [ + "artist_credit": [ { "artist": { "name": "some-artist", @@ -818,10 +818,10 @@ class MBLibraryTest(MusicBrainzTestCase): }, } ], - "release-group": { + "release_group": { "id": "another-id", }, - "release-relations": [ + "release_relations": [ { "type": "transl-tracklisting", "direction": "backward", @@ -852,7 +852,7 @@ class MBLibraryTest(MusicBrainzTestCase): "position": 5, } ], - "artist-credit": [ + "artist_credit": [ { "artist": { "name": "some-artist", @@ -860,7 +860,7 @@ class MBLibraryTest(MusicBrainzTestCase): }, } ], - "release-group": { + "release_group": { "id": "another-id", }, "country": "COUNTRY", @@ -897,7 +897,7 @@ class MBLibraryTest(MusicBrainzTestCase): "position": 5, } ], - "artist-credit": [ + "artist_credit": [ { "artist": { "name": "some-artist", @@ -905,7 +905,7 @@ class MBLibraryTest(MusicBrainzTestCase): }, } ], - "release-group": { + "release_group": { "id": "another-id", }, } @@ -941,7 +941,7 @@ class MBLibraryTest(MusicBrainzTestCase): "position": 5, } ], - "artist-credit": [ + "artist_credit": [ { "artist": { "name": "some-artist", @@ -949,7 +949,7 @@ class MBLibraryTest(MusicBrainzTestCase): }, } ], - "release-group": { + "release_group": { "id": "another-id", }, } @@ -985,7 +985,7 @@ class MBLibraryTest(MusicBrainzTestCase): "position": 5, } ], - "artist-credit": [ + "artist_credit": [ { "artist": { "name": "some-artist", @@ -993,10 +993,10 @@ class MBLibraryTest(MusicBrainzTestCase): }, } ], - "release-group": { + "release_group": { "id": "another-id", }, - "release-relations": [ + "release_relations": [ { "type": "remaster", "direction": "backward", @@ -1097,10 +1097,10 @@ class TestMusicBrainzPlugin(PluginMixin): "position": 5, } ], - "artist-credit": [ + "artist_credit": [ {"artist": {"name": "some-artist", "id": "some-id"}} ], - "release-group": {"id": "another-id"}, + "release_group": {"id": "another-id"}, }, ) candidates = list(mb.candidates([], "hello", "there", False)) diff --git a/test/plugins/utils/test_musicbrainz.py b/test/plugins/utils/test_musicbrainz.py index 291f50eb5..0a2a40602 100644 --- a/test/plugins/utils/test_musicbrainz.py +++ b/test/plugins/utils/test_musicbrainz.py @@ -1,26 +1,44 @@ from beetsplug._utils.musicbrainz import MusicBrainzAPI -def test_group_relations(): +def test_normalize_data(): raw_release = { "id": "r1", "relations": [ - {"target-type": "artist", "type": "vocal", "name": "A"}, - {"target-type": "url", "type": "streaming", "url": "http://s"}, - {"target-type": "url", "type": "purchase", "url": "http://p"}, + { + "target-type": "artist", + "type": "vocal", + "type-id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa", + "name": "A", + }, + { + "target-type": "url", + "type": "streaming", + "type-id": "b5f3058a-666c-406f-aafb-f9249fc7b122", + "url": "http://s", + }, + { + "target-type": "url", + "type": "purchase for download", + "type-id": "92777657-504c-4acb-bd33-51a201bd57e1", + "url": "http://p", + }, { "target-type": "work", "type": "performance", + "type-id": "a3005666-a872-32c3-ad06-98af558e99b0", "work": { "relations": [ { "artist": {"name": "幾田りら"}, "target-type": "artist", "type": "composer", + "type-id": "d59d99ea-23d4-4a80-b066-edca32ee158f", }, { "target-type": "url", "type": "lyrics", + "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "resource": "https://utaten.com/lyric/tt24121002/" }, @@ -29,10 +47,12 @@ def test_group_relations(): "artist": {"name": "幾田りら"}, "target-type": "artist", "type": "lyricist", + "type-id": "3e48faba-ec01-47fd-8e89-30e81161661c", }, { "target-type": "url", "type": "lyrics", + "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "resource": "https://www.uta-net.com/song/366579/" }, @@ -45,30 +65,59 @@ def test_group_relations(): ], } - assert MusicBrainzAPI._group_relations(raw_release) == { + assert MusicBrainzAPI._normalize_data(raw_release) == { "id": "r1", - "artist-relations": [{"type": "vocal", "name": "A"}], - "url-relations": [ - {"type": "streaming", "url": "http://s"}, - {"type": "purchase", "url": "http://p"}, + "artist_relations": [ + { + "type": "vocal", + "type_id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa", + "name": "A", + } ], - "work-relations": [ + "url_relations": [ + { + "type": "streaming", + "type_id": "b5f3058a-666c-406f-aafb-f9249fc7b122", + "url": "http://s", + }, + { + "type": "purchase for download", + "type_id": "92777657-504c-4acb-bd33-51a201bd57e1", + "url": "http://p", + }, + ], + "work_relations": [ { "type": "performance", + "type_id": "a3005666-a872-32c3-ad06-98af558e99b0", "work": { - "artist-relations": [ - {"type": "composer", "artist": {"name": "幾田りら"}}, - {"type": "lyricist", "artist": {"name": "幾田りら"}}, + "artist_relations": [ + { + "type": "composer", + "type_id": "d59d99ea-23d4-4a80-b066-edca32ee158f", + "artist": { + "name": "幾田りら", + }, + }, + { + "type": "lyricist", + "type_id": "3e48faba-ec01-47fd-8e89-30e81161661c", + "artist": { + "name": "幾田りら", + }, + }, ], - "url-relations": [ + "url_relations": [ { "type": "lyrics", + "type_id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "resource": "https://utaten.com/lyric/tt24121002/" }, }, { "type": "lyrics", + "type_id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "resource": "https://www.uta-net.com/song/366579/" }, diff --git a/test/rsrc/mbpseudo/official_release.json b/test/rsrc/mbpseudo/official_release.json index cd6bb3ba9..2778c9fba 100644 --- a/test/rsrc/mbpseudo/official_release.json +++ b/test/rsrc/mbpseudo/official_release.json @@ -7,12 +7,12 @@ "locale": "en", "name": "In Bloom", "primary": true, - "sort-name": "In Bloom", + "sort_name": "In Bloom", "type": "Release name", - "type-id": "df187855-059b-3514-9d5e-d240de0b4228" + "type_id": "df187855-059b-3514-9d5e-d240de0b4228" } ], - "artist-credit": [ + "artist_credit": [ { "artist": { "aliases": [ @@ -23,9 +23,9 @@ "locale": "en", "name": "Lilas Ikuta", "primary": true, - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Artist name", - "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + "type_id": "894afba6-2816-3c24-8072-eadb66bd04bc" } ], "country": "JP", @@ -46,7 +46,7 @@ ], "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "tags": [ { "count": 1, @@ -58,34 +58,34 @@ } ], "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "幾田りら" } ], - "artist-relations": [ + "artist_relations": [ { "artist": { "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": "2025", "direction": "backward", "end": "2025", "ended": true, - "source-credit": "", - "target-credit": "Lilas Ikuta", + "source_credit": "", + "target_credit": "Lilas Ikuta", "type": "copyright", - "type-id": "730b5251-7432-4896-8fc6-e1cba943bfe1" + "type_id": "730b5251-7432-4896-8fc6-e1cba943bfe1" }, { "artist": { @@ -93,27 +93,27 @@ "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": "2025", "direction": "backward", "end": "2025", "ended": true, - "source-credit": "", - "target-credit": "Lilas Ikuta", + "source_credit": "", + "target_credit": "Lilas Ikuta", "type": "phonographic copyright", - "type-id": "01d3488d-8d2a-4cff-9226-5250404db4dc" + "type_id": "01d3488d-8d2a-4cff-9226-5250404db4dc" } ], "asin": "B0DR8Y2YDC", "barcode": "199066336168", "country": "XW", - "cover-art-archive": { + "cover_art_archive": { "artwork": true, "back": false, "count": 1, @@ -124,9 +124,9 @@ "disambiguation": "", "genres": [], "id": "a5ce1d11-2e32-45a4-b37f-c1589d46b103", - "label-info": [ + "label_info": [ { - "catalog-number": "Lilas-020", + "catalog_number": "Lilas-020", "label": { "aliases": [ { @@ -136,9 +136,9 @@ "locale": null, "name": "2636621 Records DK", "primary": null, - "sort-name": "2636621 Records DK", + "sort_name": "2636621 Records DK", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -147,9 +147,9 @@ "locale": null, "name": "Antipole", "primary": null, - "sort-name": "Antipole", + "sort_name": "Antipole", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -158,9 +158,9 @@ "locale": null, "name": "Auto production", "primary": null, - "sort-name": "Auto production", + "sort_name": "Auto production", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -169,9 +169,9 @@ "locale": null, "name": "Auto-Edición", "primary": null, - "sort-name": "Auto-Edición", + "sort_name": "Auto-Edición", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -180,9 +180,9 @@ "locale": null, "name": "Auto-Product", "primary": null, - "sort-name": "Auto-Product", + "sort_name": "Auto-Product", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -191,9 +191,9 @@ "locale": null, "name": "Autoedición", "primary": null, - "sort-name": "Autoedición", + "sort_name": "Autoedición", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -202,9 +202,9 @@ "locale": null, "name": "Autoeditado", "primary": null, - "sort-name": "Autoeditado", + "sort_name": "Autoeditado", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -213,9 +213,9 @@ "locale": null, "name": "Autoproduit", "primary": null, - "sort-name": "Autoproduit", + "sort_name": "Autoproduit", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -224,9 +224,9 @@ "locale": null, "name": "Banana Skin Records", "primary": null, - "sort-name": "Banana Skin Records", + "sort_name": "Banana Skin Records", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -235,9 +235,9 @@ "locale": null, "name": "Cannelle", "primary": null, - "sort-name": "Cannelle", + "sort_name": "Cannelle", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -246,9 +246,9 @@ "locale": null, "name": "Cece Natalie", "primary": null, - "sort-name": "Cece Natalie", + "sort_name": "Cece Natalie", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -257,9 +257,9 @@ "locale": null, "name": "Cherry X", "primary": null, - "sort-name": "Cherry X", + "sort_name": "Cherry X", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -268,9 +268,9 @@ "locale": null, "name": "Chung", "primary": null, - "sort-name": "Chung", + "sort_name": "Chung", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -279,9 +279,9 @@ "locale": null, "name": "Cody Johnson", "primary": null, - "sort-name": "Cody Johnson", + "sort_name": "Cody Johnson", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -290,9 +290,9 @@ "locale": null, "name": "Cowgirl Clue", "primary": null, - "sort-name": "Cowgirl Clue", + "sort_name": "Cowgirl Clue", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -301,9 +301,9 @@ "locale": null, "name": "D.I.Y.", "primary": null, - "sort-name": "D.I.Y.", + "sort_name": "D.I.Y.", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -312,9 +312,9 @@ "locale": null, "name": "Damjan Mravunac Self-released)", "primary": null, - "sort-name": "Damjan Mravunac Self-released)", + "sort_name": "Damjan Mravunac Self-released)", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -323,9 +323,9 @@ "locale": null, "name": "Demo", "primary": null, - "sort-name": "Demo", + "sort_name": "Demo", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -334,9 +334,9 @@ "locale": null, "name": "DistroKid", "primary": null, - "sort-name": "DistroKid", + "sort_name": "DistroKid", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -345,9 +345,9 @@ "locale": null, "name": "Egzod", "primary": null, - "sort-name": "Egzod", + "sort_name": "Egzod", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -356,9 +356,9 @@ "locale": null, "name": "Eigenverlag", "primary": null, - "sort-name": "Eigenverlag", + "sort_name": "Eigenverlag", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -367,9 +367,9 @@ "locale": null, "name": "Eigenvertrieb", "primary": null, - "sort-name": "Eigenvertrieb", + "sort_name": "Eigenvertrieb", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -378,9 +378,9 @@ "locale": null, "name": "GRIND MODE", "primary": null, - "sort-name": "GRIND MODE", + "sort_name": "GRIND MODE", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -389,9 +389,9 @@ "locale": null, "name": "INDIPENDANT", "primary": null, - "sort-name": "INDIPENDANT", + "sort_name": "INDIPENDANT", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -400,9 +400,9 @@ "locale": null, "name": "Indepandant", "primary": null, - "sort-name": "Indepandant", + "sort_name": "Indepandant", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -411,9 +411,9 @@ "locale": null, "name": "Independant release", "primary": null, - "sort-name": "Independant release", + "sort_name": "Independant release", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -422,9 +422,9 @@ "locale": null, "name": "Independent", "primary": null, - "sort-name": "Independent", + "sort_name": "Independent", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -433,9 +433,9 @@ "locale": null, "name": "Independente", "primary": null, - "sort-name": "Independente", + "sort_name": "Independente", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -444,9 +444,9 @@ "locale": null, "name": "Independiente", "primary": null, - "sort-name": "Independiente", + "sort_name": "Independiente", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -455,9 +455,9 @@ "locale": null, "name": "Indie", "primary": null, - "sort-name": "Indie", + "sort_name": "Indie", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -466,9 +466,9 @@ "locale": null, "name": "Joost Klein", "primary": null, - "sort-name": "Joost Klein", + "sort_name": "Joost Klein", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -477,9 +477,9 @@ "locale": null, "name": "Millington Records", "primary": null, - "sort-name": "Millington Records", + "sort_name": "Millington Records", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -488,9 +488,9 @@ "locale": null, "name": "MoroseSound", "primary": null, - "sort-name": "MoroseSound", + "sort_name": "MoroseSound", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -499,9 +499,9 @@ "locale": null, "name": "N/A", "primary": null, - "sort-name": "N/A", + "sort_name": "N/A", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -510,9 +510,9 @@ "locale": null, "name": "No Label", "primary": null, - "sort-name": "No Label", + "sort_name": "No Label", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -521,9 +521,9 @@ "locale": null, "name": "None", "primary": null, - "sort-name": "None", + "sort_name": "None", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -532,9 +532,9 @@ "locale": null, "name": "None Like Joshua", "primary": null, - "sort-name": "None Like Joshua", + "sort_name": "None Like Joshua", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -543,9 +543,9 @@ "locale": null, "name": "Not On A Lebel", "primary": null, - "sort-name": "Not On A Lebel", + "sort_name": "Not On A Lebel", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -554,9 +554,9 @@ "locale": null, "name": "Not On Label", "primary": null, - "sort-name": "Not On Label", + "sort_name": "Not On Label", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -565,9 +565,9 @@ "locale": null, "name": "Offensively Average Productions", "primary": null, - "sort-name": "Offensively Average Productions", + "sort_name": "Offensively Average Productions", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -576,9 +576,9 @@ "locale": null, "name": "Ours", "primary": null, - "sort-name": "Ours", + "sort_name": "Ours", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -587,9 +587,9 @@ "locale": null, "name": "P2019", "primary": null, - "sort-name": "P2019", + "sort_name": "P2019", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -598,9 +598,9 @@ "locale": null, "name": "P2020", "primary": null, - "sort-name": "P2020", + "sort_name": "P2020", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -609,9 +609,9 @@ "locale": null, "name": "P2021", "primary": null, - "sort-name": "P2021", + "sort_name": "P2021", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -620,9 +620,9 @@ "locale": null, "name": "P2022", "primary": null, - "sort-name": "P2022", + "sort_name": "P2022", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -631,9 +631,9 @@ "locale": null, "name": "P2023", "primary": null, - "sort-name": "P2023", + "sort_name": "P2023", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -642,9 +642,9 @@ "locale": null, "name": "P2024", "primary": null, - "sort-name": "P2024", + "sort_name": "P2024", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -653,9 +653,9 @@ "locale": null, "name": "P2025", "primary": null, - "sort-name": "P2025", + "sort_name": "P2025", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -664,9 +664,9 @@ "locale": null, "name": "Patriarchy", "primary": null, - "sort-name": "Patriarchy", + "sort_name": "Patriarchy", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -675,9 +675,9 @@ "locale": null, "name": "Plini", "primary": null, - "sort-name": "Plini", + "sort_name": "Plini", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -686,9 +686,9 @@ "locale": null, "name": "Records DK", "primary": null, - "sort-name": "Records DK", + "sort_name": "Records DK", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -697,9 +697,9 @@ "locale": null, "name": "Self Digital", "primary": null, - "sort-name": "Self Digital", + "sort_name": "Self Digital", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -708,9 +708,9 @@ "locale": null, "name": "Self Release", "primary": null, - "sort-name": "Self Release", + "sort_name": "Self Release", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -719,9 +719,9 @@ "locale": null, "name": "Self Released", "primary": null, - "sort-name": "Self Released", + "sort_name": "Self Released", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -730,9 +730,9 @@ "locale": null, "name": "Self-release", "primary": null, - "sort-name": "Self-release", + "sort_name": "Self-release", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -741,9 +741,9 @@ "locale": null, "name": "Self-released", "primary": null, - "sort-name": "Self-released", + "sort_name": "Self-released", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -752,9 +752,9 @@ "locale": null, "name": "Self-released/independent", "primary": null, - "sort-name": "Self-released/independent", + "sort_name": "Self-released/independent", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -763,9 +763,9 @@ "locale": null, "name": "Sevdaliza", "primary": null, - "sort-name": "Sevdaliza", + "sort_name": "Sevdaliza", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -774,9 +774,9 @@ "locale": null, "name": "TOMMY CASH", "primary": null, - "sort-name": "TOMMY CASH", + "sort_name": "TOMMY CASH", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -785,9 +785,9 @@ "locale": null, "name": "Take Van", "primary": null, - "sort-name": "Take Van", + "sort_name": "Take Van", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -796,9 +796,9 @@ "locale": null, "name": "Talwiinder", "primary": null, - "sort-name": "Talwiinder", + "sort_name": "Talwiinder", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -807,9 +807,9 @@ "locale": null, "name": "Unsigned", "primary": null, - "sort-name": "Unsigned", + "sort_name": "Unsigned", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -818,9 +818,9 @@ "locale": null, "name": "VGR", "primary": null, - "sort-name": "VGR", + "sort_name": "VGR", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -829,9 +829,9 @@ "locale": null, "name": "Woo Da Savage", "primary": null, - "sort-name": "Woo Da Savage", + "sort_name": "Woo Da Savage", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -840,9 +840,9 @@ "locale": null, "name": "YANAA", "primary": null, - "sort-name": "YANAA", + "sort_name": "YANAA", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -851,9 +851,9 @@ "locale": "fi", "name": "[ei levymerkkiä]", "primary": true, - "sort-name": "ei levymerkkiä", + "sort_name": "ei levymerkkiä", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -862,9 +862,9 @@ "locale": "nl", "name": "[geen platenmaatschappij]", "primary": true, - "sort-name": "[geen platenmaatschappij]", + "sort_name": "[geen platenmaatschappij]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -873,9 +873,9 @@ "locale": "et", "name": "[ilma plaadifirmata]", "primary": false, - "sort-name": "[ilma plaadifirmata]", + "sort_name": "[ilma plaadifirmata]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -884,9 +884,9 @@ "locale": "es", "name": "[nada]", "primary": true, - "sort-name": "[nada]", + "sort_name": "[nada]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -895,9 +895,9 @@ "locale": "en", "name": "[no label]", "primary": true, - "sort-name": "[no label]", + "sort_name": "[no label]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -906,9 +906,9 @@ "locale": null, "name": "[nolabel]", "primary": null, - "sort-name": "[nolabel]", + "sort_name": "[nolabel]", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -917,9 +917,9 @@ "locale": null, "name": "[none]", "primary": null, - "sort-name": "[none]", + "sort_name": "[none]", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -928,9 +928,9 @@ "locale": "lt", "name": "[nėra leidybinės kompanijos]", "primary": false, - "sort-name": "[nėra leidybinės kompanijos]", + "sort_name": "[nėra leidybinės kompanijos]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -939,9 +939,9 @@ "locale": "lt", "name": "[nėra leidyklos]", "primary": false, - "sort-name": "[nėra leidyklos]", + "sort_name": "[nėra leidyklos]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -950,9 +950,9 @@ "locale": "lt", "name": "[nėra įrašų kompanijos]", "primary": true, - "sort-name": "[nėra įrašų kompanijos]", + "sort_name": "[nėra įrašų kompanijos]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -961,9 +961,9 @@ "locale": "et", "name": "[puudub]", "primary": false, - "sort-name": "[puudub]", + "sort_name": "[puudub]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -972,9 +972,9 @@ "locale": "ru", "name": "[самиздат]", "primary": false, - "sort-name": "samizdat", + "sort_name": "samizdat", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -983,9 +983,9 @@ "locale": "ja", "name": "[レーベルなし]", "primary": true, - "sort-name": "[レーベルなし]", + "sort_name": "[レーベルなし]", "type": "Label name", - "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + "type_id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" }, { "begin": null, @@ -994,9 +994,9 @@ "locale": null, "name": "annapantsu music", "primary": null, - "sort-name": "annapantsu music", + "sort_name": "annapantsu music", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1005,9 +1005,9 @@ "locale": null, "name": "auto-release", "primary": null, - "sort-name": "auto-release", + "sort_name": "auto-release", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1016,9 +1016,9 @@ "locale": null, "name": "autoprod.", "primary": null, - "sort-name": "autoprod.", + "sort_name": "autoprod.", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1027,9 +1027,9 @@ "locale": null, "name": "ayesha erotica", "primary": null, - "sort-name": "ayesha erotica", + "sort_name": "ayesha erotica", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1038,9 +1038,9 @@ "locale": null, "name": "blank", "primary": null, - "sort-name": "blank", + "sort_name": "blank", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1049,9 +1049,9 @@ "locale": null, "name": "cupcakKe", "primary": null, - "sort-name": "cupcakKe", + "sort_name": "cupcakKe", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1060,9 +1060,9 @@ "locale": null, "name": "d.silvestre", "primary": null, - "sort-name": "d.silvestre", + "sort_name": "d.silvestre", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1071,9 +1071,9 @@ "locale": null, "name": "dj-Jo", "primary": null, - "sort-name": "dj-Jo", + "sort_name": "dj-Jo", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1082,9 +1082,9 @@ "locale": null, "name": "independent release", "primary": null, - "sort-name": "independent release", + "sort_name": "independent release", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1093,9 +1093,9 @@ "locale": null, "name": "lor2mg", "primary": null, - "sort-name": "lor2mg", + "sort_name": "lor2mg", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1104,9 +1104,9 @@ "locale": null, "name": "nyamura", "primary": null, - "sort-name": "nyamura", + "sort_name": "nyamura", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1115,9 +1115,9 @@ "locale": null, "name": "pls dnt stp", "primary": null, - "sort-name": "pls dnt stp", + "sort_name": "pls dnt stp", "type": null, - "type-id": null + "type_id": null }, { "begin": null, @@ -1126,9 +1126,9 @@ "locale": null, "name": "self", "primary": null, - "sort-name": "self", + "sort_name": "self", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1137,9 +1137,9 @@ "locale": null, "name": "self issued", "primary": null, - "sort-name": "self issued", + "sort_name": "self issued", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1148,9 +1148,9 @@ "locale": null, "name": "self-issued", "primary": null, - "sort-name": "self-issued", + "sort_name": "self-issued", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1159,9 +1159,9 @@ "locale": null, "name": "white label", "primary": null, - "sort-name": "white label", + "sort_name": "white label", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1170,9 +1170,9 @@ "locale": null, "name": "но лабел", "primary": null, - "sort-name": "но лабел", + "sort_name": "но лабел", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" }, { "begin": null, @@ -1181,17 +1181,17 @@ "locale": null, "name": "独立发行", "primary": null, - "sort-name": "独立发行", + "sort_name": "独立发行", "type": "Search hint", - "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + "type_id": "829662f2-a781-3ec8-8b46-fbcea6196f81" } ], "disambiguation": "Special purpose label – white labels, self-published releases and other “no label” releases", "genres": [], "id": "157afde4-4bf5-4039-8ad2-5a15acc85176", - "label-code": null, + "label_code": null, "name": "[no label]", - "sort-name": "[no label]", + "sort_name": "[no label]", "tags": [ { "count": 12, @@ -1203,22 +1203,22 @@ } ], "type": "Production", - "type-id": "a2426aab-2dd4-339c-b47d-b4923a241678" + "type_id": "a2426aab-2dd4-339c-b47d-b4923a241678" } } ], "media": [ { "format": "Digital Media", - "format-id": "907a28d9-b3b2-3ef6-89a8-7b18d91d4794", + "format_id": "907a28d9-b3b2-3ef6-89a8-7b18d91d4794", "id": "43f08d54-a896-3561-be75-b881cbc832d5", "position": 1, "title": "", - "track-count": 1, - "track-offset": 0, + "track_count": 1, + "track_offset": 0, "tracks": [ { - "artist-credit": [ + "artist_credit": [ { "artist": { "aliases": [ @@ -1229,18 +1229,18 @@ "locale": "en", "name": "Lilas Ikuta", "primary": true, - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Artist name", - "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + "type_id": "894afba6-2816-3c24-8072-eadb66bd04bc" } ], "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "幾田りら" @@ -1252,43 +1252,43 @@ "position": 1, "recording": { "aliases": [], - "artist-credit": [ + "artist_credit": [ { "artist": { "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "幾田りら" } ], - "artist-relations": [ + "artist_relations": [ { "artist": { "country": "JP", "disambiguation": "Japanese composer/arranger/guitarist, agehasprings", "id": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", "name": "KOHD", - "sort-name": "KOHD", + "sort_name": "KOHD", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "arranger", - "type-id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d" + "type_id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d" }, { "artist": { @@ -1296,21 +1296,21 @@ "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": "2025", "direction": "backward", "end": "2025", "ended": true, - "source-credit": "", - "target-credit": "Lilas Ikuta", + "source_credit": "", + "target_credit": "Lilas Ikuta", "type": "phonographic copyright", - "type-id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30" + "type_id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30" }, { "artist": { @@ -1318,21 +1318,21 @@ "disambiguation": "", "id": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", "name": "山本秀哉", - "sort-name": "Yamamoto, Shuya", + "sort_name": "Yamamoto, Shuya", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "producer", - "type-id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0" + "type_id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0" }, { "artist": { @@ -1340,25 +1340,25 @@ "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "vocal", - "type-id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa" + "type_id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa" } ], "disambiguation": "", - "first-release-date": "2025-01-10", + "first_release_date": "2025-01-10", "genres": [], "id": "781724c1-a039-41e6-bd9b-770c3b9d5b8e", "isrcs": [ @@ -1367,53 +1367,53 @@ "length": 179546, "tags": [], "title": "百花繚乱", - "url-relations": [ + "url_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "free streaming", - "type-id": "7e41ef12-a124-4324-afdb-fdbae687a89c", + "type_id": "7e41ef12-a124-4324-afdb-fdbae687a89c", "url": { "id": "d076eaf9-5fde-4f6e-a946-cde16b67aa3b", "resource": "https://open.spotify.com/track/782PTXsbAWB70ySDZ5NHmP" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "92777657-504c-4acb-bd33-51a201bd57e1", + "type_id": "92777657-504c-4acb-bd33-51a201bd57e1", "url": { "id": "64879627-6eca-4755-98b5-b2234a8dbc61", "resource": "https://music.apple.com/jp/song/1857886416" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "streaming", - "type-id": "b5f3058a-666c-406f-aafb-f9249fc7b122", + "type_id": "b5f3058a-666c-406f-aafb-f9249fc7b122", "url": { "id": "64879627-6eca-4755-98b5-b2234a8dbc61", "resource": "https://music.apple.com/jp/song/1857886416" @@ -1421,42 +1421,42 @@ } ], "video": false, - "work-relations": [ + "work_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "performance", - "type-id": "a3005666-a872-32c3-ad06-98af558e99b0", + "type_id": "a3005666-a872-32c3-ad06-98af558e99b0", "work": { - "artist-relations": [ + "artist_relations": [ { "artist": { "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "composer", - "type-id": "d59d99ea-23d4-4a80-b066-edca32ee158f" + "type_id": "d59d99ea-23d4-4a80-b066-edca32ee158f" }, { "artist": { @@ -1464,21 +1464,21 @@ "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "lyricist", - "type-id": "3e48faba-ec01-47fd-8e89-30e81161661c" + "type_id": "3e48faba-ec01-47fd-8e89-30e81161661c" } ], "attributes": [], @@ -1491,37 +1491,37 @@ ], "title": "百花繚乱", "type": "Song", - "type-id": "f061270a-2fd6-32f1-a641-f0f8676d14e6", - "url-relations": [ + "type_id": "f061270a-2fd6-32f1-a641-f0f8676d14e6", + "url_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "type_id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "id": "dfac3640-6b23-4991-a59c-7cb80e8eb950", "resource": "https://utaten.com/lyric/tt24121002/" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "type_id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "id": "b1b5d5df-e79d-4cda-bb2a-8014e5505415", "resource": "https://www.uta-net.com/song/366579/" @@ -1538,27 +1538,27 @@ } ], "packaging": "None", - "packaging-id": "119eba76-b343-3e02-a292-f0f00644bb9b", + "packaging_id": "119eba76-b343-3e02-a292-f0f00644bb9b", "quality": "normal", - "release-events": [ + "release_events": [ { "area": { "disambiguation": "", "id": "525d4e18-3d00-31b9-a58b-a146a916de8f", - "iso-3166-1-codes": [ + "iso_3166_1_codes": [ "XW" ], "name": "[Worldwide]", - "sort-name": "[Worldwide]", + "sort_name": "[Worldwide]", "type": null, - "type-id": null + "type_id": null }, "date": "2025-01-10" } ], - "release-group": { + "release_group": { "aliases": [], - "artist-credit": [ + "artist_credit": [ { "artist": { "aliases": [ @@ -1569,54 +1569,54 @@ "locale": "en", "name": "Lilas Ikuta", "primary": true, - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Artist name", - "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + "type_id": "894afba6-2816-3c24-8072-eadb66bd04bc" } ], "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "幾田りら" } ], "disambiguation": "", - "first-release-date": "2025-01-10", + "first_release_date": "2025-01-10", "genres": [], "id": "da0d6bbb-f44b-4fff-8739-9d72db0402a1", - "primary-type": "Single", - "primary-type-id": "d6038452-8ee0-3f68-affc-2de9a1ede0b9", - "secondary-type-ids": [], - "secondary-types": [], + "primary_type": "Single", + "primary_type_id": "d6038452-8ee0-3f68-affc-2de9a1ede0b9", + "secondary_type_ids": [], + "secondary_types": [], "tags": [], "title": "百花繚乱" }, - "release-relations": [ + "release_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, "release": { - "artist-credit": [ + "artist_credit": [ { "artist": { "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": null, - "type-id": null + "type_id": null }, "joinphrase": "", "name": "Lilas Ikuta" @@ -1627,248 +1627,248 @@ "id": "dc3ee2df-0bc1-49eb-b8c4-34473d279a43", "media": [], "packaging": null, - "packaging-id": null, + "packaging_id": null, "quality": "normal", - "release-group": null, + "release_group": null, "status": null, - "status-id": null, - "text-representation": { + "status_id": null, + "text_representation": { "language": "eng", "script": "Latn" }, "title": "In Bloom" }, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "transl-tracklisting", - "type-id": "fc399d47-23a7-4c28-bfcf-0607a562b644" + "type_id": "fc399d47-23a7-4c28-bfcf-0607a562b644" } ], "status": "Official", - "status-id": "4e304316-386d-3409-af2e-78857eec5cfe", + "status_id": "4e304316-386d-3409-af2e-78857eec5cfe", "tags": [], - "text-representation": { + "text_representation": { "language": "jpn", "script": "Jpan" }, "title": "百花繚乱", - "url-relations": [ + "url_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "amazon asin", - "type-id": "4f2e710d-166c-480c-a293-2e2c8d658d87", + "type_id": "4f2e710d-166c-480c-a293-2e2c8d658d87", "url": { "id": "b50c7fb8-2327-4a05-b989-f2211a41afee", "resource": "https://www.amazon.co.jp/gp/product/B0DR8Y2YDC" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "free streaming", - "type-id": "08445ccf-7b99-4438-9f9a-fb9ac18099ee", + "type_id": "08445ccf-7b99-4438-9f9a-fb9ac18099ee", "url": { "id": "5106a7b0-1443-4803-91a2-28cac2cfb5e0", "resource": "https://open.spotify.com/album/3LDV2xGL9HiqCsQujEPQLb" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "free streaming", - "type-id": "08445ccf-7b99-4438-9f9a-fb9ac18099ee", + "type_id": "08445ccf-7b99-4438-9f9a-fb9ac18099ee", "url": { "id": "d481d94b-a7bf-4e82-8da0-1757fedcda62", "resource": "https://www.deezer.com/album/687686261" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", + "type_id": "98e08c20-8402-4163-8970-53504bb6a1e4", "url": { "id": "6156d2e4-d107-43f9-8f44-52f04d39c78e", "resource": "https://mora.jp/package/43000011/199066336168/" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", + "type_id": "98e08c20-8402-4163-8970-53504bb6a1e4", "url": { "id": "a4eabb88-1746-4aa2-ab09-c28cfbe65efb", "resource": "https://mora.jp/package/43000011/199066336168_HD/" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", + "type_id": "98e08c20-8402-4163-8970-53504bb6a1e4", "url": { "id": "ab8440f0-3b13-4436-b3ad-f4695c9d8875", "resource": "https://mora.jp/package/43000011/199066336168_LL/" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", + "type_id": "98e08c20-8402-4163-8970-53504bb6a1e4", "url": { "id": "9a8ee8d1-f946-44a1-be16-8f7a77c951e9", "resource": "https://music.apple.com/jp/album/1786972161" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", + "type_id": "98e08c20-8402-4163-8970-53504bb6a1e4", "url": { "id": "c6faaa80-38fb-46a4-aa2b-78cddc5cbe70", "resource": "https://ototoy.jp/_/default/p/2501951" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", + "type_id": "98e08c20-8402-4163-8970-53504bb6a1e4", "url": { "id": "0e7e8bc5-0779-492d-a9db-9ab58f96d23b", "resource": "https://www.qobuz.com/jp-ja/album/lilas-ikuta-/fl9tx2j78reza" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", + "type_id": "98e08c20-8402-4163-8970-53504bb6a1e4", "url": { "id": "c0cf8fe0-3413-4544-a026-37d346a59a77", "resource": "https://www.qobuz.com/jp-ja/album/lilas-ikuta-/l1dnc4xoi6l7a" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "streaming", - "type-id": "320adf26-96fa-4183-9045-1f5f32f833cb", + "type_id": "320adf26-96fa-4183-9045-1f5f32f833cb", "url": { "id": "e4ce55a9-a5e1-4842-b42d-11be6a31fdab", "resource": "https://music.amazon.co.jp/albums/B0DR8Y2YDC" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "streaming", - "type-id": "320adf26-96fa-4183-9045-1f5f32f833cb", + "type_id": "320adf26-96fa-4183-9045-1f5f32f833cb", "url": { "id": "9a8ee8d1-f946-44a1-be16-8f7a77c951e9", "resource": "https://music.apple.com/jp/album/1786972161" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "vgmdb", - "type-id": "6af0134a-df6a-425a-96e2-895f9cd342ba", + "type_id": "6af0134a-df6a-425a-96e2-895f9cd342ba", "url": { "id": "1885772a-4004-4d45-9512-d0c8822506c9", "resource": "https://vgmdb.net/album/145936" diff --git a/test/rsrc/mbpseudo/pseudo_release.json b/test/rsrc/mbpseudo/pseudo_release.json index ae4bf7b6b..1b5d9857c 100644 --- a/test/rsrc/mbpseudo/pseudo_release.json +++ b/test/rsrc/mbpseudo/pseudo_release.json @@ -1,6 +1,6 @@ { "aliases": [], - "artist-credit": [ + "artist_credit": [ { "artist": { "aliases": [ @@ -11,9 +11,9 @@ "locale": "en", "name": "Lilas Ikuta", "primary": true, - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Artist name", - "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + "type_id": "894afba6-2816-3c24-8072-eadb66bd04bc" } ], "country": "JP", @@ -34,7 +34,7 @@ ], "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "tags": [ { "count": 1, @@ -46,7 +46,7 @@ } ], "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "Lilas Ikuta" @@ -54,7 +54,7 @@ ], "asin": null, "barcode": null, - "cover-art-archive": { + "cover_art_archive": { "artwork": false, "back": false, "count": 0, @@ -64,19 +64,19 @@ "disambiguation": "", "genres": [], "id": "dc3ee2df-0bc1-49eb-b8c4-34473d279a43", - "label-info": [], + "label_info": [], "media": [ { "format": "Digital Media", - "format-id": "907a28d9-b3b2-3ef6-89a8-7b18d91d4794", + "format_id": "907a28d9-b3b2-3ef6-89a8-7b18d91d4794", "id": "606faab7-60fa-3a8b-a40f-2c66150cce81", "position": 1, "title": "", - "track-count": 1, - "track-offset": 0, + "track_count": 1, + "track_offset": 0, "tracks": [ { - "artist-credit": [ + "artist_credit": [ { "artist": { "aliases": [ @@ -87,18 +87,18 @@ "locale": "en", "name": "Lilas Ikuta", "primary": true, - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Artist name", - "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + "type_id": "894afba6-2816-3c24-8072-eadb66bd04bc" } ], "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "Lilas Ikuta" @@ -110,43 +110,43 @@ "position": 1, "recording": { "aliases": [], - "artist-credit": [ + "artist_credit": [ { "artist": { "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "幾田りら" } ], - "artist-relations": [ + "artist_relations": [ { "artist": { "country": "JP", "disambiguation": "Japanese composer/arranger/guitarist, agehasprings", "id": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", "name": "KOHD", - "sort-name": "KOHD", + "sort_name": "KOHD", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "arranger", - "type-id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d" + "type_id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d" }, { "artist": { @@ -154,21 +154,21 @@ "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": "2025", "direction": "backward", "end": "2025", "ended": true, - "source-credit": "", - "target-credit": "Lilas Ikuta", + "source_credit": "", + "target_credit": "Lilas Ikuta", "type": "phonographic copyright", - "type-id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30" + "type_id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30" }, { "artist": { @@ -176,21 +176,21 @@ "disambiguation": "", "id": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", "name": "山本秀哉", - "sort-name": "Yamamoto, Shuya", + "sort_name": "Yamamoto, Shuya", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "producer", - "type-id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0" + "type_id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0" }, { "artist": { @@ -198,25 +198,25 @@ "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "vocal", - "type-id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa" + "type_id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa" } ], "disambiguation": "", - "first-release-date": "2025-01-10", + "first_release_date": "2025-01-10", "genres": [], "id": "781724c1-a039-41e6-bd9b-770c3b9d5b8e", "isrcs": [ @@ -225,53 +225,53 @@ "length": 179546, "tags": [], "title": "百花繚乱", - "url-relations": [ + "url_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "free streaming", - "type-id": "7e41ef12-a124-4324-afdb-fdbae687a89c", + "type_id": "7e41ef12-a124-4324-afdb-fdbae687a89c", "url": { "id": "d076eaf9-5fde-4f6e-a946-cde16b67aa3b", "resource": "https://open.spotify.com/track/782PTXsbAWB70ySDZ5NHmP" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "purchase for download", - "type-id": "92777657-504c-4acb-bd33-51a201bd57e1", + "type_id": "92777657-504c-4acb-bd33-51a201bd57e1", "url": { "id": "64879627-6eca-4755-98b5-b2234a8dbc61", "resource": "https://music.apple.com/jp/song/1857886416" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "streaming", - "type-id": "b5f3058a-666c-406f-aafb-f9249fc7b122", + "type_id": "b5f3058a-666c-406f-aafb-f9249fc7b122", "url": { "id": "64879627-6eca-4755-98b5-b2234a8dbc61", "resource": "https://music.apple.com/jp/song/1857886416" @@ -279,42 +279,42 @@ } ], "video": false, - "work-relations": [ + "work_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "forward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "performance", - "type-id": "a3005666-a872-32c3-ad06-98af558e99b0", + "type_id": "a3005666-a872-32c3-ad06-98af558e99b0", "work": { - "artist-relations": [ + "artist_relations": [ { "artist": { "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "composer", - "type-id": "d59d99ea-23d4-4a80-b066-edca32ee158f" + "type_id": "d59d99ea-23d4-4a80-b066-edca32ee158f" }, { "artist": { @@ -322,21 +322,21 @@ "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "lyricist", - "type-id": "3e48faba-ec01-47fd-8e89-30e81161661c" + "type_id": "3e48faba-ec01-47fd-8e89-30e81161661c" } ], "attributes": [], @@ -349,37 +349,37 @@ ], "title": "百花繚乱", "type": "Song", - "type-id": "f061270a-2fd6-32f1-a641-f0f8676d14e6", - "url-relations": [ + "type_id": "f061270a-2fd6-32f1-a641-f0f8676d14e6", + "url_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "type_id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "id": "dfac3640-6b23-4991-a59c-7cb80e8eb950", "resource": "https://utaten.com/lyric/tt24121002/" } }, { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "type_id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", "url": { "id": "b1b5d5df-e79d-4cda-bb2a-8014e5505415", "resource": "https://www.uta-net.com/song/366579/" @@ -396,11 +396,11 @@ } ], "packaging": null, - "packaging-id": null, + "packaging_id": null, "quality": "normal", - "release-group": { + "release_group": { "aliases": [], - "artist-credit": [ + "artist_credit": [ { "artist": { "aliases": [ @@ -411,54 +411,54 @@ "locale": "en", "name": "Lilas Ikuta", "primary": true, - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Artist name", - "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + "type_id": "894afba6-2816-3c24-8072-eadb66bd04bc" } ], "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": "Person", - "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + "type_id": "b6e035f4-3ce9-331c-97df-83397230b0df" }, "joinphrase": "", "name": "幾田りら" } ], "disambiguation": "", - "first-release-date": "2025-01-10", + "first_release_date": "2025-01-10", "genres": [], "id": "da0d6bbb-f44b-4fff-8739-9d72db0402a1", - "primary-type": "Single", - "primary-type-id": "d6038452-8ee0-3f68-affc-2de9a1ede0b9", - "secondary-type-ids": [], - "secondary-types": [], + "primary_type": "Single", + "primary_type_id": "d6038452-8ee0-3f68-affc-2de9a1ede0b9", + "secondary_type_ids": [], + "secondary_types": [], "tags": [], "title": "百花繚乱" }, - "release-relations": [ + "release_relations": [ { - "attribute-ids": {}, - "attribute-values": {}, + "attribute_ids": {}, + "attribute_values": {}, "attributes": [], "begin": null, "direction": "backward", "end": null, "ended": false, "release": { - "artist-credit": [ + "artist_credit": [ { "artist": { "country": "JP", "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", "name": "幾田りら", - "sort-name": "Ikuta, Lilas", + "sort_name": "Ikuta, Lilas", "type": null, - "type-id": null + "type_id": null }, "joinphrase": "", "name": "幾田りら" @@ -471,43 +471,43 @@ "id": "a5ce1d11-2e32-45a4-b37f-c1589d46b103", "media": [], "packaging": null, - "packaging-id": null, + "packaging_id": null, "quality": "normal", - "release-events": [ + "release_events": [ { "area": { "disambiguation": "", "id": "525d4e18-3d00-31b9-a58b-a146a916de8f", - "iso-3166-1-codes": [ + "iso_3166_1_codes": [ "XW" ], "name": "[Worldwide]", - "sort-name": "[Worldwide]", + "sort_name": "[Worldwide]", "type": null, - "type-id": null + "type_id": null }, "date": "2025-01-10" } ], - "release-group": null, + "release_group": null, "status": null, - "status-id": null, - "text-representation": { + "status_id": null, + "text_representation": { "language": "jpn", "script": "Jpan" }, "title": "百花繚乱" }, - "source-credit": "", - "target-credit": "", + "source_credit": "", + "target_credit": "", "type": "transl-tracklisting", - "type-id": "fc399d47-23a7-4c28-bfcf-0607a562b644" + "type_id": "fc399d47-23a7-4c28-bfcf-0607a562b644" } ], "status": "Pseudo-Release", - "status-id": "41121bb9-3413-3818-8a9a-9742318349aa", + "status_id": "41121bb9-3413-3818-8a9a-9742318349aa", "tags": [], - "text-representation": { + "text_representation": { "language": "eng", "script": "Latn" },