From 76527188031bf5f37fb9a351d017341034020379 Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Thu, 16 Apr 2026 13:54:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=95=B0=E6=8D=AE=E5=BA=93=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E6=9C=BA=E5=88=B6=20v2.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增备份管理 API 和页面 - 自动备份:每天 04:00 执行 - 手动备份:页面一键备份 - 备份清理规则: - 保留最近 30 天 - 每月第一天永久保留 - 手动备份最多保留 10 个 - 支持恢复和删除备份 --- scripts/auto_backup.py | 35 ++++++++ xian_favor/api.py | 174 ++++++++++++++++++++++++++++++++++++++ xian_favor/db.py | 185 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 393 insertions(+), 1 deletion(-) create mode 100755 scripts/auto_backup.py diff --git a/scripts/auto_backup.py b/scripts/auto_backup.py new file mode 100755 index 0000000..7f47e5a --- /dev/null +++ b/scripts/auto_backup.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +""" +Xian Favor 自动备份脚本 +定时任务调用此脚本进行自动备份 +""" + +import sys +import os + +# 添加项目路径 +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from xian_favor.db import db + +def main(): + """执行自动备份""" + print(f"[{datetime.now().isoformat()}] 开始自动备份...") + + try: + backup_info = db.create_backup(manual=False) + print(f"备份成功: {backup_info['name']}") + print(f"大小: {backup_info['size']} bytes") + print(f"位置: {backup_info['path']}") + + # 清理旧备份 + db._cleanup_old_backups() + print("旧备份清理完成") + + except Exception as e: + print(f"备份失败: {e}") + sys.exit(1) + +if __name__ == '__main__': + from datetime import datetime + main() \ No newline at end of file diff --git a/xian_favor/api.py b/xian_favor/api.py index 6fe0e15..4696b13 100644 --- a/xian_favor/api.py +++ b/xian_favor/api.py @@ -511,6 +511,44 @@ def send_email(): return jsonify({'success': False, 'error': f'发送失败: {str(e)}'}), 500 +# ============ 备份管理 API ============ + +@app.route('/api/backups', methods=['GET']) +def list_backups(): + """列出所有备份""" + backups = db.list_backups() + return jsonify({'success': True, 'data': backups}) + + +@app.route('/api/backups', methods=['POST']) +def create_backup(): + """创建手动备份""" + try: + backup_info = db.create_backup(manual=True) + return jsonify({'success': True, 'data': backup_info}), 201 + except Exception as e: + return jsonify({'success': False, 'error': str(e)}), 500 + + +@app.route('/api/backups/', methods=['POST']) +def restore_backup(backup_name): + """恢复备份""" + try: + if db.restore_backup(backup_name): + return jsonify({'success': True, 'message': f'已恢复备份 {backup_name}'}) + return jsonify({'success': False, 'error': '备份不存在'}), 404 + except Exception as e: + return jsonify({'success': False, 'error': str(e)}), 500 + + +@app.route('/api/backups/', methods=['DELETE']) +def delete_backup(backup_name): + """删除备份""" + if db.delete_backup(backup_name): + return jsonify({'success': True}) + return jsonify({'success': False, 'error': '备份不存在'}), 404 + + # ============ Web 页面 ============ @app.route('/') @@ -579,6 +617,7 @@ INDEX_TEMPLATE = '''
标签管理 邮箱管理 + 备份管理 @@ -954,6 +993,41 @@ INDEX_TEMPLATE = ''' + + +