"""Proxies for AGO backward compatibility, works by redirecting traffic from legacy apollo-api routes to these through traefik. """ from aiohttp import web from aiohttp_apispec import docs, headers_schema, json_schema, querystring_schema from apollo_utils.core.utils.multikeysort import multikeysort from apollo_utils.service.exceptions import BadRequest from http import HTTPStatus from server.client import services from server.constants import BASE_API_PREFIX, DSP, cache_keys from server.constants.favorites import EntityType from server.scenarios.users.favorites import FavoriteTacksDetailedInclude, get_favorite_tracks_detailed from server.schemas.auth import AccountHeader from server.schemas.favorites.tracks import UserFavoritesTracksV0, UserFavoritesTracksV0Check, \ UsersFavoritesTrackV0sDetailed from server.utils.pagination import paginate from server.utils.response import dump_response_schema router = web.RouteTableDef() @router.get(BASE_API_PREFIX + "/v0/users/favorites/tracks/detailed/") @docs(tags=["favorites", "tracks", "v0"], summary="Get account favorite tracks extended v0.") @headers_schema(AccountHeader) @querystring_schema(UsersFavoritesTrackV0sDetailed.Request) @dump_response_schema(UsersFavoritesTrackV0sDetailed.Response, apply=False) @paginate(cache_keys.V0_USERS_FAVORITES_TRACKS_DETAILED, params_keys=("querystring", "headers"), cache_ttl=0) async def get(request: web.Request) -> web.Response: params, headers = request["querystring"], request["headers"] result = await get_favorite_tracks_detailed( country_code=params.get("market"), headers=headers, distributors=params.get("distributors", []), tag_id=params.get("tag_id", []), include=[FavoriteTacksDetailedInclude.WEEKLY_STREAMS.value], ) items = multikeysort(result["items"], ["-streams"]) return items @router.get(BASE_API_PREFIX + "/v0/users/favorites/tracks/") @docs(tags=["favorites", "tracks", "v0"], summary="Get account favorite tracks v0.") @headers_schema(AccountHeader) @dump_response_schema(UserFavoritesTracksV0.Get.Response(many=True), apply=False) async def get(request: web.Request) -> web.Response: headers = request["headers"] favorite_tracks_response = await services.user_data.get_user_favorites( headers=headers, entity_type=EntityType.TRACK.value ) result = [] for track in favorite_tracks_response.get("items", []): dsp, track_id = ( track.get("data", {}).get("dsp"), track.get("data", {}).get("id"), ) result.append( { "uri": f"spotify:track:{track_id}" if dsp == DSP.SPOTIFY.value else str(track_id), "isrc": track["entity_id"], "favorites_id": track["favorites_id"], } ) return web.json_response(result) @router.post(BASE_API_PREFIX + "/v0/users/favorites/tracks/") @docs(tags=["favorites", "tracks", "v0"], summary="Add account favorite tracks v0.") @headers_schema(AccountHeader) @json_schema(UserFavoritesTracksV0.Create.Request) @dump_response_schema(UserFavoritesTracksV0.Create.Response, apply=False) async def post(request: web.Request) -> web.Response: headers, data = request["headers"], request["json"] body = { "entity_id": data["isrc"], "entity_type": EntityType.TRACK.value, "data": {"dsp": data["dsp"], "id": data["track_id"], "country_code": data["country_code"]}, "include": "count" } status_code, response = await services.user_data.add_user_favorites( headers=headers, body=body, with_status_code=True ) if status_code == HTTPStatus.BAD_REQUEST: raise BadRequest(**response) return web.json_response( { "status": "OK", "count": response["count"], "favorites_id": response["favorites_id"], "code": "starring.success", "detail": "Track successfully starred", }, status=HTTPStatus.CREATED, ) @router.delete(BASE_API_PREFIX + "/v0/users/favorites/tracks/") @docs(tags=["favorites", "tracks", "v0"], summary="Remove account favorite tracks v0.") @headers_schema(AccountHeader) @querystring_schema(UserFavoritesTracksV0.Delete.Request) @dump_response_schema(UserFavoritesTracksV0.Delete.Response, apply=False) async def post(request: web.Request) -> web.Response: headers, params = request["headers"], request["querystring"] status_code, response = await services.user_data.remove_user_favorites( headers=headers, with_status_code=True, entity_id=params["isrc"], include="count", entity_type="track" ) if status_code == HTTPStatus.BAD_REQUEST: raise BadRequest(**response) return web.json_response( { "status": "OK", "count": response["count"], "code": "starring.success", "detail": "Track successfully unstarred", }, status=HTTPStatus.OK, ) @router.get(BASE_API_PREFIX + "/v0/users/favorites/tracks/check/") @docs(tags=["favorites", "tracks", "v0"], summary="Check account favorite tracks v0.") @headers_schema(AccountHeader) @querystring_schema(UserFavoritesTracksV0Check.Request) async def get(request: web.Request) -> web.Response: headers, isrc_list = request["headers"], request["querystring"]["isrc"] favorite_tracks_response = await services.user_data.get_user_favorites( headers=headers, entity_type=EntityType.TRACK.value, entity_id=isrc_list ) result = {t["entity_id"]: True for t in favorite_tracks_response["items"]} result.update({isrc: False for isrc in set(isrc_list) - result.keys()}) return web.json_response(result)