Download sync_data.sh from zx2323/webx: direct link, hf CLI and curl.
- Browser
- Download file 6.81 kB
-
https://huggingface.co/spaces/zx2323/webx/resolve/main/sync_data.sh
- Command line
-
hf download hf://spaces/zx2323/webx/sync_data.sh
-
curl -L -o sync_data.sh https://huggingface.co/spaces/zx2323/webx/resolve/main/sync_data.sh
6.81 kB
| # 打印环境变量以进行调试 | |
| 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 | |
| # 定义上传函数,包含MD5校验和重试逻辑 | |
| 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 | |
| # 计算源文件的MD5 | |
| 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 | |
| # 获取远程文件的MD5 | |
| 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 | |
| } | |
| # 定义函数:清理 TeraCloud 网盘中的旧文件 | |
| clean_remote_files() { | |
| echo "正在清理 TeraCloud 网盘中的旧文件..." | |
| # 发送 PROPFIND 请求列出 WebDAV 文件 | |
| RESPONSE=$(curl -s -L -X PROPFIND --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -H "Depth: 1" "$WEBDAV_URL") | |
| if [ -z "$RESPONSE" ]; then | |
| echo "无法获取 WebDAV 文件列表" | |
| return | |
| fi | |
| # 使用 xmlstarlet 解析 XML 响应,提取文件名 | |
| 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 网盘清理完成" | |
| } | |
| # 在第一次运行时清理 TeraCloud 网盘中的旧文件 | |
| clean_remote_files | |
| # 从 WebDAV 下载 webui.db 文件 | |
| 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 | |
| # 检查是否安装了 sqlite3 命令,如果安装了,执行 WAL checkpoint | |
| 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 上传成功" | |
| # 更新主文件 webui.db | |
| 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 | |
| # 清理本地旧文件(保留最新3个) | |
| 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 & |