From ae09c2ad48d2dc23314759223ff2c9c360b8cc3c Mon Sep 17 00:00:00 2001 From: Hay1tsme Date: Fri, 12 Jan 2024 18:03:11 -0500 Subject: [PATCH] chuni: add frontend --- core/templates/widgets/err_banner.jinja | 1 - titles/chuni/__init__.py | 10 +-- titles/chuni/frontend.py | 83 ++++++++++++++++++++++++ titles/chuni/schema/profile.py | 11 ++++ titles/chuni/templates/chuni_index.jinja | 43 ++++++++++++ 5 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 titles/chuni/frontend.py create mode 100644 titles/chuni/templates/chuni_index.jinja diff --git a/core/templates/widgets/err_banner.jinja b/core/templates/widgets/err_banner.jinja index bb0e0eb..eec204a 100644 --- a/core/templates/widgets/err_banner.jinja +++ b/core/templates/widgets/err_banner.jinja @@ -19,7 +19,6 @@ New password not acceptable New Nickname too long {% elif error == 9 %} You must be logged in to preform this action -New Nickname too long {% elif error == 10 %} Invalid serial number {% else %} diff --git a/titles/chuni/__init__.py b/titles/chuni/__init__.py index d886d18..226594a 100644 --- a/titles/chuni/__init__.py +++ b/titles/chuni/__init__.py @@ -1,9 +1,11 @@ -from titles.chuni.index import ChuniServlet -from titles.chuni.const import ChuniConstants -from titles.chuni.database import ChuniData -from titles.chuni.read import ChuniReader +from .index import ChuniServlet +from .const import ChuniConstants +from .database import ChuniData +from .read import ChuniReader +from .frontend import ChuniFrontend index = ChuniServlet database = ChuniData reader = ChuniReader +frontend = ChuniFrontend game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW, ChuniConstants.GAME_CODE_INT] diff --git a/titles/chuni/frontend.py b/titles/chuni/frontend.py new file mode 100644 index 0000000..ed58d52 --- /dev/null +++ b/titles/chuni/frontend.py @@ -0,0 +1,83 @@ +from typing import List +from starlette.routing import Route +from starlette.requests import Request +from starlette.responses import Response, RedirectResponse +from os import path +import yaml +import jinja2 + +from core.frontend import FE_Base, UserSession +from core.config import CoreConfig +from .database import ChuniData +from .config import ChuniConfig +from .const import ChuniConstants + + +class ChuniFrontend(FE_Base): + def __init__( + self, cfg: CoreConfig, environment: jinja2.Environment, cfg_dir: str + ) -> None: + super().__init__(cfg, environment) + self.data = ChuniData(cfg) + self.game_cfg = ChuniConfig() + if path.exists(f"{cfg_dir}/{ChuniConstants.CONFIG_NAME}"): + self.game_cfg.update( + yaml.safe_load(open(f"{cfg_dir}/{ChuniConstants.CONFIG_NAME}")) + ) + self.nav_name = "Chunithm" + + def get_routes(self) -> List[Route]: + return [ + Route("/", self.render_GET, methods=['GET']), + Route("/update.name", self.update_name, methods=['POST']), + ] + + async def render_GET(self, request: Request) -> bytes: + template = self.environment.get_template( + "titles/chuni/templates/chuni_index.jinja" + ) + usr_sesh = self.validate_session(request) + if not usr_sesh: + usr_sesh = UserSession() + + return Response(template.render( + title=f"{self.core_config.server.name} | {self.nav_name}", + game_list=self.environment.globals["game_list"], + sesh=vars(usr_sesh) + ), media_type="text/html; charset=utf-16") + + async def update_name(self, request: Request) -> bytes: + usr_sesh = self.validate_session(request) + if not usr_sesh: + return RedirectResponse("/gate/", 303) + + new_name: str = request.query_params.get('new_name', '') + new_name_full = "" + + if not new_name: + return RedirectResponse("/gate/?e=4", 303) + + if len(new_name) > 8: + return RedirectResponse("/gate/?e=8", 303) + + for x in new_name: # FIXME: This will let some invalid characters through atm + o = ord(x) + try: + if o == 0x20: + new_name_full += chr(0x3000) + elif o < 0x7F and o > 0x20: + new_name_full += chr(o + 0xFEE0) + elif o <= 0x7F: + self.logger.warn(f"Invalid ascii character {o:02X}") + return RedirectResponse("/gate/?e=4", 303) + else: + new_name_full += x + + except Exception as e: + self.logger.error(f"Something went wrong parsing character {o:04X} - {e}") + return RedirectResponse("/gate/?e=4", 303) + + if not await self.data.profile.update_name(usr_sesh, new_name_full): + return RedirectResponse("/gate/?e=999", 303) + + return RedirectResponse("/gate/?s=1", 303) \ No newline at end of file diff --git a/titles/chuni/schema/profile.py b/titles/chuni/schema/profile.py index b5ac493..849a5b3 100644 --- a/titles/chuni/schema/profile.py +++ b/titles/chuni/schema/profile.py @@ -395,6 +395,17 @@ team = Table( class ChuniProfileData(BaseData): + async def update_name(self, user_id: int, new_name: str) -> bool: + sql = profile.update(profile.c.user == user_id).values( + userName=new_name + ) + result = await self.execute(sql) + + if result is None: + self.logger.warning(f"Failed to set user {user_id} name to {new_name}") + return False + return True + async def put_profile_data( self, aime_id: int, version: int, profile_data: Dict ) -> Optional[int]: diff --git a/titles/chuni/templates/chuni_index.jinja b/titles/chuni/templates/chuni_index.jinja new file mode 100644 index 0000000..e310054 --- /dev/null +++ b/titles/chuni/templates/chuni_index.jinja @@ -0,0 +1,43 @@ +{% extends "core/templates/index.jinja" %} +{% block content %} +

Chunithm

+{% if profile is defined and profile is not none and profile.id > 0 %} + +

Profile for {{ profile.userName }} 

+{% if error is defined %} +{% include "core/templates/widgets/err_banner.jinja" %} +{% endif %} +{% if success is defined and success == 1 %} +
+Update successful +
+{% endif %} + +{% elif sesh is defined and sesh is not none and sesh.user_id > 0 %} +No profile information found for this account. +{% else %} +Login to view profile information. +{% endif %} +{% endblock content %} \ No newline at end of file