Stage Engine web interface assets at runtime

This commit is contained in:
2025-10-26 03:37:05 -06:00
parent 021ba436f7
commit 1fe349af85
2 changed files with 64 additions and 2 deletions

View File

@@ -8,9 +8,11 @@ legacy server defaults by binding to ``0.0.0.0:5001`` and honouring the
from __future__ import annotations from __future__ import annotations
import logging
import os import os
import shutil
from pathlib import Path from pathlib import Path
from typing import Any, Dict from typing import Any, Dict, Set
from .server import EngineContext, create_app from .server import EngineContext, create_app
@@ -19,6 +21,10 @@ DEFAULT_HOST = "0.0.0.0"
DEFAULT_PORT = 5001 DEFAULT_PORT = 5001
def _project_root() -> Path:
return Path(__file__).resolve().parents[2]
def _build_runtime_config() -> Dict[str, Any]: def _build_runtime_config() -> Dict[str, Any]:
return { return {
"HOST": os.environ.get("BOREALIS_ENGINE_HOST", DEFAULT_HOST), "HOST": os.environ.get("BOREALIS_ENGINE_HOST", DEFAULT_HOST),
@@ -29,6 +35,55 @@ def _build_runtime_config() -> Dict[str, Any]:
} }
def _stage_web_interface_assets(logger: logging.Logger) -> None:
project_root = _project_root()
engine_web_root = project_root / "Engine" / "web-interface"
legacy_source = project_root / "Data" / "Server" / "WebUI"
package_json = engine_web_root / "package.json"
src_dir = engine_web_root / "src"
if package_json.is_file() and src_dir.is_dir():
return
if not legacy_source.is_dir():
logger.warning(
"Legacy WebUI source missing; unable to stage Engine web interface from %s",
legacy_source,
)
return
engine_web_root.mkdir(parents=True, exist_ok=True)
preserved: Set[str] = {".gitignore", "README.md"}
for child in engine_web_root.iterdir():
if child.name in preserved:
continue
if child.is_dir():
shutil.rmtree(child, ignore_errors=True)
else:
try:
child.unlink()
except FileNotFoundError:
continue
for item in legacy_source.iterdir():
destination = engine_web_root / item.name
if item.is_dir():
shutil.copytree(item, destination, dirs_exist_ok=True)
else:
shutil.copy2(item, destination)
if not package_json.is_file() or not src_dir.is_dir():
raise RuntimeError(
f"Failed to stage Engine web interface assets into {engine_web_root}"
)
logger.info(
"Engine web interface staged from %s to %s", legacy_source, engine_web_root
)
def _ensure_tls_material(context: EngineContext) -> None: def _ensure_tls_material(context: EngineContext) -> None:
"""Ensure TLS certificate material exists, updating the context if created.""" """Ensure TLS certificate material exists, updating the context if created."""
@@ -96,6 +151,12 @@ def main() -> None:
config = _build_runtime_config() config = _build_runtime_config()
app, socketio, context = create_app(config) app, socketio, context = create_app(config)
try:
_stage_web_interface_assets(context.logger)
except Exception as exc:
context.logger.error("Failed to stage Engine web interface: %s", exc)
raise
host = config.get("HOST", DEFAULT_HOST) host = config.get("HOST", DEFAULT_HOST)
port = int(config.get("PORT", DEFAULT_PORT)) port = int(config.get("PORT", DEFAULT_PORT))

View File

@@ -65,8 +65,9 @@ def _ensure_parent(path: Path) -> None:
def _resolve_static_folder() -> str: def _resolve_static_folder() -> str:
candidate_roots = [ candidate_roots = [
ENGINE_DIR.parent / "Engine" / "web-interface", PROJECT_ROOT / "Engine" / "web-interface",
ENGINE_DIR / "web-interface", ENGINE_DIR / "web-interface",
PROJECT_ROOT / "Data" / "Server" / "web-interface",
] ]
candidates = [] candidates = []