diff --git a/README.md b/README.md index 01df802..26f48dc 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,10 @@ For searching, as well as for downloading I use the programm `youtube-dl`, which There are two bottlenecks with this approach though: 1. `youtube-dl` is just slow. Actually it has to be, to not get blocked by youtube. -2. Ofthen musicbrainz just doesn't give the isrc for some songs. +2. Often musicbrainz just doesn't give the isrc for some songs. **TODO** - look at how the isrc id derived an try to generate it for the tracks without directly getting it from mb. + +**Progress** +- There is a great site whith a huge isrc database [https://isrc.soundexchange.com/](https://isrc.soundexchange.com/). diff --git a/src/download.py b/src/download.py index 6f1d185..342c945 100644 --- a/src/download.py +++ b/src/download.py @@ -50,13 +50,11 @@ def path_stuff(path: str, file_: str): class Download: - def __init__(self, session: requests.Session = requests.Session(), file: str = ".cache3.csv", temp: str = "temp", + def __init__(self, proxies: dict = None, file: str = ".cache3.csv", temp: str = "temp", base_path: str = ""): - self.session = session - self.session.headers = { - "Connection": "keep-alive", - "Referer": "https://musify.club/" - } + if proxies is not None: + musify.set_proxy(proxies) + self.temp = temp self.file = file diff --git a/src/download_links.py b/src/download_links.py index 78e7178..22baec6 100644 --- a/src/download_links.py +++ b/src/download_links.py @@ -9,8 +9,11 @@ import youtube_music class Download: - def __init__(self, metadata_csv: str = ".cache1.csv", session: requests.Session = requests.Session(), + def __init__(self, metadata_csv: str = ".cache1.csv", proxies: dict = None, file: str = ".cache2.csv", temp: str = "temp") -> None: + if proxies is not None: + musify.set_proxy(proxies) + self.temp = temp self.metadata = pd.read_csv(os.path.join(self.temp, metadata_csv), index_col=0) diff --git a/src/main.py b/src/main.py index c92a055..507beab 100644 --- a/src/main.py +++ b/src/main.py @@ -1,10 +1,9 @@ -import metadata +import metadata.metadata import download_links import url_to_path import download import logging -import requests import os @@ -15,7 +14,7 @@ STEP_THREE_CACHE = ".cache3.csv" NOT_A_GENRE = ".", "..", "misc_scripts", "Music", "script", ".git", ".idea" MUSIC_DIR = os.path.expanduser('~/Music') -TOR = False +TOR = True logging.basicConfig(level=logging.INFO) @@ -30,7 +29,7 @@ def get_existing_genre(): def search_for_metadata(query: str): - search = metadata.Search(query=query, temp=TEMP) + search = metadata.metadata.Search(query=query, temp=TEMP) print(search.options) while True: @@ -71,9 +70,9 @@ def get_genre(): def cli(start_at: int = 0): - session = requests.Session() + proxies = None if TOR: - session.proxies = { + proxies = { 'http': 'socks5h://127.0.0.1:9150', 'https': 'socks5h://127.0.0.1:9150' } @@ -89,7 +88,7 @@ def cli(start_at: int = 0): if start_at <= 1: logging.info("Fetching Download Links") - download_links.Download(file=STEP_TWO_CACHE, metadata_csv=STEP_ONE_CACHE, temp=TEMP, session=session) + download_links.Download(file=STEP_TWO_CACHE, metadata_csv=STEP_ONE_CACHE, temp=TEMP, proxies=proxies) if start_at <= 2: logging.info("creating Paths") @@ -97,7 +96,7 @@ def cli(start_at: int = 0): if start_at <= 3: logging.info("starting to download the mp3's") - download.Download(session=session, file=STEP_THREE_CACHE, temp=TEMP, base_path=MUSIC_DIR) + download.Download(proxies=proxies, file=STEP_THREE_CACHE, temp=TEMP, base_path=MUSIC_DIR) if __name__ == "__main__": diff --git a/src/metadata.py b/src/metadata.py deleted file mode 100644 index 8a6d24c..0000000 --- a/src/metadata.py +++ /dev/null @@ -1,461 +0,0 @@ -import os.path -import logging - -import musicbrainzngs -import pandas as pd - -mb_log = logging.getLogger("musicbrainzngs") -mb_log.setLevel(logging.WARNING) -musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader") - -KNOWN_KIND_OF_OPTIONS = ["artist", "release", "track"] - - -def output(msg: str): - print(msg) - - -def get_elem_from_obj(current_object, keys: list, after_process=lambda x: x, return_if_none=None): - current_object = current_object - for key in keys: - if key in current_object or (type(key) == int and key < len(current_object)): - current_object = current_object[key] - else: - return return_if_none - return after_process(current_object) - - -class Search: - def __init__(self, query: str = None, artist: str = None, temp: str = "temp"): - if query is None and artist is None: - raise ValueError("no query provided") - - self.options_history = [] - self.current_options = None - self.current_chosen_option = None - - self.temp = temp - - # initial search - if query is not None: - self.set_options(self.Options([musicbrainzngs.search_artists(query), musicbrainzngs.search_releases(query), - musicbrainzngs.search_recordings(query)])) - elif artist is not None: - self.set_options(self.Options([musicbrainzngs.search_artists(artist=artist)])) - - def download(self, file: str = ".cache1.csv"): - kind = self.current_chosen_option['kind'] - mb_id = self.current_chosen_option['id'] - - metadata_list = [] - if kind == "artist": - - metadata_list = self.download_artist(mb_id) - elif kind == "release": - metadata_list = self.download_release(mb_id) - elif kind == "track": - metadata_list = self.download_track(mb_id) - - metadata_df = pd.DataFrame(metadata_list) - metadata_df.to_csv(os.path.join(self.temp, file)) - - return metadata_df - - def download_artist(self, mb_id): - """ - Available includes: recordings, releases, release-groups, works, various-artists, discids, media, isrcs, - aliases, annotation, area-rels, artist-rels, label-rels, place-rels, event-rels, recording-rels, - release-rels, release-group-rels, series-rels, url-rels, work-rels, instrument-rels, tags, user-tags, - ratings, user-ratings - """ - metadata_list = [] - result = musicbrainzngs.get_artist_by_id(mb_id, includes=["releases"]) - - for i, release in enumerate(result["artist"]["release-list"]): - metadata_list.extend(self.download_release(release["id"], i)) - return metadata_list - - def download_release(self, mb_id, album_sort: int = None): - """ - Available includes: artists, labels, recordings, release-groups, media, artist-credits, discids, isrcs, - recording-level-rels, work-level-rels, annotation, aliases, tags, user-tags, area-rels, artist-rels, - label-rels, place-rels, event-rels, recording-rels, release-rels, release-group-rels, series-rels, url-rels, - work-rels, instrument-rels - """ - - def get_additional_artist_info(mb_id_): - r = musicbrainzngs.get_artist_by_id(mb_id_, includes=["releases"]) - - album_sort = 0 - for i, release in enumerate(r["artist"]["release-list"]): - id_ = release["id"] - if id_ == mb_id: - album_sort = i - break - - return album_sort - - result = musicbrainzngs.get_release_by_id(mb_id, includes=["artists", "recordings", 'release-groups']) - - if album_sort is None: - album_sort = get_additional_artist_info( - get_elem_from_obj(result, ['release', 'artist-credit', 0, 'artist', 'id'])) - release_type = get_elem_from_obj(result, ['release', 'release-group', 'type']) - - tracklist_metadata = [] - - is_various_artist = len(result['release']['artist-credit']) > 1 - tracklist = result['release']['medium-list'][0]['track-list'] - track_count = len(tracklist) - this_track = 0 - for track in tracklist: - track_id = track["recording"]["id"] - this_track = track["position"] - - tracklist_metadata.extend( - self.download_track(track_id, is_various_artist=is_various_artist, track=this_track, - total_tracks=track_count, album_sort=album_sort, album_type=release_type, - release_data=result['release'])) - - return tracklist_metadata - - def download_track(self, mb_id, is_various_artist: bool = None, track: int = None, total_tracks: int = None, - album_sort: int = None, album_type: str = None, release_data: dict = None): - """ - TODO - bpm its kind of possible via the AcousticBrainz API. however, the data may not be of very good - quality and AB is scheduled to go away in some time. - - compilation Field that is used by iTunes to mark albums as compilation. - Either enter the value 1 or delete the field. https://en.wikipedia.org/wiki/Compilation_album - How should I get it? I don't fucking know. Now I do. Release Group Type is Compilation - - composer, copyright, discsubtitle - 'musicbrainz_discid', - 'asin', - 'performer', - 'catalognumber', - 'musicbrainz_releasetrackid', - 'musicbrainz_releasegroupid', - 'musicbrainz_workid', - 'acoustid_fingerprint', - 'acoustid_id' - - DONE - - album - title - artist - albumartist - tracknumber - !!!albumsort can sort albums cronological - titlesort is just set to the tracknumber to sort by track order to sort correctly - isrc - musicbrainz_artistid - musicbrainz_albumid - musicbrainz_albumartistid - musicbrainz_albumstatus - language - musicbrainz_albumtype - 'releasecountry' - 'barcode' - - Album Art - """ - """ - Available includes: artists, releases, discids, media, artist-credits, isrcs, work-level-rels, annotation, - aliases, tags, user-tags, ratings, user-ratings, area-rels, artist-rels, label-rels, place-rels, event-rels, - recording-rels, release-rels, release-group-rels, series-rels, url-rels, work-rels, instrument-rels - """ - - result = musicbrainzngs.get_recording_by_id(mb_id, includes=["artists", "releases", "recording-rels", "isrcs", - "work-level-rels"]) - recording_data = result['recording'] - isrc = get_elem_from_obj(recording_data, ['isrc-list', 0]) - - if release_data is None: - # choosing the last release, because it is the least likely one to be a single - release_data = recording_data['release-list'][-1] - mb_release_id = release_data['id'] - - title = recording_data['title'] - - artist = [] - mb_artist_ids = [] - for artist_ in recording_data['artist-credit']: - name_ = get_elem_from_obj(artist_, ['artist', 'name']) - if name_ is None: - continue - artist.append(name_) - mb_artist_ids.append(get_elem_from_obj(artist_, ['artist', 'id'])) - - def get_additional_artist_info(mb_id_): - r = musicbrainzngs.get_artist_by_id(mb_id_, includes=["releases"]) - - album_sort = 0 - for i, release in enumerate(r["artist"]["release-list"]): - id_ = release["id"] - if id_ == mb_release_id: - album_sort = i - break - - return album_sort - - def get_additional_release_info(mb_id_): - r = musicbrainzngs.get_release_by_id(mb_id_, - includes=["artists", "recordings", "recording-rels", 'release-groups']) - is_various_artist_ = len(r['release']['artist-credit']) > 1 - tracklist = r['release']['medium-list'][0]['track-list'] - track_count_ = len(tracklist) - this_track_ = 0 - for track in tracklist: - if track["recording"]["id"] == mb_id: - this_track_ = track["position"] - - release_type = get_elem_from_obj(r, ['release', 'release-group', 'type']) - - return is_various_artist_, this_track_, track_count_, release_type - - album_id = get_elem_from_obj(release_data, ['id']) - album = get_elem_from_obj(release_data, ['title']) - album_status = get_elem_from_obj(release_data, ['status']) - language = get_elem_from_obj(release_data, ['text-representation', 'language']) - - year = get_elem_from_obj(release_data, ['date'], lambda x: x.split("-")[0]) - date = get_elem_from_obj(release_data, ['date']) - if is_various_artist is None or track is None or total_tracks is None or album_type is None: - is_various_artist, track, total_tracks, album_type = get_additional_release_info(album_id) - if album_sort is None: - album_sort = get_additional_artist_info(mb_artist_ids[0]) - album_artist = "Various Artists" if is_various_artist else artist[0] - album_artist_id = None if album_artist == "Various Artists" else mb_artist_ids[0] - compilation = "1" if album_type == "Compilation" else None - country = get_elem_from_obj(release_data, ['country']) - barcode = get_elem_from_obj(release_data, ['barcode']) - - return [{ - 'id': mb_id, - 'album': album, - 'title': title, - 'artist': artist, - 'album_artist': album_artist, - 'tracknumber': str(track), - 'albumsort': album_sort, - 'titlesort': track, - 'isrc': isrc, - 'date': date, - 'year': year, - 'musicbrainz_artistid': mb_artist_ids[0], - 'musicbrainz_albumid': mb_release_id, - 'musicbrainz_albumartistid': album_artist_id, - 'musicbrainz_albumstatus': album_status, - 'total_tracks': total_tracks, - 'language': language, - 'musicbrainz_albumtype': album_type, - 'compilation': compilation, - 'releasecountry': country, - 'barcode': barcode - }] - - def browse_artist(self, artist: dict, limit: int = 25): - options_sets = [ - {"artist-list": [artist, ], "artist-count": 1}, - musicbrainzngs.browse_releases(artist=artist["id"], limit=limit), - musicbrainzngs.browse_recordings(artist=artist["id"], limit=limit) - ] - return self.set_options(self.Options(options_sets)) - - def browse_release(self, release: dict, limit: int = 25): - options_sets = [ - musicbrainzngs.browse_artists(release=release["id"], limit=limit), - {"release-list": [release, ], "release-count": 1}, - musicbrainzngs.browse_recordings(release=release["id"], limit=limit) - ] - return self.set_options(self.Options(options_sets)) - - def browse_track(self, track: dict, limit: int = 25): - options_sets = [ - musicbrainzngs.browse_artists(recording=track["id"], limit=limit), - musicbrainzngs.browse_releases(recording=track["id"], limit=limit), - {"recording-list": [track, ], "recording-count": 1} - ] - return self.set_options(self.Options(options_sets)) - - def choose(self, index, limit: int = 25, ignore_limit_for_tracklist: bool = True): - if not self.current_options.choose(index): - return self.current_options - - self.current_chosen_option = self.current_options.get_current_option() - kind = self.current_chosen_option['kind'] - if kind == 'artist': - return self.browse_artist(self.current_chosen_option, limit=limit) - if kind == 'release': - release_limit = limit if not ignore_limit_for_tracklist else 100 - return self.browse_release(self.current_chosen_option, limit=release_limit) - if kind == 'track': - track_limit = limit if not ignore_limit_for_tracklist else 100 - return self.browse_track(self.current_chosen_option, limit=track_limit) - - return self.current_options - - def get_options(self): - return self.current_options - - def set_options(self, option_instance): - self.options_history.append(option_instance) - self.current_options = option_instance - - return option_instance - - def get_previous_options(self): - self.options_history.pop(-1) - self.current_options = self.options_history[-1] - return self.current_options - - options = property(fget=get_options) - - class Options: - def __init__(self, results: list): - self.results = results - - self.artist_count = 0 - self.release_count = 0 - self.track_count = 0 - self.result_list = [] - self.set_options_values() - - self.current_option_ind = None - - def get_current_option(self): - if self.current_option_ind is None: - raise Exception("It must first be chosen, which option to get, before getting it") - - return self.result_list[self.current_option_ind] - - def choose(self, index: int) -> bool: - if len(self.result_list) <= index - 1: - return False - self.current_option_ind = index - return True - - def get_string_for_artist(self, artist: dict) -> str: - string = f"'{artist['name']}'" - if "country" in artist: - string += f" from {artist['country']}" - if 'disambiguation' in artist: - string += f", '{artist['disambiguation']}'" - return string + "\n" - - def get_string_for_release(self, release: dict) -> str: - string = "" - if "type" in release: - string += f"the {release['type']} titled " - string += f"'{release['title']}'" - if "artist-credit-phrase" in release: - string += f" by: {release['artist-credit-phrase']}" - - return string + "\n" - - def get_string_for_tracks(self, tracks: dict) -> str: - # I know it's not the best practice but whatever - return self.get_string_for_release(tracks) - - def get_string_for_option(self, option: dict) -> str: - kind = option['kind'] - if kind == "artist": - return self.get_string_for_artist(option) - if kind == "release": - return self.get_string_for_release(option) - if kind == "track": - return self.get_string_for_tracks(option) - return "Error\n" - - def __str__(self) -> str: - string = f"artists: {self.artist_count}; releases {self.release_count}; tracks {self.track_count}\n" - for i, option in enumerate(self.result_list): - string += f"{i})\t{option['kind']}:\t" + self.get_string_for_option(option) - return string - - def set_options_values(self): - for option_set in self.results: - if "artist-list" in option_set: - self.set_artist_values(option_set) - continue - if "release-list" in option_set: - self.set_release_values(option_set) - continue - if "recording-list" in option_set: - self.set_track_values(option_set) - continue - - def set_artist_values(self, option_set: dict): - self.artist_count += option_set['artist-count'] - for artist in option_set['artist-list']: - artist['kind'] = "artist" - self.result_list.append(artist) - - def set_release_values(self, option_set: dict): - self.release_count += option_set['release-count'] - for release in option_set['release-list']: - release['kind'] = "release" - self.result_list.append(release) - - def set_track_values(self, option_set: dict): - self.track_count += option_set['recording-count'] - for track in option_set['recording-list']: - track['kind'] = "track" - self.result_list.append(track) - - -def automated_demo(): - search = Search(query="psychonaut 4") - print(search.options) - print(search.choose(0)) - search.download() - print(search.choose(2)) - search.download() - print(search.choose(4)) - print(search.download()) - - -def interactive_demo(): - search = Search(query=input("initial query: ")) - print(search.options) - while True: - input_ = input( - "d to download, q to quit, .. for previous options, . for current options, int for this element: ").lower() - input_.strip() - if input_ == "q": - break - if input_ == ".": - print(search.options) - continue - if input_ == "..": - print(search.get_previous_options()) - continue - if input_.isdigit(): - print(search.choose(int(input_))) - continue - if input_ == "d": - search.download() - break - - -if __name__ == "__main__": - # interactive_demo() - # automated_demo() - search = Search(query="psychonaut 4") - # search.download_release("27f00fb8-983c-4d5c-950f-51418aac55dc") - search.download_release("1aeb676f-e556-4b17-b45e-64ab69ef0375") - # for track_ in search.download_artist("c0c720b5-012f-4204-a472-981403f37b12"): - # print(track_) - # res = search.download_track("83a30323-aee1-401a-b767-b3c1bdd026c0") - # res = search.download_track("5e1ee2c5-502c-44d3-b1bc-22803441d8c6") - res = search.download_track("86b43bec-eea6-40ae-8624-c1e404204ba1") - # res = search.download_track("5cc28584-10c6-40e2-b6d4-6891e7e7c575") - - for key in res[0]: - if res[0][key] is None: - continue - - print(key, res[0][key]) diff --git a/src/metadata/download.py b/src/metadata/download.py new file mode 100644 index 0000000..08ed57d --- /dev/null +++ b/src/metadata/download.py @@ -0,0 +1,424 @@ +from typing import List + +import musicbrainzngs +import pandas as pd +import logging +from datetime import date + +from object_handeling import get_elem_from_obj, parse_music_brainz_date + +mb_log = logging.getLogger("musicbrainzngs") +mb_log.setLevel(logging.WARNING) +musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader") + + +# IMPORTANT +# https://python-musicbrainzngs.readthedocs.io/en/v0.7.1/api/#getting-data + +class Artist: + def __init__( + self, + musicbrainz_artistid: str, + release_groups: List = [], + new_release_groups: bool = True + ): + """ + release_groups: list + """ + self.release_groups = release_groups + + self.musicbrainz_artistid = musicbrainz_artistid + + result = musicbrainzngs.get_artist_by_id(self.musicbrainz_artistid, includes=["release-groups", "releases"]) + artist_data = get_elem_from_obj(result, ['artist'], return_if_none={}) + + self.artist = get_elem_from_obj(artist_data, ['name']) + + if not new_release_groups: + return + # sort all release groups by date and add album sort to have them in chronological order. + release_groups = artist_data['release-group-list'] + for i, release_group in enumerate(release_groups): + release_groups[i]['first-release-date'] = parse_music_brainz_date(release_group['first-release-date']) + release_groups.sort(key=lambda x: x['first-release-date']) + + for i, release_group in enumerate(release_groups): + self.release_groups.append(ReleaseGroup( + musicbrainz_releasegroupid=release_group['id'], + artists=[self], + albumsort=i + 1 + )) + + def __str__(self): + newline = "\n" + return f"id: {self.musicbrainz_artistid}\nname: {self.artist}\n{newline.join([str(release_group) for release_group in self.release_groups])}" + + +class ReleaseGroup: + def __init__( + self, + musicbrainz_releasegroupid: str, + artists: List[Artist] = [], + albumsort: int = None, + only_download_distinct_releases: bool = True + ): + """ + split_artists: list -> if len > 1: album_artist=VariousArtists + releases: list + """ + + self.musicbrainz_releasegroupid = musicbrainz_releasegroupid + self.artists = artists + self.releases = [] + + result = musicbrainzngs.get_release_group_by_id(musicbrainz_releasegroupid, + includes=["artist-credits", "releases"]) + release_group_data = get_elem_from_obj(result, ['release-group'], return_if_none={}) + artist_datas = get_elem_from_obj(release_group_data, ['artist-credit'], return_if_none={}) + release_datas = get_elem_from_obj(release_group_data, ['release-list'], return_if_none={}) + + for artist_data in artist_datas: + artist_id = get_elem_from_obj(artist_data, ['artist', 'id']) + if artist_id is None: + continue + self.append_artist(artist_id) + self.albumartist = "Various Artists" if len(self.artists) >= 1 else self.artists[0].artist + + self.albumsort = albumsort + self.musicbrainz_albumtype = get_elem_from_obj(release_group_data, ['primary-type']) + self.compilation = "1" if self.musicbrainz_albumtype == "Compilation" else None + + if only_download_distinct_releases: + self.append_distinct_releases(release_datas) + else: + self.append_all_releases(release_datas) + + def __str__(self): + newline = "\n" + return f"{newline.join([str(release_group) for release_group in self.releases])}" + + def append_artist(self, artist_id: str) -> Artist: + for existing_artist in self.artists: + if artist_id == existing_artist.musicbrainz_artistid: + return existing_artist + new_artist = Artist(artist_id, release_groups=[self], new_release_groups=False) + self.artists.append(new_artist) + return new_artist + + def append_release(self, release_data: dict): + musicbrainz_albumid = get_elem_from_obj(release_data, ['id']) + if musicbrainz_albumid is None: + return + self.releases.append(Release(musicbrainz_albumid, release_group=self)) + + def append_distinct_releases(self, release_datas: List[dict]): + titles = {} + + for release_data in release_datas: + title = get_elem_from_obj(release_data, ['title']) + if title is None: + continue + titles[title] = release_data + + for key in titles: + self.append_release(titles[key]) + + def append_all_releases(self, release_datas: List[dict]): + for release_data in release_datas: + self.append_release(release_data) + + +class Release: + def __init__( + self, + musicbrainz_albumid: str, + release_group: ReleaseGroup = None + ): + """ + release_group: ReleaseGroup + tracks: list + """ + self.musicbrainz_albumid = musicbrainz_albumid + self.release_group = release_group + self.tracklist = [] + + result = musicbrainzngs.get_release_by_id(self.musicbrainz_albumid, includes=["recordings", "labels"]) + release_data = get_elem_from_obj(result, ['release'], return_if_none={}) + label_data = get_elem_from_obj(release_data, ['label-info-list'], return_if_none={}) + recording_datas = get_elem_from_obj(release_data, ['medium-list', 0, 'track-list'], return_if_none=[]) + + self.title = get_elem_from_obj(release_data, ['title']) + self.copyright = get_elem_from_obj(label_data, [0, 'label', 'name']) + + self.append_recordings(recording_datas) + + def append_recordings(self, recording_datas: dict): + for recording_data in recording_datas: + musicbrainz_releasetrackid = get_elem_from_obj(recording_data, ['id']) + if musicbrainz_releasetrackid is None: + continue + + self.tracklist.append(musicbrainz_releasetrackid) + + def __str__(self): + return f"{self.title} ©{self.copyright}" + + +class Track: + def __init__( + self, + musicbrainz_releasetrackid: str, + release: Release = None + ): + """ + release: Release + feature_artists: list + """ + + self.musicbrainz_releasetrackid = musicbrainz_releasetrackid + self.release = release + + +def download(option: dict): + type_ = option['type'] + mb_id = option['id'] + + metadata_list = [] + if type_ == "artist": + artist = Artist(mb_id) + print(artist) + elif type_ == "release": + metadata_list = download_release(mb_id) + elif type_ == "track": + metadata_list = download_track(mb_id) + + print(metadata_list) + metadata_df = pd.DataFrame(metadata_list) + # metadata_df.to_csv(os.path.join(self.temp, file)) + return metadata_df + + +def download_artist(mb_id): + """ + Available includes: recordings, releases, release-groups, works, various-artists, discids, media, isrcs, + aliases, annotation, area-rels, artist-rels, label-rels, place-rels, event-rels, recording-rels, + release-rels, release-group-rels, series-rels, url-rels, work-rels, instrument-rels, tags, user-tags, + ratings, user-ratings + """ + + metadata_list = [] + # from this dict everything will be taken + following_data = {} + + result = musicbrainzngs.get_artist_by_id(mb_id, includes=["release-groups", "releases"]) + artist_data = result['artist'] + + # sort all release groups by date and add album sort to have them in chronological order. + release_groups = artist_data['release-group-list'] + for i, release_group in enumerate(release_groups): + release_groups[i]['first-release-date'] = parse_music_brainz_date(release_group['first-release-date']) + release_groups.sort(key=lambda x: x['first-release-date']) + + for i, release_group in enumerate(release_groups): + release_groups[i]['albumsort'] = i + 1 + + def numeric_release_type(release_type: str) -> int: + if release_type == "Album" or release_type == "EP": + return 1 + return 2 + + release_groups.sort(key=lambda x: numeric_release_type(x['type'])) + + for release_group in release_groups: + download_release_groups() + + +def download_release(mb_id, album_sort: int = None): + """ + Available includes: artists, labels, recordings, release-groups, media, artist-credits, discids, isrcs, + recording-level-rels, work-level-rels, annotation, aliases, tags, user-tags, area-rels, artist-rels, + label-rels, place-rels, event-rels, recording-rels, release-rels, release-group-rels, series-rels, url-rels, + work-rels, instrument-rels + """ + + def get_additional_artist_info(mb_id_): + r = musicbrainzngs.get_artist_by_id(mb_id_, includes=["releases"]) + + album_sort = 0 + for i, release in enumerate(r["artist"]["release-list"]): + id_ = release["id"] + if id_ == mb_id: + album_sort = i + break + + return album_sort + + result = musicbrainzngs.get_release_by_id(mb_id, includes=["artists", "recordings", 'release-groups']) + + if album_sort is None: + album_sort = get_additional_artist_info( + get_elem_from_obj(result, ['release', 'artist-credit', 0, 'artist', 'id'])) + release_type = get_elem_from_obj(result, ['release', 'release-group', 'type']) + + tracklist_metadata = [] + + is_various_artist = len(result['release']['artist-credit']) > 1 + tracklist = result['release']['medium-list'][0]['track-list'] + track_count = len(tracklist) + for track in tracklist: + track_id = track["recording"]["id"] + this_track = track["position"] + + tracklist_metadata.extend( + download_track(track_id, is_various_artist=is_various_artist, track=this_track, + total_tracks=track_count, album_sort=album_sort, album_type=release_type, + release_data=result['release'])) + + return tracklist_metadata + + +def download_track(mb_id, is_various_artist: bool = None, track: int = None, total_tracks: int = None, + album_sort: int = None, album_type: str = None, release_data: dict = None): + """ + TODO + bpm its kind of possible via the AcousticBrainz API. however, the data may not be of very good + quality and AB is scheduled to go away in some time. + + compilation Field that is used by iTunes to mark albums as compilation. + Either enter the value 1 or delete the field. https://en.wikipedia.org/wiki/Compilation_album + How should I get it? I don't fucking know. Now I do. Release Group Type is Compilation + + composer, copyright, discsubtitle + 'musicbrainz_discid', + 'asin', + 'performer', + 'catalognumber', + 'musicbrainz_releasetrackid', + 'musicbrainz_releasegroupid', + 'musicbrainz_workid', + 'acoustid_fingerprint', + 'acoustid_id' + + DONE + + album + title + artist + albumartist + tracknumber + !!!albumsort can sort albums cronological + titlesort is just set to the tracknumber to sort by track order to sort correctly + isrc + musicbrainz_artistid + musicbrainz_albumid + musicbrainz_albumartistid + musicbrainz_albumstatus + language + musicbrainz_albumtype + 'releasecountry' + 'barcode' + + Album Art + """ + """ + Available includes: artists, releases, discids, media, artist-credits, isrcs, work-level-rels, annotation, + aliases, tags, user-tags, ratings, user-ratings, area-rels, artist-rels, label-rels, place-rels, event-rels, + recording-rels, release-rels, release-group-rels, series-rels, url-rels, work-rels, instrument-rels + """ + + result = musicbrainzngs.get_recording_by_id(mb_id, includes=["artists", "releases", "recording-rels", "isrcs", + "work-level-rels"]) + recording_data = result['recording'] + isrc = get_elem_from_obj(recording_data, ['isrc-list', 0]) + + if release_data is None: + # choosing the last release, because it is the least likely one to be a single + release_data = recording_data['release-list'][-1] + mb_release_id = release_data['id'] + + title = recording_data['title'] + + artist = [] + mb_artist_ids = [] + for artist_ in recording_data['artist-credit']: + name_ = get_elem_from_obj(artist_, ['artist', 'name']) + if name_ is None: + continue + artist.append(name_) + mb_artist_ids.append(get_elem_from_obj(artist_, ['artist', 'id'])) + + def get_additional_artist_info(mb_id_): + r = musicbrainzngs.get_artist_by_id(mb_id_, includes=["releases"]) + + album_sort = 0 + for i, release in enumerate(r["artist"]["release-list"]): + id_ = release["id"] + if id_ == mb_release_id: + album_sort = i + break + + return album_sort + + def get_additional_release_info(mb_id_): + r = musicbrainzngs.get_release_by_id(mb_id_, + includes=["artists", "recordings", "recording-rels", 'release-groups']) + is_various_artist_ = len(r['release']['artist-credit']) > 1 + tracklist = r['release']['medium-list'][0]['track-list'] + track_count_ = len(tracklist) + this_track_ = 0 + for track in tracklist: + if track["recording"]["id"] == mb_id: + this_track_ = track["position"] + + release_type = get_elem_from_obj(r, ['release', 'release-group', 'type']) + + return is_various_artist_, this_track_, track_count_, release_type + + album_id = get_elem_from_obj(release_data, ['id']) + album = get_elem_from_obj(release_data, ['title']) + album_status = get_elem_from_obj(release_data, ['status']) + language = get_elem_from_obj(release_data, ['text-representation', 'language']) + + year = get_elem_from_obj(release_data, ['date'], lambda x: x.split("-")[0]) + date = get_elem_from_obj(release_data, ['date']) + if is_various_artist is None or track is None or total_tracks is None or album_type is None: + is_various_artist, track, total_tracks, album_type = get_additional_release_info(album_id) + if album_sort is None: + album_sort = get_additional_artist_info(mb_artist_ids[0]) + album_artist = "Various Artists" if is_various_artist else artist[0] + album_artist_id = None if album_artist == "Various Artists" else mb_artist_ids[0] + compilation = "1" if album_type == "Compilation" else None + country = get_elem_from_obj(release_data, ['country']) + barcode = get_elem_from_obj(release_data, ['barcode']) + + return [{ + 'id': mb_id, + 'album': album, + 'title': title, + 'artist': artist, + 'album_artist': album_artist, + 'tracknumber': str(track), + 'albumsort': album_sort, + 'titlesort': track, + 'isrc': isrc, + 'date': date, + 'year': year, + 'musicbrainz_artistid': mb_artist_ids[0], + 'musicbrainz_albumid': mb_release_id, + 'musicbrainz_albumartistid': album_artist_id, + 'musicbrainz_albumstatus': album_status, + 'total_tracks': total_tracks, + 'language': language, + 'musicbrainz_albumtype': album_type, + 'compilation': compilation, + 'releasecountry': country, + 'barcode': barcode + }] + + +if __name__ == "__main__": + logging.basicConfig(level=logging.DEBUG) + + download({'id': '5cfecbe4-f600-45e5-9038-ce820eedf3d1', 'type': 'artist'}) + # download({'id': '4b9af532-ef7e-42ab-8b26-c466327cb5e0', 'type': 'release'}) + # download({'id': 'c24ed9e7-6df9-44de-8570-975f1a5a75d1', 'type': 'track'}) diff --git a/src/metadata/metadata.py b/src/metadata/metadata.py new file mode 100644 index 0000000..25c6680 --- /dev/null +++ b/src/metadata/metadata.py @@ -0,0 +1,142 @@ +import logging +import musicbrainzngs + +import options +from object_handeling import get_elem_from_obj + +mb_log = logging.getLogger("musicbrainzngs") +mb_log.setLevel(logging.WARNING) +musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader") + +KNOWN_KIND_OF_OPTIONS = ["artist", "release", "track"] + + +class Search: + def __init__(self, query: str = None, artist: str = None, temp: str = "temp"): + if query is None and artist is None: + raise ValueError("no query provided") + + self.options_history = [] + self.current_options = None + self.current_chosen_option = None + + self.temp = temp + + # initial search + if query is not None: + self.set_options( + options.Options([musicbrainzngs.search_artists(query), musicbrainzngs.search_releases(query), + musicbrainzngs.search_recordings(query)])) + elif artist is not None: + self.set_options(options.Options([musicbrainzngs.search_artists(artist=artist)])) + + def browse_artist(self, artist: dict, limit: int = 25): + options_sets = [ + {"artist-list": [artist, ], "artist-count": 1}, + musicbrainzngs.browse_releases(artist=artist["id"], limit=limit), + musicbrainzngs.browse_recordings(artist=artist["id"], limit=limit) + ] + return self.set_options(options.Options(options_sets)) + + def browse_release(self, release: dict, limit: int = 25): + options_sets = [ + musicbrainzngs.browse_artists(release=release["id"], limit=limit), + {"release-list": [release, ], "release-count": 1}, + musicbrainzngs.browse_recordings(release=release["id"], limit=limit) + ] + return self.set_options(options.Options(options_sets)) + + def browse_track(self, track: dict, limit: int = 25): + options_sets = [ + musicbrainzngs.browse_artists(recording=track["id"], limit=limit), + musicbrainzngs.browse_releases(recording=track["id"], limit=limit), + {"recording-list": [track, ], "recording-count": 1} + ] + return self.set_options(options.Options(options_sets)) + + def choose(self, index, limit: int = 25, ignore_limit_for_tracklist: bool = True): + if not self.current_options.choose(index): + return self.current_options + + self.current_chosen_option = self.current_options.get_current_option() + kind = self.current_chosen_option['kind'] + if kind == 'artist': + return self.browse_artist(self.current_chosen_option, limit=limit) + if kind == 'release': + release_limit = limit if not ignore_limit_for_tracklist else 100 + return self.browse_release(self.current_chosen_option, limit=release_limit) + if kind == 'track': + track_limit = limit if not ignore_limit_for_tracklist else 100 + return self.browse_track(self.current_chosen_option, limit=track_limit) + + return self.current_options + + def get_options(self): + return self.current_options + + def set_options(self, option_instance): + self.options_history.append(option_instance) + self.current_options = option_instance + + return option_instance + + def get_previous_options(self): + self.options_history.pop(-1) + self.current_options = self.options_history[-1] + return self.current_options + + options = property(fget=get_options) + + +def automated_demo(): + search = Search(query="psychonaut 4") + print(search.options) + print(search.choose(0)) + search.download() + print(search.choose(2)) + search.download() + print(search.choose(4)) + print(search.download()) + + +def interactive_demo(): + search = Search(query=input("initial query: ")) + print(search.options) + while True: + input_ = input( + "d to download, q to quit, .. for previous options, . for current options, int for this element: ").lower() + input_.strip() + if input_ == "q": + break + if input_ == ".": + print(search.options) + continue + if input_ == "..": + print(search.get_previous_options()) + continue + if input_.isdigit(): + print(search.choose(int(input_))) + continue + if input_ == "d": + search.download() + break + + +if __name__ == "__main__": + # interactive_demo() + # automated_demo() + search = Search(query="psychonaut 4") + # search.download_release("27f00fb8-983c-4d5c-950f-51418aac55dc") + search.download_release("1aeb676f-e556-4b17-b45e-64ab69ef0375") + # for track_ in search.download_artist("c0c720b5-012f-4204-a472-981403f37b12"): + # print(track_) + # res = search.download_track("83a30323-aee1-401a-b767-b3c1bdd026c0") + # res = search.download_track("5e1ee2c5-502c-44d3-b1bc-22803441d8c6") + res = search.download_track("86b43bec-eea6-40ae-8624-c1e404204ba1") + # res = search.download_track("5cc28584-10c6-40e2-b6d4-6891e7e7c575") + + for key in res[0]: + if res[0][key] is None: + continue + + print(key, res[0][key]) diff --git a/src/metadata/object_handeling.py b/src/metadata/object_handeling.py new file mode 100644 index 0000000..3830c8e --- /dev/null +++ b/src/metadata/object_handeling.py @@ -0,0 +1,22 @@ +from datetime import date + +def get_elem_from_obj(current_object, keys: list, after_process=lambda x: x, return_if_none=None): + current_object = current_object + for key in keys: + if key in current_object or (type(key) == int and key < len(current_object)): + current_object = current_object[key] + else: + return return_if_none + return after_process(current_object) + +def parse_music_brainz_date(mb_date: str) -> date: + year = 1 + month = 1 + day = 1 + + first_release_date = mb_date + if first_release_date.count("-") == 2: + year, month, day = [int(i) for i in first_release_date.split("-")] + elif first_release_date.count("-") == 0: + year = int(first_release_date) + return date(year, month, day) diff --git a/src/metadata/options.py b/src/metadata/options.py new file mode 100644 index 0000000..07ae634 --- /dev/null +++ b/src/metadata/options.py @@ -0,0 +1,118 @@ +def get_string_for_artist(artist: dict) -> str: + string = f"'{artist['name']}'" + if "country" in artist: + string += f" from {artist['country']}" + if 'disambiguation' in artist: + string += f", '{artist['disambiguation']}'" + return string + "\n" + + +def get_string_for_release(release: dict) -> str: + string = "" + if "type" in release: + string += f"the {release['type']} titled " + string += f"'{release['title']}'" + if "artist-credit-phrase" in release: + string += f" by: {release['artist-credit-phrase']}" + + return string + "\n" + + +def get_string_for_tracks(tracks: dict) -> str: + # I know it's not the best practice but whatever + return get_string_for_release(tracks) + + +def get_string_for_option(option: dict) -> str: + kind = option['kind'] + if kind == "artist": + return get_string_for_artist(option) + if kind == "release": + return get_string_for_release(option) + if kind == "track": + return get_string_for_tracks(option) + return "Error\n" + + +class Options: + def __init__(self, results: list): + self.results = results + + self.artist_count = 0 + self.release_count = 0 + self.track_count = 0 + self.result_list = [] + self.set_options_values() + + self.current_option_ind = None + + def get_current_option(self, komplex: bool = False): + if self.current_option_ind is None: + raise Exception("It must first be chosen, which option to get, before getting it") + + if komplex: + return self.result_list[self.current_option_ind] + + komplex_information = self.result_list[self.current_option_ind] + return { + 'id': komplex_information['id'], + 'type': komplex_information['kind'] + } + + def choose(self, index: int) -> bool: + if len(self.result_list) <= index - 1: + return False + self.current_option_ind = index + return True + + def __str__(self) -> str: + string = f"artists: {self.artist_count}; releases {self.release_count}; tracks {self.track_count}\n" + for i, option in enumerate(self.result_list): + string += f"{i})\t{option['kind']}:\t" + get_string_for_option(option) + return string + + def set_options_values(self): + for option_set in self.results: + if "artist-list" in option_set: + self.set_artist_values(option_set) + continue + if "release-list" in option_set: + self.set_release_values(option_set) + continue + if "recording-list" in option_set: + self.set_track_values(option_set) + continue + + def set_artist_values(self, option_set: dict): + self.artist_count += option_set['artist-count'] + for artist in option_set['artist-list']: + artist['kind'] = "artist" + self.result_list.append(artist) + + def set_release_values(self, option_set: dict): + self.release_count += option_set['release-count'] + for release in option_set['release-list']: + release['kind'] = "release" + self.result_list.append(release) + + def set_track_values(self, option_set: dict): + self.track_count += option_set['recording-count'] + for track in option_set['recording-list']: + track['kind'] = "track" + self.result_list.append(track) + +""" +example +{'artist-list': [{'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'type': 'Group', 'ext:score': '100', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'country': 'GE', 'area': {'id': '7e081aa0-817b-3ae0-9fe2-4bb4e3b3cc95', 'type': 'Country', 'name': 'Georgia', 'sort-name': 'Georgia', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': '76c77b6c-f1e1-4a58-8fe1-01a7efadd1f7', 'type': 'City', 'name': 'Tbilisi', 'sort-name': 'Tbilisi', 'life-span': {'ended': 'false'}}, 'disambiguation': 'Georgian depressive black metal', 'life-span': {'begin': '2010', 'ended': 'false'}, 'tag-list': [{'count': '0', 'name': 'black metal'}, {'count': '5', 'name': 'depressive black metal'}, {'count': '1', 'name': 'sex'}, {'count': '1', 'name': 'suicide'}, {'count': '1', 'name': 'hopelessness'}, {'count': '1', 'name': 'drugs'}, {'count': '1', 'name': 'depression'}, {'count': '1', 'name': 'alcohol'}]}, {'id': '55e84562-e29b-4967-8d2b-a7fff673cd1e', 'type': 'Group', 'ext:score': '82', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'country': 'BE', 'area': {'id': '5b8a5ee5-0bb3-34cf-9a75-c27c44e341fc', 'type': 'Country', 'name': 'Belgium', 'sort-name': 'Belgium', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': 'f05e07a9-0ea2-4b8e-9538-370456752089', 'type': 'City', 'name': 'Mechelen', 'sort-name': 'Mechelen', 'life-span': {'ended': 'false'}}, 'disambiguation': 'Belgian sludge metal band', 'isni-list': ['0000000475468695'], 'life-span': {'begin': '2013', 'ended': 'false'}}, {'id': '35ed62b6-a358-41a5-8c09-80e7aaae1e1b', 'type': 'Group', 'ext:score': '81', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'country': 'DE', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'type': 'Country', 'name': 'Germany', 'sort-name': 'Germany', 'life-span': {'ended': 'false'}}, 'disambiguation': 'German trance group; Lothar Herrmann & Oliver Balser', 'life-span': {'ended': 'false'}}, {'id': 'ad37f13c-73b6-48c0-8606-2321059a41ce', 'type': 'Group', 'ext:score': '81', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'country': 'AU', 'area': {'id': '106e0bec-b638-3b37-b731-f53d507dc00e', 'type': 'Country', 'name': 'Australia', 'sort-name': 'Australia', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': '21e8495a-32fa-4a97-8a92-57184e36235a', 'type': 'City', 'name': 'Perth', 'sort-name': 'Perth', 'life-span': {'ended': 'false'}}, 'disambiguation': 'Australian thrash metal band', 'life-span': {'begin': '1997', 'ended': 'false'}}, {'id': '48abf0e3-14e6-4bf9-a14e-45bc7f327891', 'type': 'Group', 'ext:score': '81', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'country': 'CZ', 'area': {'id': '51d34c28-61bf-3d21-849f-7492672a9d44', 'type': 'Country', 'name': 'Czechia', 'sort-name': 'Czechia', 'life-span': {'begin': '1993-01-01', 'ended': 'false'}}, 'begin-area': {'id': 'a99b59f9-f506-4c1a-876c-43d8dda0ce0e', 'type': 'City', 'name': 'Opava', 'sort-name': 'Opava', 'life-span': {'ended': 'false'}}, 'disambiguation': 'Czech funk rock band from Opava', 'life-span': {'begin': '1999', 'ended': 'false'}}, {'id': '6ece3c88-f052-4529-bacf-5e12290a331a', 'ext:score': '79', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'bass/dubstep artist', 'life-span': {'ended': 'false'}}, {'id': '113f46a8-8cc9-4c81-8681-dbc0d947bb5a', 'type': 'Group', 'ext:score': '79', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'country': 'US', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'type': 'Country', 'name': 'United States', 'sort-name': 'United States', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': '4fb3cf81-d45c-4607-aa90-53856d69f5ff', 'type': 'City', 'name': 'Harrisonburg', 'sort-name': 'Harrisonburg', 'life-span': {'ended': 'false'}}, 'disambiguation': 'Garage psych band from Virginia', 'life-span': {'begin': '2016', 'ended': 'false'}}, {'id': '7c976521-a20f-4107-b3e0-766ebae07a56', 'type': 'Person', 'ext:score': '79', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Alias of Spanish trance DJ Javi Golo', 'life-span': {'ended': 'false'}}, {'id': 'e2e692b5-efbc-4cd7-ab38-bce0bd457a8b', 'type': 'Group', 'ext:score': '74', 'name': 'Psychonaut 75', 'sort-name': 'Psychonaut 75', 'country': 'US', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'type': 'Country', 'name': 'United States', 'sort-name': 'United States', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': 'c920948b-83e3-40b7-8fe9-9ab5abaac55b', 'type': 'City', 'name': 'Houston', 'sort-name': 'Houston', 'life-span': {'ended': 'false'}}, 'disambiguation': 'dark industrial dance', 'life-span': {'begin': '1997', 'ended': 'false'}, 'alias-list': [{'sort-name': 'Psychonaut', 'type': 'Artist name', 'begin-date': '1997', 'end-date': '2001', 'alias': 'Psychonaut'}, {'sort-name': 'Psychonaut 75', 'type': 'Artist name', 'begin-date': '2001', 'alias': 'Psychonaut 75'}], 'tag-list': [{'count': '1', 'name': 'industrial'}, {'count': '1', 'name': 'ritual ambient'}]}, {'id': 'fa6521a7-56b5-4e56-b946-fda469becba9', 'type': 'Group', 'ext:score': '69', 'name': '4 Strings', 'sort-name': '4 Strings', 'country': 'NL', 'area': {'id': 'ef1b7cc0-cd26-36f4-8ea0-04d9623786c7', 'type': 'Country', 'name': 'Netherlands', 'sort-name': 'Netherlands', 'life-span': {'ended': 'false'}}, 'disambiguation': 'Netherlands dance duo', 'life-span': {'ended': 'false'}, 'alias-list': [{'sort-name': '4Strings', 'alias': '4Strings'}], 'tag-list': [{'count': '1', 'name': 'dance pop'}, {'count': '0', 'name': 'dutch trance'}, {'count': '1', 'name': 'trance pop'}, {'count': '2', 'name': 'vocal trance'}, {'count': '3', 'name': 'trance'}, {'count': '1', 'name': 'uplifting'}, {'count': '1', 'name': 'uplifting trance'}, {'count': '1', 'name': 'female vocal trance'}, {'count': '1', 'name': 'dutch'}, {'count': '1', 'name': 'pop trance'}, {'count': '1', 'name': 'dance trance'}, {'count': '1', 'name': 'female vocal dance'}, {'count': '1', 'name': 'vocal dance'}, {'count': '2', 'name': 'dance-pop'}]}, {'id': 'bdbd99ab-3f4b-4028-9306-cd71d8695fbc', 'type': 'Group', 'ext:score': '66', 'name': 'Anonymous 4', 'sort-name': 'Anonymous 4', 'country': 'US', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'type': 'Country', 'name': 'United States', 'sort-name': 'United States', 'life-span': {'ended': 'false'}}, 'disambiguation': 'vocal quartet specialising in medieval chant and polyphony', 'isni-list': ['0000000123640949'], 'life-span': {'begin': '1986', 'ended': 'false'}, 'alias-list': [{'sort-name': 'An English Ladymass', 'alias': 'An English Ladymass'}, {'sort-name': 'A Star in the East', 'alias': 'A Star in the East'}, {'sort-name': 'On Yoolis Night', 'alias': 'On Yoolis Night'}, {'sort-name': 'Eleven Thousand Virgins', 'alias': 'Eleven Thousand Virgins'}, {'sort-name': "Miracles of Saint'Iago", 'alias': "Miracles of Saint'Iago"}, {'sort-name': "Love's Illusion", 'alias': "Love's Illusion"}, {'sort-name': 'The Lily & The Lamb', 'alias': 'The Lily & The Lamb'}], 'tag-list': [{'count': '1', 'name': 'early music'}, {'count': '1', 'name': 'medieval'}, {'count': '2', 'name': 'a cappella'}]}, {'id': 'c869ad3e-6e8f-46e3-89e0-dc9d28d6bc61', 'type': 'Person', 'ext:score': '64', 'name': '4*', 'sort-name': '4*', 'gender': 'male', 'area': {'id': '30bcaa92-9870-4798-be1a-4e0036755316', 'type': 'City', 'name': 'Osaka', 'sort-name': 'Osaka', 'life-span': {'ended': 'false'}}, 'life-span': {'ended': 'false'}}, {'id': '3d1dc3db-4fc3-42b2-a8cd-4d8983637450', 'type': 'Group', 'ext:score': '63', 'name': 'Radio 4', 'sort-name': 'Radio 4', 'country': 'US', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'type': 'Country', 'name': 'United States', 'sort-name': 'United States', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': 'a71b0d32-7752-49e9-8594-2247ad6ac12c', 'type': 'District', 'name': 'Brooklyn', 'sort-name': 'Brooklyn', 'life-span': {'ended': 'false'}}, 'isni-list': ['000000011882564X'], 'life-span': {'begin': '1999', 'ended': 'false'}, 'alias-list': [{'sort-name': 'Radio4', 'alias': 'Radio4'}], 'tag-list': [{'count': '1', 'name': 'indie rock'}, {'count': '1', 'name': 'rock and indie'}, {'count': '1', 'name': 'dance-punk'}, {'count': '1', 'name': 'american'}, {'count': '1', 'name': 'post-punk revival'}]}, {'id': '5fdbf7e7-8643-44ad-94a7-3d669e3876e4', 'type': 'Group', 'ext:score': '62', 'name': 'Twenty 4 Seven', 'sort-name': 'Twenty 4 Seven', 'country': 'NL', 'area': {'id': 'ef1b7cc0-cd26-36f4-8ea0-04d9623786c7', 'type': 'Country', 'name': 'Netherlands', 'sort-name': 'Netherlands', 'life-span': {'ended': 'false'}}, 'disambiguation': 'euro house', 'isni-list': ['0000000122900577'], 'life-span': {'begin': '1989', 'ended': 'false'}, 'alias-list': [{'sort-name': 'Twenty 4th Street', 'alias': 'Twenty 4th Street'}, {'sort-name': 'Twenty Four Seven', 'alias': 'Twenty Four Seven'}, {'sort-name': '24-7', 'alias': '24-7'}], 'tag-list': [{'count': '1', 'name': 'dance'}, {'count': '1', 'name': 'euro house'}, {'count': '1', 'name': 'house'}, {'count': '1', 'name': 'eurodance'}]}, {'id': '32ff0254-5c1f-425c-910a-ff62ff888ca2', 'type': 'Group', 'ext:score': '62', 'name': 'Lab 4', 'sort-name': 'Lab 4', 'country': 'GB', 'area': {'id': '8a754a16-0027-3a29-b6d7-2b40ea0481ed', 'type': 'Country', 'name': 'United Kingdom', 'sort-name': 'United Kingdom', 'life-span': {'ended': 'false'}}, 'life-span': {'begin': '1994', 'ended': 'false'}, 'alias-list': [{'sort-name': 'LAB4', 'alias': 'LAB4'}, {'sort-name': 'Lab-4', 'alias': 'Lab-4'}]}, {'id': '95711c34-6d6a-4acd-a713-e460a7915494', 'type': 'Group', 'ext:score': '62', 'name': '4', 'sort-name': '4', 'country': 'US', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'type': 'Country', 'name': 'United States', 'sort-name': 'United States', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': '398c6575-6e22-44f9-b93a-349c9f5c8889', 'type': 'City', 'name': 'Costa Mesa', 'sort-name': 'Costa Mesa', 'life-span': {'ended': 'false'}}, 'disambiguation': '1990s California alternative/punk band', 'life-span': {'ended': 'false'}}, {'id': 'a21768f9-0bb1-41f2-9860-90e95aaa0f34', 'type': 'Group', 'ext:score': '61', 'name': '4 Clubbers', 'sort-name': '4 Clubbers', 'country': 'DE', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'type': 'Country', 'name': 'Germany', 'sort-name': 'Germany', 'life-span': {'ended': 'false'}}, 'life-span': {'ended': 'false'}, 'alias-list': [{'sort-name': '4Clubbers', 'alias': '4Clubbers'}]}, {'id': '7e5134b6-add1-4cbe-accd-f01547a4b6c3', 'ext:score': '61', 'name': '4$', 'sort-name': '4$', 'disambiguation': 'trap', 'life-span': {'ended': 'false'}}, {'id': 'c0e9bf2e-9c31-4ff1-8e23-0021652a9015', 'type': 'Group', 'ext:score': '61', 'name': '4 Позиции Бруно', 'sort-name': '4 Positions of Bruno', 'country': 'RU', 'area': {'id': '1f1fc3a4-9500-39b8-9f10-f0a465557eef', 'type': 'Country', 'name': 'Russia', 'sort-name': 'Russia', 'life-span': {'ended': 'false'}}, 'begin-area': {'id': '0918dfa2-f667-4dbe-bac9-644d81a06612', 'type': 'City', 'name': 'Yekaterinburg', 'sort-name': 'Yekaterinburg', 'life-span': {'ended': 'false'}}, 'life-span': {'begin': '2002', 'ended': 'false'}, 'alias-list': [{'sort-name': '4 pozitsii Bruno', 'alias': '4 pozitsii Bruno'}, {'locale': 'en', 'sort-name': 'Bruno’s 4 Positions', 'alias': 'Bruno’s 4 Positions'}], 'tag-list': [{'count': '3', 'name': 'electronic'}, {'count': '3', 'name': 'ambient'}, {'count': '3', 'name': 'experimental'}]}, {'id': 'df659499-80f2-4301-bb46-0eade0213f5b', 'ext:score': '61', 'name': ':4:', 'sort-name': 'channel4four', 'disambiguation': 'experimental music', 'life-span': {'ended': 'false'}, 'alias-list': [{'sort-name': 'channel4four', 'alias': 'channel4four'}]}, {'id': 'a5891a6b-d0a9-4264-b47d-bcf526bbb826', 'ext:score': '61', 'name': 'Eponymous 4', 'sort-name': 'Eponymous 4', 'area': {'id': '10adc6b5-63bf-4b4e-993e-ed83b05c22fc', 'type': 'City', 'name': 'Seattle', 'sort-name': 'Seattle', 'life-span': {'ended': 'false'}}, 'life-span': {'begin': '1999', 'ended': 'false'}}, {'id': '318ec65f-9046-4c41-a60f-664f5f997ba5', 'ext:score': '61', 'name': '⦅౪⦆', 'sort-name': '⦅౪⦆', 'life-span': {'ended': 'false'}, 'alias-list': [{'sort-name': 'drunkenhigh', 'alias': 'drunkenhigh'}], 'tag-list': [{'count': '1', 'name': 'sillyname'}, {'count': '1', 'name': '!hyperfocus'}]}, {'id': 'e3891ce8-1f22-4ee9-8b3d-5c8f1bb8dbd2', 'ext:score': '61', 'name': '4', 'sort-name': '4', 'disambiguation': '/v/', 'life-span': {'ended': 'false'}}, {'id': 'ceb3cccd-3c71-4acf-a2da-146abd021760', 'ext:score': '61', 'name': '4', 'sort-name': '4', 'disambiguation': 'rapper us ?', 'life-span': {'ended': 'false'}}, {'id': 'a5c07e9f-1995-4c81-9425-7fea1489c37d', 'type': 'Group', 'ext:score': '60', 'name': '4 Promille', 'sort-name': '4 Promille', 'country': 'DE', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'type': 'Country', 'name': 'Germany', 'sort-name': 'Germany', 'life-span': {'ended': 'false'}}, 'life-span': {'ended': 'false'}, 'alias-list': [{'sort-name': 'Promille', 'alias': 'Promille'}], 'tag-list': [{'count': '1', 'name': 'punk'}]}], 'artist-count': 941} +{'release-list': [{'id': 'd6e6be74-b7a4-4982-955a-d3361885541c', 'ext:score': '100', 'title': '40%', 'status': 'Official', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': 'a557bf98-e902-4336-8b28-ecbede7f93bf', 'type': 'Album', 'title': '40%', 'primary-type': 'Album', 'secondary-type-list': ['Demo']}, 'date': '2011-06-04', 'country': 'UA', 'release-event-list': [{'date': '2011-06-04', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'label-info-list': [{'label': {'id': 'ce4c6532-a7a4-47e7-83c1-169e68e461df', 'name': 'Depressive Illusions Records'}}], 'medium-list': [{'format': 'Cassette', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 3}], 'medium-track-count': 3, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '4b9af532-ef7e-42ab-8b26-c466327cb5e0', 'ext:score': '100', 'title': 'Dipsomania', 'status': 'Official', 'packaging': 'Digipak', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': 'a37697eb-176b-4242-95fc-27de66342463', 'type': 'Album', 'title': 'Dipsomania', 'primary-type': 'Album'}, 'date': '2015-04-25', 'country': 'AT', 'release-event-list': [{'date': '2015-04-25', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'label-info-list': [{'catalog-number': 'TR025CD', 'label': {'id': 'f6824a99-ac3b-4cc4-95fe-8e47769b33a7', 'name': 'Talheim Records'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 12}], 'medium-track-count': 12, 'medium-count': 1, 'tag-list': [{'count': '1', 'name': 'metal'}, {'count': '0', 'name': 'dipsomania'}, {'count': '1', 'name': 'psychonaut 4'}, {'count': '0', 'name': 'psychonaut'}, {'count': '1', 'name': 'depressive'}, {'count': '1', 'name': 'black'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'ab61f4b0-88e8-43b5-9b24-af184c6f1f12', 'ext:score': '100', 'title': 'Free Portion ov Madness I', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': 'fe7f2480-fa00-483e-bad6-e6fc839ec3ea', 'type': 'Single', 'title': 'Free Portion ov Madness I', 'primary-type': 'Single'}, 'date': '2014-04-11', 'country': 'XW', 'release-event-list': [{'date': '2014-04-11', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'barcode': '', 'label-info-list': [{'label': {'id': '157afde4-4bf5-4039-8ad2-5a15acc85176', 'name': '[no label]'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 1}], 'medium-track-count': 1, 'medium-count': 1, 'tag-list': [{'count': '2', 'name': 'metal'}, {'count': '1', 'name': 'dsbm'}, {'count': '1', 'name': 'suicidal black metal'}, {'count': '1', 'name': 'depressive suicidal black metal'}, {'count': '2', 'name': 'post black metal'}, {'count': '1', 'name': 'depressive rock'}, {'count': '1', 'name': 'tbilisi'}, {'count': '1', 'name': 'post suicidal black metal'}, {'count': '2', 'name': 'depressive black metal'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'ext:score': '100', 'title': 'Have a Nice Trip', 'status': 'Official', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'label-info-list': [{'catalog-number': 'cut 668', 'label': {'id': 'ce4c6532-a7a4-47e7-83c1-169e68e461df', 'name': 'Depressive Illusions Records'}}], 'medium-list': [{'format': 'Cassette', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '0d229a02-74f6-4c77-8c20-6612295870ae', 'ext:score': '100', 'title': 'Neurasthenia', 'status': 'Official', 'packaging': 'Digipak', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': '855c95c7-b7c2-40b2-b453-e3d37f43401e', 'type': 'Album', 'title': 'Neurasthenia', 'primary-type': 'Album'}, 'date': '2016-10-07', 'country': 'AT', 'release-event-list': [{'date': '2016-10-07', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'label-info-list': [{'catalog-number': 'TR045CD', 'label': {'id': 'f6824a99-ac3b-4cc4-95fe-8e47769b33a7', 'name': 'Talheim Records'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'f8d4b24d-2c46-4e9c-8078-0c0f337c84dd', 'ext:score': '100', 'title': 'Beautyfall', 'status': 'Official', 'packaging': 'Digipak', 'text-representation': {'language': 'mul', 'script': 'Qaaa'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': 'b58eaf6e-1cb3-4d61-bf3b-54dd6971e0d0', 'type': 'Album', 'title': 'Beautyfall', 'primary-type': 'Album'}, 'date': '2020-10-31', 'country': 'GE', 'release-event-list': [{'date': '2020-10-31', 'area': {'id': '7e081aa0-817b-3ae0-9fe2-4bb4e3b3cc95', 'name': 'Georgia', 'sort-name': 'Georgia', 'iso-3166-1-code-list': ['GE']}}], 'label-info-list': [{'catalog-number': 'TR068CD', 'label': {'id': 'f6824a99-ac3b-4cc4-95fe-8e47769b33a7', 'name': 'Talheim Records'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 8}], 'medium-track-count': 8, 'medium-count': 1, 'tag-list': [{'count': '1', 'name': 'depressive black metal'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'afb2e006-7e6f-4f37-b43e-f844bf3ea94b', 'ext:score': '100', 'title': 'Beautyfall / სულდაცემა', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': 'b58eaf6e-1cb3-4d61-bf3b-54dd6971e0d0', 'type': 'Album', 'title': 'Beautyfall', 'primary-type': 'Album'}, 'date': '2020-10-30', 'country': 'XW', 'release-event-list': [{'date': '2020-10-30', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 8}], 'medium-track-count': 8, 'medium-count': 1, 'tag-list': [{'count': '1', 'name': 'post suicidal black metal'}, {'count': '2', 'name': 'metal'}, {'count': '2', 'name': 'black metal'}, {'count': '1', 'name': 'tbilisi'}, {'count': '1', 'name': 'depressive suicidal black metal'}, {'count': '1', 'name': 'metal metal'}, {'count': '1', 'name': 'suicidal depressive black'}, {'count': '1', 'name': 'depressivesuicidalblackmetal'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'da90dfc2-95cf-4c24-8549-84339d6d3076', 'ext:score': '100', 'title': 'Have a Nice Trip', 'status': 'Official', 'packaging': 'None', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2018-08-15', 'country': 'XW', 'release-event-list': [{'date': '2018-08-15', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'barcode': '4061707064036', 'asin': 'B07G2D5GZ9', 'label-info-list': [{'catalog-number': 'none', 'label': {'id': 'f6824a99-ac3b-4cc4-95fe-8e47769b33a7', 'name': 'Talheim Records'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1, 'tag-list': [{'count': '2', 'name': 'depressive black metal'}, {'count': '1', 'name': 'tbilisi'}, {'count': '1', 'name': 'depressive rock'}, {'count': '2', 'name': 'metal'}, {'count': '1', 'name': 'post suicidal black metal'}, {'count': '1', 'name': 'depressive/black-metal'}, {'count': '1', 'name': 'depressive suicidal black metal'}, {'count': '1', 'name': 'suicidal black metal'}, {'count': '2', 'name': 'post black metal'}, {'count': '1', 'name': 'dsbm'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '2b7e9b09-8651-490f-a638-0b99e157a12c', 'ext:score': '100', 'title': 'Have a Nice Trip', 'status': 'Official', 'packaging': 'Digipak', 'text-representation': {'language': 'mul', 'script': 'Qaaa'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2018-12-01', 'country': 'AT', 'release-event-list': [{'date': '2018-12-01', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'barcode': '', 'label-info-list': [{'catalog-number': 'TR050CD', 'label': {'id': 'f6824a99-ac3b-4cc4-95fe-8e47769b33a7', 'name': 'Talheim Records'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 1, 'track-list': [], 'track-count': 12}], 'medium-track-count': 12, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'ext:score': '100', 'title': 'Have a Nice Trip', 'status': 'Official', 'text-representation': {'language': 'mul', 'script': 'Qaaa'}, 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'label-info-list': [{'catalog-number': 'SAD 008', 'label': {'id': 'efb18b12-0baa-4592-ac33-14cdd684aaff', 'name': 'Solitude and Despair Music'}}, {'catalog-number': 'DNW025', 'label': {'id': 'ebc3b589-d7ff-4978-baa4-434588819f6d', 'name': 'Der Neue Weg'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '3fb91753-fb1a-47d5-b83f-5cf88a12b904', 'ext:score': '71', 'title': 'Liber Al Vel Legis', 'status': 'Official', 'packaging': 'Digipak', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': 'e2e692b5-efbc-4cd7-ab38-bce0bd457a8b', 'name': 'Psychonaut 75', 'sort-name': 'Psychonaut 75', 'disambiguation': 'dark industrial dance'}}], 'release-group': {'id': 'bd708a0f-26c5-3fd9-981f-b2149401c8d3', 'type': 'Album', 'title': 'Liber Al Vel Legis', 'primary-type': 'Album'}, 'date': '2001', 'country': 'FR', 'release-event-list': [{'date': '2001', 'area': {'id': '08310658-51eb-3801-80de-5a0739207115', 'name': 'France', 'sort-name': 'France', 'iso-3166-1-code-list': ['FR']}}], 'label-info-list': [{'catalog-number': 'ATNR 013', 'label': {'id': '820c7c21-2d29-4e2f-83cb-692cfd335fab', 'name': 'Athanor'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 16}], 'medium-track-count': 16, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '5c08a8fe-c644-494b-9a1f-a0943b0cd18b', 'ext:score': '71', 'title': 'Pylon of Daath', 'status': 'Official', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': 'e2e692b5-efbc-4cd7-ab38-bce0bd457a8b', 'name': 'Psychonaut 75', 'sort-name': 'Psychonaut 75', 'disambiguation': 'dark industrial dance'}}], 'release-group': {'id': '7b1b38a1-e024-48d3-a824-b412e633bd4b', 'type': 'Album', 'title': 'Pylon of Daath', 'primary-type': 'Album'}, 'date': '1999', 'country': 'US', 'release-event-list': [{'date': '1999', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'name': 'United States', 'sort-name': 'United States', 'iso-3166-1-code-list': ['US']}}], 'label-info-list': [{'catalog-number': 'LBRF 008', 'label': {'id': '7ea66d0f-b37d-4010-879e-5fa4c3efe4ad', 'name': 'Live Bait Recording Foundation'}}], 'medium-list': [{'format': 'Cassette', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '037f04c6-5326-4df2-87fc-a2855e6c43a8', 'ext:score': '71', 'title': 'Antagonistic Pathways', 'status': 'Official', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '35ed62b6-a358-41a5-8c09-80e7aaae1e1b', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'German trance group; Lothar Herrmann & Oliver Balser'}}], 'release-group': {'id': 'cb177b0b-1ea2-3f04-8515-846038dac043', 'type': 'Album', 'title': 'Antagonistic Pathways', 'primary-type': 'Album'}, 'date': '2002-07-23', 'country': 'DE', 'release-event-list': [{'date': '2002-07-23', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'barcode': '5413356178920', 'asin': 'B00006643W', 'label-info-list': [{'catalog-number': 'GTN 1105.20', 'label': {'id': 'e7e72105-7013-495a-b360-47dbe4c7e4e0', 'name': 'GTN'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 8}], 'medium-track-count': 8, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': 'b44b3d0d-6b9d-4ff8-8e80-274cdf3ead59', 'ext:score': '71', 'title': 'Volume 1', 'status': 'Official', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '35ed62b6-a358-41a5-8c09-80e7aaae1e1b', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'German trance group; Lothar Herrmann & Oliver Balser'}}], 'release-group': {'id': 'fab107ed-fae5-3a96-abb2-04bb0c3bbb7b', 'type': 'Album', 'title': 'Volume 1', 'primary-type': 'Album'}, 'date': '2000-09', 'country': 'DE', 'release-event-list': [{'date': '2000-09', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'barcode': '5413356771121', 'label-info-list': [{'catalog-number': 'GTN 1035.20', 'label': {'id': 'e7e72105-7013-495a-b360-47dbe4c7e4e0', 'name': 'GTN'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 8}], 'medium-track-count': 8, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '98a85c0c-7315-4c0b-b6fb-4c4fcbaccf8c', 'ext:score': '71', 'title': 'Zos Vel Thanatos', 'status': 'Official', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': 'e2e692b5-efbc-4cd7-ab38-bce0bd457a8b', 'name': 'Psychonaut 75', 'sort-name': 'Psychonaut 75', 'disambiguation': 'dark industrial dance'}}], 'release-group': {'id': '4f4be69c-cfb3-35f5-8388-b9e197dc4b2e', 'type': 'Album', 'title': 'Zos Vel Thanatos', 'primary-type': 'Album'}, 'date': '1999', 'country': 'US', 'release-event-list': [{'date': '1999', 'area': {'id': '489ce91b-6658-3307-9877-795b68554c98', 'name': 'United States', 'sort-name': 'United States', 'iso-3166-1-code-list': ['US']}}], 'label-info-list': [{'catalog-number': 'AJNA02.1999', 'label': {'id': '8bffe0f3-8f22-4090-9e64-6d18d4ab7efc', 'name': 'The Ajna Offensive'}}], 'medium-list': [{'format': '7" Vinyl', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 2}], 'medium-track-count': 2, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': 'db637be8-0f8f-4235-b8fc-dd844341395e', 'ext:score': '71', 'title': "The Witches' Sabbath", 'status': 'Official', 'packaging': 'Jewel Case', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': 'e2e692b5-efbc-4cd7-ab38-bce0bd457a8b', 'name': 'Psychonaut 75', 'sort-name': 'Psychonaut 75', 'disambiguation': 'dark industrial dance'}}], 'release-group': {'id': '66a591cf-f7df-3000-b32c-56fe91a7e2f9', 'type': 'Album', 'title': "The Witches' Sabbath", 'primary-type': 'Album'}, 'date': '2000', 'country': 'FR', 'release-event-list': [{'date': '2000', 'area': {'id': '08310658-51eb-3801-80de-5a0739207115', 'name': 'France', 'sort-name': 'France', 'iso-3166-1-code-list': ['FR']}}], 'barcode': '', 'label-info-list': [{'catalog-number': 'ATNR 007', 'label': {'id': '820c7c21-2d29-4e2f-83cb-692cfd335fab', 'name': 'Athanor'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '9c9824e3-6fb7-4e02-a92b-469d72f36281', 'ext:score': '71', 'title': 'Free-Rider', 'status': 'Official', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '35ed62b6-a358-41a5-8c09-80e7aaae1e1b', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'German trance group; Lothar Herrmann & Oliver Balser'}}], 'release-group': {'id': 'ace22e92-832d-4a5d-942d-c5ae6fbd5715', 'type': 'Album', 'title': 'Free-Rider', 'primary-type': 'Album'}, 'date': '2010-09-03', 'country': 'DE', 'release-event-list': [{'date': '2010-09-03', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'asin': 'B003GNIO7E', 'label-info-list': [{'label': {'id': 'd8a2de8d-1e2b-4ff7-9b78-61dfb26e545d', 'name': 'Crotus Records'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 9}], 'medium-track-count': 9, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': 'c4d68715-beec-4d3a-ab74-1f18682ee437', 'ext:score': '71', 'title': 'Interbeing', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '55e84562-e29b-4967-8d2b-a7fff673cd1e', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Belgian sludge metal band'}}], 'release-group': {'id': '59e54a49-9a2c-429f-9bbd-56f729018289', 'type': 'Single', 'title': 'Interbeing', 'primary-type': 'Single'}, 'date': '2022-06-28', 'country': 'XW', 'release-event-list': [{'date': '2022-06-28', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'label-info-list': [{'label': {'id': 'df682909-df86-4be1-b2e8-1bd12c06bd01', 'name': 'Pelagic Records'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 1}], 'medium-track-count': 1, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '1b0bfd1c-8698-4177-9bb6-5395f4c2691b', 'ext:score': '71', 'title': '... Jsem tady', 'status': 'Official', 'text-representation': {'language': 'ces', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '48abf0e3-14e6-4bf9-a14e-45bc7f327891', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Czech funk rock band from Opava'}}], 'release-group': {'id': '9844eb39-01f0-4144-9dad-b1872b950a89', 'type': 'Album', 'title': '... Jsem tady', 'primary-type': 'Album'}, 'date': '2004', 'country': 'CZ', 'release-event-list': [{'date': '2004', 'area': {'id': '51d34c28-61bf-3d21-849f-7492672a9d44', 'name': 'Czechia', 'sort-name': 'Czechia', 'iso-3166-1-code-list': ['CZ']}}], 'barcode': '8594056290130', 'label-info-list': [{'catalog-number': 'XP 013', 'label': {'id': '1e2ea326-ffac-45f0-a8f3-2e2966d84016', 'name': 'X Production'}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 13}], 'medium-track-count': 13, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '159542de-8d9c-46dc-818b-d9c52c3ca90b', 'ext:score': '71', 'title': 'Live at Penthouse Studio', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '55e84562-e29b-4967-8d2b-a7fff673cd1e', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Belgian sludge metal band'}}], 'release-group': {'id': 'fc7913fe-6a17-4819-8efd-02b0b3613797', 'type': 'EP', 'title': 'Live at Penthouse Studio', 'primary-type': 'EP', 'secondary-type-list': ['Live']}, 'date': '2021-02-05', 'country': 'XW', 'release-event-list': [{'date': '2021-02-05', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'label-info-list': [{'label': {'id': 'df682909-df86-4be1-b2e8-1bd12c06bd01', 'name': 'Pelagic Records'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 3}], 'medium-track-count': 3, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '3d9703c6-be9e-4043-8a5c-5ea0ea4af923', 'ext:score': '71', 'title': 'The Story of Your Enslavement', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '55e84562-e29b-4967-8d2b-a7fff673cd1e', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Belgian sludge metal band'}}], 'release-group': {'id': '287f1682-d297-4f6e-8248-0461d3ef06b0', 'type': 'Single', 'title': 'The Story of Your Enslavement', 'primary-type': 'Single'}, 'date': '2020-02-14', 'country': 'XW', 'release-event-list': [{'date': '2020-02-14', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'label-info-list': [{'label': {'id': 'df682909-df86-4be1-b2e8-1bd12c06bd01', 'name': 'Pelagic Records'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 1}], 'medium-track-count': 1, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '7c206048-26d6-4296-b5dd-0bf02dc0c691', 'ext:score': '71', 'title': 'Kabuddah', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '55e84562-e29b-4967-8d2b-a7fff673cd1e', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Belgian sludge metal band'}}], 'release-group': {'id': 'ac846cfe-e7ff-4e7d-bbfd-a50331fd1396', 'type': 'Single', 'title': 'Kabuddah', 'primary-type': 'Single'}, 'date': '2020-01-31', 'country': 'XW', 'release-event-list': [{'date': '2020-01-31', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'label-info-list': [{'label': {'id': 'df682909-df86-4be1-b2e8-1bd12c06bd01', 'name': 'Pelagic Records'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 1}], 'medium-track-count': 1, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '09cd3222-c863-4c55-a14e-dd7c02ec18be', 'ext:score': '71', 'title': 'Violate Consensus Reality', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '55e84562-e29b-4967-8d2b-a7fff673cd1e', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Belgian sludge metal band'}}], 'release-group': {'id': '9fd45de3-4497-43c4-88c5-8fbb26cfdfbd', 'type': 'Single', 'title': 'Violate Consensus Reality', 'primary-type': 'Single'}, 'date': '2022-09-08', 'country': 'XW', 'release-event-list': [{'date': '2022-09-08', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'label-info-list': [{'label': {'id': 'df682909-df86-4be1-b2e8-1bd12c06bd01', 'name': 'Pelagic Records'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 2}], 'medium-track-count': 2, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': 'e5df1bf9-e573-4549-9791-aa5f87704f69', 'ext:score': '71', 'title': 'Violate Consensus Reality', 'status': 'Official', 'packaging': 'None', 'text-representation': {'language': 'eng', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '55e84562-e29b-4967-8d2b-a7fff673cd1e', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Belgian sludge metal band'}}], 'release-group': {'id': 'f1d9dcc3-6287-475b-8ddb-2cc3b8e0e348', 'type': 'Album', 'title': 'Violate Consensus Reality', 'primary-type': 'Album'}, 'date': '2022-10-28', 'country': 'XW', 'release-event-list': [{'date': '2022-10-28', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'label-info-list': [{'label': {'id': 'df682909-df86-4be1-b2e8-1bd12c06bd01', 'name': 'Pelagic Records'}}], 'medium-list': [{'format': 'Digital Media', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 8}], 'medium-track-count': 8, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}, {'id': '8ce4c671-50e6-4fb7-a1e7-e93344dce010', 'ext:score': '71', 'title': 'Zeměven', 'status': 'Official', 'text-representation': {'language': 'ces', 'script': 'Latn'}, 'artist-credit': [{'name': 'Psychonaut', 'artist': {'id': '48abf0e3-14e6-4bf9-a14e-45bc7f327891', 'name': 'Psychonaut', 'sort-name': 'Psychonaut', 'disambiguation': 'Czech funk rock band from Opava'}}], 'release-group': {'id': '29a0c11f-3700-4133-a15a-5da0d6b1b119', 'type': 'Album', 'title': 'Zeměven', 'primary-type': 'Album'}, 'date': '2001', 'country': 'CZ', 'release-event-list': [{'date': '2001', 'area': {'id': '51d34c28-61bf-3d21-849f-7492672a9d44', 'name': 'Czechia', 'sort-name': 'Czechia', 'iso-3166-1-code-list': ['CZ']}}], 'medium-list': [{'format': 'CD', 'disc-list': [], 'disc-count': 0, 'track-list': [], 'track-count': 9}], 'medium-track-count': 9, 'medium-count': 1, 'tag-list': [], 'artist-credit-phrase': 'Psychonaut'}], 'release-count': 1421} +{'recording-list': [{'id': '20011be9-e649-4a11-ab66-7a2d8bc20c91', 'ext:score': '100', 'title': 'Have a Nice Trip', 'length': '540000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '89d0bbd9-5e9c-41c2-80a7-a156e93a8b3a', 'number': '4', 'title': 'Have A Nice Trip', 'length': '540000', 'track_or_recording_length': '540000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'be904c08-c8e8-36cb-9ba1-9c479e40afba', 'number': 'A4', 'title': 'Have a Nice Trip', 'length': '540000', 'track_or_recording_length': '540000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'tag-list': [{'count': '1', 'name': 'rock'}, {'count': '1', 'name': 'metal'}, {'count': '2', 'name': 'black metal'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'c5a7fef9-6391-44be-a5ab-73ac88ff7226', 'ext:score': '100', 'title': 'Overdose Was the Best Way to Die', 'length': '323000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'ad6ea3fd-6df4-43e0-85d0-f388692966b7', 'number': '5', 'title': 'Overdose Was The Best Way To Die', 'length': '323000', 'track_or_recording_length': '323000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': '689f7df6-81a7-3e2a-8c3f-90999bcf468e', 'number': 'A5', 'title': 'Overdose Was the Best Way to Die', 'length': '323000', 'track_or_recording_length': '323000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '13a505ec-97ab-4053-adf9-c54b5cb944ae', 'ext:score': '100', 'title': 'Drop by Drop', 'length': '411000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '3b58ca08-cf3c-430b-8f1d-fce2d7e5f9af', 'number': '8', 'title': 'Drop By Drop (Album Version)', 'length': '411000', 'track_or_recording_length': '411000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'ed936633-cf6e-323a-858b-8577dcc1f8e4', 'number': 'B3', 'title': 'Drop by Drop', 'length': '411000', 'track_or_recording_length': '411000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '71c9beb2-7cf2-416a-a69e-ce6aa05aa327', 'ext:score': '100', 'title': 'Intro', 'length': '139000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '84f768d5-a6af-429f-8384-b1f998eda172', 'number': '6', 'title': 'Intro (Part II)', 'length': '139000', 'track_or_recording_length': '139000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'b2e1c794-eb71-3b7c-aa9c-73bd31fa28df', 'number': 'B1', 'title': 'Intro', 'length': '139000', 'track_or_recording_length': '139000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'b9bcdb8b-4bd4-4252-8f30-8b9a746474e0', 'ext:score': '100', 'title': 'Pseudo', 'length': '279000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'f7e18fd1-ac16-43b4-ab30-586f0775ec16', 'number': '3', 'title': 'Pseudo', 'length': '345000', 'track_or_recording_length': '345000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': '27b4f585-1f3a-3a3e-a6fc-3785e9f98f09', 'number': 'B2', 'title': 'Pseudo', 'length': '279000', 'track_or_recording_length': '279000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'b55c4962-f80f-4bd9-9103-4fd319a7b6f6', 'ext:score': '100', 'title': 'Lethargic Dialogue', 'length': '279000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '711cda4c-cd20-4974-893d-6a3b5a0a4ae2', 'number': '7', 'title': 'Lethargic Dialogue', 'length': '279000', 'track_or_recording_length': '279000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'ceb575a9-fc84-379c-844f-b32413d1dd9f', 'number': 'A3', 'title': 'Lethargic Dialogue', 'length': '345000', 'track_or_recording_length': '345000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '917481b6-8549-4127-a319-4b8c2198e863', 'ext:score': '100', 'title': 'Hate Parade', 'length': '285000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'c8e6b62c-c350-4cbe-90e2-2a8db4d636aa', 'number': '9', 'title': 'Hate Parade', 'length': '285000', 'track_or_recording_length': '285000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': '03faf038-50d1-363a-b0dd-e0b9a2f0133a', 'number': 'B4', 'title': 'Hate Parade', 'length': '285000', 'track_or_recording_length': '285000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'f301ed85-0a36-4d41-b60a-bb31b59ab4e4', 'ext:score': '100', 'title': 'ყლე', 'length': '279000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'bef00ad1-df23-4626-90d5-940f1e8b15e7', 'number': '11', 'title': 'ყლე', 'length': '279000', 'track_or_recording_length': '279000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'f7262517-fe52-365b-9770-7f167bb111a8', 'number': 'B6', 'title': 'ყლე', 'length': '279000', 'track_or_recording_length': '279000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '1cdce395-3618-471b-a7ce-cf05b5e23261', 'ext:score': '100', 'title': 'Parasite', 'length': '458000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'e7a0d5cd-ba0b-41f0-b723-a12a2a47a250', 'number': '2', 'title': 'Parasite', 'length': '458000', 'track_or_recording_length': '458000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': '0b711166-1075-3c69-9c14-a28ca5d0e4e0', 'number': 'A2', 'title': 'Parasite', 'length': '458000', 'track_or_recording_length': '458000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'tag-list': [{'count': '1', 'name': 'rock'}, {'count': '1', 'name': 'metal'}, {'count': '2', 'name': 'black metal'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '4c10e8fb-4e22-4ed1-8a06-8e00c0e104bd', 'ext:score': '100', 'title': 'Intro', 'length': '211000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'faa570ec-44de-3ee3-a007-1231230197bb', 'number': 'A1', 'title': 'Intro', 'length': '211000', 'track_or_recording_length': '211000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}], 'tag-list': [{'count': '1', 'name': 'rock'}, {'count': '1', 'name': 'metal'}, {'count': '2', 'name': 'black metal'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'dd53f08d-27e0-4ce7-aae2-b79e8a53526f', 'ext:score': '100', 'title': 'Serial Lier', 'length': '380000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'd6e6be74-b7a4-4982-955a-d3361885541c', 'title': '40%', 'status': 'Official', 'release-group': {'id': 'a557bf98-e902-4336-8b28-ecbede7f93bf', 'type': 'Album', 'title': '40%', 'primary-type': 'Album', 'secondary-type-list': ['Demo']}, 'date': '2011-06-04', 'country': 'UA', 'release-event-list': [{'date': '2011-06-04', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': '4ea2d709-a6b9-3704-b1c1-1b200997d1a7', 'number': '1', 'title': 'Serial Lier', 'length': '380000', 'track_or_recording_length': '380000'}], 'track-count': 3}], 'medium-track-count': 3, 'medium-count': 1}], 'tag-list': [{'count': '1', 'name': 'rock'}, {'count': '1', 'name': 'metal'}, {'count': '2', 'name': 'black metal'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '97aaef50-a3bf-40e2-b38d-ea47b40611af', 'ext:score': '100', 'title': 'Parasite', 'length': '425000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'd6e6be74-b7a4-4982-955a-d3361885541c', 'title': '40%', 'status': 'Official', 'release-group': {'id': 'a557bf98-e902-4336-8b28-ecbede7f93bf', 'type': 'Album', 'title': '40%', 'primary-type': 'Album', 'secondary-type-list': ['Demo']}, 'date': '2011-06-04', 'country': 'UA', 'release-event-list': [{'date': '2011-06-04', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'c24b8241-8611-3259-b976-3118a5465e42', 'number': '2', 'title': 'Parasite', 'length': '425000', 'track_or_recording_length': '425000'}], 'track-count': 3}], 'medium-track-count': 3, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'd44a8347-ba77-4a1b-9d61-d55f1c60c52f', 'ext:score': '100', 'title': 'Antihuman [Drug = Друг]', 'length': '548000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'e37ff962-2c1e-4af2-887d-89d2d88c4bea', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-11', 'country': 'DE', 'release-event-list': [{'date': '2012-11', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'bd8d9250-749e-4968-ab24-8f5c74ebc58a', 'number': '10', 'title': 'Antihuman [Drug=Друг]', 'length': '548000', 'track_or_recording_length': '548000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'a3015b31-3b62-4ffa-9184-9fb7bfd39660', 'title': 'Have a Nice Trip', 'status': 'Official', 'release-group': {'id': '9b1453e9-5b74-43c3-8e4f-0f4c78e46aff', 'type': 'Album', 'title': 'Have a Nice Trip', 'primary-type': 'Album'}, 'date': '2012-08-11', 'country': 'UA', 'release-event-list': [{'date': '2012-08-11', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'be7a59ea-5000-3cad-ae91-4e2f540a33e8', 'number': 'B5', 'title': 'Antihuman [Drug=Друг]', 'length': '548000', 'track_or_recording_length': '548000'}], 'track-count': 11}], 'medium-track-count': 11, 'medium-count': 1}, {'id': 'd6e6be74-b7a4-4982-955a-d3361885541c', 'title': '40%', 'status': 'Official', 'release-group': {'id': 'a557bf98-e902-4336-8b28-ecbede7f93bf', 'type': 'Album', 'title': '40%', 'primary-type': 'Album', 'secondary-type-list': ['Demo']}, 'date': '2011-06-04', 'country': 'UA', 'release-event-list': [{'date': '2011-06-04', 'area': {'id': '904768d0-61ca-3c40-93ac-93adc36fef4b', 'name': 'Ukraine', 'sort-name': 'Ukraine', 'iso-3166-1-code-list': ['UA']}}], 'medium-list': [{'position': '1', 'format': 'Cassette', 'track-list': [{'id': 'e3931ca8-1281-3b38-b4cb-6f2f0503a87b', 'number': '3', 'title': 'Antihuman [Drug = Друг]', 'length': '548000', 'track_or_recording_length': '548000'}], 'track-count': 3}], 'medium-track-count': 3, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'e183ef11-de34-4fa4-9381-44a7117e8611', 'ext:score': '100', 'title': 'Nackskott', 'length': '175000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '27f00fb8-983c-4d5c-950f-51418aac55dc', 'title': 'Tired, Numb, Still Alive', 'status': 'Official', 'artist-credit': [{'name': 'Unjoy', 'artist': {'id': '52685d5c-f5a9-40f9-8664-dc083ff242bd', 'name': 'Unjoy', 'sort-name': 'Unjoy', 'disambiguation': 'Black Metal band'}}, ' / ', {'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}, ' / ', {'name': 'Eurythmie', 'artist': {'id': 'c148d680-4739-429a-8550-53c098ac0b16', 'name': 'Eurythmie', 'sort-name': 'Eurythmie'}}], 'release-group': {'id': '6f46e1a4-0d33-48f5-b809-b131c369c97e', 'type': 'Album', 'title': 'Tired, Numb, Still Alive', 'primary-type': 'Album'}, 'date': '2012-06-15', 'country': 'DE', 'release-event-list': [{'date': '2012-06-15', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'f788c549-ece2-370b-95de-b6219347da45', 'number': '6', 'title': 'Nackskott', 'length': '175000', 'track_or_recording_length': '175000'}], 'track-count': 6}], 'medium-track-count': 6, 'medium-count': 1, 'artist-credit-phrase': 'Unjoy / Psychonaut 4 / Eurythmie'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '83a30323-aee1-401a-b767-b3c1bdd026c0', 'ext:score': '100', 'title': 'Drop by Drop', 'length': '414000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '27f00fb8-983c-4d5c-950f-51418aac55dc', 'title': 'Tired, Numb, Still Alive', 'status': 'Official', 'artist-credit': [{'name': 'Unjoy', 'artist': {'id': '52685d5c-f5a9-40f9-8664-dc083ff242bd', 'name': 'Unjoy', 'sort-name': 'Unjoy', 'disambiguation': 'Black Metal band'}}, ' / ', {'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}, ' / ', {'name': 'Eurythmie', 'artist': {'id': 'c148d680-4739-429a-8550-53c098ac0b16', 'name': 'Eurythmie', 'sort-name': 'Eurythmie'}}], 'release-group': {'id': '6f46e1a4-0d33-48f5-b809-b131c369c97e', 'type': 'Album', 'title': 'Tired, Numb, Still Alive', 'primary-type': 'Album'}, 'date': '2012-06-15', 'country': 'DE', 'release-event-list': [{'date': '2012-06-15', 'area': {'id': '85752fda-13c4-31a3-bee5-0e5cb1f51dad', 'name': 'Germany', 'sort-name': 'Germany', 'iso-3166-1-code-list': ['DE']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'f8efd599-3df2-342c-9521-b531ca74c89d', 'number': '5', 'title': 'Drop by Drop', 'length': '414000', 'track_or_recording_length': '414000'}], 'track-count': 6}], 'medium-track-count': 6, 'medium-count': 1, 'artist-credit-phrase': 'Unjoy / Psychonaut 4 / Eurythmie'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '975a7b3d-d66d-431b-8a76-4aba81ddad83', 'ext:score': '100', 'title': 'I Measure Time in Mililiters', 'length': '377920', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '66b70765-0c9f-41ff-9190-4830a3bd59e4', 'title': 'Urban Negativism', 'status': 'Official', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}, ' / ', {'name': 'In Luna', 'artist': {'id': 'fe7d5a6d-ad23-4444-aad5-14b7bf64304c', 'name': 'In Luna', 'sort-name': 'In Luna'}}, ' / ', {'name': 'Ofdrykkja', 'artist': {'id': '553462b6-fbb5-4bee-8536-d524ae3b5d13', 'name': 'Ofdrykkja', 'sort-name': 'Ofdrykkja'}}, ' / ', {'name': 'Vanhelga', 'artist': {'id': '20365b56-cd76-4f49-8e1d-87251724bbd8', 'name': 'Vanhelga', 'sort-name': 'Vanhelga'}}], 'release-group': {'id': '3378a8fd-8d9a-4bdf-85f1-10d630213053', 'type': 'Album', 'title': 'Urban Negativism', 'primary-type': 'Album'}, 'date': '2015-04-06', 'country': 'XW', 'release-event-list': [{'date': '2015-04-06', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '7debff25-a430-458b-9aea-f139d276b4c6', 'number': '7', 'title': 'I Measure Time in Mililiters', 'length': '377920', 'track_or_recording_length': '377920'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1, 'artist-credit-phrase': 'Psychonaut 4 / In Luna / Ofdrykkja / Vanhelga'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'cb0ad965-c7d6-4510-994c-1351134e9879', 'ext:score': '100', 'title': 'In a Good Movie Hero Always Dies', 'length': '199453', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '66b70765-0c9f-41ff-9190-4830a3bd59e4', 'title': 'Urban Negativism', 'status': 'Official', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}, ' / ', {'name': 'In Luna', 'artist': {'id': 'fe7d5a6d-ad23-4444-aad5-14b7bf64304c', 'name': 'In Luna', 'sort-name': 'In Luna'}}, ' / ', {'name': 'Ofdrykkja', 'artist': {'id': '553462b6-fbb5-4bee-8536-d524ae3b5d13', 'name': 'Ofdrykkja', 'sort-name': 'Ofdrykkja'}}, ' / ', {'name': 'Vanhelga', 'artist': {'id': '20365b56-cd76-4f49-8e1d-87251724bbd8', 'name': 'Vanhelga', 'sort-name': 'Vanhelga'}}], 'release-group': {'id': '3378a8fd-8d9a-4bdf-85f1-10d630213053', 'type': 'Album', 'title': 'Urban Negativism', 'primary-type': 'Album'}, 'date': '2015-04-06', 'country': 'XW', 'release-event-list': [{'date': '2015-04-06', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '15d8d514-9a95-44a5-a3a3-fc62ccc67d48', 'number': '8', 'title': 'In a Good Movie Hero Always Dies', 'length': '199453', 'track_or_recording_length': '199453'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1, 'artist-credit-phrase': 'Psychonaut 4 / In Luna / Ofdrykkja / Vanhelga'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '0c8cbbc4-84be-4f5a-8a56-be1777029960', 'ext:score': '100', 'title': 'Not a Love Song', 'length': '353613', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '66b70765-0c9f-41ff-9190-4830a3bd59e4', 'title': 'Urban Negativism', 'status': 'Official', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}, ' / ', {'name': 'In Luna', 'artist': {'id': 'fe7d5a6d-ad23-4444-aad5-14b7bf64304c', 'name': 'In Luna', 'sort-name': 'In Luna'}}, ' / ', {'name': 'Ofdrykkja', 'artist': {'id': '553462b6-fbb5-4bee-8536-d524ae3b5d13', 'name': 'Ofdrykkja', 'sort-name': 'Ofdrykkja'}}, ' / ', {'name': 'Vanhelga', 'artist': {'id': '20365b56-cd76-4f49-8e1d-87251724bbd8', 'name': 'Vanhelga', 'sort-name': 'Vanhelga'}}], 'release-group': {'id': '3378a8fd-8d9a-4bdf-85f1-10d630213053', 'type': 'Album', 'title': 'Urban Negativism', 'primary-type': 'Album'}, 'date': '2015-04-06', 'country': 'XW', 'release-event-list': [{'date': '2015-04-06', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'ed49885b-037d-45a7-b642-8dc11a194c89', 'number': '6', 'title': 'Not a Love Song', 'length': '353613', 'track_or_recording_length': '353613'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1, 'artist-credit-phrase': 'Psychonaut 4 / In Luna / Ofdrykkja / Vanhelga'}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'f6424595-9d4d-4a44-908b-99bdea5fa7e7', 'ext:score': '100', 'title': 'Prologue', 'length': '450000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '0d229a02-74f6-4c77-8c20-6612295870ae', 'title': 'Neurasthenia', 'status': 'Official', 'release-group': {'id': '855c95c7-b7c2-40b2-b453-e3d37f43401e', 'type': 'Album', 'title': 'Neurasthenia', 'primary-type': 'Album'}, 'date': '2016-10-07', 'country': 'AT', 'release-event-list': [{'date': '2016-10-07', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '015ba6d6-cb44-41a6-931f-3e40f68a0f2c', 'number': '1', 'title': 'Prologue', 'length': '450000', 'track_or_recording_length': '450000'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': 'a154d647-80ea-4372-8590-b307ed10999c', 'ext:score': '100', 'title': 'Death Is a Form of Art', 'length': '498000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '0d229a02-74f6-4c77-8c20-6612295870ae', 'title': 'Neurasthenia', 'status': 'Official', 'release-group': {'id': '855c95c7-b7c2-40b2-b453-e3d37f43401e', 'type': 'Album', 'title': 'Neurasthenia', 'primary-type': 'Album'}, 'date': '2016-10-07', 'country': 'AT', 'release-event-list': [{'date': '2016-10-07', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '2e558d0a-ce38-4b78-8902-497a1d1e8a91', 'number': '2', 'title': 'Death Is a Form of Art', 'length': '498000', 'track_or_recording_length': '498000'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '19baec10-dd65-4826-bc2b-daaea6004cb7', 'ext:score': '100', 'title': 'Bad t.RIP', 'length': '519000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '0d229a02-74f6-4c77-8c20-6612295870ae', 'title': 'Neurasthenia', 'status': 'Official', 'release-group': {'id': '855c95c7-b7c2-40b2-b453-e3d37f43401e', 'type': 'Album', 'title': 'Neurasthenia', 'primary-type': 'Album'}, 'date': '2016-10-07', 'country': 'AT', 'release-event-list': [{'date': '2016-10-07', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '44106bbc-dbed-485d-9c91-2ee100680109', 'number': '5', 'title': 'Bad t.RIP', 'length': '519000', 'track_or_recording_length': '519000'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '5ff80fa9-8e63-42e7-9a3d-49befc5101c9', 'ext:score': '100', 'title': 'Song Written in Paris', 'length': '353000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '0d229a02-74f6-4c77-8c20-6612295870ae', 'title': 'Neurasthenia', 'status': 'Official', 'release-group': {'id': '855c95c7-b7c2-40b2-b453-e3d37f43401e', 'type': 'Album', 'title': 'Neurasthenia', 'primary-type': 'Album'}, 'date': '2016-10-07', 'country': 'AT', 'release-event-list': [{'date': '2016-10-07', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': '883577c7-eac4-4274-ab31-3d55adf910da', 'number': '6', 'title': 'Song Written in Paris', 'length': '353000', 'track_or_recording_length': '353000'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '0f8ddb6b-5e2f-4817-83bf-069edd6c7daf', 'ext:score': '100', 'title': 'Thoughts of Death', 'length': '457000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '0d229a02-74f6-4c77-8c20-6612295870ae', 'title': 'Neurasthenia', 'status': 'Official', 'release-group': {'id': '855c95c7-b7c2-40b2-b453-e3d37f43401e', 'type': 'Album', 'title': 'Neurasthenia', 'primary-type': 'Album'}, 'date': '2016-10-07', 'country': 'AT', 'release-event-list': [{'date': '2016-10-07', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'e6737a96-7646-4e1d-93d0-57df708a99d1', 'number': '10', 'title': 'Thoughts of Death', 'length': '457000', 'track_or_recording_length': '457000'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '7bdd08b3-efd7-4421-89bf-d499b36c230d', 'ext:score': '100', 'title': 'I Wanna Be Your Dog', 'length': '308000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': 'ab61f4b0-88e8-43b5-9b24-af184c6f1f12', 'title': 'Free Portion ov Madness I', 'status': 'Official', 'release-group': {'id': 'fe7f2480-fa00-483e-bad6-e6fc839ec3ea', 'type': 'Single', 'title': 'Free Portion ov Madness I', 'primary-type': 'Single'}, 'date': '2014-04-11', 'country': 'XW', 'release-event-list': [{'date': '2014-04-11', 'area': {'id': '525d4e18-3d00-31b9-a58b-a146a916de8f', 'name': '[Worldwide]', 'sort-name': '[Worldwide]', 'iso-3166-1-code-list': ['XW']}}], 'medium-list': [{'position': '1', 'format': 'Digital Media', 'track-list': [{'id': '2cbaf960-3e0d-4ccf-933d-7a790f051dec', 'number': '1', 'title': 'I Wanna Be Your Dog', 'length': '308000', 'track_or_recording_length': '308000'}], 'track-count': 1}], 'medium-track-count': 1, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}, {'id': '6b40186b-6678-4328-a4b8-eb7c9806a9fb', 'ext:score': '100', 'title': 'Sweet Decadance', 'length': '718000', 'artist-credit': [{'name': 'Psychonaut 4', 'artist': {'id': 'c0c720b5-012f-4204-a472-981403f37b12', 'name': 'Psychonaut 4', 'sort-name': 'Psychonaut 4', 'disambiguation': 'Georgian depressive black metal'}}], 'release-list': [{'id': '0d229a02-74f6-4c77-8c20-6612295870ae', 'title': 'Neurasthenia', 'status': 'Official', 'release-group': {'id': '855c95c7-b7c2-40b2-b453-e3d37f43401e', 'type': 'Album', 'title': 'Neurasthenia', 'primary-type': 'Album'}, 'date': '2016-10-07', 'country': 'AT', 'release-event-list': [{'date': '2016-10-07', 'area': {'id': 'caac77d1-a5c8-3e6e-8e27-90b44dcc1446', 'name': 'Austria', 'sort-name': 'Austria', 'iso-3166-1-code-list': ['AT']}}], 'medium-list': [{'position': '1', 'format': 'CD', 'track-list': [{'id': 'b01fa728-514b-4730-879c-4ffc1df2554a', 'number': '3', 'title': 'Sweet Decadance', 'length': '718000', 'track_or_recording_length': '718000'}], 'track-count': 10}], 'medium-track-count': 10, 'medium-count': 1}], 'artist-credit-phrase': 'Psychonaut 4'}], 'recording-count': 13023} + +""" + +if __name__ == "__main__": + import musicbrainzngs + + musicbrainzngs.set_useragent("metadata receiver", "0.1", "https://github.com/HeIIow2/music-downloader") + options = Options([musicbrainzngs.search_artists("Crystal F")]) + options.choose(0) + print(options.get_current_option()) diff --git a/src/musify.py b/src/musify.py index 795d067..5a652e1 100644 --- a/src/musify.py +++ b/src/musify.py @@ -11,6 +11,10 @@ session.headers = { } +def set_proxy(proxies): + session.proxies = proxies + + def get_musify_url(row): title = row.title artists = row.artist @@ -75,6 +79,8 @@ def search_for_track(row): soup = get_soup_of_search(f"{artist[0]} - {track}") tracklist_container_soup = soup.find_all("div", {"class": "playlist"}) + if len(tracklist_container_soup) == 0: + return None if len(tracklist_container_soup) != 1: raise Exception("Connfusion Error. HTML Layout of https://musify.club changed.") tracklist_container_soup = tracklist_container_soup[0] @@ -113,12 +119,17 @@ if __name__ == "__main__": import pandas as pd import json + TOR = True + if TOR: + set_proxy({ + 'http': 'socks5h://127.0.0.1:9150', + 'https': 'socks5h://127.0.0.1:9150' + }) + df = pd.read_csv("../temp/.cache1.csv") for idx, row in df.iterrows(): row['artist'] = json.loads(row['artist'].replace("'", '"')) print("-" * 200) - print("fast") - print(get_musify_url(row)) print("slow") print(get_musify_url_slow(row))