from apollo_utils.core.constants.dsp import DSP from functools import partial from typing import Dict, List, Optional from server.client import services from server.constants.distributors import DISTRIBUTORS from server.constants.playlists.delphi.by_api.track_positions_playlists import TrackPositionsPlaylists from server.scenarios.distributors.distributors import get_upc_distributors_map from server.utils.audio_features import get_audio_features from server.utils.mappers.core.getters import getter from server.utils.parallel import make_requests from server.utils.processor import process_by_item, processor from server.utils.processor.core import Processor from server.utils.processor.playlists.playlists import playlist_basic_processors from server.utils.processor.playlists.tracks import collector, track_in_playlist_basic_processors from server.utils.processor.tracks import track_basic_processors, track_extra_data_processors async def process_track_in_playlist_items_with_extra_data( items: List[dict], processors: Optional[List[Processor]] = None, # another (previous) processors to apply is_sony_country_code: Optional[str] = None, # passing 'distributors' overrides 'is_sony' parameters include_is_sony: bool = False, include_audio_features: bool = False, distributors_country_code: Optional[str] = None, distributors: Optional[List[DISTRIBUTORS]] = None, ) -> List[dict]: """ Apply extra_data processors for track-in-playlist items: - adding 'is_sony' flag for 'track' inner object - adding 'audio_features' for 'track' inner object - adding 'distributed_by' for 'track' inner object """ id_getter = partial(getter, key="track_id") # add item_id to extra_data processors track_id_list, upc_list = [], [] processors = processors or [] processors.append(processor(collector, key="track_id", storage=track_id_list, skip_none=True)) processors.append(processor(collector, key="track.album.upc", storage=upc_list, skip_none=True)) process_by_item(items, processors) # to get track_id_list filled results = await make_requests( ( ( get_upc_distributors_map, dict(upc=upc_list, country_code=distributors_country_code, distributors=distributors), {}, bool(distributors) and upc_list, ), ( # keep it for backward compatibility; passing 'distributors' overrides this services.apollo.get_albums_is_sony, dict(upc=upc_list, market=is_sony_country_code), [], not distributors and include_is_sony, ), (get_audio_features, dict(track_id_list=track_id_list), [], include_audio_features), ) ) upc_to_distributor, is_sony_data, audio_features_data = results process_by_item( items, track_extra_data_processors( key_prefix="track", upc_path="track.album.upc", is_sony_upc_data=is_sony_data, audio_features_data=audio_features_data, upc_to_distributor_data=upc_to_distributor, ), id_getter=id_getter, ) return items def check_delphi_include( delphi_include: Optional[List[TrackPositionsPlaylists.INCLUDE]], include_is_sony: bool ) -> Optional[List[TrackPositionsPlaylists.INCLUDE]]: if include_is_sony and (not delphi_include or TrackPositionsPlaylists.INCLUDE.TRACK_INFO not in delphi_include): if delphi_include: delphi_include.append(TrackPositionsPlaylists.INCLUDE.TRACK_INFO) else: delphi_include = [TrackPositionsPlaylists.INCLUDE.TRACK_INFO] return delphi_include async def process_track_in_playlists_items( items: List[dict], dsp: DSP, is_sony_country_code: Optional[str] = None, include_is_sony: bool = False, include_audio_features: bool = False, with_tracks: bool = False, # process inner track object with_playlists: bool = False, # process inner playlist object playlist_map: Optional[Dict[str, dict]] = None, distributors_country_code: Optional[str] = None, distributors: Optional[List[DISTRIBUTORS]] = None, ) -> List[dict]: """Apply common processors for track-in-playlist items.""" id_to_int = dsp is DSP.APPLE need_extra_data = distributors or ((dsp.value == DSP.SPOTIFY.value) and (include_is_sony or include_audio_features)) processors = track_in_playlist_basic_processors(dsp=dsp, id_to_int=id_to_int, playlist_map=playlist_map) if with_playlists: processors.extend(playlist_basic_processors(dsp=dsp, key_prefix="playlist")) if with_tracks: processors.extend(track_basic_processors(dsp=dsp, key_prefix="track", id_to_int=id_to_int)) if not need_extra_data: process_by_item(items, processors) return items return await process_track_in_playlist_items_with_extra_data( items, processors=processors, is_sony_country_code=is_sony_country_code, include_is_sony=include_is_sony, include_audio_features=include_audio_features, distributors_country_code=distributors_country_code, distributors=distributors, )