import datetime from typing import Any, Dict, List, Union from apollo_utils.core.constants.dsp import DSP from apollo_utils.core.utils.multikeysort import multikeysort from server.constants.playlists.v0.misc import StreamsTypeRequest from server.utils.mappers.core.getters import getter from server.utils.mappers.playlists.misc import get_streams_key from tests.api.playlists.v1.responses.helpers import remove_dsp_prefix, get_expected_trend 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 def get_v3_playlists_dsp_by_track_expected_response( dsp: DSP, isrc: str, items: List[Dict[str, Any]], sort_by: List["str"], streams_country_code: str = "local", streams_type: StreamsTypeRequest = StreamsTypeRequest.TRACK, limit: int = 10, ): """GET v3/playlists/{dsp}/by-track response from items Args: dsp: DSP isrc: items: List of track in playlist items streams_country_code: streams_type: limit sort_by """ response_items = [] categories = dict() for i in items: dsp_is_spotify = dsp.value == DSP.SPOTIFY.value pl_id = i["playlist"]["dsp_playlist_id"] country_code = i["playlist"]["country_code"] is_top_track_for_isrc = i["is_top_track_for_isrc"] personalised = i["playlist"]["is_personalised"] last_added_date_time = i["last_added_date_time"] num_days_on = i["num_days_on"] is_entry = is_top_track_for_isrc and not personalised and num_days_on == 0 streams_type_key = "isrc_in_playlist" if streams_type == StreamsTypeRequest.TRACK else "playlist" current_streams = i["streaming_info"][streams_country_code]["7"][streams_type_key] previous_streams = get_prev_streams( current_streams, getter(i, key=get_streams_key(streams_country_code, streams_type, current_streams=False)) ) category_id = i["playlist"]["owner"]["owner_category"]["owner_category_id"] category_name = i["playlist"]["owner"]["owner_category"]["name"] image_url_by = "by_spotify_id" if dsp_is_spotify else "by_apple_music_id" resolution_and_country_code = f"?storefront={country_code}&resolution=large" if not dsp_is_spotify \ else "?resolution=large" item = { "id": pl_id, "added_date": i["earliest_position_date_time"], "category_id": category_id, "category_name": category_name, "country_code": i["playlist"]["country_code"], "current_position": i["current"] + 1, "current_streams": current_streams, "followers": i["playlist"]["followers"], "image_url": f"https://images-api.atlas.stream/v2/playlists/" f"{image_url_by}/{pl_id}{resolution_and_country_code}", "is_new": is_entry and datetime.date.fromisoformat(last_added_date_time) == datetime.date.today(), "position_change_date": None, "prev_streams": previous_streams, "track_id": i["dsp_track_id"], "trend": get_expected_trend(i, is_top_track_for_isrc, personalised), "updated_date": i["latest_position_date_time"], "username": remove_dsp_prefix(dsp, i["playlist"]["owner"]["username"]) } if dsp_is_spotify: item.update({"personalized": i["playlist"]["is_personalised"]}) response_items.append(item) categories[category_id] = { "category_id": category_id, "category_name": category_name } next_page = None if len(response_items) > 10: next_page = f"/gate-api/v3/playlists/apple/by-track/?isrc={isrc}&limit=10&offset=10" response_items = multikeysort(response_items, sort_by) return { "categories": list(categories.values()), "count": len(response_items), "items": response_items[:limit], "next": next_page, "previous": None, "streams_type": streams_type.value } def get_v3_playlists_dsp_by_track_history_expected_response( dsp: DSP, isrc: str, items: List[Dict[str, Any]], sort_by: List["str"], limit: int = 10, *args, **kwargs ): """GET v3/playlists/{dsp}/by-track response from items Args: dsp: DSP isrc: items: List of track in playlist items limit sort_by """ response_items = [] categories = dict() for i in items: dsp_is_spotify = dsp.value == DSP.SPOTIFY.value pl_id = i["playlist"]["dsp_playlist_id"] country_code = i["playlist"]["country_code"] category_id = i["playlist"]["owner"]["owner_category"]["owner_category_id"] category_name = i["playlist"]["owner"]["owner_category"]["name"] image_url_by = "by_spotify_id" if dsp_is_spotify else "by_apple_music_id" resolution_and_country_code = f"?storefront={country_code}&resolution=large" if not dsp_is_spotify \ else "?resolution=large" item = { "updated_date": i["playlist_dates"]["dsp_sync_date_time"], "image_url": f"https://images-api.atlas.stream/v2/playlists/" f"{image_url_by}/{pl_id}{resolution_and_country_code}", "id": pl_id, "name": i["playlist"]["name"], "category_name": category_name, "removed_date": i["removed_date_time"], "followers": i["playlist"]["followers"], "category_id": category_id, "num_days_on": i["num_days_on"], "added_date": i["earliest_position_date_time"], "country_code": country_code } if dsp_is_spotify: item.update({"personalized": i["playlist"]["is_personalised"]}) response_items.append(item) categories[category_id] = { "category_id": category_id, "category_name": category_name } next_page = None if len(response_items) > 10 and limit < 200: next_page = f"/gate-api/v3/playlists/apple/by-track/history?isrc={isrc}&limit={limit}&offset={limit}" response_items = multikeysort(response_items, sort_by) return { "categories": list(categories.values()), "count": len(response_items), "items": response_items[:limit], "next": next_page, "previous": None, } def get_playlists_amazon_track_expected_response(item: Dict[str, Any], playlist_id: str = None, isrc: str = None): """Get expected response for Amazon Track in Playlist -> playlists/amazon/track/ endpoint""" return { "playlist_id": playlist_id or item["playlist_id"], "playlist_name": item["playlist"]["name"], "country_code": item["playlist"]["country_code"], "playlist_image": item["playlist"]["image"]["uri"], "current_position": item["current"], "isrc": isrc or item["isrc"], "added_date": item["earliest_position_date"], "changed_date": item["date"], "is_new": False, "trend": item["trend_change_14_days"], "previous_position": item["previous_position_change_14_days"], } def get_playlists_amazon_expected_response(items: List[Dict[str, Any]]): """Get expected response for Amazon Track in Playlist -> playlists/amazon/track/ endpoint""" response = [] for item in items: expected_response = { "country_code": item["playlist"]["country_code"], "id": f"{item['playlist']['amazon_playlist_id']}:{item['playlist']['playlist_id'].replace('amazon_', '')}", "name": item["playlist"]["name"], "image_url": item["playlist"]["image"]["uri"], "updated_date": item["date"] } response.append(expected_response) return response