chore: add reliable local business run scripts

This commit is contained in:
kris
2026-03-21 02:59:52 +08:00
parent c09a976628
commit 39216d18b4
7 changed files with 156 additions and 54 deletions

View File

@@ -1,7 +1,6 @@
#!/bin/sh
set -eu
cd /Users/kris/code/StoryForge/collector-service
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --host 0.0.0.0 --port 8081 --reload
ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
"$ROOT/scripts/start_business.sh"

39
scripts/cleanup_debug_ui.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/bin/sh
set -eu
PORT="${1:-3618}"
SCRIPT_PATH="/Users/kris/code/StoryForge-gitea/scripts/douyin-browser-capture/control_panel.mjs"
lsof -tiTCP:"$PORT" -sTCP:LISTEN | xargs -r kill || true
osascript -e 'tell application "Terminal"' \
-e 'if it is running then' \
-e 'repeat with w in windows' \
-e 'set shouldClose to false' \
-e 'repeat with t in tabs of w' \
-e 'try' \
-e 'set tabText to contents of t' \
-e 'if tabText contains "'"$SCRIPT_PATH"'" then set shouldClose to true' \
-e 'end try' \
-e 'end repeat' \
-e 'if shouldClose then close w saving no' \
-e 'end repeat' \
-e 'end if' \
-e 'end tell' >/dev/null 2>&1 || true
for app in "Google Chrome" "Brave Browser" "Arc" "Safari"; do
osascript -e 'try' \
-e 'tell application "'"$app"'"' \
-e 'repeat with w in windows' \
-e 'repeat with i from (count of tabs of w) to 1 by -1' \
-e 'try' \
-e 'set tabUrl to URL of tab i of w' \
-e 'if tabUrl contains "127.0.0.1:'"$PORT"'" then close tab i of w' \
-e 'end try' \
-e 'end repeat' \
-e 'end repeat' \
-e 'end tell' \
-e 'end try' >/dev/null 2>&1 || true
done
echo "debug ui cleaned: port $PORT"

39
scripts/start_business.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/bin/sh
set -eu
ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
COMPOSE_FILE="$ROOT/docker-compose.yml"
cd "$ROOT"
docker compose -f "$COMPOSE_FILE" up -d --build collector n8n
python3 - <<'PY'
import time
import urllib.request
checks = [
("collector", "http://127.0.0.1:8081/healthz"),
("n8n", "http://127.0.0.1:5670/healthz"),
]
deadline = time.time() + 45
pending = dict(checks)
while pending and time.time() < deadline:
for name, url in list(pending.items()):
try:
with urllib.request.urlopen(url, timeout=5) as resp:
print(f"{name} ready: {resp.status}")
pending.pop(name, None)
except Exception:
pass
if pending:
time.sleep(1)
if pending:
print("startup timeout:", ", ".join(pending))
raise SystemExit(1)
PY
echo "business started"
echo "collector: http://127.0.0.1:8081/healthz"
echo "n8n: http://127.0.0.1:5670/healthz"

View File

@@ -1,25 +1,28 @@
#!/bin/sh
set -eu
ROOT="/Users/kris/code/StoryForge"
PID_FILE="$ROOT/data/collector/collector.pid"
LOG_FILE="$ROOT/data/collector/collector.log"
VENV="$ROOT/collector-service/.venv311"
mkdir -p "$ROOT/data/collector"
if [ ! -x "$VENV/bin/python" ]; then
/opt/homebrew/bin/python3.11 -m venv "$VENV"
. "$VENV/bin/activate"
pip install -q -r "$ROOT/collector-service/requirements.txt"
else
. "$VENV/bin/activate"
fi
if [ -f "$PID_FILE" ]; then
PID="$(cat "$PID_FILE" || true)"
if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
echo "collector already running: $PID"
exit 0
fi
fi
cd "$ROOT/collector-service"
nohup "$VENV/bin/python" -m uvicorn app.main:app --host 0.0.0.0 --port 8081 >"$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
echo "collector started: $(cat "$PID_FILE")"
ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
COMPOSE_FILE="$ROOT/docker-compose.yml"
cd "$ROOT"
docker compose -f "$COMPOSE_FILE" up -d --build collector
python3 - <<'PY'
import time
import urllib.request
url = "http://127.0.0.1:8081/healthz"
deadline = time.time() + 30
last_error = ""
while time.time() < deadline:
try:
with urllib.request.urlopen(url, timeout=5) as resp:
print(f"collector ready: {resp.status} {resp.read().decode('utf-8', 'ignore')[:160]}")
raise SystemExit(0)
except Exception as exc:
last_error = str(exc)
time.sleep(1)
print(f"collector start timeout: {last_error}")
raise SystemExit(1)
PY

22
scripts/status_business.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/sh
set -eu
ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
COMPOSE_FILE="$ROOT/docker-compose.yml"
cd "$ROOT"
docker compose -f "$COMPOSE_FILE" ps
echo "---"
python3 - <<'PY'
import urllib.request
for name, url in [
("collector", "http://127.0.0.1:8081/healthz"),
("n8n", "http://127.0.0.1:5670/healthz"),
]:
try:
with urllib.request.urlopen(url, timeout=5) as resp:
print(f"{name}: {resp.status} {resp.read().decode('utf-8', 'ignore')[:200]}")
except Exception as exc:
print(f"{name}: ERROR {exc}")
PY

View File

@@ -1,15 +1,21 @@
#!/bin/sh
set -eu
PID_FILE="/Users/kris/code/StoryForge/data/collector/collector.pid"
if [ -f "$PID_FILE" ]; then
PID="$(cat "$PID_FILE" || true)"
if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
echo "running:$PID"
exit 0
fi
fi
if lsof -nP -iTCP:8081 -sTCP:LISTEN >/dev/null 2>&1; then
echo "running:port"
else
echo "stopped"
fi
ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
COMPOSE_FILE="$ROOT/docker-compose.yml"
cd "$ROOT"
docker compose -f "$COMPOSE_FILE" ps collector
echo "---"
python3 - <<'PY'
import urllib.request
url = "http://127.0.0.1:8081/healthz"
try:
with urllib.request.urlopen(url, timeout=5) as resp:
print(f"collector health: {resp.status}")
print(resp.read().decode("utf-8", "ignore")[:400])
except Exception as exc:
print(f"collector health error: {exc}")
raise SystemExit(1)
PY

View File

@@ -1,15 +1,9 @@
#!/bin/sh
set -eu
PID_FILE="/Users/kris/code/StoryForge/data/collector/collector.pid"
if [ ! -f "$PID_FILE" ]; then
echo "collector not running"
exit 0
fi
PID="$(cat "$PID_FILE" || true)"
if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
kill "$PID"
echo "collector stopped: $PID"
else
echo "collector pid stale: $PID"
fi
rm -f "$PID_FILE"
ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
COMPOSE_FILE="$ROOT/docker-compose.yml"
cd "$ROOT"
docker compose -f "$COMPOSE_FILE" stop collector
echo "collector stopped"