Spaces:
Running
Running
fix
Browse files
app.py
CHANGED
@@ -3035,6 +3035,54 @@ def send_to_sandbox(code):
|
|
3035 |
iframe = f'<iframe src="{data_uri}" width="100%" height="920px" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-presentation" allow="display-capture"></iframe>'
|
3036 |
return iframe
|
3037 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3038 |
def is_streamlit_code(code: str) -> bool:
|
3039 |
"""Heuristic check to determine if Python code is a Streamlit app."""
|
3040 |
if not code:
|
@@ -3894,10 +3942,14 @@ This will help me create a better design for you."""
|
|
3894 |
|
3895 |
preview_val = None
|
3896 |
if language == "html":
|
3897 |
-
|
3898 |
-
_mpf2 = parse_multipage_html_output(
|
3899 |
_mpf2 = validate_and_autofix_files(_mpf2)
|
3900 |
-
|
|
|
|
|
|
|
|
|
3901 |
elif language == "python" and is_streamlit_code(final_content):
|
3902 |
preview_val = send_streamlit_to_stlite(final_content)
|
3903 |
yield {
|
@@ -4319,7 +4371,7 @@ This will help me create a better design for you."""
|
|
4319 |
yield {
|
4320 |
code_output: clean_content,
|
4321 |
history: _history,
|
4322 |
-
sandbox: ((
|
4323 |
history_output: history_to_chatbot_messages(_history),
|
4324 |
}
|
4325 |
else:
|
@@ -4348,10 +4400,14 @@ This will help me create a better design for you."""
|
|
4348 |
_history.append([query, final_content])
|
4349 |
preview_val = None
|
4350 |
if language == "html":
|
4351 |
-
|
4352 |
-
_mpf = parse_multipage_html_output(
|
4353 |
_mpf = validate_and_autofix_files(_mpf)
|
4354 |
-
|
|
|
|
|
|
|
|
|
4355 |
elif language == "python" and is_streamlit_code(final_content):
|
4356 |
preview_val = send_streamlit_to_stlite(final_content)
|
4357 |
elif language == "gradio" or (language == "python" and is_gradio_code(final_content)):
|
|
|
3035 |
iframe = f'<iframe src="{data_uri}" width="100%" height="920px" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-presentation" allow="display-capture"></iframe>'
|
3036 |
return iframe
|
3037 |
|
3038 |
+
def send_to_sandbox_with_refresh(code):
|
3039 |
+
"""Render HTML in a sandboxed iframe with cache-busting for media generation updates."""
|
3040 |
+
import time
|
3041 |
+
html_doc = (code or "").strip()
|
3042 |
+
# For preview only: inline local file URLs (e.g., file:///.../video.mp4) as data URIs so the
|
3043 |
+
# data: iframe can load them. The original code (shown to the user) still contains file URLs.
|
3044 |
+
try:
|
3045 |
+
import re
|
3046 |
+
import base64 as _b64
|
3047 |
+
import mimetypes as _mtypes
|
3048 |
+
import urllib.parse as _uparse
|
3049 |
+
def _file_url_to_data_uri(file_url: str) -> str | None:
|
3050 |
+
try:
|
3051 |
+
parsed = _uparse.urlparse(file_url)
|
3052 |
+
path = _uparse.unquote(parsed.path)
|
3053 |
+
if not path:
|
3054 |
+
return None
|
3055 |
+
with open(path, 'rb') as _f:
|
3056 |
+
raw = _f.read()
|
3057 |
+
mime = _mtypes.guess_type(path)[0] or 'application/octet-stream'
|
3058 |
+
b64 = _b64.b64encode(raw).decode()
|
3059 |
+
return f"data:{mime};base64,{b64}"
|
3060 |
+
except Exception:
|
3061 |
+
return None
|
3062 |
+
def _repl_double(m):
|
3063 |
+
url = m.group(1)
|
3064 |
+
data_uri = _file_url_to_data_uri(url)
|
3065 |
+
return f'src="{data_uri}"' if data_uri else m.group(0)
|
3066 |
+
def _repl_single(m):
|
3067 |
+
url = m.group(1)
|
3068 |
+
data_uri = _file_url_to_data_uri(url)
|
3069 |
+
return f"src='{data_uri}'" if data_uri else m.group(0)
|
3070 |
+
html_doc = re.sub(r'src="(file:[^"]+)"', _repl_double, html_doc)
|
3071 |
+
html_doc = re.sub(r"src='(file:[^']+)'", _repl_single, html_doc)
|
3072 |
+
except Exception:
|
3073 |
+
# Best-effort; continue without inlining
|
3074 |
+
pass
|
3075 |
+
|
3076 |
+
# Add cache-busting timestamp to force iframe refresh when content changes
|
3077 |
+
timestamp = str(int(time.time() * 1000))
|
3078 |
+
cache_bust_comment = f"<!-- refresh-{timestamp} -->"
|
3079 |
+
html_doc = cache_bust_comment + html_doc
|
3080 |
+
|
3081 |
+
encoded_html = base64.b64encode(html_doc.encode('utf-8')).decode('utf-8')
|
3082 |
+
data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
|
3083 |
+
iframe = f'<iframe src="{data_uri}" width="100%" height="920px" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-presentation" allow="display-capture" key="preview-{timestamp}"></iframe>'
|
3084 |
+
return iframe
|
3085 |
+
|
3086 |
def is_streamlit_code(code: str) -> bool:
|
3087 |
"""Heuristic check to determine if Python code is a Streamlit app."""
|
3088 |
if not code:
|
|
|
3942 |
|
3943 |
preview_val = None
|
3944 |
if language == "html":
|
3945 |
+
# Use full content for multipage detection, then extract for single-page rendering
|
3946 |
+
_mpf2 = parse_multipage_html_output(final_content)
|
3947 |
_mpf2 = validate_and_autofix_files(_mpf2)
|
3948 |
+
if _mpf2 and _mpf2.get('index.html'):
|
3949 |
+
preview_val = send_to_sandbox_with_refresh(inline_multipage_into_single_preview(_mpf2))
|
3950 |
+
else:
|
3951 |
+
safe_preview = extract_html_document(final_content)
|
3952 |
+
preview_val = send_to_sandbox_with_refresh(safe_preview)
|
3953 |
elif language == "python" and is_streamlit_code(final_content):
|
3954 |
preview_val = send_streamlit_to_stlite(final_content)
|
3955 |
yield {
|
|
|
4371 |
yield {
|
4372 |
code_output: clean_content,
|
4373 |
history: _history,
|
4374 |
+
sandbox: ((send_to_sandbox_with_refresh(inline_multipage_into_single_preview(parse_multipage_html_output(clean_content))) if parse_multipage_html_output(clean_content).get('index.html') else send_to_sandbox_with_refresh(clean_content)) if language == "html" else (send_streamlit_to_stlite(clean_content) if (language == "python" and is_streamlit_code(clean_content)) else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>")),
|
4375 |
history_output: history_to_chatbot_messages(_history),
|
4376 |
}
|
4377 |
else:
|
|
|
4400 |
_history.append([query, final_content])
|
4401 |
preview_val = None
|
4402 |
if language == "html":
|
4403 |
+
# Use full content for multipage detection, then extract for single-page rendering
|
4404 |
+
_mpf = parse_multipage_html_output(final_content)
|
4405 |
_mpf = validate_and_autofix_files(_mpf)
|
4406 |
+
if _mpf and _mpf.get('index.html'):
|
4407 |
+
preview_val = send_to_sandbox_with_refresh(inline_multipage_into_single_preview(_mpf))
|
4408 |
+
else:
|
4409 |
+
safe_preview = extract_html_document(final_content)
|
4410 |
+
preview_val = send_to_sandbox_with_refresh(safe_preview)
|
4411 |
elif language == "python" and is_streamlit_code(final_content):
|
4412 |
preview_val = send_streamlit_to_stlite(final_content)
|
4413 |
elif language == "gradio" or (language == "python" and is_gradio_code(final_content)):
|