autotrain/scripts/restart_web_ui.sh
xinxin6623 7a01ed4db9 feat: add invoice batch wrap-up (name extraction + roster annotation) and web ui automation improvements
- add scripts/annotate_roster_invoices.py: match passenger names to invoice PDFs, write status + relative encoded hyperlinks into roster xlsx
- add scripts/add_invoice_passenger_name.py, scripts/calibrate.py
- add .opencode/skills/invoice-wrapup skill
- improve invoice_tool.py / web_ui.py / vision_fallback.py automation
- add device/screen/windows adaptation docs
- ignore out/ (delivered invoice PDFs contain sensitive data)
2026-07-10 00:11:45 +08:00

104 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PORT="${WEB_UI_PORT:-8765}"
LOG_FILE="$ROOT_DIR/work/web_ui.log"
PID_FILE="$ROOT_DIR/work/web_ui.pid"
WATCHDOG_PID_FILE="$ROOT_DIR/work/web_ui_watchdog.pid"
LABEL="com.james.autotrain.web-ui"
LAUNCHD_TARGET="gui/$(id -u)/$LABEL"
mkdir -p "$ROOT_DIR/work"
echo "[web-ui] project: $ROOT_DIR"
launchctl bootout "gui/$(id -u)" "$HOME/Library/LaunchAgents/$LABEL.plist" >/dev/null 2>&1 || true
if [[ -f "$WATCHDOG_PID_FILE" ]]; then
WATCHDOG_PID="$(cat "$WATCHDOG_PID_FILE" 2>/dev/null || true)"
if [[ -n "$WATCHDOG_PID" ]] && kill -0 "$WATCHDOG_PID" 2>/dev/null; then
echo "[web-ui] stopping old watchdog -> $WATCHDOG_PID"
kill "$WATCHDOG_PID" 2>/dev/null || true
sleep 1
fi
fi
WATCHDOG_PIDS="$(pgrep -f "$ROOT_DIR/scripts/web_ui_watchdog.sh" 2>/dev/null || true)"
if [[ -n "$WATCHDOG_PIDS" ]]; then
echo "[web-ui] stopping stray watchdog(s) -> $WATCHDOG_PIDS"
kill $WATCHDOG_PIDS 2>/dev/null || true
sleep 1
fi
SERVER_PIDS="$(pgrep -f "$ROOT_DIR/scripts/web_ui.py" 2>/dev/null || true)"
if [[ -n "$SERVER_PIDS" ]]; then
echo "[web-ui] stopping stray server(s) -> $SERVER_PIDS"
kill $SERVER_PIDS 2>/dev/null || true
sleep 1
fi
PIDS="$(lsof -tiTCP:"$PORT" -sTCP:LISTEN 2>/dev/null || true)"
if [[ -n "$PIDS" ]]; then
echo "[web-ui] stopping old listener on :$PORT -> $PIDS"
kill $PIDS 2>/dev/null || true
sleep 1
fi
PIDS="$(lsof -tiTCP:"$PORT" -sTCP:LISTEN 2>/dev/null || true)"
if [[ -n "$PIDS" ]]; then
echo "[web-ui] force stopping old listener on :$PORT -> $PIDS"
kill -9 $PIDS 2>/dev/null || true
sleep 1
fi
cd "$ROOT_DIR"
echo "[web-ui] starting watchdog..."
ROOT_DIR="$ROOT_DIR" LOG_FILE="$LOG_FILE" python3 - <<'PY'
import os
import pathlib
import subprocess
import sys
root = pathlib.Path(os.environ["ROOT_DIR"])
log_path = pathlib.Path(os.environ["LOG_FILE"])
watchdog_path = root / "scripts" / "web_ui_watchdog.sh"
pid = os.fork()
if pid > 0:
sys.exit(0)
os.setsid()
pid = os.fork()
if pid > 0:
sys.exit(0)
os.chdir(root)
log = open(log_path, "ab", buffering=0)
os.dup2(log.fileno(), 1)
os.dup2(log.fileno(), 2)
subprocess.Popen([str(watchdog_path)], cwd=str(root), stdout=log, stderr=log, start_new_session=True)
PY
WATCHDOG_PID="$(cat "$WATCHDOG_PID_FILE" 2>/dev/null || echo starting)"
for _ in {1..30}; do
if lsof -tiTCP:"$PORT" -sTCP:LISTEN >/dev/null 2>&1; then
if curl -fsS --max-time 2 "http://127.0.0.1:$PORT/" >/dev/null; then
echo "[web-ui] ready: http://127.0.0.1:$PORT"
echo "[web-ui] watchdog pid: $WATCHDOG_PID"
echo "[web-ui] server pid: $(cat "$PID_FILE" 2>/dev/null || echo unknown)"
echo "[web-ui] log: $LOG_FILE"
exit 0
fi
fi
WATCHDOG_PID="$(cat "$WATCHDOG_PID_FILE" 2>/dev/null || echo "")"
if [[ -z "$WATCHDOG_PID" ]] || ! kill -0 "$WATCHDOG_PID" 2>/dev/null; then
echo "[web-ui] watchdog exited early. log: $LOG_FILE" >&2
tail -80 "$LOG_FILE" >&2 || true
exit 1
fi
sleep 0.2
done
echo "[web-ui] startup timeout. log: $LOG_FILE" >&2
tail -80 "$LOG_FILE" >&2 || true
exit 1