from apollo_utils.core.constants.dsp import DSP from typing import Any, Callable, Tuple, Union from server.constants.playlists.v0.misc import StreamsTypeRequest from server.utils.common import prefix_str from server.utils.glom import delete from server.utils.images.core_image_service import get_core_image_service_image_url from server.utils.mappers.core.getters import DEFAULT_NONE_VALUES, getter from server.utils.mappers.core.mappers import mapper from server.utils.mappers.core.setters import setter def map_image_url( item: dict, dsp: DSP, key_prefix: str = None, entity: str = None, key: str = "image.uri", key_to: str = "image_url", none_result: Any = None, none_values: Tuple[Any] = DEFAULT_NONE_VALUES, getter: Callable = getter, setter: Callable = setter, core_image_url: bool = True, ): """Image Url mapper Hint: If you use Core Image Service and to be sure that _core_image_url_f runs anyway even inside the getter of the mapper we caught a case when: "image_url" value is in DEFAULT_NONE_VALUES=(ABSENT, EMPTY_DICT, None, "null", "", "unknown") you should pass none_values=() """ def _core_image_url_f(*args, **kwargs): return get_core_image_service_image_url( entity=entity, dsp=dsp, entity_id=getter(item, key=prefix_str("id", prefix=key_prefix)), country_code=getter(item, key=prefix_str("country_code", prefix=key_prefix)), ) return mapper( item, key=prefix_str(key, prefix=key_prefix), key_to=prefix_str(key_to or key, prefix=key_prefix), none_values=none_values, none_result=none_result, getter=getter, setter=setter, f=_core_image_url_f if core_image_url else None, ) def map_playlist_dates(item: dict): def dsp_sync_date_time_as_a_list(value: Any): if value is not None and isinstance(v, str): value = [value] return value for k in ("playlist_updated_at_date_time", "dsp_update_date_time", "dsp_sync_date_time"): v = getter(item, key=prefix_str(k, prefix="playlist_dates")) if k == "dsp_sync_date_time" and isinstance(v, str): v = dsp_sync_date_time_as_a_list(v) setter(item, prefix_str(k, prefix="playlist"), v) delete(item, prefix_str("playlist_dates"), ignore_missing=True) def get_streams_key(streams_country_code: str, streams_type: StreamsTypeRequest, current_streams: bool = True) -> str: """Get streams key based on StreamsTypeRequest.PLAYLIST or StreamsTypeRequest.TRACK and country_code""" streams_days = 7 if current_streams else 14 streams_type_key = "isrc_in_playlist" if streams_type == StreamsTypeRequest.TRACK else "playlist" return f"streaming_info.{streams_country_code}.{streams_days}.{streams_type_key}" def map_streams_metrics( item: dict, streams_country_code: str, streams_type: StreamsTypeRequest, return_current_streams: bool = False ) -> Union[None, int]: """Get streams [current, previous] by one of types: Playlist or Track and set them to the high level of a dict item""" def get_prev_streams(streams_current: Union[int, None], streams_previous: Union[int, None]) -> Union[int, None]: if not streams_current or not streams_previous: return None return streams_previous - streams_current current_streams = getter(item, key=get_streams_key(streams_country_code, streams_type)) prev_streams = get_prev_streams( current_streams, getter(item, key=get_streams_key(streams_country_code, streams_type, current_streams=False)) ) item["current_streams"], item["prev_streams"] = current_streams, prev_streams if return_current_streams: return current_streams def map_followers( item: dict, key_prefix: str = None, ): """Map followers to the top level of an item""" for k in ("followers",): v = getter(item, key=prefix_str(k, prefix=key_prefix)) setter(item, prefix_str(k), v) def get_country_playlist_id(dsp: str, playlist_id: str, country_code: str, delimiter: str = '_') -> str: if dsp == DSP.APPLE.value: return f"{playlist_id or ''}{delimiter}{country_code or ''}" return playlist_id # for amazon id already include cc, for spotify - playlist in not market related def map_country_playlist_id( item: dict, id_key="id", country_code_key="country_code", dsp_key="dsp.dsp_id", key_to: str = "country_playlist_id" ): def _get_country_playlist_id(_item: dict): return get_country_playlist_id( dsp=getter(item, key=dsp_key), playlist_id=getter(item, key=id_key), country_code=getter(item, key=country_code_key) ) setter(item, key_to, _get_country_playlist_id(item))