#!/bin/bash set -e WEBDAV_URL="${WEBDAV_URL}" WEBDAV_USERNAME="${WEBDAV_USERNAME}" WEBDAV_PASSWORD="${WEBDAV_PASSWORD}" DB_PATH="${DB_PATH:-/app/db}" BACKUP_PATH="${BACKUP_PATH:-/app/backup}" BACKUP_FILENAME="${BACKUP_FILENAME:-tgdrive_db_backup.tar.gz}" REMOTE_BACKUP_DIR="${REMOTE_BACKUP_DIR:-tgdrive_backup}" CONFIG_FILE="/app/config/sync_config" PYTHON_CMD="/app/venv/bin/python3" mkdir -p ${BACKUP_PATH} mkdir -p /app/logs log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> /app/logs/sync.log 2>/dev/null || true echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" } mkdir -p /app/logs 2>/dev/null || true touch /app/logs/sync.log 2>/dev/null || true if [ ! -f "$CONFIG_FILE" ]; then log "创建初始配置文件" mkdir -p /app/config 2>/dev/null || true echo "LAST_SYNC=0" > "$CONFIG_FILE" 2>/dev/null || true fi if [ -f "$CONFIG_FILE" ]; then source "$CONFIG_FILE" 2>/dev/null || true fi if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then log "错误: WebDAV配置不完整,请设置WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD环境变量" exit 1 fi backup_db() { log "开始备份数据库..." if [ -d "$DB_PATH" ]; then if [[ "$DB_PATH" == "/app/db" ]]; then tar -czf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /app db else tar -czf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C $(dirname "$DB_PATH") $(basename "$DB_PATH") fi log "数据库已备份到 ${BACKUP_PATH}/${BACKUP_FILENAME}" return 0 else log "警告: 数据库目录不存在" return 1 fi } upload_to_webdav() { log "开始上传备份到WebDAV (目标目录: ${REMOTE_BACKUP_DIR})..." $PYTHON_CMD -c " import webdav3.client as wc import os options = { 'webdav_hostname': '$WEBDAV_URL', 'webdav_login': '$WEBDAV_USERNAME', 'webdav_password': '$WEBDAV_PASSWORD', 'webdav_timeout': 30 } client = wc.Client(options) # 检查远程目录是否存在 if not client.check('$REMOTE_BACKUP_DIR'): client.mkdir('$REMOTE_BACKUP_DIR') # 上传文件 local_path = '${BACKUP_PATH}/${BACKUP_FILENAME}' remote_path = '$REMOTE_BACKUP_DIR/${BACKUP_FILENAME}' if os.path.exists(local_path): try: client.upload_sync(remote_path=remote_path, local_path=local_path) print('上传成功') except Exception as e: print(f'上传失败: {e}') else: print('本地备份文件不存在') " if [ $? -eq 0 ]; then log "备份已成功上传到WebDAV (${REMOTE_BACKUP_DIR}/${BACKUP_FILENAME})" echo "LAST_SYNC=$(date +%s)" > "$CONFIG_FILE" return 0 else log "上传到WebDAV失败" return 1 fi } download_from_webdav() { log "开始从WebDAV下载备份 (源目录: ${REMOTE_BACKUP_DIR})..." $PYTHON_CMD -c " import webdav3.client as wc import os options = { 'webdav_hostname': '$WEBDAV_URL', 'webdav_login': '$WEBDAV_USERNAME', 'webdav_password': '$WEBDAV_PASSWORD', 'webdav_timeout': 30 } client = wc.Client(options) # 检查远程文件是否存在 remote_path = '$REMOTE_BACKUP_DIR/${BACKUP_FILENAME}' local_path = '${BACKUP_PATH}/${BACKUP_FILENAME}' if client.check(remote_path): try: client.download_sync(remote_path=remote_path, local_path=local_path) print('下载成功') except Exception as e: print(f'下载失败: {e}') else: print('远程备份文件不存在') " if [ $? -eq 0 ]; then log "备份已成功从WebDAV (${REMOTE_BACKUP_DIR}/${BACKUP_FILENAME}) 下载" return 0 else log "从WebDAV下载备份失败" return 1 fi } restore_db() { log "开始恢复数据库到 ${DB_PATH}..." if [ -f "${BACKUP_PATH}/${BACKUP_FILENAME}" ]; then if [ -d "$DB_PATH" ] && [ "$(ls -A $DB_PATH 2>/dev/null)" ]; then local timestamp=$(date +%Y%m%d%H%M%S) if [[ "$DB_PATH" == "/app/db" ]]; then tar -czf "${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz" -C /app db else tar -czf "${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz" -C $(dirname "$DB_PATH") $(basename "$DB_PATH") fi log "当前数据库已备份到 ${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz" fi rm -rf "$DB_PATH" mkdir -p "$DB_PATH" if [[ "$DB_PATH" == "/app/db" ]]; then tar -xzf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /app else mkdir -p /tmp/tgdrive_restore tar -xzf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /tmp/tgdrive_restore cp -r /tmp/tgdrive_restore/db/* "$DB_PATH"/ rm -rf /tmp/tgdrive_restore fi log "数据库已成功恢复到 ${DB_PATH}" return 0 else log "错误: 备份文件不存在,无法恢复数据库" return 1 fi } case "$1" in backup) backup_db && upload_to_webdav ;; restore) download_from_webdav && restore_db ;; sync) current_time=$(date +%s) download_from_webdav if { [ ! -d "$DB_PATH" ] || [ ! "$(ls -A $DB_PATH 2>/dev/null)" ]; } && [ -f "${BACKUP_PATH}/${BACKUP_FILENAME}" ]; then log "检测到本地数据库不存在或为空,开始恢复..." restore_db fi backup_db && upload_to_webdav ;; *) echo "用法: $0 {backup|restore|sync}" echo " backup - 备份数据库并上传到WebDAV" echo " restore - 从WebDAV下载备份并恢复数据库" echo " sync - 同步数据库(双向)" exit 1 ;; esac exit 0