Files
Andros Fenollosa 7d6197cc17 Translate all UI text and seed data from Spanish to English
- Translate all templates: login, dashboard, expense success, categories
  CRUD, subcategory CRUD, month start page, nav bar, partials
- Translate seed categories: Survival, Leisure & vice, Culture, Extras
  with all subcategories in English
- Translate form placeholders and view titles
- Translate error messages (login, delete confirmations)
- Change LANGUAGE_CODE from "es" to "en-us"
- Change html lang from "es" to "en"
- Format all Python files with Ruff (tabs)
2026-03-12 08:20:59 +01:00

255 lines
5.7 KiB
Python

import re
import traceback
from django.test import Client
from liveview import liveview_handler, send
def _make_client(consumer):
client = Client()
user = consumer.scope.get("user")
if user and user.is_authenticated:
client.force_login(user)
return client
def _extract_main(html):
match = re.search(r"<main[^>]*>(.*?)</main>", html, re.DOTALL)
return match.group(1) if match else None
def _inject_liveview_submit(html, url):
def _replace(match):
attrs = match.group(1)
if "data-liveview-function" not in attrs:
attrs += (
f' data-liveview-function="submit_modal_form"'
f' data-action="submit->page#run"'
f' data-data-url="{url}"'
)
return f"<form{attrs}>"
return re.sub(r"<form([^>]*)>", _replace, html)
def _inject_liveview_submit_page(html, url):
def _replace(match):
attrs = match.group(1)
if "data-liveview-function" not in attrs:
attrs += (
f' data-liveview-function="submit_page_form"'
f' data-action="submit->page#run"'
f' data-data-url="{url}"'
)
return f"<form{attrs}>"
return re.sub(r"<form([^>]*)>", _replace, html)
def _build_modal(inner_html):
return f"""
<div class="modal modal-open">
<div class="modal-box">
{inner_html}
</div>
<div class="modal-backdrop"
data-liveview-function="close_modal"
data-action="click->page#run">
</div>
</div>
"""
def _navigate_to(consumer, client, url):
try:
response = client.get(url, follow=True, SERVER_NAME="localhost")
if response.status_code != 200:
return
html_content = response.content.decode("utf-8")
main_html = _extract_main(html_content)
if not main_html:
return
main_html = _inject_liveview_submit_page(main_html, url)
title_match = re.search(r"<title>(.*?)</title>", html_content)
page_title = title_match.group(1) if title_match else "Kakebo"
send(
consumer,
{
"target": "#main-content",
"html": main_html,
"url": url,
"title": page_title,
},
)
except Exception:
pass
def _preprocess_form_data(raw):
processed = {}
for key, value in raw.items():
if key == "csrfmiddlewaretoken":
continue
if value is True:
processed[key] = "on"
elif value is False:
pass
else:
processed[key] = value
return processed
@liveview_handler("open_modal")
def open_modal(consumer, content):
url = content.get("data", {}).get("data_url", "/")
client = _make_client(consumer)
try:
response = client.get(url, follow=True, SERVER_NAME="localhost")
if response.status_code == 200:
html_content = response.content.decode("utf-8")
main_html = _extract_main(html_content)
if main_html:
main_html = _inject_liveview_submit(main_html, url)
modal_html = _build_modal(main_html)
send(consumer, {"target": "#modal-wrapper", "html": modal_html})
else:
send(
consumer,
{
"target": "#modal-wrapper",
"html": _build_modal(
'<div class="alert alert-error">Could not load content.</div>'
),
},
)
else:
send(
consumer,
{
"target": "#modal-wrapper",
"html": _build_modal(
f'<div class="alert alert-error">Error {response.status_code}</div>'
),
},
)
except Exception as e:
send(
consumer,
{
"target": "#modal-wrapper",
"html": _build_modal(f'<div class="alert alert-error">{e}</div>'),
},
)
@liveview_handler("close_modal")
def close_modal(consumer, content):
send(consumer, {"target": "#modal-wrapper", "html": ""})
@liveview_handler("submit_modal_form")
def submit_modal_form(consumer, content):
url = content.get("data", {}).get("data_url", "/")
raw_form = content.get("form", {})
form_data = _preprocess_form_data(raw_form)
client = _make_client(consumer)
try:
response = client.post(
url, data=form_data, follow=False, SERVER_NAME="localhost"
)
if response.status_code in (301, 302):
redirect_url = response.url
send(consumer, {"target": "#modal-wrapper", "html": ""})
_navigate_to(consumer, client, redirect_url)
elif response.status_code == 200:
html_content = response.content.decode("utf-8")
main_html = _extract_main(html_content)
if main_html:
main_html = _inject_liveview_submit(main_html, url)
modal_html = _build_modal(main_html)
send(consumer, {"target": "#modal-wrapper", "html": modal_html})
else:
send(
consumer,
{
"target": "#modal-wrapper",
"html": _build_modal(
f'<div class="alert alert-error">Error {response.status_code}</div>'
),
},
)
except Exception as e:
send(
consumer,
{
"target": "#modal-wrapper",
"html": _build_modal(
f'<div class="alert alert-error">{e}<br><pre>{traceback.format_exc()}</pre></div>'
),
},
)
@liveview_handler("submit_page_form")
def submit_page_form(consumer, content):
url = content.get("data", {}).get("data_url", "/")
raw_form = content.get("form", {})
form_data = _preprocess_form_data(raw_form)
client = _make_client(consumer)
try:
response = client.post(
url, data=form_data, follow=False, SERVER_NAME="localhost"
)
if response.status_code in (301, 302):
redirect_url = response.url
_navigate_to(consumer, client, redirect_url)
elif response.status_code == 200:
html_content = response.content.decode("utf-8")
main_html = _extract_main(html_content)
if main_html:
main_html = _inject_liveview_submit_page(main_html, url)
send(
consumer,
{
"target": "#main-content",
"html": main_html,
},
)
else:
send(
consumer,
{
"target": "#main-content",
"html": f'<div class="alert alert-error">Error {response.status_code}</div>',
},
)
except Exception as e:
send(
consumer,
{
"target": "#main-content",
"html": f'<div class="alert alert-error">{e}<br><pre>{traceback.format_exc()}</pre></div>',
},
)