|
#!/bin/bash |
|
|
|
|
|
echo "===== Application Startup at $(date '+%Y-%m-%d %H:%M:%S') =====" |
|
echo "===== 应用程序启动于 $(date '+%Y-%m-%d %H:%M:%S') =====" |
|
echo "调试信息:" |
|
echo "WEBDAV_URL: $WEBDAV_URL" |
|
echo "WEBDAV_USERNAME: $WEBDAV_USERNAME" |
|
echo "WEBDAV_PASSWORD: $WEBDAV_PASSWORD" |
|
echo "SYNC_INTERVAL: $SYNC_INTERVAL" |
|
|
|
|
|
if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then |
|
echo "缺少必要的环境变量 WEBDAV_URL、WEBDAV_USERNAME 或 WEBDAV_PASSWORD" |
|
exit 1 |
|
fi |
|
|
|
|
|
mkdir -p ./data |
|
|
|
|
|
upload_with_verification() { |
|
local source_file="$1" |
|
local target_url="$2" |
|
local max_retries=3 |
|
local retry_count=0 |
|
local success=false |
|
|
|
while [ $retry_count -lt $max_retries ] && [ "$success" = false ]; do |
|
|
|
local local_md5=$(md5sum "$source_file" | cut -d' ' -f1) |
|
echo "本地文件 MD5: $local_md5" |
|
|
|
|
|
if curl -L -f --connect-timeout 30 --max-time 600 \ |
|
-T "$source_file" \ |
|
--user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" \ |
|
"$target_url"; then |
|
|
|
|
|
sleep 5 |
|
|
|
|
|
local remote_md5=$(curl -s -L --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" \ |
|
"$target_url" | md5sum | cut -d' ' -f1) |
|
echo "远程文件 MD5: $remote_md5" |
|
|
|
if [ "$local_md5" = "$remote_md5" ]; then |
|
echo "MD5校验通过" |
|
success=true |
|
break |
|
else |
|
echo "MD5校验失败,准备重试..." |
|
retry_count=$((retry_count + 1)) |
|
if [ $retry_count -lt $max_retries ]; then |
|
echo "等待30秒后进行第 $((retry_count + 1)) 次重试..." |
|
sleep 30 |
|
fi |
|
fi |
|
else |
|
echo "上传失败,准备重试..." |
|
retry_count=$((retry_count + 1)) |
|
if [ $retry_count -lt $max_retries ]; then |
|
echo "等待30秒后进行第 $((retry_count + 1)) 次重试..." |
|
sleep 30 |
|
fi |
|
fi |
|
done |
|
|
|
if [ "$success" = true ]; then |
|
return 0 |
|
else |
|
return 1 |
|
fi |
|
} |
|
|
|
|
|
clean_remote_files() { |
|
echo "正在清理 TeraCloud 网盘中的旧文件..." |
|
|
|
RESPONSE=$(curl -s -L -X PROPFIND --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -H "Depth: 1" "$WEBDAV_URL") |
|
if [ -z "$RESPONSE" ]; then |
|
echo "无法获取 WebDAV 文件列表" |
|
return |
|
fi |
|
|
|
|
|
FILE_LIST=$(echo "$RESPONSE" | xmlstarlet sel -N d="DAV:" -t -v "//d:href/text()" 2>/dev/null | sed 's|.*/||') |
|
if [ -z "$FILE_LIST" ]; then |
|
echo "未找到文件" |
|
return |
|
fi |
|
|
|
|
|
TIMESTAMPED_FILES=$(echo "$FILE_LIST" | grep -E '^webui_[0-9]{2}_[0-9]{2}_[0-9]{4}\.db$') |
|
if [ -z "$TIMESTAMPED_FILES" ]; then |
|
echo "未找到带有时间戳的文件,跳过清理" |
|
return |
|
fi |
|
|
|
|
|
SORTED_FILES=$(echo "$TIMESTAMPED_FILES" | sort -r) |
|
|
|
|
|
COUNT=0 |
|
for FILE in $SORTED_FILES; do |
|
COUNT=$((COUNT + 1)) |
|
if [ $COUNT -gt 1 ]; then |
|
echo "删除旧文件: $FILE" |
|
curl -X DELETE --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/$FILE" || { |
|
echo "删除失败: $FILE" |
|
} |
|
else |
|
echo "保留最新文件: $FILE" |
|
fi |
|
done |
|
echo "TeraCloud 网盘清理完成" |
|
} |
|
|
|
|
|
clean_remote_files |
|
|
|
|
|
echo "正在从 WebDAV 下载数据库文件..." |
|
if ! curl -L -f --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/webui.db" -o "./data/webui.db"; then |
|
echo "下载失败,脚本退出" |
|
exit 1 |
|
fi |
|
echo "下载成功" |
|
|
|
|
|
sync_data() { |
|
|
|
SYNC_INTERVAL=${SYNC_INTERVAL:-7200} |
|
echo "初始下载完成,等待 ${SYNC_INTERVAL} 秒后开始同步..." |
|
sleep $SYNC_INTERVAL |
|
|
|
while true; do |
|
echo "正在开始同步" |
|
if [ -f "./data/webui.db" ]; then |
|
|
|
if command -v sqlite3 &> /dev/null; then |
|
echo "执行 SQLite WAL checkpoint 以确保数据一致性..." |
|
sqlite3 "./data/webui.db" "PRAGMA wal_checkpoint(TRUNCATE);" |
|
else |
|
echo "未找到 sqlite3 命令,跳过 SQLite WAL checkpoint." |
|
fi |
|
|
|
|
|
TIMESTAMP=$(date +%s) |
|
TEMP_FILE="./data/webui_temp_${TIMESTAMP}.db" |
|
if ! cp "./data/webui.db" "$TEMP_FILE"; then |
|
echo "复制数据库文件失败,跳过本次同步" |
|
continue |
|
fi |
|
|
|
|
|
FILENAME="webui_$(date +'%m_%d_%H%M').db" |
|
echo "同步到 WebDAV: $FILENAME" |
|
|
|
|
|
if upload_with_verification "$TEMP_FILE" "$WEBDAV_URL/$FILENAME"; then |
|
echo "文件 $FILENAME 上传成功" |
|
|
|
|
|
if upload_with_verification "$TEMP_FILE" "$WEBDAV_URL/webui.db"; then |
|
echo "主文件 webui.db 更新成功" |
|
else |
|
echo "主文件 webui.db 更新失败" |
|
fi |
|
else |
|
echo "文件 $FILENAME 上传失败" |
|
fi |
|
|
|
|
|
rm -f "$TEMP_FILE" |
|
|
|
|
|
clean_remote_files |
|
|
|
|
|
echo "清理本地旧备份..." |
|
find "./data" -name "webui_*.db" -type f -printf "%T@ %p\n" | \ |
|
sort -rn | tail -n +4 | cut -d' ' -f2- | xargs rm -f |
|
echo "本地备份清理完成" |
|
else |
|
echo "未找到 webui.db 文件,跳过同步" |
|
fi |
|
|
|
echo "当前时间 $(date '+%Y-%m-%d %H:%M:%S')" |
|
echo "等待 ${SYNC_INTERVAL} 秒后进行下一次同步..." |
|
sleep $SYNC_INTERVAL |
|
done |
|
} |
|
|
|
|
|
sync_data & |