import os import zipfile import subprocess import base64 import sys import pathlib import gradio as gr ZIP_FILE = "newtons-cradle-simulation.zip" APP_DIR = "app" BUILD_DIR = os.path.join(APP_DIR, "dist") # vite default output POSSIBLE_INDEXES = [ os.path.join(BUILD_DIR, "index.html"), os.path.join(APP_DIR, "build", "index.html"), os.path.join(APP_DIR, "public", "index.html"), ] def run_cmd(cmd, cwd=None): try: res = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, check=False) print(f"CMD: {' '.join(cmd)} (cwd={cwd})") print("returncode:", res.returncode) if res.stdout: print("--- stdout ---") print(res.stdout) if res.stderr: print("--- stderr ---", file=sys.stderr) print(res.stderr, file=sys.stderr) return res.returncode == 0 except Exception as e: print("Exception running command:", e, file=sys.stderr) return False # 1) Распаковка архива (если ещё не распаковано) if not os.path.exists(APP_DIR): if not os.path.exists(ZIP_FILE): raise FileNotFoundError(f"Zip file not found in repo root: {ZIP_FILE}") with zipfile.ZipFile(ZIP_FILE, "r") as z: z.extractall(APP_DIR) print(f"Archive extracted to '{APP_DIR}'") else: print(f"App dir '{APP_DIR}' already exists (runtime).") # 2) npm install if os.path.exists(APP_DIR): run_cmd(["npm", "install"], cwd=APP_DIR) else: print("Skipping npm install: app dir missing") # 3) npm run build if os.path.exists(APP_DIR): run_cmd(["npm", "run", "build"], cwd=APP_DIR) else: print("Skipping npm run build: app dir missing") # 4) найти index.html index_path = None for p in POSSIBLE_INDEXES: if os.path.exists(p): index_path = p break if index_path is None: # fallback: try to find any index.html under app dir for p in pathlib.Path(APP_DIR).rglob("index.html"): index_path = str(p) break if index_path is None: raise RuntimeError("index.html not found after build. Проверь структуру сборки в логах.") print("Using index:", index_path) # 5) прочитать и встроить в iframe через data: URL with open(index_path, "rb") as f: html_bytes = f.read() b64 = base64.b64encode(html_bytes).decode("ascii") data_url = f"data:text/html;base64,{b64}" with gr.Blocks() as demo: gr.Markdown("### Newtons pendulum — встроенное приложение (build → dist/index.html)") gr.HTML(f'') # 6) Запуск Gradio demo.launch()