File size: 4,189 Bytes
6ef16db
 
9af1039
6ef16db
9af1039
54e4a6b
9af1039
 
 
 
 
 
 
 
 
 
6ef16db
 
9af1039
 
 
6ef16db
 
9af1039
6ef16db
54e4a6b
6ef16db
9af1039
6ef16db
 
 
 
9af1039
6ef16db
 
54e4a6b
 
 
 
 
 
 
 
 
 
 
 
 
 
9af1039
54e4a6b
 
9af1039
 
 
54e4a6b
9af1039
 
6ef16db
9af1039
6ef16db
9af1039
6ef16db
54e4a6b
 
 
 
 
 
 
 
 
 
 
9af1039
 
6ef16db
54e4a6b
6ef16db
 
 
54e4a6b
9af1039
54e4a6b
9af1039
54e4a6b
9af1039
 
 
6ef16db
 
9af1039
6ef16db
54e4a6b
 
6ef16db
54e4a6b
9af1039
54e4a6b
 
 
 
 
9af1039
 
 
54e4a6b
 
 
 
9af1039
54e4a6b
 
6ef16db
54e4a6b
 
6ef16db
 
 
 
9af1039
54e4a6b
 
 
9af1039
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/bash

# ================= 配置 =================
WEBDAV_URL=${WEBDAV_URL%/}
WEBDAV_BACKUP_PATH=${WEBDAV_BACKUP_PATH:-""}
# 处理子路径
WEBDAV_BACKUP_PATH=${WEBDAV_BACKUP_PATH#/}
WEBDAV_BACKUP_PATH=${WEBDAV_BACKUP_PATH%/}

if [ -n "$WEBDAV_BACKUP_PATH" ]; then
    FULL_WEBDAV_URL="${WEBDAV_URL}/${WEBDAV_BACKUP_PATH}"
else
    FULL_WEBDAV_URL="${WEBDAV_URL}"
fi

SYNC_INTERVAL=${SYNC_INTERVAL:-60}
TARGET_FILENAME="accounts.json"
REMOTE_FILENAME="antigravity_accounts.json"
TEMP_DIR="/tmp/backup_temp"

# =======================================

log() { echo "[Backup] [$(date '+%H:%M:%S')] $1"; }
mkdir -p "$TEMP_DIR"

# 检查环境
if [[ -z "$WEBDAV_URL" ]]; then
    log "未设置 WEBDAV_URL,跳过备份"
    exit 0
fi

if ! command -v curl &> /dev/null; then
    apk add --no-cache curl || (apt-get update && apt-get install -y curl)
fi

# === 核心修复:智能寻找真正活跃的文件 ===
find_active_file() {
    FILE_ROOT="/app/$TARGET_FILENAME"
    FILE_DATA="/app/data/$TARGET_FILENAME"
    
    # 获取文件修改时间戳 (如果文件不存在则为0)
    TIME_ROOT=$(stat -c %Y "$FILE_ROOT" 2>/dev/null || echo 0)
    TIME_DATA=$(stat -c %Y "$FILE_DATA" 2>/dev/null || echo 0)
    
    # 比较哪个文件更新
    if [ "$TIME_ROOT" -gt "$TIME_DATA" ]; then
        echo "$FILE_ROOT"
    elif [ "$TIME_DATA" -gt 0 ]; then
        echo "$FILE_DATA"
    else
        # 如果都没有,尝试用 find 找 (兼容性兜底)
        find /app -name "$TARGET_FILENAME" -type f -not -path "*/node_modules/*" | head -n 1
    fi
}

# === 恢复功能 ===
restore() {
    log "正在从 WebDAV 恢复备份..."
    REMOTE_FILE="$FULL_WEBDAV_URL/$REMOTE_FILENAME"
    TEMP_FILE="$TEMP_DIR/restored.json"
    
    HTTP_CODE=$(curl -s -o "$TEMP_FILE" -w "%{http_code}" -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$REMOTE_FILE")
    
    if [[ "$HTTP_CODE" == "200" ]] && [ -s "$TEMP_FILE" ]; then
        # 恢复策略:只恢复到 /app 根目录
        # 为什么?因为我们确定程序会优先读取根目录,或者在根目录生成
        # 如果程序之前在 data 目录,它找不到 data 里的文件通常会自动回落或重建
        
        DEST_PATH="/app/$TARGET_FILENAME"
        cp "$TEMP_FILE" "$DEST_PATH"
        log "✅ 备份已恢复到: $DEST_PATH"
        
        # 只有当 data 目录已经存在时,才顺便放一份进去,但不强求
        if [ -d "/app/data" ]; then
            cp "$TEMP_FILE" "/app/data/$TARGET_FILENAME"
        fi
    else
        log "📭 未找到远程备份或文件为空,将以新状态启动"
    fi
}

# === 循环备份功能 ===
loop() {
    log "启动智能增量备份 (间隔: ${SYNC_INTERVAL}秒)"
    
    # 尝试创建远程目录
    if [ -n "$WEBDAV_BACKUP_PATH" ]; then
        curl -s -o /dev/null -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -X MKCOL "$FULL_WEBDAV_URL/"
    fi
    
    while true; do
        sleep $SYNC_INTERVAL
        
        # 每次都重新判断哪个文件是最新的
        CURRENT_PATH=$(find_active_file)
        
        if [ -n "$CURRENT_PATH" ] && [ -f "$CURRENT_PATH" ]; then
            FILE_SIZE=$(wc -c < "$CURRENT_PATH")
            
            # 只有大于 10 字节才备份 (避免备份空的 [])
            if [ "$FILE_SIZE" -gt 10 ]; then
                # log "正在备份活跃文件: $CURRENT_PATH (大小: $FILE_SIZE)"
                
                HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "$CURRENT_PATH" "$FULL_WEBDAV_URL/$REMOTE_FILENAME")
                
                if [[ "$HTTP_CODE" != "201" ]] && [[ "$HTTP_CODE" != "204" ]] && [[ "$HTTP_CODE" != "200" ]]; then
                    log "❌ 上传失败: HTTP $HTTP_CODE"
                else
                    # 成功时不刷屏,静默成功
                    : 
                fi
            else
                log "⚠️ 文件过小 ($FILE_SIZE bytes),跳过备份以免覆盖数据"
            fi
        else
            log "等待 accounts.json 生成..."
        fi
    done
}

case "$1" in
    "restore") restore ;;
    "loop") loop ;;
    *) restore; loop ;;
esac