import json from os import path from typing import List import jinja2 import yaml from core.config import CoreConfig from core.frontend import FE_Base, UserSession from starlette.requests import Request from starlette.responses import RedirectResponse, Response from starlette.routing import Route from titles.idac.config import IDACConfig from titles.idac.const import IDACConstants from titles.idac.database import IDACData from titles.idac.schema.item import * from titles.idac.schema.profile import * class IDACFrontend(FE_Base): def __init__( self, cfg: CoreConfig, environment: jinja2.Environment, cfg_dir: str ) -> None: super().__init__(cfg, environment) self.data = IDACData(cfg) self.game_cfg = IDACConfig() if path.exists(f"{cfg_dir}/{IDACConstants.CONFIG_NAME}"): self.game_cfg.update( yaml.safe_load(open(f"{cfg_dir}/{IDACConstants.CONFIG_NAME}")) ) # self.nav_name = "頭文字D THE ARCADE" self.nav_name = "IDAC" # TODO: Add version list self.version = IDACConstants.VER_IDAC_SEASON_2 self.ticket_names = { 3: "car_dressup_points", 5: "avatar_points", 25: "full_tune_tickets", 34: "full_tune_fragments", } def get_routes(self) -> List[Route]: return [Route("/", self.render_GET)] async def generate_all_tables_json(self, user_id: int): json_export = {} idac_tables = { profile, config, avatar, rank, stock, theory, car, ticket, story, episode, difficulty, course, trial, challenge, theory_course, theory_partner, theory_running, vs_info, stamp, timetrial_event, } for table in idac_tables: sql = select(table).where( table.c.user == user_id, ) # check if the table has a version column if "version" in table.c: sql = sql.where(table.c.version == self.version) # lol use the profile connection for items, dirty hack result = await self.data.profile.execute(sql) data_list = result.fetchall() # add the list to the json export with the correct table name json_export[table.name] = [] for data in data_list: tmp = data._asdict() tmp.pop("id") tmp.pop("user") json_export[table.name].append(tmp) return json.dumps(json_export, indent=4, default=str, ensure_ascii=False) async def render_GET(self, request: Request) -> bytes: uri: str = request.url.path template = self.environment.get_template( "titles/idac/templates/idac_index.jinja" ) usr_sesh = self.validate_session(request) if not usr_sesh: usr_sesh = UserSession() user_id = usr_sesh.user_id # user_id = usr_sesh.user_id # profile export if uri.startswith("/game/idac/export"): if user_id == 0: return RedirectResponse(b"/game/idac", request) # set the file name, content type and size to download the json content = await self.generate_all_tables_json(user_id).encode("utf-8") self.logger.info(f"User {user_id} exported their IDAC data") return Response( content, 200, {"content-disposition": "attachment; filename=idac_profile.json"}, "application/octet-stream", ) profile_data, tickets, rank = None, None, None if user_id > 0: profile_data = await self.data.profile.get_profile(user_id, self.version) ticket_data = await self.data.item.get_tickets(user_id) rank = await self.data.profile.get_profile_rank(user_id, self.version) if ticket_data: tickets = { self.ticket_names[ticket["ticket_id"]]: ticket["ticket_cnt"] for ticket in ticket_data } return Response( template.render( title=f"{self.core_config.server.name} | {self.nav_name}", game_list=self.environment.globals["game_list"], profile=profile_data, tickets=tickets, rank=rank, sesh=vars(usr_sesh), active_page="idac", ), media_type="text/html; charset=utf-8", )