234 lines
5.9 KiB
Python
234 lines
5.9 KiB
Python
from fastapi import APIRouter, Request
|
|
from fastapi.responses import HTMLResponse
|
|
import json
|
|
import os
|
|
|
|
router = APIRouter()
|
|
|
|
# Load deployment config
|
|
deployment_config = None
|
|
_translations_cache = {}
|
|
|
|
def load_config():
|
|
"""Load configuration files on startup."""
|
|
global deployment_config
|
|
|
|
config_path = os.path.join('deployment_config.json')
|
|
|
|
with open(config_path) as f:
|
|
deployment_config = json.load(f)
|
|
|
|
def load_characters(lang: str = "de"):
|
|
"""Load character data for given language."""
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
characters_path = os.path.join('static', 'data', f'characters.{lang}.json')
|
|
try:
|
|
with open(characters_path) as f:
|
|
return json.load(f)
|
|
except FileNotFoundError:
|
|
# Fallback to German
|
|
with open(os.path.join('static', 'data', 'characters.de.json')) as f:
|
|
return json.load(f)
|
|
|
|
def load_translations(lang: str = "de"):
|
|
"""Load translation JSON for given language with caching."""
|
|
global _translations_cache
|
|
|
|
# Default to German if language not supported
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
# Check cache first
|
|
if lang not in _translations_cache:
|
|
translation_path = os.path.join('i18n', f'{lang}.json')
|
|
try:
|
|
with open(translation_path) as f:
|
|
_translations_cache[lang] = json.load(f)
|
|
except FileNotFoundError:
|
|
# Fallback to German if translation file not found
|
|
with open(os.path.join('i18n', 'de.json')) as f:
|
|
_translations_cache[lang] = json.load(f)
|
|
|
|
return _translations_cache[lang]
|
|
|
|
# Load on module import
|
|
load_config()
|
|
|
|
@router.get("/", response_class=HTMLResponse)
|
|
async def home_index(req: Request, lang: str = None):
|
|
"""
|
|
Public home page - no auth required.
|
|
"""
|
|
# Get language from query param or session
|
|
if lang is None:
|
|
lang = req.session.get("lang", "de")
|
|
|
|
# Validate lang
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
|
|
|
|
req.session["lang"] = lang
|
|
translations = load_translations(lang)
|
|
|
|
return req.app.state.render(
|
|
req,
|
|
"home/index.html",
|
|
deployment=deployment_config,
|
|
t=translations,
|
|
lang=lang
|
|
)
|
|
|
|
@router.get("/about", response_class=HTMLResponse)
|
|
async def home_about(req: Request, lang: str = None):
|
|
"""
|
|
About / Mission page.
|
|
"""
|
|
if lang is None:
|
|
lang = req.session.get("lang", "de")
|
|
|
|
# Validate lang
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
req.session["lang"] = lang
|
|
translations = load_translations(lang)
|
|
|
|
return req.app.state.render(
|
|
req,
|
|
"home/about.html",
|
|
deployment=deployment_config,
|
|
t=translations,
|
|
lang=lang
|
|
)
|
|
|
|
@router.get("/crew", response_class=HTMLResponse)
|
|
async def home_crew(req: Request, lang: str = None):
|
|
"""
|
|
Crew / Characters page.
|
|
"""
|
|
if lang is None:
|
|
lang = req.session.get("lang", "de")
|
|
|
|
# Validate lang
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
req.session["lang"] = lang
|
|
translations = load_translations(lang)
|
|
|
|
# Load roles from central config (15 roles)
|
|
from services.config_loader import ConfigLoader
|
|
from services.localization import merge_role_localization
|
|
|
|
config = ConfigLoader.load_config()
|
|
# Merge localized content using service
|
|
characters = merge_role_localization(config.get('roles', {}), lang)
|
|
|
|
user = req.session.get("user")
|
|
|
|
return req.app.state.render(
|
|
req,
|
|
"home/crew.html",
|
|
deployment=deployment_config,
|
|
roles=characters,
|
|
t=translations,
|
|
lang=lang,
|
|
user=user
|
|
)
|
|
|
|
@router.get("/hardware", response_class=HTMLResponse)
|
|
async def home_hardware(req: Request, lang: str = None):
|
|
"""
|
|
Hardware information page.
|
|
"""
|
|
if lang is None:
|
|
lang = req.session.get("lang", "de")
|
|
|
|
# Validate lang
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
req.session["lang"] = lang
|
|
translations = load_translations(lang)
|
|
|
|
return req.app.state.render(
|
|
req,
|
|
"home/hardware.html",
|
|
deployment=deployment_config,
|
|
t=translations,
|
|
lang=lang
|
|
)
|
|
|
|
@router.get("/software", response_class=HTMLResponse)
|
|
async def home_software(req: Request, lang: str = None):
|
|
"""
|
|
Software information page.
|
|
"""
|
|
if lang is None:
|
|
lang = req.session.get("lang", "de")
|
|
|
|
# Validate lang
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
req.session["lang"] = lang
|
|
translations = load_translations(lang)
|
|
|
|
return req.app.state.render(
|
|
req,
|
|
"home/software.html",
|
|
deployment=deployment_config,
|
|
t=translations,
|
|
lang=lang
|
|
)
|
|
|
|
@router.get("/impressum", response_class=HTMLResponse)
|
|
async def home_impressum(req: Request, lang: str = None):
|
|
"""
|
|
Impressum / Legal notice page.
|
|
"""
|
|
if lang is None:
|
|
lang = req.session.get("lang", "de")
|
|
|
|
# Validate lang
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
req.session["lang"] = lang
|
|
translations = load_translations(lang)
|
|
|
|
return req.app.state.render(
|
|
req,
|
|
"home/impressum.html",
|
|
deployment=deployment_config,
|
|
t=translations,
|
|
lang=lang
|
|
)
|
|
|
|
@router.get("/datenschutz", response_class=HTMLResponse)
|
|
async def home_datenschutz(req: Request, lang: str = None):
|
|
"""
|
|
Privacy policy / Datenschutz page.
|
|
"""
|
|
if lang is None:
|
|
lang = req.session.get("lang", "de")
|
|
|
|
# Validate lang
|
|
if lang not in ["de", "en", "fr"]:
|
|
lang = "de"
|
|
|
|
req.session["lang"] = lang
|
|
translations = load_translations(lang)
|
|
|
|
return req.app.state.render(
|
|
req,
|
|
"home/datenschutz.html",
|
|
deployment=deployment_config,
|
|
t=translations,
|
|
lang=lang
|
|
)
|