from aiohttp import web from aiohttp_apispec import docs, querystring_schema from server.client import services from server.constants import BASE_API_PREFIX, cache_keys from server.constants.charts import CHART_MIN_DATE, ChartType, SourceType from server.scenarios.charts import digest as scenarios from server.schemas.charts.digest import ChartBase, ChartDateRange, ChartMoves, ChartOut, ChartTop from server.utils.pagination import paginate from server.utils.response import dump_response_schema router = web.RouteTableDef() @router.get(BASE_API_PREFIX + "/charts/top/") @docs( tags=["charts", "spotify", "apple"], summary="Get chart tracks that current position is within the range.", ) @querystring_schema(ChartTop.Request) @dump_response_schema(ChartTop.Response, apply=False) async def get_charts_top(request: web.Request) -> web.Response: result = await scenarios.get_chart(**request["querystring"]) return web.json_response(result) @router.get(BASE_API_PREFIX + "/charts/out/") @docs( tags=["charts", "spotify", "apple"], summary="Get chart tracks that previous position is in the range and current position is not in the range.", ) @querystring_schema(ChartOut.Request) @dump_response_schema(ChartOut.Response, apply=False) async def get_charts_out(request: web.Request) -> web.Response: result = await scenarios.get_chart(**request["querystring"]) return web.json_response(result) @router.get(BASE_API_PREFIX + "/charts/additions/") @docs( tags=["charts", "spotify", "apple"], summary="Get tracks that enter the chart on the selected date.", ) @querystring_schema(ChartBase.Request) @dump_response_schema(ChartBase.Response, apply=False) async def get_charts_additions(request: web.Request) -> web.Response: result = await scenarios.get_chart(**request["querystring"], source_type=SourceType.ADDITIONS) return web.json_response(result) @router.get(BASE_API_PREFIX + "/charts/removals/") @docs( tags=["charts", "spotify", "apple"], summary="Get tracks that exit the chart on the selected date.", ) @querystring_schema(ChartBase.Request) @dump_response_schema(ChartBase.Response, apply=False) async def get_charts_removals(request: web.Request) -> web.Response: result = await scenarios.get_chart(**request["querystring"], source_type=SourceType.REMOVALS) return web.json_response(result) @router.get(BASE_API_PREFIX + "/charts/moves/") @docs( tags=["charts", "spotify", "apple"], summary="Get tracks that position change is greater or equal some value.", ) @querystring_schema(ChartMoves.Request) @dump_response_schema(ChartMoves.Response, apply=False) @paginate(cache_keys.CHART_MOVES, items_key="tracks", extend_original_dict=True) async def get_charts_moves(request: web.Request) -> dict: return await scenarios.get_chart(**request["querystring"], schema=ChartMoves.Response) @router.get(BASE_API_PREFIX + "/charts/date-range/") @docs(tags=["charts", "spotify", "apple"], summary="Get chart available dates range.") @querystring_schema(ChartDateRange.Request) @dump_response_schema(ChartDateRange.Response) async def get_charts_date_range(request: web.Request) -> dict: params = request["querystring"] chart_breakdown = params["chart_breakdown"] latest_date = await services.dsp.get_charts_latest_date( dsp=params["dsp"], chart_breakdown=chart_breakdown.value, chart_type=ChartType.REGIONAL.value, country_code=params["market"], ) return {"min_date": CHART_MIN_DATE[chart_breakdown], "max_date": latest_date.isoformat() if latest_date else None}