diff --git a/beetsplug/_utils/requests.py b/beetsplug/_utils/requests.py index 9b82d4538..a9a1af372 100644 --- a/beetsplug/_utils/requests.py +++ b/beetsplug/_utils/requests.py @@ -6,7 +6,7 @@ import requests from beets import __version__ -class NotFoundError(requests.exceptions.HTTPError): +class HTTPNotFoundError(requests.exceptions.HTTPError): pass @@ -29,7 +29,7 @@ class TimeoutSession(requests.Session): kwargs.setdefault("timeout", 10) r = super().request(*args, **kwargs) if r.status_code == HTTPStatus.NOT_FOUND: - raise NotFoundError("HTTP Error: Not Found", response=r) + raise HTTPNotFoundError("HTTP Error: Not Found", response=r) if 300 <= r.status_code < 400: raise CaptchaError("Captcha is required", response=r) diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index 145438f19..8b28a6179 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -39,7 +39,7 @@ from beets import plugins, ui from beets.autotag.distance import string_dist from beets.util.config import sanitize_choices -from ._utils.requests import TimeoutSession +from ._utils.requests import CaptchaError, HTTPNotFoundError, TimeoutSession if TYPE_CHECKING: from collections.abc import Iterable, Iterator @@ -327,7 +327,7 @@ class LRCLib(Backend): yield self.fetch_json(self.SEARCH_URL, params=base_params) - with suppress(NotFoundError): + with suppress(HTTPNotFoundError): yield [self.fetch_json(self.GET_URL, params=get_params)] @classmethod diff --git a/beetsplug/mbpseudo.py b/beetsplug/mbpseudo.py index 9cfa99969..0e131a712 100644 --- a/beetsplug/mbpseudo.py +++ b/beetsplug/mbpseudo.py @@ -22,7 +22,6 @@ from copy import deepcopy from typing import TYPE_CHECKING, Any import mediafile -import musicbrainzngs from typing_extensions import override from beets import config @@ -32,7 +31,6 @@ from beets.autotag.match import assign_items from beets.plugins import find_plugins from beets.util.id_extractors import extract_release_id from beetsplug.musicbrainz import ( - RELEASE_INCLUDES, MusicBrainzAPIError, MusicBrainzPlugin, _merge_pseudo_and_actual_album, @@ -53,8 +51,6 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): def __init__(self) -> None: super().__init__() - self._release_getter = musicbrainzngs.get_release_by_id - self.config.add( { "scripts": [], @@ -143,12 +139,12 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): if release.get("status") == _STATUS_PSEUDO: return official_release - elif pseudo_release_ids := self._intercept_mb_release(release): - album_id = self._extract_id(pseudo_release_ids[0]) + + if (ids := self._intercept_mb_release(release)) and ( + album_id := self._extract_id(ids[0]) + ): try: - raw_pseudo_release = self._release_getter( - album_id, RELEASE_INCLUDES - )["release"] + raw_pseudo_release = self.api.get_release(album_id) pseudo_release = super().album_info(raw_pseudo_release) if self.config["custom_tags_only"].get(bool): @@ -181,7 +177,7 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): return [ pr_id - for rel in data.get("release-relation-list", []) + for rel in data.get("release-relations", []) if (pr_id := self._wanted_pseudo_release_id(album_id, rel)) is not None ] @@ -234,7 +230,7 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): "artist-credit", [] ) aliases = [ - artist_credit.get("artist", {}).get("alias-list", []) + artist_credit.get("artist", {}).get("aliases", []) for artist_credit in artist_credits ] @@ -247,7 +243,7 @@ class MusicBrainzPseudoReleasePlugin(MusicBrainzPlugin): aliases_flattened, ) if alias_dict := _preferred_alias(aliases_flattened, [locale]): - if alias := alias_dict.get("alias"): + if alias := alias_dict.get("name"): self._log.debug("Got alias '{0}'", alias) pseudo_release.artist = alias for track in pseudo_release.tracks: diff --git a/beetsplug/musicbrainz.py b/beetsplug/musicbrainz.py index 9a41b2a04..ac82aeec9 100644 --- a/beetsplug/musicbrainz.py +++ b/beetsplug/musicbrainz.py @@ -16,11 +16,12 @@ from __future__ import annotations +import operator import traceback from collections import Counter from contextlib import suppress -from functools import cached_property -from itertools import product +from functools import cached_property, singledispatchmethod +from itertools import groupby, product from typing import TYPE_CHECKING, Any from urllib.parse import urljoin @@ -35,7 +36,7 @@ from beets.metadata_plugins import MetadataSourcePlugin from beets.util.deprecation import deprecate_for_user from beets.util.id_extractors import extract_release_id -from ._utils.requests import TimeoutSession +from ._utils.requests import HTTPNotFoundError, TimeoutSession if TYPE_CHECKING: from collections.abc import Iterable, Sequence @@ -83,27 +84,24 @@ class MusicBrainzAPIError(util.HumanReadableError): return f"{self._reasonstr()} in {self.verb} with query {self.query!r}" -RELEASE_INCLUDES = list( - { - "artists", - "media", - "recordings", - "release-groups", - "labels", - "artist-credits", - "aliases", - "recording-level-rels", - "work-rels", - "work-level-rels", - "artist-rels", - "isrcs", - "url-rels", - "release-rels", - "genres", - "tags", - } - & set(musicbrainzngs.VALID_INCLUDES["release"]) -) +RELEASE_INCLUDES = [ + "artists", + "media", + "recordings", + "release-groups", + "labels", + "artist-credits", + "aliases", + "recording-level-rels", + "work-rels", + "work-level-rels", + "artist-rels", + "isrcs", + "url-rels", + "release-rels", + "genres", + "tags", +] TRACK_INCLUDES = list( { @@ -130,7 +128,7 @@ BROWSE_MAXTRACKS = 500 class MusicBrainzAPI: - api_url = "https://musicbrainz.org/ws/2/" + api_url = "https://musicbrainz.org/ws/2" @cached_property def session(self) -> LimiterTimeoutSession: @@ -141,6 +139,54 @@ class MusicBrainzAPI: f"{self.api_url}/{entity}", params={**kwargs, "fmt": "json"} ).json() + def get_release(self, id_: str) -> JSONDict: + return self._group_relations( + self._get(f"release/{id_}", inc=" ".join(RELEASE_INCLUDES)) + ) + + @singledispatchmethod + @classmethod + def _group_relations(cls, data: Any) -> Any: + """Normalize MusicBrainz 'relations' into type-keyed fields recursively. + + 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. + """ + return data + + @_group_relations.register(list) + @classmethod + def _(cls, data: list[Any]) -> list[Any]: + return [cls._group_relations(i) for i in data] + + @_group_relations.register(dict) + @classmethod + def _(cls, data: JSONDict) -> JSONDict: + for k, v in list(data.items()): + if k == "relations": + get_target_type = operator.methodcaller("get", "target-type") + for target_type, group in groupby( + sorted(v, key=get_target_type), get_target_type + ): + relations = [ + {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 + ) + data.pop("relations") + else: + data[k] = cls._group_relations(v) + return data + def _preferred_alias( aliases: list[JSONDict], languages: list[str] | None = None @@ -169,7 +215,7 @@ def _preferred_alias( for alias in valid_aliases: if ( alias["locale"] == locale - and "primary" in alias + and alias.get("primary") and alias.get("type", "").lower() not in ignored_alias_types ): matches.append(alias) @@ -194,36 +240,33 @@ def _multi_artist_credit( artist_sort_parts = [] artist_credit_parts = [] for el in credit: - if isinstance(el, str): - # Join phrase. - if include_join_phrase: - artist_parts.append(el) - artist_credit_parts.append(el) - artist_sort_parts.append(el) + alias = _preferred_alias(el["artist"].get("aliases", ())) + # An artist. + if alias: + cur_artist_name = alias["name"] else: - alias = _preferred_alias(el["artist"].get("alias-list", ())) + cur_artist_name = el["artist"]["name"] + artist_parts.append(cur_artist_name) - # An artist. - if alias: - cur_artist_name = alias["alias"] - else: - cur_artist_name = el["artist"]["name"] - artist_parts.append(cur_artist_name) + # 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"]) + else: + artist_sort_parts.append(cur_artist_name) - # 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"]) - else: - artist_sort_parts.append(cur_artist_name) + # Artist credit. + if "name" in el: + artist_credit_parts.append(el["name"]) + else: + artist_credit_parts.append(cur_artist_name) - # Artist credit. - if "name" in el: - artist_credit_parts.append(el["name"]) - else: - artist_credit_parts.append(cur_artist_name) + if include_join_phrase and (joinphrase := el.get("joinphrase")): + artist_parts.append(joinphrase) + artist_sort_parts.append(joinphrase) + artist_credit_parts.append(joinphrase) return ( artist_parts, @@ -293,9 +336,9 @@ def _preferred_release_event( ].as_str_seq() for country in preferred_countries: - for event in release.get("release-event-list", {}): + for event in release.get("release-events", {}): try: - if country in event["area"]["iso-3166-1-code-list"]: + if country in event["area"]["iso-3166-1-codes"]: return country, event["date"] except KeyError: pass @@ -370,7 +413,11 @@ def _merge_pseudo_and_actual_album( class MusicBrainzPlugin(MetadataSourcePlugin): @cached_property def genres_field(self) -> str: - return f"{self.config['genres_tag'].as_choice(['genre', 'tag'])}-list" + return f"{self.config['genres_tag'].as_choice(['genre', 'tag'])}s" + + @cached_property + def api(self) -> MusicBrainzAPI: + return MusicBrainzAPI() def __init__(self): """Set up the python-musicbrainz-ngs module according to settings @@ -461,9 +508,9 @@ class MusicBrainzPlugin(MetadataSourcePlugin): info.artists_ids = _artist_ids(recording["artist-credit"]) info.artist_id = info.artists_ids[0] - if recording.get("artist-relation-list"): + if recording.get("artist-relations"): info.remixer = _get_related_artist_names( - recording["artist-relation-list"], relation_type="remixer" + recording["artist-relations"], relation_type="remixer" ) if recording.get("length"): @@ -477,7 +524,7 @@ class MusicBrainzPlugin(MetadataSourcePlugin): lyricist = [] composer = [] composer_sort = [] - for work_relation in recording.get("work-relation-list", ()): + for work_relation in recording.get("work-relations", ()): if work_relation["type"] != "performance": continue info.work = work_relation["work"]["title"] @@ -486,7 +533,7 @@ class MusicBrainzPlugin(MetadataSourcePlugin): info.work_disambig = work_relation["work"]["disambiguation"] for artist_relation in work_relation["work"].get( - "artist-relation-list", () + "artist-relations", () ): if "type" in artist_relation: type = artist_relation["type"] @@ -504,7 +551,7 @@ class MusicBrainzPlugin(MetadataSourcePlugin): info.composer_sort = ", ".join(composer_sort) arranger = [] - for artist_relation in recording.get("artist-relation-list", ()): + for artist_relation in recording.get("artist-relations", ()): if "type" in artist_relation: type = artist_relation["type"] if type == "arranger": @@ -536,9 +583,9 @@ class MusicBrainzPlugin(MetadataSourcePlugin): release["artist-credit"], include_join_phrase=False ) - ntracks = sum(len(m["track-list"]) for m in release["medium-list"]) + ntracks = sum(len(m["tracks"]) for m in release["media"]) - # The MusicBrainz API omits 'artist-relation-list' and 'work-relation-list' + # The MusicBrainz API omits 'relations' # when the release has more than 500 tracks. So we use browse_recordings # on chunks of tracks to recover the same information in this case. if ntracks > BROWSE_MAXTRACKS: @@ -555,27 +602,27 @@ class MusicBrainzPlugin(MetadataSourcePlugin): )["recording-list"] ) track_map = {r["id"]: r for r in recording_list} - for medium in release["medium-list"]: - for recording in medium["track-list"]: + for medium in release["media"]: + for recording in medium["tracks"]: recording_info = track_map[recording["recording"]["id"]] recording["recording"] = recording_info # Basic info. track_infos = [] index = 0 - for medium in release["medium-list"]: + for medium in release["media"]: disctitle = medium.get("title") format = medium.get("format") if format in config["match"]["ignored_media"].as_str_seq(): continue - all_tracks = medium["track-list"] + all_tracks = medium["tracks"] if ( - "data-track-list" in medium + "data-tracks" in medium and not config["match"]["ignore_data_tracks"] ): - all_tracks += medium["data-track-list"] + all_tracks += medium["data-tracks"] track_count = len(all_tracks) if "pregap" in medium: @@ -590,7 +637,7 @@ class MusicBrainzPlugin(MetadataSourcePlugin): if ( "video" in track["recording"] - and track["recording"]["video"] == "true" + and track["recording"]["video"] and config["match"]["ignore_video_tracks"] ): continue @@ -644,7 +691,7 @@ class MusicBrainzPlugin(MetadataSourcePlugin): artists=artists_names, artists_ids=album_artist_ids, tracks=track_infos, - mediums=len(release["medium-list"]), + mediums=len(release["media"]), artist_sort=artist_sort_name, artists_sort=artists_sort_names, artist_credit=artist_credit_name, @@ -684,9 +731,9 @@ class MusicBrainzPlugin(MetadataSourcePlugin): rel_primarytype = release["release-group"]["primary-type"] if rel_primarytype: albumtypes.append(rel_primarytype.lower()) - if "secondary-type-list" in release["release-group"]: - if release["release-group"]["secondary-type-list"]: - for sec_type in release["release-group"]["secondary-type-list"]: + 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 @@ -702,8 +749,8 @@ class MusicBrainzPlugin(MetadataSourcePlugin): _set_date_str(info, release_group_date, True) # Label name. - if release.get("label-info-list"): - label_info = release["label-info-list"][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]": @@ -717,10 +764,10 @@ class MusicBrainzPlugin(MetadataSourcePlugin): info.language = rep.get("language") # Media (format). - if release["medium-list"]: + if release["media"]: # If all media are the same, use that medium name - if len({m.get("format") for m in release["medium-list"]}) == 1: - info.media = release["medium-list"][0].get("format") + if len({m.get("format") for m in release["media"]}) == 1: + info.media = release["media"][0].get("format") # Otherwise, let's just call it "Media" else: info.media = "Media" @@ -744,11 +791,11 @@ class MusicBrainzPlugin(MetadataSourcePlugin): wanted_sources = { site for site, wanted in external_ids.items() if wanted } - if wanted_sources and (url_rels := release.get("url-relation-list")): + if wanted_sources and (url_rels := release.get("url-relations")): urls = {} for source, url in product(wanted_sources, url_rels): - if f"{source}.com" in (target := url["target"]): + if f"{source}.com" in (target := url["url"]["resource"]): urls[source] = target self._log.debug( "Found link to {} release via MusicBrainz", @@ -838,7 +885,10 @@ class MusicBrainzPlugin(MetadataSourcePlugin): criteria = self.get_album_criteria(items, artist, album, va_likely) release_ids = (r["id"] for r in self._search_api("release", criteria)) - yield from filter(None, map(self.album_for_id, release_ids)) + for id_ in release_ids: + with suppress(HTTPNotFoundError): + if album_info := self.album_for_id(id_): + yield album_info def item_candidates( self, item: Item, artist: str, title: str @@ -862,22 +912,20 @@ class MusicBrainzPlugin(MetadataSourcePlugin): return None try: - res = musicbrainzngs.get_release_by_id(albumid, RELEASE_INCLUDES) + res = self.api.get_release(albumid) # resolve linked release relations actual_res = None if res.get("status") == "Pseudo-Release" and ( - relations := res["release"].get("release-relation-list") + relations := res.get("release-relations") ): for rel in relations: if ( rel["type"] == "transl-tracklisting" and rel["direction"] == "backward" ): - actual_res = musicbrainzngs.get_release_by_id( - rel["target"], RELEASE_INCLUDES - ) + actual_res = self.api.get_release(rel["target"]) except musicbrainzngs.ResponseError: self._log.debug("Album ID match failed.") @@ -888,11 +936,11 @@ class MusicBrainzPlugin(MetadataSourcePlugin): ) # release is potentially a pseudo release - release = self.album_info(res["release"]) + release = self.album_info(res) # should be None unless we're dealing with a pseudo release if actual_res is not None: - actual_release = self.album_info(actual_res["release"]) + actual_release = self.album_info(actual_res) return _merge_pseudo_and_actual_album(release, actual_release) else: return release diff --git a/test/plugins/test_mbpseudo.py b/test/plugins/test_mbpseudo.py index 621e08950..b333800a3 100644 --- a/test/plugins/test_mbpseudo.py +++ b/test/plugins/test_mbpseudo.py @@ -1,14 +1,14 @@ import json import pathlib +from copy import deepcopy import pytest -from beets import config from beets.autotag import AlbumMatch from beets.autotag.distance import Distance from beets.autotag.hooks import AlbumInfo, TrackInfo from beets.library import Item -from beets.test.helper import PluginMixin +from beets.test.helper import ConfigMixin, PluginMixin from beetsplug._typing import JSONDict from beetsplug.mbpseudo import ( _STATUS_PSEUDO, @@ -18,6 +18,23 @@ from beetsplug.mbpseudo import ( @pytest.fixture(scope="module") +def rsrc_dir(pytestconfig: pytest.Config): + return pytestconfig.rootpath / "test" / "rsrc" / "mbpseudo" + + +@pytest.fixture +def official_release(rsrc_dir: pathlib.Path) -> JSONDict: + info_json = (rsrc_dir / "official_release.json").read_text(encoding="utf-8") + return json.loads(info_json) + + +@pytest.fixture +def pseudo_release(rsrc_dir: pathlib.Path) -> JSONDict: + info_json = (rsrc_dir / "pseudo_release.json").read_text(encoding="utf-8") + return json.loads(info_json) + + +@pytest.fixture def official_release_info() -> AlbumInfo: return AlbumInfo( tracks=[TrackInfo(title="百花繚乱")], @@ -26,7 +43,7 @@ def official_release_info() -> AlbumInfo: ) -@pytest.fixture(scope="module") +@pytest.fixture def pseudo_release_info() -> AlbumInfo: return AlbumInfo( tracks=[TrackInfo(title="In Bloom")], @@ -35,6 +52,14 @@ def pseudo_release_info() -> AlbumInfo: ) +@pytest.fixture(scope="module", autouse=True) +def config(): + config = ConfigMixin().config + with pytest.MonkeyPatch.context() as m: + m.setattr("beetsplug.mbpseudo.config", config) + yield config + + class TestPseudoAlbumInfo: def test_album_id_always_from_pseudo( self, official_release_info: AlbumInfo, pseudo_release_info: AlbumInfo @@ -62,8 +87,7 @@ class TestPseudoAlbumInfo: info = PseudoAlbumInfo( pseudo_release_info, official_release_info, data_source="test" ) - item = Item() - item["title"] = "百花繚乱" + item = Item(title="百花繚乱") assert info.determine_best_ref([item]) == "official" @@ -71,37 +95,29 @@ class TestPseudoAlbumInfo: assert info.data_source == "test" -@pytest.fixture(scope="module") -def rsrc_dir(pytestconfig: pytest.Config): - return pytestconfig.rootpath / "test" / "rsrc" / "mbpseudo" - - -class TestMBPseudoPlugin(PluginMixin): +class TestMBPseudoMixin(PluginMixin): plugin = "mbpseudo" + @pytest.fixture(autouse=True) + def patch_get_release(self, monkeypatch, pseudo_release: JSONDict): + monkeypatch.setattr( + "beetsplug.musicbrainz.MusicBrainzAPI.get_release", + lambda _, album_id: deepcopy( + {pseudo_release["id"]: pseudo_release}[album_id] + ), + ) + @pytest.fixture(scope="class") def plugin_config(self): return {"scripts": ["Latn", "Dummy"]} - @pytest.fixture(scope="class") + @pytest.fixture def mbpseudo_plugin(self, plugin_config) -> MusicBrainzPseudoReleasePlugin: self.config[self.plugin].set(plugin_config) return MusicBrainzPseudoReleasePlugin() - @pytest.fixture - def official_release(self, rsrc_dir: pathlib.Path) -> JSONDict: - info_json = (rsrc_dir / "official_release.json").read_text( - encoding="utf-8" - ) - return json.loads(info_json) - - @pytest.fixture - def pseudo_release(self, rsrc_dir: pathlib.Path) -> JSONDict: - info_json = (rsrc_dir / "pseudo_release.json").read_text( - encoding="utf-8" - ) - return json.loads(info_json) +class TestMBPseudoPlugin(TestMBPseudoMixin): def test_scripts_init( self, mbpseudo_plugin: MusicBrainzPseudoReleasePlugin ): @@ -129,7 +145,7 @@ class TestMBPseudoPlugin(PluginMixin): mbpseudo_plugin: MusicBrainzPseudoReleasePlugin, pseudo_release: JSONDict, ): - album_info = mbpseudo_plugin.album_info(pseudo_release["release"]) + album_info = mbpseudo_plugin.album_info(pseudo_release) assert not isinstance(album_info, PseudoAlbumInfo) assert album_info.data_source == "MusicBrainzPseudoRelease" assert album_info.albumstatus == _STATUS_PSEUDO @@ -148,9 +164,9 @@ class TestMBPseudoPlugin(PluginMixin): official_release: JSONDict, json_key: str, ): - del official_release["release"]["release-relation-list"][0][json_key] + del official_release["release-relations"][0][json_key] - album_info = mbpseudo_plugin.album_info(official_release["release"]) + album_info = mbpseudo_plugin.album_info(official_release) assert not isinstance(album_info, PseudoAlbumInfo) assert album_info.data_source == "MusicBrainzPseudoRelease" @@ -159,11 +175,11 @@ class TestMBPseudoPlugin(PluginMixin): mbpseudo_plugin: MusicBrainzPseudoReleasePlugin, official_release: JSONDict, ): - official_release["release"]["release-relation-list"][0]["release"][ + official_release["release-relations"][0]["release"][ "text-representation" ]["script"] = "Null" - album_info = mbpseudo_plugin.album_info(official_release["release"]) + album_info = mbpseudo_plugin.album_info(official_release) assert not isinstance(album_info, PseudoAlbumInfo) assert album_info.data_source == "MusicBrainzPseudoRelease" @@ -171,12 +187,8 @@ class TestMBPseudoPlugin(PluginMixin): self, mbpseudo_plugin: MusicBrainzPseudoReleasePlugin, official_release: JSONDict, - pseudo_release: JSONDict, ): - mbpseudo_plugin._release_getter = ( - lambda album_id, includes: pseudo_release - ) - album_info = mbpseudo_plugin.album_info(official_release["release"]) + album_info = mbpseudo_plugin.album_info(official_release) assert isinstance(album_info, PseudoAlbumInfo) assert album_info.data_source == "MusicBrainzPseudoRelease" @@ -226,40 +238,19 @@ class TestMBPseudoPlugin(PluginMixin): assert match.info.album == "In Bloom" -class TestMBPseudoPluginCustomTagsOnly(PluginMixin): - plugin = "mbpseudo" - +class TestMBPseudoPluginCustomTagsOnly(TestMBPseudoMixin): @pytest.fixture(scope="class") - def mbpseudo_plugin(self) -> MusicBrainzPseudoReleasePlugin: - self.config[self.plugin]["scripts"] = ["Latn"] - self.config[self.plugin]["custom_tags_only"] = True - return MusicBrainzPseudoReleasePlugin() - - @pytest.fixture(scope="class") - def official_release(self, rsrc_dir: pathlib.Path) -> JSONDict: - info_json = (rsrc_dir / "official_release.json").read_text( - encoding="utf-8" - ) - return json.loads(info_json) - - @pytest.fixture(scope="class") - def pseudo_release(self, rsrc_dir: pathlib.Path) -> JSONDict: - info_json = (rsrc_dir / "pseudo_release.json").read_text( - encoding="utf-8" - ) - return json.loads(info_json) + def plugin_config(self): + return {"scripts": ["Latn", "Dummy"], "custom_tags_only": True} def test_custom_tags( self, + config, mbpseudo_plugin: MusicBrainzPseudoReleasePlugin, official_release: JSONDict, - pseudo_release: JSONDict, ): - config["import"]["languages"] = [] - mbpseudo_plugin._release_getter = ( - lambda album_id, includes: pseudo_release - ) - album_info = mbpseudo_plugin.album_info(official_release["release"]) + config["import"]["languages"] = ["en", "jp"] + album_info = mbpseudo_plugin.album_info(official_release) assert not isinstance(album_info, PseudoAlbumInfo) assert album_info.data_source == "MusicBrainzPseudoRelease" assert album_info["album_transl"] == "In Bloom" @@ -269,15 +260,12 @@ class TestMBPseudoPluginCustomTagsOnly(PluginMixin): def test_custom_tags_with_import_languages( self, + config, mbpseudo_plugin: MusicBrainzPseudoReleasePlugin, official_release: JSONDict, - pseudo_release: JSONDict, ): - config["import"]["languages"] = ["en", "jp"] - mbpseudo_plugin._release_getter = ( - lambda album_id, includes: pseudo_release - ) - album_info = mbpseudo_plugin.album_info(official_release["release"]) + config["import"]["languages"] = [] + album_info = mbpseudo_plugin.album_info(official_release) assert not isinstance(album_info, PseudoAlbumInfo) assert album_info.data_source == "MusicBrainzPseudoRelease" assert album_info["album_transl"] == "In Bloom" diff --git a/test/plugins/test_musicbrainz.py b/test/plugins/test_musicbrainz.py index 9e271a481..749e2805c 100644 --- a/test/plugins/test_musicbrainz.py +++ b/test/plugins/test_musicbrainz.py @@ -64,10 +64,10 @@ class MBAlbumInfoTest(MusicBrainzTestCase): } ], "date": "3001", - "medium-list": [], - "genre-list": [{"count": 1, "name": "GENRE"}], - "tag-list": [{"count": 1, "name": "TAG"}], - "label-info-list": [ + "media": [], + "genres": [{"count": 1, "name": "GENRE"}], + "tags": [{"count": 1, "name": "TAG"}], + "label-info": [ { "catalog-number": "CATALOG NUMBER", "label": {"name": "LABEL NAME"}, @@ -83,7 +83,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): } if multi_artist_credit: - release["artist-credit"].append(" & ") # add join phase + release["artist-credit"][0]["joinphrase"] = " & " release["artist-credit"].append( { "artist": { @@ -124,7 +124,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): ] if multi_artist_credit: - track["artist-credit"].append(" & ") # add join phase + track["artist-credit"][0]["joinphrase"] = " & " track["artist-credit"].append( { "artist": { @@ -148,11 +148,11 @@ class MBAlbumInfoTest(MusicBrainzTestCase): "number": "A1", } data_track_list.append(data_track) - release["medium-list"].append( + release["media"].append( { "position": "1", - "track-list": track_list, - "data-track-list": data_track_list, + "tracks": track_list, + "data-tracks": data_track_list, "format": medium_format, "title": "MEDIUM TITLE", } @@ -188,7 +188,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): } ] if multi_artist_credit: - track["artist-credit"].append(" & ") # add join phase + track["artist-credit"][0]["joinphrase"] = " & " track["artist-credit"].append( { "artist": { @@ -200,7 +200,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): } ) if remixer: - track["artist-relation-list"] = [ + track["artist-relations"] = [ { "type": "remixer", "type-id": "RELATION TYPE ID", @@ -215,7 +215,7 @@ class MBAlbumInfoTest(MusicBrainzTestCase): } ] if video: - track["video"] = "true" + track["video"] = True if disambiguation: track["disambiguation"] = disambiguation return track @@ -301,10 +301,10 @@ class MBAlbumInfoTest(MusicBrainzTestCase): "number": "A1", } ] - release["medium-list"].append( + release["media"].append( { "position": "2", - "track-list": second_track_list, + "tracks": second_track_list, } ) @@ -700,15 +700,15 @@ class ArtistFlatteningTest(unittest.TestCase): def _add_alias(self, credit_dict, suffix="", locale="", primary=False): alias = { - "alias": f"ALIAS{suffix}", + "name": f"ALIAS{suffix}", "locale": locale, "sort-name": f"ALIASSORT{suffix}", } if primary: alias["primary"] = "primary" - if "alias-list" not in credit_dict["artist"]: - credit_dict["artist"]["alias-list"] = [] - credit_dict["artist"]["alias-list"].append(alias) + if "aliases" not in credit_dict["artist"]: + credit_dict["artist"]["aliases"] = [] + credit_dict["artist"]["aliases"].append(alias) def test_single_artist(self): credit = [self._credit_dict()] @@ -725,7 +725,10 @@ class ArtistFlatteningTest(unittest.TestCase): assert c == ["CREDIT"] def test_two_artists(self): - credit = [self._credit_dict("a"), " AND ", self._credit_dict("b")] + credit = [ + {**self._credit_dict("a"), "joinphrase": " AND "}, + self._credit_dict("b"), + ] a, s, c = musicbrainz._flatten_artist_credit(credit) assert a == "NAMEa AND NAMEb" assert s == "SORTa AND SORTb" @@ -783,86 +786,84 @@ class MBLibraryTest(MusicBrainzTestCase): def test_follow_pseudo_releases(self): side_effect = [ { - "release": { - "title": "pseudo", - "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", - "status": "Pseudo-Release", - "medium-list": [ - { - "track-list": [ - { - "id": "baz", - "recording": { - "title": "translated title", - "id": "bar", - "length": 42, - }, - "position": 9, - "number": "A1", - } - ], - "position": 5, - } - ], - "artist-credit": [ - { - "artist": { - "name": "some-artist", - "id": "some-id", - }, - } - ], - "release-group": { - "id": "another-id", - }, - "release-relation-list": [ - { - "type": "transl-tracklisting", - "target": "d2a6f856-b553-40a0-ac54-a321e8e2da01", - "direction": "backward", - } - ], - } + "title": "pseudo", + "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", + "status": "Pseudo-Release", + "media": [ + { + "tracks": [ + { + "id": "baz", + "recording": { + "title": "translated title", + "id": "bar", + "length": 42, + }, + "position": 9, + "number": "A1", + } + ], + "position": 5, + } + ], + "artist-credit": [ + { + "artist": { + "name": "some-artist", + "id": "some-id", + }, + } + ], + "release-group": { + "id": "another-id", + }, + "release-relations": [ + { + "type": "transl-tracklisting", + "target": "d2a6f856-b553-40a0-ac54-a321e8e2da01", + "direction": "backward", + } + ], }, { - "release": { - "title": "actual", - "id": "d2a6f856-b553-40a0-ac54-a321e8e2da01", - "status": "Official", - "medium-list": [ - { - "track-list": [ - { - "id": "baz", - "recording": { - "title": "original title", - "id": "bar", - "length": 42, - }, - "position": 9, - "number": "A1", - } - ], - "position": 5, - } - ], - "artist-credit": [ - { - "artist": { - "name": "some-artist", - "id": "some-id", - }, - } - ], - "release-group": { - "id": "another-id", - }, - "country": "COUNTRY", - } + "title": "actual", + "id": "d2a6f856-b553-40a0-ac54-a321e8e2da01", + "status": "Official", + "media": [ + { + "tracks": [ + { + "id": "baz", + "recording": { + "title": "original title", + "id": "bar", + "length": 42, + }, + "position": 9, + "number": "A1", + } + ], + "position": 5, + } + ], + "artist-credit": [ + { + "artist": { + "name": "some-artist", + "id": "some-id", + }, + } + ], + "release-group": { + "id": "another-id", + }, + "country": "COUNTRY", }, ] - with mock.patch("musicbrainzngs.get_release_by_id") as gp: + with mock.patch( + "beetsplug.musicbrainz.MusicBrainzAPI.get_release" + ) as gp: gp.side_effect = side_effect album = self.mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") assert album.country == "COUNTRY" @@ -870,44 +871,43 @@ class MBLibraryTest(MusicBrainzTestCase): def test_pseudo_releases_with_empty_links(self): side_effect = [ { - "release": { - "title": "pseudo", - "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", - "status": "Pseudo-Release", - "medium-list": [ - { - "track-list": [ - { - "id": "baz", - "recording": { - "title": "translated title", - "id": "bar", - "length": 42, - }, - "position": 9, - "number": "A1", - } - ], - "position": 5, - } - ], - "artist-credit": [ - { - "artist": { - "name": "some-artist", - "id": "some-id", - }, - } - ], - "release-group": { - "id": "another-id", - }, - "release-relation-list": [], - } - }, + "title": "pseudo", + "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", + "status": "Pseudo-Release", + "media": [ + { + "tracks": [ + { + "id": "baz", + "recording": { + "title": "translated title", + "id": "bar", + "length": 42, + }, + "position": 9, + "number": "A1", + } + ], + "position": 5, + } + ], + "artist-credit": [ + { + "artist": { + "name": "some-artist", + "id": "some-id", + }, + } + ], + "release-group": { + "id": "another-id", + }, + } ] - with mock.patch("musicbrainzngs.get_release_by_id") as gp: + with mock.patch( + "beetsplug.musicbrainz.MusicBrainzAPI.get_release" + ) as gp: gp.side_effect = side_effect album = self.mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") assert album.country is None @@ -915,43 +915,43 @@ class MBLibraryTest(MusicBrainzTestCase): def test_pseudo_releases_without_links(self): side_effect = [ { - "release": { - "title": "pseudo", - "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", - "status": "Pseudo-Release", - "medium-list": [ - { - "track-list": [ - { - "id": "baz", - "recording": { - "title": "translated title", - "id": "bar", - "length": 42, - }, - "position": 9, - "number": "A1", - } - ], - "position": 5, - } - ], - "artist-credit": [ - { - "artist": { - "name": "some-artist", - "id": "some-id", - }, - } - ], - "release-group": { - "id": "another-id", - }, - } - }, + "title": "pseudo", + "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", + "status": "Pseudo-Release", + "media": [ + { + "tracks": [ + { + "id": "baz", + "recording": { + "title": "translated title", + "id": "bar", + "length": 42, + }, + "position": 9, + "number": "A1", + } + ], + "position": 5, + } + ], + "artist-credit": [ + { + "artist": { + "name": "some-artist", + "id": "some-id", + }, + } + ], + "release-group": { + "id": "another-id", + }, + } ] - with mock.patch("musicbrainzngs.get_release_by_id") as gp: + with mock.patch( + "beetsplug.musicbrainz.MusicBrainzAPI.get_release" + ) as gp: gp.side_effect = side_effect album = self.mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") assert album.country is None @@ -959,50 +959,50 @@ class MBLibraryTest(MusicBrainzTestCase): def test_pseudo_releases_with_unsupported_links(self): side_effect = [ { - "release": { - "title": "pseudo", - "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", - "status": "Pseudo-Release", - "medium-list": [ - { - "track-list": [ - { - "id": "baz", - "recording": { - "title": "translated title", - "id": "bar", - "length": 42, - }, - "position": 9, - "number": "A1", - } - ], - "position": 5, - } - ], - "artist-credit": [ - { - "artist": { - "name": "some-artist", - "id": "some-id", - }, - } - ], - "release-group": { - "id": "another-id", - }, - "release-relation-list": [ - { - "type": "remaster", - "target": "d2a6f856-b553-40a0-ac54-a321e8e2da01", - "direction": "backward", - } - ], - } - }, + "title": "pseudo", + "id": "d2a6f856-b553-40a0-ac54-a321e8e2da02", + "status": "Pseudo-Release", + "media": [ + { + "tracks": [ + { + "id": "baz", + "recording": { + "title": "translated title", + "id": "bar", + "length": 42, + }, + "position": 9, + "number": "A1", + } + ], + "position": 5, + } + ], + "artist-credit": [ + { + "artist": { + "name": "some-artist", + "id": "some-id", + }, + } + ], + "release-group": { + "id": "another-id", + }, + "release-relations": [ + { + "type": "remaster", + "target": "d2a6f856-b553-40a0-ac54-a321e8e2da01", + "direction": "backward", + } + ], + } ] - with mock.patch("musicbrainzngs.get_release_by_id") as gp: + with mock.patch( + "beetsplug.musicbrainz.MusicBrainzAPI.get_release" + ) as gp: gp.side_effect = side_effect album = self.mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") assert album.country is None @@ -1069,30 +1069,28 @@ class TestMusicBrainzPlugin(PluginMixin): lambda *_, **__: {"release-list": [{"id": self.mbid}]}, ) monkeypatch.setattr( - "musicbrainzngs.get_release_by_id", + "beetsplug.musicbrainz.MusicBrainzAPI.get_release", lambda *_, **__: { - "release": { - "title": "hi", - "id": self.mbid, - "status": "status", - "medium-list": [ - { - "track-list": [ - { - "id": "baz", - "recording": self.RECORDING, - "position": 9, - "number": "A1", - } - ], - "position": 5, - } - ], - "artist-credit": [ - {"artist": {"name": "some-artist", "id": "some-id"}} - ], - "release-group": {"id": "another-id"}, - } + "title": "hi", + "id": self.mbid, + "status": "status", + "media": [ + { + "tracks": [ + { + "id": "baz", + "recording": self.RECORDING, + "position": 9, + "number": "A1", + } + ], + "position": 5, + } + ], + "artist-credit": [ + {"artist": {"name": "some-artist", "id": "some-id"}} + ], + "release-group": {"id": "another-id"}, }, ) candidates = list(mb.candidates([], "hello", "there", False)) @@ -1100,3 +1098,84 @@ class TestMusicBrainzPlugin(PluginMixin): assert len(candidates) == 1 assert candidates[0].tracks[0].track_id == self.RECORDING["id"] assert candidates[0].album == "hi" + + +def test_group_relations(): + 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": "work", + "type": "performance", + "work": { + "relations": [ + { + "artist": {"name": "幾田りら"}, + "target-type": "artist", + "type": "composer", + }, + { + "target-type": "url", + "type": "lyrics", + "url": { + "resource": "https://utaten.com/lyric/tt24121002/" + }, + }, + { + "artist": {"name": "幾田りら"}, + "target-type": "artist", + "type": "lyricist", + }, + { + "target-type": "url", + "type": "lyrics", + "url": { + "resource": "https://www.uta-net.com/song/366579/" + }, + }, + ], + "title": "百花繚乱", + "type": "Song", + }, + }, + ], + } + + assert musicbrainz.MusicBrainzAPI._group_relations(raw_release) == { + "id": "r1", + "artist-relations": [{"type": "vocal", "name": "A"}], + "url-relations": [ + {"type": "streaming", "url": "http://s"}, + {"type": "purchase", "url": "http://p"}, + ], + "work-relations": [ + { + "type": "performance", + "work": { + "artist-relations": [ + {"type": "composer", "artist": {"name": "幾田りら"}}, + {"type": "lyricist", "artist": {"name": "幾田りら"}}, + ], + "url-relations": [ + { + "type": "lyrics", + "url": { + "resource": "https://utaten.com/lyric/tt24121002/" + }, + }, + { + "type": "lyrics", + "url": { + "resource": "https://www.uta-net.com/song/366579/" + }, + }, + ], + "title": "百花繚乱", + "type": "Song", + }, + }, + ], + } diff --git a/test/rsrc/mbpseudo/official_release.json b/test/rsrc/mbpseudo/official_release.json index 63f1d60dd..cd6bb3ba9 100644 --- a/test/rsrc/mbpseudo/official_release.json +++ b/test/rsrc/mbpseudo/official_release.json @@ -1,841 +1,1878 @@ { - "release": { - "id": "a5ce1d11-2e32-45a4-b37f-c1589d46b103", - "title": "百花繚乱", - "status": "Official", - "quality": "normal", - "packaging": "None", - "text-representation": { - "language": "jpn", - "script": "Jpan" - }, - "artist-credit": [ - { - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP", - "alias-list": [ - { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" - } - ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" - }, - { - "count": "1", - "name": "singer-songwriter" - } - ] - } - } - ], - "release-group": { - "id": "da0d6bbb-f44b-4fff-8739-9d72db0402a1", - "type": "Single", - "title": "百花繚乱", - "first-release-date": "2025-01-10", - "primary-type": "Single", - "artist-credit": [ - { - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP", - "alias-list": [ - { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" - } - ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" - }, - { - "count": "1", - "name": "singer-songwriter" - } - ] - } - } - ], - "artist-credit-phrase": "幾田りら" - }, - "date": "2025-01-10", - "country": "XW", - "release-event-list": [ - { - "date": "2025-01-10", - "area": { - "id": "525d4e18-3d00-31b9-a58b-a146a916de8f", - "name": "[Worldwide]", - "sort-name": "[Worldwide]", - "iso-3166-1-code-list": [ - "XW" - ] - } - } - ], - "release-event-count": 1, - "barcode": "199066336168", - "asin": "B0DR8Y2YDC", - "cover-art-archive": { - "artwork": "true", - "count": "1", - "front": "true", - "back": "false" - }, - "label-info-list": [ - { - "catalog-number": "Lilas-020", - "label": { - "id": "157afde4-4bf5-4039-8ad2-5a15acc85176", - "type": "Production", - "name": "[no label]", - "sort-name": "[no label]", - "disambiguation": "Special purpose label – white labels, self-published releases and other “no label” releases", - "alias-list": [ - { - "sort-name": "2636621 Records DK", - "alias": "2636621 Records DK" - }, - { - "sort-name": "Auto production", - "type": "Search hint", - "alias": "Auto production" - }, - { - "sort-name": "Auto-Edición", - "type": "Search hint", - "alias": "Auto-Edición" - }, - { - "sort-name": "Auto-Product", - "type": "Search hint", - "alias": "Auto-Product" - }, - { - "sort-name": "Autoedición", - "type": "Search hint", - "alias": "Autoedición" - }, - { - "sort-name": "Autoeditado", - "type": "Search hint", - "alias": "Autoeditado" - }, - { - "sort-name": "Autoproduit", - "type": "Search hint", - "alias": "Autoproduit" - }, - { - "sort-name": "D.I.Y.", - "type": "Search hint", - "alias": "D.I.Y." - }, - { - "sort-name": "Demo", - "type": "Search hint", - "alias": "Demo" - }, - { - "sort-name": "DistroKid", - "type": "Search hint", - "alias": "DistroKid" - }, - { - "sort-name": "Eigenverlag", - "type": "Search hint", - "alias": "Eigenverlag" - }, - { - "sort-name": "Eigenvertrieb", - "type": "Search hint", - "alias": "Eigenvertrieb" - }, - { - "sort-name": "GRIND MODE", - "alias": "GRIND MODE" - }, - { - "sort-name": "INDIPENDANT", - "type": "Search hint", - "alias": "INDIPENDANT" - }, - { - "sort-name": "Indepandant", - "type": "Search hint", - "alias": "Indepandant" - }, - { - "sort-name": "Independant release", - "type": "Search hint", - "alias": "Independant release" - }, - { - "sort-name": "Independent", - "type": "Search hint", - "alias": "Independent" - }, - { - "sort-name": "Independente", - "type": "Search hint", - "alias": "Independente" - }, - { - "sort-name": "Independiente", - "type": "Search hint", - "alias": "Independiente" - }, - { - "sort-name": "Indie", - "type": "Search hint", - "alias": "Indie" - }, - { - "sort-name": "Joost Klein", - "alias": "Joost Klein" - }, - { - "sort-name": "MoroseSound", - "alias": "MoroseSound" - }, - { - "sort-name": "N/A", - "type": "Search hint", - "alias": "N/A" - }, - { - "sort-name": "No Label", - "type": "Search hint", - "alias": "No Label" - }, - { - "sort-name": "None", - "type": "Search hint", - "alias": "None" - }, - { - "sort-name": "Not On A Lebel", - "type": "Search hint", - "alias": "Not On A Lebel" - }, - { - "sort-name": "Not On Label", - "type": "Search hint", - "alias": "Not On Label" - }, - { - "sort-name": "P2019", - "alias": "P2019" - }, - { - "sort-name": "P2020", - "alias": "P2020" - }, - { - "sort-name": "P2021", - "alias": "P2021" - }, - { - "sort-name": "P2022", - "alias": "P2022" - }, - { - "sort-name": "P2023", - "alias": "P2023" - }, - { - "sort-name": "P2024", - "alias": "P2024" - }, - { - "sort-name": "P2025", - "alias": "P2025" - }, - { - "sort-name": "Records DK", - "type": "Search hint", - "alias": "Records DK" - }, - { - "sort-name": "Self Digital", - "type": "Search hint", - "alias": "Self Digital" - }, - { - "sort-name": "Self Release", - "type": "Search hint", - "alias": "Self Release" - }, - { - "sort-name": "Self Released", - "type": "Search hint", - "alias": "Self Released" - }, - { - "sort-name": "Self-release", - "type": "Search hint", - "alias": "Self-release" - }, - { - "sort-name": "Self-released", - "type": "Search hint", - "alias": "Self-released" - }, - { - "sort-name": "Self-released/independent", - "type": "Search hint", - "alias": "Self-released/independent" - }, - { - "sort-name": "Sevdaliza", - "alias": "Sevdaliza" - }, - { - "sort-name": "TOMMY CASH", - "alias": "TOMMY CASH" - }, - { - "sort-name": "Talwiinder", - "alias": "Talwiinder" - }, - { - "sort-name": "Unsigned", - "type": "Search hint", - "alias": "Unsigned" - }, - { - "locale": "fi", - "sort-name": "ei levymerkkiä", - "type": "Label name", - "primary": "primary", - "alias": "[ei levymerkkiä]" - }, - { - "locale": "nl", - "sort-name": "[geen platenmaatschappij]", - "type": "Label name", - "primary": "primary", - "alias": "[geen platenmaatschappij]" - }, - { - "locale": "et", - "sort-name": "[ilma plaadifirmata]", - "type": "Label name", - "alias": "[ilma plaadifirmata]" - }, - { - "locale": "es", - "sort-name": "[nada]", - "type": "Label name", - "primary": "primary", - "alias": "[nada]" - }, - { - "locale": "en", - "sort-name": "[no label]", - "type": "Label name", - "primary": "primary", - "alias": "[no label]" - }, - { - "sort-name": "[nolabel]", - "type": "Search hint", - "alias": "[nolabel]" - }, - { - "sort-name": "[none]", - "type": "Search hint", - "alias": "[none]" - }, - { - "locale": "lt", - "sort-name": "[nėra leidybinės kompanijos]", - "type": "Label name", - "alias": "[nėra leidybinės kompanijos]" - }, - { - "locale": "lt", - "sort-name": "[nėra leidyklos]", - "type": "Label name", - "alias": "[nėra leidyklos]" - }, - { - "locale": "lt", - "sort-name": "[nėra įrašų kompanijos]", - "type": "Label name", - "primary": "primary", - "alias": "[nėra įrašų kompanijos]" - }, - { - "locale": "et", - "sort-name": "[puudub]", - "type": "Label name", - "alias": "[puudub]" - }, - { - "locale": "ru", - "sort-name": "samizdat", - "type": "Label name", - "alias": "[самиздат]" - }, - { - "locale": "ja", - "sort-name": "[レーベルなし]", - "type": "Label name", - "primary": "primary", - "alias": "[レーベルなし]" - }, - { - "sort-name": "auto-release", - "type": "Search hint", - "alias": "auto-release" - }, - { - "sort-name": "autoprod.", - "type": "Search hint", - "alias": "autoprod." - }, - { - "sort-name": "blank", - "type": "Search hint", - "alias": "blank" - }, - { - "sort-name": "d.silvestre", - "alias": "d.silvestre" - }, - { - "sort-name": "independent release", - "type": "Search hint", - "alias": "independent release" - }, - { - "sort-name": "nyamura", - "alias": "nyamura" - }, - { - "sort-name": "pls dnt stp", - "alias": "pls dnt stp" - }, - { - "sort-name": "self", - "type": "Search hint", - "alias": "self" - }, - { - "sort-name": "self issued", - "type": "Search hint", - "alias": "self issued" - }, - { - "sort-name": "self-issued", - "type": "Search hint", - "alias": "self-issued" - }, - { - "sort-name": "white label", - "type": "Search hint", - "alias": "white label" - }, - { - "sort-name": "но лабел", - "type": "Search hint", - "alias": "но лабел" - }, - { - "sort-name": "独立发行", - "type": "Search hint", - "alias": "独立发行" - } - ], - "alias-count": 71, - "tag-list": [ - { - "count": "12", - "name": "special purpose" - }, - { - "count": "18", - "name": "special purpose label" - } - ] - } - } - ], - "label-info-count": 1, - "medium-list": [ - { - "position": "1", - "format": "Digital Media", - "track-list": [ + "aliases": [ + { + "begin": null, + "end": null, + "ended": false, + "locale": "en", + "name": "In Bloom", + "primary": true, + "sort-name": "In Bloom", + "type": "Release name", + "type-id": "df187855-059b-3514-9d5e-d240de0b4228" + } + ], + "artist-credit": [ + { + "artist": { + "aliases": [ { - "id": "0bd01e8b-18e1-4708-b0a3-c9603b89ab97", - "position": "1", - "number": "1", - "length": "179239", - "recording": { - "id": "781724c1-a039-41e6-bd9b-770c3b9d5b8e", - "title": "百花繚乱", - "length": "179546", - "artist-credit": [ - { - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", + "begin": null, + "end": null, + "ended": false, + "locale": "en", + "name": "Lilas Ikuta", + "primary": true, + "sort-name": "Ikuta, Lilas", + "type": "Artist name", + "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + } + ], + "country": "JP", + "disambiguation": "", + "genres": [ + { + "count": 1, + "disambiguation": "", + "id": "eba7715e-ee26-4989-8d49-9db382955419", + "name": "j-pop" + }, + { + "count": 1, + "disambiguation": "", + "id": "455f264b-db00-4716-991d-fbd32dc24523", + "name": "singer-songwriter" + } + ], + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "tags": [ + { + "count": 1, + "name": "j-pop" + }, + { + "count": 1, + "name": "singer-songwriter" + } + ], + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "幾田りら" + } + ], + "artist-relations": [ + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": "2025", + "direction": "backward", + "end": "2025", + "ended": true, + "source-credit": "", + "target-credit": "Lilas Ikuta", + "type": "copyright", + "type-id": "730b5251-7432-4896-8fc6-e1cba943bfe1" + }, + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": "2025", + "direction": "backward", + "end": "2025", + "ended": true, + "source-credit": "", + "target-credit": "Lilas Ikuta", + "type": "phonographic copyright", + "type-id": "01d3488d-8d2a-4cff-9226-5250404db4dc" + } + ], + "asin": "B0DR8Y2YDC", + "barcode": "199066336168", + "country": "XW", + "cover-art-archive": { + "artwork": true, + "back": false, + "count": 1, + "darkened": false, + "front": true + }, + "date": "2025-01-10", + "disambiguation": "", + "genres": [], + "id": "a5ce1d11-2e32-45a4-b37f-c1589d46b103", + "label-info": [ + { + "catalog-number": "Lilas-020", + "label": { + "aliases": [ + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "2636621 Records DK", + "primary": null, + "sort-name": "2636621 Records DK", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Antipole", + "primary": null, + "sort-name": "Antipole", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Auto production", + "primary": null, + "sort-name": "Auto production", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Auto-Edición", + "primary": null, + "sort-name": "Auto-Edición", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Auto-Product", + "primary": null, + "sort-name": "Auto-Product", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Autoedición", + "primary": null, + "sort-name": "Autoedición", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Autoeditado", + "primary": null, + "sort-name": "Autoeditado", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Autoproduit", + "primary": null, + "sort-name": "Autoproduit", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Banana Skin Records", + "primary": null, + "sort-name": "Banana Skin Records", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Cannelle", + "primary": null, + "sort-name": "Cannelle", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Cece Natalie", + "primary": null, + "sort-name": "Cece Natalie", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Cherry X", + "primary": null, + "sort-name": "Cherry X", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Chung", + "primary": null, + "sort-name": "Chung", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Cody Johnson", + "primary": null, + "sort-name": "Cody Johnson", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Cowgirl Clue", + "primary": null, + "sort-name": "Cowgirl Clue", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "D.I.Y.", + "primary": null, + "sort-name": "D.I.Y.", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Damjan Mravunac Self-released)", + "primary": null, + "sort-name": "Damjan Mravunac Self-released)", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Demo", + "primary": null, + "sort-name": "Demo", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "DistroKid", + "primary": null, + "sort-name": "DistroKid", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Egzod", + "primary": null, + "sort-name": "Egzod", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Eigenverlag", + "primary": null, + "sort-name": "Eigenverlag", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Eigenvertrieb", + "primary": null, + "sort-name": "Eigenvertrieb", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "GRIND MODE", + "primary": null, + "sort-name": "GRIND MODE", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "INDIPENDANT", + "primary": null, + "sort-name": "INDIPENDANT", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Indepandant", + "primary": null, + "sort-name": "Indepandant", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Independant release", + "primary": null, + "sort-name": "Independant release", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Independent", + "primary": null, + "sort-name": "Independent", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Independente", + "primary": null, + "sort-name": "Independente", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Independiente", + "primary": null, + "sort-name": "Independiente", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Indie", + "primary": null, + "sort-name": "Indie", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Joost Klein", + "primary": null, + "sort-name": "Joost Klein", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Millington Records", + "primary": null, + "sort-name": "Millington Records", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "MoroseSound", + "primary": null, + "sort-name": "MoroseSound", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "N/A", + "primary": null, + "sort-name": "N/A", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "No Label", + "primary": null, + "sort-name": "No Label", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "None", + "primary": null, + "sort-name": "None", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "None Like Joshua", + "primary": null, + "sort-name": "None Like Joshua", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Not On A Lebel", + "primary": null, + "sort-name": "Not On A Lebel", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Not On Label", + "primary": null, + "sort-name": "Not On Label", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Offensively Average Productions", + "primary": null, + "sort-name": "Offensively Average Productions", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Ours", + "primary": null, + "sort-name": "Ours", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "P2019", + "primary": null, + "sort-name": "P2019", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "P2020", + "primary": null, + "sort-name": "P2020", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "P2021", + "primary": null, + "sort-name": "P2021", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "P2022", + "primary": null, + "sort-name": "P2022", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "P2023", + "primary": null, + "sort-name": "P2023", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "P2024", + "primary": null, + "sort-name": "P2024", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "P2025", + "primary": null, + "sort-name": "P2025", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Patriarchy", + "primary": null, + "sort-name": "Patriarchy", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Plini", + "primary": null, + "sort-name": "Plini", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Records DK", + "primary": null, + "sort-name": "Records DK", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Self Digital", + "primary": null, + "sort-name": "Self Digital", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Self Release", + "primary": null, + "sort-name": "Self Release", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Self Released", + "primary": null, + "sort-name": "Self Released", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Self-release", + "primary": null, + "sort-name": "Self-release", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Self-released", + "primary": null, + "sort-name": "Self-released", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Self-released/independent", + "primary": null, + "sort-name": "Self-released/independent", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Sevdaliza", + "primary": null, + "sort-name": "Sevdaliza", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "TOMMY CASH", + "primary": null, + "sort-name": "TOMMY CASH", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Take Van", + "primary": null, + "sort-name": "Take Van", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Talwiinder", + "primary": null, + "sort-name": "Talwiinder", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Unsigned", + "primary": null, + "sort-name": "Unsigned", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "VGR", + "primary": null, + "sort-name": "VGR", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "Woo Da Savage", + "primary": null, + "sort-name": "Woo Da Savage", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "YANAA", + "primary": null, + "sort-name": "YANAA", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "fi", + "name": "[ei levymerkkiä]", + "primary": true, + "sort-name": "ei levymerkkiä", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "nl", + "name": "[geen platenmaatschappij]", + "primary": true, + "sort-name": "[geen platenmaatschappij]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "et", + "name": "[ilma plaadifirmata]", + "primary": false, + "sort-name": "[ilma plaadifirmata]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "es", + "name": "[nada]", + "primary": true, + "sort-name": "[nada]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "en", + "name": "[no label]", + "primary": true, + "sort-name": "[no label]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "[nolabel]", + "primary": null, + "sort-name": "[nolabel]", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "[none]", + "primary": null, + "sort-name": "[none]", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "lt", + "name": "[nėra leidybinės kompanijos]", + "primary": false, + "sort-name": "[nėra leidybinės kompanijos]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "lt", + "name": "[nėra leidyklos]", + "primary": false, + "sort-name": "[nėra leidyklos]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "lt", + "name": "[nėra įrašų kompanijos]", + "primary": true, + "sort-name": "[nėra įrašų kompanijos]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "et", + "name": "[puudub]", + "primary": false, + "sort-name": "[puudub]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "ru", + "name": "[самиздат]", + "primary": false, + "sort-name": "samizdat", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": "ja", + "name": "[レーベルなし]", + "primary": true, + "sort-name": "[レーベルなし]", + "type": "Label name", + "type-id": "3a1a0c48-d885-3b89-87b2-9e8a483c5675" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "annapantsu music", + "primary": null, + "sort-name": "annapantsu music", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "auto-release", + "primary": null, + "sort-name": "auto-release", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "autoprod.", + "primary": null, + "sort-name": "autoprod.", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "ayesha erotica", + "primary": null, + "sort-name": "ayesha erotica", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "blank", + "primary": null, + "sort-name": "blank", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "cupcakKe", + "primary": null, + "sort-name": "cupcakKe", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "d.silvestre", + "primary": null, + "sort-name": "d.silvestre", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "dj-Jo", + "primary": null, + "sort-name": "dj-Jo", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "independent release", + "primary": null, + "sort-name": "independent release", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "lor2mg", + "primary": null, + "sort-name": "lor2mg", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "nyamura", + "primary": null, + "sort-name": "nyamura", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "pls dnt stp", + "primary": null, + "sort-name": "pls dnt stp", + "type": null, + "type-id": null + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "self", + "primary": null, + "sort-name": "self", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "self issued", + "primary": null, + "sort-name": "self issued", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "self-issued", + "primary": null, + "sort-name": "self-issued", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "white label", + "primary": null, + "sort-name": "white label", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "но лабел", + "primary": null, + "sort-name": "но лабел", + "type": "Search hint", + "type-id": "829662f2-a781-3ec8-8b46-fbcea6196f81" + }, + { + "begin": null, + "end": null, + "ended": false, + "locale": null, + "name": "独立发行", + "primary": null, + "sort-name": "独立发行", + "type": "Search hint", + "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, + "name": "[no label]", + "sort-name": "[no label]", + "tags": [ + { + "count": 12, + "name": "special purpose" + }, + { + "count": 18, + "name": "special purpose label" + } + ], + "type": "Production", + "type-id": "a2426aab-2dd4-339c-b47d-b4923a241678" + } + } + ], + "media": [ + { + "format": "Digital Media", + "format-id": "907a28d9-b3b2-3ef6-89a8-7b18d91d4794", + "id": "43f08d54-a896-3561-be75-b881cbc832d5", + "position": 1, + "title": "", + "track-count": 1, + "track-offset": 0, + "tracks": [ + { + "artist-credit": [ + { + "artist": { + "aliases": [ + { + "begin": null, + "end": null, + "ended": false, + "locale": "en", + "name": "Lilas Ikuta", + "primary": true, "sort-name": "Ikuta, Lilas", - "country": "JP", - "alias-list": [ - { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" - } - ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" - }, - { - "count": "1", - "name": "singer-songwriter" - } - ] + "type": "Artist name", + "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" } - } - ], - "isrc-list": [ - "JPP302400868" - ], - "isrc-count": 1, - "artist-relation-list": [ - { - "type": "arranger", - "type-id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d", - "target": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", - "direction": "backward", - "artist": { - "id": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", - "type": "Person", - "name": "KOHD", - "sort-name": "KOHD", - "country": "JP", - "disambiguation": "Japanese composer/arranger/guitarist, agehasprings" - } - }, - { - "type": "phonographic copyright", - "type-id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "begin": "2025", - "end": "2025", - "ended": "true", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - }, - "target-credit": "Lilas Ikuta" - }, - { - "type": "producer", - "type-id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0", - "target": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", - "direction": "backward", - "artist": { - "id": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", - "type": "Person", - "name": "山本秀哉", - "sort-name": "Yamamoto, Shuya", - "country": "JP" - } - }, - { - "type": "vocal", - "type-id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } - } - ], - "work-relation-list": [ - { - "type": "performance", - "type-id": "a3005666-a872-32c3-ad06-98af558e99b0", - "target": "9e14d6b2-ac7d-43e9-82a9-561bc76ce2ed", - "direction": "forward", - "work": { - "id": "9e14d6b2-ac7d-43e9-82a9-561bc76ce2ed", - "type": "Song", - "title": "百花繚乱", - "language": "jpn", - "artist-relation-list": [ - { - "type": "composer", - "type-id": "d59d99ea-23d4-4a80-b066-edca32ee158f", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } - }, - { - "type": "lyricist", - "type-id": "3e48faba-ec01-47fd-8e89-30e81161661c", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } - } - ], - "url-relation-list": [ - { - "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", - "target": "https://utaten.com/lyric/tt24121002/", - "direction": "backward" - }, - { - "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", - "target": "https://www.uta-net.com/song/366579/", - "direction": "backward" - } - ] - } - } - ], - "artist-credit-phrase": "幾田りら" - }, + ], + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "幾田りら" + } + ], + "id": "0bd01e8b-18e1-4708-b0a3-c9603b89ab97", + "length": 179239, + "number": "1", + "position": 1, + "recording": { + "aliases": [], "artist-credit": [ { "artist": { + "country": "JP", + "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", "name": "幾田りら", "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "幾田りら" + } + ], + "artist-relations": [ + { + "artist": { "country": "JP", - "alias-list": [ + "disambiguation": "Japanese composer/arranger/guitarist, agehasprings", + "id": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", + "name": "KOHD", + "sort-name": "KOHD", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "arranger", + "type-id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d" + }, + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": "2025", + "direction": "backward", + "end": "2025", + "ended": true, + "source-credit": "", + "target-credit": "Lilas Ikuta", + "type": "phonographic copyright", + "type-id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30" + }, + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", + "name": "山本秀哉", + "sort-name": "Yamamoto, Shuya", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "producer", + "type-id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0" + }, + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "vocal", + "type-id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa" + } + ], + "disambiguation": "", + "first-release-date": "2025-01-10", + "genres": [], + "id": "781724c1-a039-41e6-bd9b-770c3b9d5b8e", + "isrcs": [ + "JPP302400868" + ], + "length": 179546, + "tags": [], + "title": "百花繚乱", + "url-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "free streaming", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "streaming", + "type-id": "b5f3058a-666c-406f-aafb-f9249fc7b122", + "url": { + "id": "64879627-6eca-4755-98b5-b2234a8dbc61", + "resource": "https://music.apple.com/jp/song/1857886416" + } + } + ], + "video": false, + "work-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "performance", + "type-id": "a3005666-a872-32c3-ad06-98af558e99b0", + "work": { + "artist-relations": [ { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" - } - ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "composer", + "type-id": "d59d99ea-23d4-4a80-b066-edca32ee158f" }, { - "count": "1", - "name": "singer-songwriter" + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "lyricist", + "type-id": "3e48faba-ec01-47fd-8e89-30e81161661c" + } + ], + "attributes": [], + "disambiguation": "", + "id": "9e14d6b2-ac7d-43e9-82a9-561bc76ce2ed", + "iswcs": [], + "language": "jpn", + "languages": [ + "jpn" + ], + "title": "百花繚乱", + "type": "Song", + "type-id": "f061270a-2fd6-32f1-a641-f0f8676d14e6", + "url-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "lyrics", + "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "url": { + "id": "dfac3640-6b23-4991-a59c-7cb80e8eb950", + "resource": "https://utaten.com/lyric/tt24121002/" + } + }, + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "lyrics", + "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "url": { + "id": "b1b5d5df-e79d-4cda-bb2a-8014e5505415", + "resource": "https://www.uta-net.com/song/366579/" + } } ] } } - ], - "artist-credit-phrase": "幾田りら", - "track_or_recording_length": "179239" - } - ], - "track-count": 1 - } - ], - "medium-count": 1, - "artist-relation-list": [ - { - "type": "copyright", - "type-id": "730b5251-7432-4896-8fc6-e1cba943bfe1", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "begin": "2025", - "end": "2025", - "ended": "true", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - }, - "target-credit": "Lilas Ikuta" - }, - { - "type": "phonographic copyright", - "type-id": "01d3488d-8d2a-4cff-9226-5250404db4dc", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "begin": "2025", - "end": "2025", - "ended": "true", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - }, - "target-credit": "Lilas Ikuta" - } - ], - "release-relation-list": [ - { - "type": "transl-tracklisting", - "type-id": "fc399d47-23a7-4c28-bfcf-0607a562b644", - "target": "dc3ee2df-0bc1-49eb-b8c4-34473d279a43", - "direction": "forward", - "release": { - "id": "dc3ee2df-0bc1-49eb-b8c4-34473d279a43", - "title": "In Bloom", - "quality": "normal", - "text-representation": { - "language": "eng", - "script": "Latn" + ] }, - "artist-credit": [ + "title": "百花繚乱" + } + ] + } + ], + "packaging": "None", + "packaging-id": "119eba76-b343-3e02-a292-f0f00644bb9b", + "quality": "normal", + "release-events": [ + { + "area": { + "disambiguation": "", + "id": "525d4e18-3d00-31b9-a58b-a146a916de8f", + "iso-3166-1-codes": [ + "XW" + ], + "name": "[Worldwide]", + "sort-name": "[Worldwide]", + "type": null, + "type-id": null + }, + "date": "2025-01-10" + } + ], + "release-group": { + "aliases": [], + "artist-credit": [ + { + "artist": { + "aliases": [ { + "begin": null, + "end": null, + "ended": false, + "locale": "en", "name": "Lilas Ikuta", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } + "primary": true, + "sort-name": "Ikuta, Lilas", + "type": "Artist name", + "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" } ], - "medium-list": [], - "medium-count": 0, - "artist-credit-phrase": "Lilas Ikuta" - } + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "幾田りら" } ], - "url-relation-list": [ - { - "type": "amazon asin", - "type-id": "4f2e710d-166c-480c-a293-2e2c8d658d87", - "target": "https://www.amazon.co.jp/gp/product/B0DR8Y2YDC", - "direction": "forward" + "disambiguation": "", + "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": [], + "tags": [], + "title": "百花繚乱" + }, + "release-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "release": { + "artist-credit": [ + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": null, + "type-id": null + }, + "joinphrase": "", + "name": "Lilas Ikuta" + } + ], + "barcode": null, + "disambiguation": "", + "id": "dc3ee2df-0bc1-49eb-b8c4-34473d279a43", + "media": [], + "packaging": null, + "packaging-id": null, + "quality": "normal", + "release-group": null, + "status": null, + "status-id": null, + "text-representation": { + "language": "eng", + "script": "Latn" + }, + "title": "In Bloom" }, - { - "type": "free streaming", - "type-id": "08445ccf-7b99-4438-9f9a-fb9ac18099ee", - "target": "https://open.spotify.com/album/3LDV2xGL9HiqCsQujEPQLb", - "direction": "forward" - }, - { - "type": "free streaming", - "type-id": "08445ccf-7b99-4438-9f9a-fb9ac18099ee", - "target": "https://www.deezer.com/album/687686261", - "direction": "forward" - }, - { - "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", - "target": "https://mora.jp/package/43000011/199066336168/", - "direction": "forward" - }, - { - "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", - "target": "https://mora.jp/package/43000011/199066336168_HD/", - "direction": "forward" - }, - { - "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", - "target": "https://mora.jp/package/43000011/199066336168_LL/", - "direction": "forward" - }, - { - "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", - "target": "https://music.apple.com/jp/album/1786972161", - "direction": "forward" - }, - { - "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", - "target": "https://ototoy.jp/_/default/p/2501951", - "direction": "forward" - }, - { - "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", - "target": "https://www.qobuz.com/jp-ja/album/lilas-ikuta-/fl9tx2j78reza", - "direction": "forward" - }, - { - "type": "purchase for download", - "type-id": "98e08c20-8402-4163-8970-53504bb6a1e4", - "target": "https://www.qobuz.com/jp-ja/album/lilas-ikuta-/l1dnc4xoi6l7a", - "direction": "forward" - }, - { - "type": "streaming", - "type-id": "320adf26-96fa-4183-9045-1f5f32f833cb", - "target": "https://music.amazon.co.jp/albums/B0DR8Y2YDC", - "direction": "forward" - }, - { - "type": "streaming", - "type-id": "320adf26-96fa-4183-9045-1f5f32f833cb", - "target": "https://music.apple.com/jp/album/1786972161", - "direction": "forward" - }, - { - "type": "vgmdb", - "type-id": "6af0134a-df6a-425a-96e2-895f9cd342ba", - "target": "https://vgmdb.net/album/145936", - "direction": "forward" + "source-credit": "", + "target-credit": "", + "type": "transl-tracklisting", + "type-id": "fc399d47-23a7-4c28-bfcf-0607a562b644" + } + ], + "status": "Official", + "status-id": "4e304316-386d-3409-af2e-78857eec5cfe", + "tags": [], + "text-representation": { + "language": "jpn", + "script": "Jpan" + }, + "title": "百花繚乱", + "url-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "amazon asin", + "type-id": "4f2e710d-166c-480c-a293-2e2c8d658d87", + "url": { + "id": "b50c7fb8-2327-4a05-b989-f2211a41afee", + "resource": "https://www.amazon.co.jp/gp/product/B0DR8Y2YDC" } - ], - "artist-credit-phrase": "幾田りら" - } + }, + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "free streaming", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "free streaming", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "streaming", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "streaming", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "vgmdb", + "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 99fa0b417..ae4bf7b6b 100644 --- a/test/rsrc/mbpseudo/pseudo_release.json +++ b/test/rsrc/mbpseudo/pseudo_release.json @@ -1,346 +1,515 @@ { - "release": { - "id": "dc3ee2df-0bc1-49eb-b8c4-34473d279a43", - "title": "In Bloom", - "status": "Pseudo-Release", - "quality": "normal", - "text-representation": { - "language": "eng", - "script": "Latn" - }, - "artist-credit": [ - { - "name": "Lilas Ikuta", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP", - "alias-list": [ + "aliases": [], + "artist-credit": [ + { + "artist": { + "aliases": [ + { + "begin": null, + "end": null, + "ended": false, + "locale": "en", + "name": "Lilas Ikuta", + "primary": true, + "sort-name": "Ikuta, Lilas", + "type": "Artist name", + "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + } + ], + "country": "JP", + "disambiguation": "", + "genres": [ + { + "count": 1, + "disambiguation": "", + "id": "eba7715e-ee26-4989-8d49-9db382955419", + "name": "j-pop" + }, + { + "count": 1, + "disambiguation": "", + "id": "455f264b-db00-4716-991d-fbd32dc24523", + "name": "singer-songwriter" + } + ], + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "tags": [ + { + "count": 1, + "name": "j-pop" + }, + { + "count": 1, + "name": "singer-songwriter" + } + ], + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "Lilas Ikuta" + } + ], + "asin": null, + "barcode": null, + "cover-art-archive": { + "artwork": false, + "back": false, + "count": 0, + "darkened": false, + "front": false + }, + "disambiguation": "", + "genres": [], + "id": "dc3ee2df-0bc1-49eb-b8c4-34473d279a43", + "label-info": [], + "media": [ + { + "format": "Digital Media", + "format-id": "907a28d9-b3b2-3ef6-89a8-7b18d91d4794", + "id": "606faab7-60fa-3a8b-a40f-2c66150cce81", + "position": 1, + "title": "", + "track-count": 1, + "track-offset": 0, + "tracks": [ + { + "artist-credit": [ { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" + "artist": { + "aliases": [ + { + "begin": null, + "end": null, + "ended": false, + "locale": "en", + "name": "Lilas Ikuta", + "primary": true, + "sort-name": "Ikuta, Lilas", + "type": "Artist name", + "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + } + ], + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "Lilas Ikuta" } ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" - }, - { - "count": "1", - "name": "singer-songwriter" - } - ] - } - } - ], - "release-group": { - "id": "da0d6bbb-f44b-4fff-8739-9d72db0402a1", - "type": "Single", - "title": "百花繚乱", - "first-release-date": "2025-01-10", - "primary-type": "Single", - "artist-credit": [ - { - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP", - "alias-list": [ - { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" - } - ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" - }, - { - "count": "1", - "name": "singer-songwriter" - } - ] - } - } - ], - "artist-credit-phrase": "幾田りら" - }, - "cover-art-archive": { - "artwork": "false", - "count": "0", - "front": "false", - "back": "false" - }, - "label-info-list": [], - "label-info-count": 0, - "medium-list": [ - { - "position": "1", - "format": "Digital Media", - "track-list": [ - { - "id": "2018b012-a184-49a2-a464-fb4628a89588", - "position": "1", - "number": "1", - "title": "In Bloom", - "length": "179239", + "id": "2018b012-a184-49a2-a464-fb4628a89588", + "length": 179239, + "number": "1", + "position": 1, + "recording": { + "aliases": [], "artist-credit": [ { - "name": "Lilas Ikuta", "artist": { + "country": "JP", + "disambiguation": "", "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", "name": "幾田りら", "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "幾田りら" + } + ], + "artist-relations": [ + { + "artist": { "country": "JP", - "alias-list": [ + "disambiguation": "Japanese composer/arranger/guitarist, agehasprings", + "id": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", + "name": "KOHD", + "sort-name": "KOHD", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "arranger", + "type-id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d" + }, + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": "2025", + "direction": "backward", + "end": "2025", + "ended": true, + "source-credit": "", + "target-credit": "Lilas Ikuta", + "type": "phonographic copyright", + "type-id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30" + }, + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", + "name": "山本秀哉", + "sort-name": "Yamamoto, Shuya", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "producer", + "type-id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0" + }, + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "vocal", + "type-id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa" + } + ], + "disambiguation": "", + "first-release-date": "2025-01-10", + "genres": [], + "id": "781724c1-a039-41e6-bd9b-770c3b9d5b8e", + "isrcs": [ + "JPP302400868" + ], + "length": 179546, + "tags": [], + "title": "百花繚乱", + "url-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "free streaming", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "purchase for download", + "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": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "streaming", + "type-id": "b5f3058a-666c-406f-aafb-f9249fc7b122", + "url": { + "id": "64879627-6eca-4755-98b5-b2234a8dbc61", + "resource": "https://music.apple.com/jp/song/1857886416" + } + } + ], + "video": false, + "work-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "forward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "performance", + "type-id": "a3005666-a872-32c3-ad06-98af558e99b0", + "work": { + "artist-relations": [ { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" - } - ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "composer", + "type-id": "d59d99ea-23d4-4a80-b066-edca32ee158f" }, { - "count": "1", - "name": "singer-songwriter" + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "lyricist", + "type-id": "3e48faba-ec01-47fd-8e89-30e81161661c" + } + ], + "attributes": [], + "disambiguation": "", + "id": "9e14d6b2-ac7d-43e9-82a9-561bc76ce2ed", + "iswcs": [], + "language": "jpn", + "languages": [ + "jpn" + ], + "title": "百花繚乱", + "type": "Song", + "type-id": "f061270a-2fd6-32f1-a641-f0f8676d14e6", + "url-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "lyrics", + "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "url": { + "id": "dfac3640-6b23-4991-a59c-7cb80e8eb950", + "resource": "https://utaten.com/lyric/tt24121002/" + } + }, + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "source-credit": "", + "target-credit": "", + "type": "lyrics", + "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", + "url": { + "id": "b1b5d5df-e79d-4cda-bb2a-8014e5505415", + "resource": "https://www.uta-net.com/song/366579/" + } } ] } } - ], - "recording": { - "id": "781724c1-a039-41e6-bd9b-770c3b9d5b8e", - "title": "百花繚乱", - "length": "179546", - "artist-credit": [ - { - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP", - "alias-list": [ - { - "locale": "en", - "sort-name": "Ikuta, Lilas", - "type": "Artist name", - "primary": "primary", - "alias": "Lilas Ikuta" - } - ], - "alias-count": 1, - "tag-list": [ - { - "count": "1", - "name": "j-pop" - }, - { - "count": "1", - "name": "singer-songwriter" - } - ] - } - } - ], - "isrc-list": [ - "JPP302400868" - ], - "isrc-count": 1, - "artist-relation-list": [ - { - "type": "arranger", - "type-id": "22661fb8-cdb7-4f67-8385-b2a8be6c9f0d", - "target": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", - "direction": "backward", - "artist": { - "id": "f24241fb-4d89-4bf2-8336-3f2a7d2c0025", - "type": "Person", - "name": "KOHD", - "sort-name": "KOHD", - "country": "JP", - "disambiguation": "Japanese composer/arranger/guitarist, agehasprings" - } - }, - { - "type": "phonographic copyright", - "type-id": "7fd5fbc0-fbf4-4d04-be23-417d50a4dc30", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "begin": "2025", - "end": "2025", - "ended": "true", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - }, - "target-credit": "Lilas Ikuta" - }, - { - "type": "producer", - "type-id": "5c0ceac3-feb4-41f0-868d-dc06f6e27fc0", - "target": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", - "direction": "backward", - "artist": { - "id": "1d27ab8a-a0df-47cf-b4cc-d2d7a0712a05", - "type": "Person", - "name": "山本秀哉", - "sort-name": "Yamamoto, Shuya", - "country": "JP" - } - }, - { - "type": "vocal", - "type-id": "0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } - } - ], - "work-relation-list": [ - { - "type": "performance", - "type-id": "a3005666-a872-32c3-ad06-98af558e99b0", - "target": "9e14d6b2-ac7d-43e9-82a9-561bc76ce2ed", - "direction": "forward", - "work": { - "id": "9e14d6b2-ac7d-43e9-82a9-561bc76ce2ed", - "type": "Song", - "title": "百花繚乱", - "language": "jpn", - "artist-relation-list": [ - { - "type": "composer", - "type-id": "d59d99ea-23d4-4a80-b066-edca32ee158f", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } - }, - { - "type": "lyricist", - "type-id": "3e48faba-ec01-47fd-8e89-30e81161661c", - "target": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "direction": "backward", - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "type": "Person", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } - } - ], - "url-relation-list": [ - { - "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", - "target": "https://utaten.com/lyric/tt24121002/", - "direction": "backward" - }, - { - "type": "lyrics", - "type-id": "e38e65aa-75e0-42ba-ace0-072aeb91a538", - "target": "https://www.uta-net.com/song/366579/", - "direction": "backward" - } - ] - } - } - ], - "artist-credit-phrase": "幾田りら" + ] + }, + "title": "In Bloom" + } + ] + } + ], + "packaging": null, + "packaging-id": null, + "quality": "normal", + "release-group": { + "aliases": [], + "artist-credit": [ + { + "artist": { + "aliases": [ + { + "begin": null, + "end": null, + "ended": false, + "locale": "en", + "name": "Lilas Ikuta", + "primary": true, + "sort-name": "Ikuta, Lilas", + "type": "Artist name", + "type-id": "894afba6-2816-3c24-8072-eadb66bd04bc" + } + ], + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": "Person", + "type-id": "b6e035f4-3ce9-331c-97df-83397230b0df" + }, + "joinphrase": "", + "name": "幾田りら" + } + ], + "disambiguation": "", + "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": [], + "tags": [], + "title": "百花繚乱" + }, + "release-relations": [ + { + "attribute-ids": {}, + "attribute-values": {}, + "attributes": [], + "begin": null, + "direction": "backward", + "end": null, + "ended": false, + "release": { + "artist-credit": [ + { + "artist": { + "country": "JP", + "disambiguation": "", + "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", + "name": "幾田りら", + "sort-name": "Ikuta, Lilas", + "type": null, + "type-id": null }, - "artist-credit-phrase": "Lilas Ikuta", - "track_or_recording_length": "179239" + "joinphrase": "", + "name": "幾田りら" } ], - "track-count": 1 - } - ], - "medium-count": 1, - "release-relation-list": [ - { - "type": "transl-tracklisting", - "type-id": "fc399d47-23a7-4c28-bfcf-0607a562b644", - "target": "a5ce1d11-2e32-45a4-b37f-c1589d46b103", - "direction": "backward", - "release": { - "id": "a5ce1d11-2e32-45a4-b37f-c1589d46b103", - "title": "百花繚乱", - "quality": "normal", - "text-representation": { - "language": "jpn", - "script": "Jpan" - }, - "artist-credit": [ - { - "artist": { - "id": "55e42264-ef27-49d8-93fd-29f930dc96e4", - "name": "幾田りら", - "sort-name": "Ikuta, Lilas", - "country": "JP" - } - } - ], - "date": "2025-01-10", - "country": "XW", - "release-event-list": [ - { - "date": "2025-01-10", - "area": { - "id": "525d4e18-3d00-31b9-a58b-a146a916de8f", - "name": "[Worldwide]", - "sort-name": "[Worldwide]", - "iso-3166-1-code-list": [ - "XW" - ] - } - } - ], - "release-event-count": 1, - "barcode": "199066336168", - "medium-list": [], - "medium-count": 0, - "artist-credit-phrase": "幾田りら" - } - } - ], - "artist-credit-phrase": "Lilas Ikuta" - } -} \ No newline at end of file + "barcode": "199066336168", + "country": "XW", + "date": "2025-01-10", + "disambiguation": "", + "id": "a5ce1d11-2e32-45a4-b37f-c1589d46b103", + "media": [], + "packaging": null, + "packaging-id": null, + "quality": "normal", + "release-events": [ + { + "area": { + "disambiguation": "", + "id": "525d4e18-3d00-31b9-a58b-a146a916de8f", + "iso-3166-1-codes": [ + "XW" + ], + "name": "[Worldwide]", + "sort-name": "[Worldwide]", + "type": null, + "type-id": null + }, + "date": "2025-01-10" + } + ], + "release-group": null, + "status": null, + "status-id": null, + "text-representation": { + "language": "jpn", + "script": "Jpan" + }, + "title": "百花繚乱" + }, + "source-credit": "", + "target-credit": "", + "type": "transl-tracklisting", + "type-id": "fc399d47-23a7-4c28-bfcf-0607a562b644" + } + ], + "status": "Pseudo-Release", + "status-id": "41121bb9-3413-3818-8a9a-9742318349aa", + "tags": [], + "text-representation": { + "language": "eng", + "script": "Latn" + }, + "title": "In Bloom" +}