feat(panel): panel web multilingüe con caché de traducciones en MySQL y soporte nest-asyncio

This commit is contained in:
2026-03-06 20:53:20 -06:00
parent 0c0a1811ef
commit 05858e26ab
7 changed files with 230 additions and 131 deletions

View File

@@ -10,6 +10,8 @@ from fastapi.responses import RedirectResponse
from pydantic import BaseModel
from botdiscord.config import load_config, get_web_config, get_libretranslate_url, get_db_type
from botdiscord.database import get_ui_translation, save_ui_translation
from botdiscord.translate import translate_text
app = FastAPI(title="Panel de Configuración - Bots de Traducción")
@@ -17,6 +19,45 @@ SCRIPT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
templates = Jinja2Templates(directory=os.path.join(SCRIPT_DIR, "panel", "templates"))
# Filtro de traducción para Jinja2
def translate_filter(text, lang="es"):
if lang == "es" or not text:
return text
# Buscamos en caché de la base de datos (acceso rápido)
from botdiscord.database import get_ui_translation, save_ui_translation
cached = get_ui_translation(text, lang)
if cached:
return cached
# Si no está en caché, traducimos de forma síncrona para la UI
from botdiscord.translate import translate_text_sync
translated = translate_text_sync(text, lang)
if translated and translated != text:
save_ui_translation(text, lang, translated)
return translated
templates.env.filters["translate"] = translate_filter
@app.get("/set-lang/{lang}")
async def set_lang(lang: str, request: Request):
# Validamos que el idioma sea de 2 letras
if len(lang) != 2:
return RedirectResponse(url="/dashboard")
response = RedirectResponse(url=request.headers.get("referer", "/dashboard"))
response.set_cookie(key="panel_lang", value=lang, max_age=31536000) # 1 año
return response
def get_panel_lang(request: Request):
lang = request.cookies.get("panel_lang")
if not lang:
accept_lang = request.headers.get("accept-language", "es")
lang = accept_lang.split(",")[0].split("-")[0]
return lang
class LoginForm(BaseModel):
username: str
password: str