import asyncio from typing import Dict, List, Tuple from server.client import services from server.constants import DSP async def _get_tracks_data(**params) -> Tuple[List[dict], Dict[str, dict], Dict[str, List[dict]]]: """Get Amazon playlist tracks data. Args: params: Playlist ID and country code. """ country_code = params["country_code"] # get Amazon playlist tracklist track_list = await services.dsp.get_track_positions_playlists( dsp=DSP.AMAZON.value, include="track_info,playlists", **params ) isrc_list = [i["isrc"] for i in track_list if i.get("isrc")] # get Apple track data by isrc list apple_track_mapping = {} if isrc_list: apple_track_list = await services.vendor.get_tracks( dsp=DSP.APPLE, isrc=isrc_list, market=country_code, include="artists" ) apple_track_mapping = {i["attributes"]["isrc"]: i for i in apple_track_list} # get artists data from Delphi API for tracks that were not found in Apple API missing_isrc = [ i["isrc"] for i in track_list if i.get("track") and i.get("isrc") and i.get("isrc") not in apple_track_mapping ] artist_mapping = {} if missing_isrc: tasks = [services.dsp.get_artists(isrc=i) for i in missing_isrc] artists_per_isrc_list = await asyncio.gather(*tasks) artist_mapping = {isrc: artist_list for isrc, artist_list in zip(missing_isrc, artists_per_isrc_list)} return track_list, apple_track_mapping, artist_mapping def _generate_tracks_result( country_code: str, track_list: List[dict], apple_track_mapping: Dict[str, dict], artist_mapping: Dict[str, List[dict]], ) -> dict: """Generate tracks result data. Args: country_code: Country code. track_list: Delphi API amazon tracklist response. apple_track_mapping: ISRC to Apple track data mapping. artist_mapping: ISRC to artist data mapping. Returns: Tracklist and playlist data. """ playlist_data = None for item in track_list: isrc = item.get("isrc") amazon_track = item.get("amazon_track") or {} gras_track = item.get("track") or {} if amazon_track: item["track"] = { "name": amazon_track["name"], "amazon_track_id": amazon_track["amazon_track_id"], "country_code": amazon_track["country_code"], } else: item["track"] = {} if isrc and isrc in apple_track_mapping: apple_track_data = apple_track_mapping[isrc] item["track"].update( { "name": apple_track_data["attributes"]["name"], "track_id": gras_track.get("track_id"), "apple_track_id": apple_track_data["id"], "artists": [ {"id": i["id"], "name": i.get("attributes", {}).get("name")} for i in apple_track_data["relationships"]["artists"]["data"] ], "image_url": apple_track_data["attributes"]["artwork"]["url"], "release_date": apple_track_data["attributes"].get("releaseDate"), } ) elif gras_track: item["track"].update( { "name": gras_track["name"], "track_id": gras_track["track_id"], "artists": [{"name": j.strip()} for i in artist_mapping[isrc] for j in i["full_name"].split(",")] if artist_mapping.get(isrc) else [], "release_date": gras_track["release_date"], } ) if "playlist" in item and country_code: if not playlist_data: playlist_data = item["playlist"] del item["playlist"] return {"items": track_list, "playlist": playlist_data} async def get_tracks(**params) -> dict: """Get Amazon playlist tracklist. Args: params: Playlist ID and optional country code. Returns: Tracklist and playlist data. """ track_list, apple_track_mapping, artist_mapping = await _get_tracks_data(**params) return _generate_tracks_result(params.get("country_code"), track_list, apple_track_mapping, artist_mapping)