chuni: add frontend

This commit is contained in:
Hay1tsme 2024-01-12 18:03:11 -05:00
parent 9a7d5bc689
commit ae09c2ad48
5 changed files with 143 additions and 5 deletions

View File

@ -19,7 +19,6 @@ New password not acceptable
New Nickname too long New Nickname too long
{% elif error == 9 %} {% elif error == 9 %}
You must be logged in to preform this action You must be logged in to preform this action
New Nickname too long
{% elif error == 10 %} {% elif error == 10 %}
Invalid serial number Invalid serial number
{% else %} {% else %}

View File

@ -1,9 +1,11 @@
from titles.chuni.index import ChuniServlet from .index import ChuniServlet
from titles.chuni.const import ChuniConstants from .const import ChuniConstants
from titles.chuni.database import ChuniData from .database import ChuniData
from titles.chuni.read import ChuniReader from .read import ChuniReader
from .frontend import ChuniFrontend
index = ChuniServlet index = ChuniServlet
database = ChuniData database = ChuniData
reader = ChuniReader reader = ChuniReader
frontend = ChuniFrontend
game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW, ChuniConstants.GAME_CODE_INT] game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW, ChuniConstants.GAME_CODE_INT]

83
titles/chuni/frontend.py Normal file
View File

@ -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)

View File

@ -395,6 +395,17 @@ team = Table(
class ChuniProfileData(BaseData): 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( async def put_profile_data(
self, aime_id: int, version: int, profile_data: Dict self, aime_id: int, version: int, profile_data: Dict
) -> Optional[int]: ) -> Optional[int]:

View File

@ -0,0 +1,43 @@
{% extends "core/templates/index.jinja" %}
{% block content %}
<h1>Chunithm</h1>
{% if profile is defined and profile is not none and profile.id > 0 %}
<script type="text/javascript">
function toggle_new_name_form() {
let frm = document.getElementById("new_name_form");
let btn = document.getElementById("btn_toggle_form");
if (frm.style['display'] != "") {
frm.style['display'] = "";
frm.style['max-height'] = "";
btn.innerText = "Cancel";
} else {
frm.style['display'] = "none";
frm.style['max-height'] = "0px";
btn.innerText = "Edit";
}
}
</script>
<h3>Profile for {{ profile.userName }}&nbsp;<button onclick="toggle_new_name_form()" class="btn btn-secondary" id="btn_toggle_form">Edit</button></h3>
{% if error is defined %}
{% include "core/templates/widgets/err_banner.jinja" %}
{% endif %}
{% if success is defined and success == 1 %}
<div style="background-color: #00AA00; padding: 20px; margin-bottom: 10px; width: 15%;">
Update successful
</div>
{% endif %}
<form style="max-width: 33%; display: none; max-height: 0px;" action="/game/chuni/update.name" method="post" id="new_name_form">
<div class="mb-3">
<label for="new_name" class="form-label">New Trainer Name</label>
<input type="text" class="form-control" id="new_name" name="new_name" aria-describedby="new_name_help" maxlength="14">
<div id="new_name_help" class="form-text">Must be 14 characters or less</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% 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 %}