- 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)
255 lines
5.7 KiB
Python
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>',
|
|
},
|
|
)
|