Spaces:
Running
Running
| 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'<iframe src="{data_url}" width="100%" height="800" style="border:none;"></iframe>') | |
| # 6) Запуск Gradio | |
| demo.launch() | |