#!/usr/bin/env bash set -euo pipefail LOCK_FILE="/var/lock/poke_radar.lock" exec 9>"$LOCK_FILE" flock -n 9 || { echo "⏳ 上一個執行尚未完成,略過這次"; exit 0; } # === 計時開始 === START_TS=$(date +%s) echo "🚀 [$(date +%T)] 開始抓取..." # === 設定參數 === WORKDIR="/opt/pokemon-radar-api" DEST_HOST="192.168.42.104" DEST_PATH="/opt/caddy/www/pokemon/spots.json" SRC_FILE="pokemon_data.json" LAST_FILE="last_pokemon_data.json" LAT=25.0478 LNG=121.5170 ZOOM=11 STATE_FILE="state.json" # === 進入工作目錄 === cd "$WORKDIR" # === 執行 Python 抓取 (加上 timeout 保護) === # 設定 300秒 (5分鐘) 強制超時,避免卡死 if timeout 300s /root/.local/bin/uv run pokemon_location_fetcher.py \ --script twpk_radar.mjs \ --lat "$LAT" --lng "$LNG" --zoom "$ZOOM" \ --state "$STATE_FILE" \ --ua-from-state \ --min-remaining 300; then echo "✅ Python 執行成功" else EXIT_CODE=$? if [ $EXIT_CODE -eq 124 ]; then echo "💀 Python 執行逾時 (被 timeout 強制終止)" else echo "❌ Python 執行失敗 (Code: $EXIT_CODE)" fi exit 1 fi # === 檢查是否成功生成資料 === if [[ ! -s "$SRC_FILE" ]]; then echo "❌ 找不到或空的 $SRC_FILE,停止傳送。" exit 1 fi # === 優化:檢查內容是否有變更 === if [[ ! -f "$LAST_FILE" ]]; then touch "$LAST_FILE"; fi if cmp -s "$SRC_FILE" "$LAST_FILE"; then echo "💤 資料未變動,跳過上傳。" else echo "📦 資料有更新,準備傳送..." # 傳送到遠端伺服器 if scp -q -o ConnectTimeout=5 "$SRC_FILE" "$DEST_HOST:$DEST_PATH"; then echo "🎉 傳送完成!" cp "$SRC_FILE" "$LAST_FILE" else echo "⚠️ 傳送失敗,請檢查網路。" fi fi # === 計時結束 === END_TS=$(date +%s) DURATION=$((END_TS - START_TS)) echo "🏁 [$(date +%T)] 全部完成 (耗時: ${DURATION} 秒)"