107 lines
3.8 KiB
Python
Executable File
107 lines
3.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
NaxOS Dashboard Automated Screenshot Utility
|
|
Builds the UI and launches headless Chrome to capture crisp, authentic application screenshots.
|
|
"""
|
|
import subprocess
|
|
import time
|
|
import os
|
|
import shutil
|
|
import sys
|
|
|
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
UI_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
|
|
DIST_DIR = os.path.join(UI_DIR, "dist")
|
|
SCREENSHOTS_DIR = os.path.join(UI_DIR, "public", "screenshots")
|
|
PORT = 4199
|
|
|
|
# Detect Chrome binary
|
|
CHROME_CANDIDATES = [
|
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
"/usr/bin/google-chrome",
|
|
"/usr/bin/chromium-browser",
|
|
"/usr/bin/chromium",
|
|
]
|
|
CHROME_BIN = None
|
|
for candidate in CHROME_CANDIDATES:
|
|
if os.path.exists(candidate):
|
|
CHROME_BIN = candidate
|
|
break
|
|
|
|
if not CHROME_BIN:
|
|
print("Error: Google Chrome / Chromium not found. Please install Chrome to use automated screenshot capture.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
os.makedirs(SCREENSHOTS_DIR, exist_ok=True)
|
|
|
|
# 1. Build UI dist
|
|
print("==> [1/3] Building NaxOS UI production bundle...")
|
|
subprocess.run(["npm", "run", "build"], cwd=UI_DIR, check=True)
|
|
|
|
# 2. Start HTTP server
|
|
print(f"==> [2/3] Serving UI dist at http://localhost:{PORT}...")
|
|
server_proc = subprocess.Popen(
|
|
[sys.executable, "-m", "http.server", str(PORT), "--directory", DIST_DIR],
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL
|
|
)
|
|
|
|
VIEWS = [
|
|
("dashboard-overview.png", "#overview", 1440, 960),
|
|
("system-telemetry.png", "#overview", 1440, 1280),
|
|
("storage-management.png", "#storage", 1440, 1000),
|
|
("app-store.png", "#apps", 1440, 1000),
|
|
("migration-wizard.png", "#wizard", 1440, 960),
|
|
("shares-management.png", "#shares", 1440, 960),
|
|
("gitops-sync.png", "#gitops", 1440, 960),
|
|
("system-logs.png", "#logs", 1440, 960),
|
|
]
|
|
|
|
try:
|
|
time.sleep(1.5)
|
|
print("==> [3/3] Capturing authentic application screenshots via headless Chrome...")
|
|
for filename, hash_route, width, height in VIEWS:
|
|
target_file = os.path.join(SCREENSHOTS_DIR, filename)
|
|
url = f"http://localhost:{PORT}/{hash_route}"
|
|
print(f" Capturing {hash_route:<10} ({width}x{height}) -> {filename}...")
|
|
cmd = [
|
|
CHROME_BIN,
|
|
"--headless=new",
|
|
"--disable-gpu",
|
|
f"--window-size={width},{height}",
|
|
"--virtual-time-budget=3000",
|
|
f"--screenshot={target_file}",
|
|
url
|
|
]
|
|
res = subprocess.run(cmd, capture_output=True, text=True)
|
|
if os.path.exists(target_file):
|
|
size = os.path.getsize(target_file)
|
|
print(f" [OK] {filename} ({size // 1024} KB)")
|
|
else:
|
|
print(f" [FAILED] {filename}: {res.stderr}", file=sys.stderr)
|
|
|
|
# Legacy alias
|
|
telemetry_src = os.path.join(SCREENSHOTS_DIR, "system-telemetry.png")
|
|
perses_dst = os.path.join(SCREENSHOTS_DIR, "perses-analytics.png")
|
|
if os.path.exists(telemetry_src):
|
|
shutil.copyfile(telemetry_src, perses_dst)
|
|
|
|
# Copy to sister documentation repositories if present
|
|
repo_root = os.path.abspath(os.path.join(UI_DIR, ".."))
|
|
for repo in ["naxos-os", "naxos-api", "naxos-docs"]:
|
|
doc_img_dir = os.path.join(repo_root, repo, "docs", "images")
|
|
if os.path.exists(doc_img_dir):
|
|
for filename, _, _, _ in VIEWS:
|
|
src_path = os.path.join(SCREENSHOTS_DIR, filename)
|
|
if os.path.exists(src_path):
|
|
shutil.copyfile(src_path, os.path.join(doc_img_dir, filename))
|
|
if os.path.exists(perses_dst):
|
|
shutil.copyfile(perses_dst, os.path.join(doc_img_dir, "perses-analytics.png"))
|
|
print(f" Synced screenshots to {repo}/docs/images/")
|
|
|
|
finally:
|
|
server_proc.terminate()
|
|
server_proc.wait()
|
|
|
|
print("\nAll NaxOS UI screenshots successfully captured and distributed!")
|