111 lines
4 KiB
Python
111 lines
4 KiB
Python
"""
|
|
Hermes Hub — Task A21 Screenshot Capture Script
|
|
Captures high-resolution (1440x920) screenshots for all 4 new screens:
|
|
1. Analytics (Аналитика)
|
|
2. Health / Readiness (Состояние)
|
|
3. Logs (Журнал событий)
|
|
4. Settings (Настройки)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import socket
|
|
import subprocess
|
|
import sys
|
|
import threading
|
|
import time
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
sys.path.insert(0, str(REPO_ROOT / "src"))
|
|
|
|
import uvicorn
|
|
from antigravity_provider.router.web.server import app
|
|
from antigravity_provider.router.unified_health import EventLogService
|
|
|
|
ARTIFACTS_DIR = REPO_ROOT / "artifacts" / "a21-screenshots"
|
|
ARTIFACTS_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
CHROME_PATHS = [
|
|
r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
|
|
r"C:\Program Files\Google\Chrome\Application\chrome.exe",
|
|
r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",
|
|
r"C:\Program Files\Microsoft\Edge\Application\msedge.exe",
|
|
]
|
|
|
|
|
|
def get_free_port() -> int:
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
s.bind(("127.0.0.1", 0))
|
|
return s.getsockname()[1]
|
|
|
|
|
|
def seed_event_logs():
|
|
svc = EventLogService.get()
|
|
svc.log("system", "Hermes Hub запущен в нативном режиме Windows.", level="info")
|
|
svc.log("account", "Обновлены квоты для 22 аккаунтов (Antigravity, Codex, Grok, Claude, OpenCode).", level="info")
|
|
svc.log("routing", "Основной маршрут 'coder-primary' переключен на ag-w1.", level="info")
|
|
svc.log("quota", "Превышен лимит запросов для резервного профиля codex-2.", level="warning", details="HTTP 429 Too Many Requests от OpenAI API")
|
|
svc.log("system", "Фоновая синхронизация конфигурации завершена успешно.", level="info")
|
|
svc.log("routing", "Автоматический failover: 'reviewer' переведён на claude-main.", level="warning", details="Таймаут первичного узла grok-fast")
|
|
|
|
|
|
def main():
|
|
seed_event_logs()
|
|
|
|
port = get_free_port()
|
|
config = uvicorn.Config(app, host="127.0.0.1", port=port, log_level="warning")
|
|
server = uvicorn.Server(config)
|
|
|
|
t = threading.Thread(target=server.run, daemon=True)
|
|
t.start()
|
|
time.sleep(1.0)
|
|
|
|
chrome_exe = None
|
|
for p in CHROME_PATHS:
|
|
if os.path.isfile(p):
|
|
chrome_exe = p
|
|
break
|
|
if not chrome_exe:
|
|
raise RuntimeError("No Chrome/Edge executable found")
|
|
|
|
temp_profile = REPO_ROOT / "artifacts" / "temp_chrome_profile_a21"
|
|
temp_profile.mkdir(parents=True, exist_ok=True)
|
|
|
|
scenarios = [
|
|
("01_analytics_view.png", f"http://127.0.0.1:{port}/index.html?view=analytics"),
|
|
("02_health_view.png", f"http://127.0.0.1:{port}/index.html?view=health"),
|
|
("03_logs_view.png", f"http://127.0.0.1:{port}/index.html?view=logs"),
|
|
("04_settings_view.png", f"http://127.0.0.1:{port}/index.html?view=settings"),
|
|
]
|
|
|
|
captured = 0
|
|
for filename, url in scenarios:
|
|
out_file = ARTIFACTS_DIR / filename
|
|
cmd = [
|
|
chrome_exe,
|
|
"--headless=new",
|
|
"--disable-gpu",
|
|
"--no-sandbox",
|
|
"--hide-scrollbars",
|
|
"--virtual-time-budget=2500",
|
|
f"--user-data-dir={temp_profile}",
|
|
"--window-size=1440,920",
|
|
f"--screenshot={out_file}",
|
|
url,
|
|
]
|
|
print(f"Capturing: {filename}...")
|
|
subprocess.run(cmd, capture_output=True, timeout=15)
|
|
if out_file.is_file() and out_file.stat().st_size > 1000:
|
|
print(f" [OK] Saved {out_file.name} ({out_file.stat().st_size // 1024} KB)")
|
|
captured += 1
|
|
else:
|
|
print(f" [FAIL] Could not generate {out_file.name}")
|
|
|
|
server.should_exit = True
|
|
print(f"\nCaptured {captured}/{len(scenarios)} screenshots in {ARTIFACTS_DIR}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|