import re from aiohttp import web from aiohttp_apispec import docs from apollo_utils.service.exceptions import NotFound from server.client import services from server.constants import BASE_API_PREFIX, EXPORT_PATTERNS from server.utils.export import json_to_csv router = web.RouteTableDef() @router.post(BASE_API_PREFIX + "/services/export/") @docs(tags=["services", "export"], summary="Export various csv data.") async def get(request: web.Request): req = await request.json() data, content_type, filename = req["data"], req["content-type"], req["filename"] data = json_to_csv(data) csv = data.encode("utf8") headers = (("Content-Disposition", f"attachment; filename*={filename}"), ("Content-Type", content_type)) resp = web.StreamResponse(headers=headers) await resp.prepare(request) # force UTF8 for Excel using BOM_UTF8 await resp.write("\ufeff".encode("utf8")) await resp.write(csv) return resp @router.get(BASE_API_PREFIX + "/services/export/{tail:.*}") @docs(tags=["services", "export"], summary="Export csv data from Filtr API.") async def get(request: web.Request): tail = request.match_info["tail"] playlist_id = request.query.getall("playlist_id") playlist_id = ",".join(playlist_id) match = any([re.match(pattern, tail) for pattern in EXPORT_PATTERNS]) if not match: raise NotFound() resp, data = await services.filtr.export_playlists_report( tail, include_original_response=True, playlistId=playlist_id ) headers = ( ("Content-Disposition", resp.headers["Content-Disposition"]), ("Content-Type", resp.headers["Content-Type"]), ) result = web.StreamResponse(headers=headers) await result.prepare(request) # force UTF8 for Excel using BOM_UTF8 await result.write("\ufeff".encode("utf8")) await result.write(data) return result