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"]*>(.*?)", 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"" return re.sub(r"]*)>", _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"" return re.sub(r"]*)>", _replace, html) def _build_modal(inner_html): return f""" """ 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"(.*?)", 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( '
Could not load content.
' ), }, ) else: send( consumer, { "target": "#modal-wrapper", "html": _build_modal( f'
Error {response.status_code}
' ), }, ) except Exception as e: send( consumer, { "target": "#modal-wrapper", "html": _build_modal(f'
{e}
'), }, ) @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'
Error {response.status_code}
' ), }, ) except Exception as e: send( consumer, { "target": "#modal-wrapper", "html": _build_modal( f'
{e}
{traceback.format_exc()}
' ), }, ) @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'
Error {response.status_code}
', }, ) except Exception as e: send( consumer, { "target": "#main-content", "html": f'
{e}
{traceback.format_exc()}
', }, )