# pan-sync **Repository Path**: reneryan/pan-sync ## Basic Information - **Project Name**: pan-sync - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-25 - **Last Updated**: 2026-04-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Pan-Sync 百度网盘 → 夸克网盘 同步服务 ## 项目简介 Pan-Sync 是一个** Web 化的网盘同步服务**,用于将百度网盘(通过 `bypy`)中的指定目录,周期性增量同步到夸克网盘(通过 `AList` 挂载)。 - **Web 管理界面**:深色主题,实时日志 + 同步历史 + 配置热重载 - **自动 AList 管理**:服务启动/停止 + 健康监控 + 异常自愈 - **并发上传 + 自动重试**:可配置并发数与失败重试次数 - **目录同步**:支持空目录创建与删除同步 - **双击启动**:`start.bat` 一键启动,自动检查依赖、清理端口、打开浏览器 --- ## 技术架构 ``` pan-sync/ ├── src/ │ ├── alist_manager.py # AList 进程生命周期管理 │ ├── baidu_pan.py # 百度网盘(bypy 封装) │ ├── quark_pan.py # 夸克网盘(AList API 封装) │ ├── sync_manager.py # 同步逻辑(比对/上传/删除/重试) │ └── scheduler.py # 周期性调度器(热重载 interval) ├── templates/ │ └── index.html # Web UI(Flask + 原生 JS) ├── config/ │ └── config.ini # 配置文件(百度/夸克/同步参数) ├── download/ # 本地缓存目录(下载文件) ├── alist/data/ # AList 数据目录(固定) ├── runtime/ # 运行时文件(PID/日志) ├── app.py # Flask Web 服务入口 ├── start.bat # 一键启动脚本 ├── stop.bat # 一键停止脚本 └── requirements.txt ``` --- ## 功能特性 | 功能 | 描述 | |------|------| | **Web 管理界面** | 深色主题,实时日志 + 同步历史 + 配置热重载 | | **自动 AList 管理** | 服务启动/停止 + 健康监控(30s检查) + 异常自愈 | | **并发上传** | 可配置并发数(默认 3),线程池管理 | | **自动重试** | 上传失败指数退避重试(默认 3 次) | | **目录同步** | 支持空目录创建与删除同步(从深到浅) | | **热重载** | 修改配置后立即生效(无需重启服务) | | **双击启动** | `start.bat` 一键启动,自动检查依赖、清理端口、打开浏览器 | | **健康检查** | 启动前检查端口占用、清理旧进程、等待服务就绪 | --- ## 快速开始 ### 1. 准备工作 - 安装 Python 3.8+ - 下载 AList(项目已包含 `alist/alist.exe`) - 百度网盘授权:`bypy info`(首次运行需扫码) - AList 配置夸克网盘存储(Web 管理后台) ### 2. 启动服务 **Windows 双击**:`start.bat` **手动启动**: ```bash pip install -r requirements.txt python app.py ``` ### 3. 访问 Web 界面 打开浏览器访问:**http://localhost:7788** --- ## 配置说明 `config/config.ini` 示例: ```ini [BaiduPan] source_dir = /apps/bypy/00-同步测试 [QuarkPan] target_dir = /夸克网盘/00-同步测试 alist_url = http://localhost:5244 alist_token = your_alist_token [Sync] interval = 3600 concurrency = 3 max_retries = 3 ``` | 参数 | 说明 | |------|------| | `source_dir` | 百度网盘源目录(bypy 路径) | | `target_dir` | 夸克网盘目标目录(AList 挂载路径) | | `alist_url` | AList 地址(默认 http://localhost:5244) | | `alist_token` | AList API Token(管理后台获取) | | `interval` | 同步间隔(秒,默认 60) | | `concurrency` | 并发上传数(默认 3) | | `max_retries` | 失败重试次数(默认 3) | --- ## Web 界面功能 ### 顶部状态栏 - **同步状态**:运行中/已停止(带脉冲动画) - **AList 状态**:运行中/启动中/已停止/异常(带颜色指示灯) ### 左侧面板 1. **AList 控制**:启动/停止 AList 服务 2. **同步控制**:启动定时同步 / 停止 / 立即同步 3. **统计面板**:已上传 / 已删除 / 错误数 4. **配置表单**:动态编辑所有配置项(保存即热重载) ### 右侧面板 1. **实时日志**:彩色分类(错误/警告/成功/信息),自动滚动 2. **同步历史**:最近 1000 条记录(时间/状态/类型/上传/建目录/删除/错误) --- ## 技术栈 | 组件 | 技术 | |------|------| | 后端 | Python 3.12 + Flask 3.1 | | 前端 | 原生 HTML/CSS/JS(无框架) | | 百度网盘 | bypy(命令行工具封装) | | 夸克网盘 | AList API(fs/list/fs/put/fs/remove) | | 调度 | threading + Event(热重载 interval) | | 并发 | ThreadPoolExecutor(可配置并发数) | --- ## 注意事项 1. **AList 数据目录**:固定使用 `alist/data/`,避免路径漂移 2. **Token 失效**:AList 重启后 Token 会失效,请及时更新配置 3. **百度路径**:bypy 的根目录是 `/apps/bypy`,请使用完整路径 4. **下载目录**:`download/` 保留目录结构,不自动清理 5. **端口占用**:启动脚本会自动清理 7788 端口占用 --- ## 常见问题 ### Q: AList 启动失败? A: 检查 `alist/alist.exe` 是否存在,或手动运行 `alist server` 查看错误 ### Q: Token 失效? A: 到 AList Web 管理后台重新获取 Token,更新配置后保存即可(热重载) ### Q: 同步显示成功但夸克网盘没有文件? A: 检查 `target_dir` 是否正确指向 AList 挂载点下的目录 ### Q: 如何停止服务? A: 双击 `stop.bat` 或访问 Web 界面点击"停止"按钮 --- ## 更新日志 详见 `README.md` 末尾的会话总结(按日期倒序)。 --- ## 会话总结 2026-03-25(第十次) ### 会话主要目的 清理无用测试文件、生成 `.gitignore`、重新梳理项目结构和功能、更新 README.md。 ### 完成的主要任务 1. **清理测试文件**:删除所有 `test_*.py`、`debug_*.py`、`check_*.py` 等测试脚本 2. **删除无用文件**:`quark_api.py`(未被引用)、`main.py`(已替换为 `app.py`) 3. **生成 `.gitignore`**:忽略 `__pycache__/`、`.venv/`、`config/config.ini`、`data/`、`download/`、`runtime/` 等 4. **重新梳理项目结构**:确认核心模块为 `src/alist_manager.py`、`src/baidu_pan.py`、`src/quark_pan.py`、`src/sync_manager.py`、`src/scheduler.py` 5. **更新 README.md**:重新编写项目简介、技术架构、功能特性、快速开始、配置说明、Web 界面功能、技术栈、注意事项、常见问题 ### 关键决策 - 保留 `app.py` 作为 Web 服务入口,删除 `main.py` - 删除未被引用的 `quark_api.py`(直连夸克 API 备用方案) - 生成 `.gitignore` 确保只提交核心源代码和配置文件 - 重新梳理项目结构,确认所有核心模块 - 更新 README.md 以反映当前项目状态 ### 使用的技术栈 - Python 3.12, Flask 3.1, bypy, AList v3, schedule, requests - 前端:原生 HTML/CSS/JS(无框架) ### 修改的文件 - `.gitignore`(新建) - `README.md`(重新编写) - 删除:`quark_api.py`、`main.py`、`test_*.py`、`debug_*.py`、`check_*.py`、`verify_*.py`、`list_*.py` --- ## 会话总结 2026-03-25(第十三次) ### 会话主要目的 优化大量文件同步时的下载/上传失败与重复执行问题。 ### 完成的主要任务 1. **下载与上传流程拆分** - 在 `sync_manager.py` 中拆分为: - `_download_with_retry()`:只负责下载 - `_upload_with_retry()`:只负责上传 - `_process_file()`:单文件完整流程(下载成功且完整后才上传) - 明确保证:**未完整下载的文件绝不上传**。 2. **下载完整性校验** - 下载完成后检查本地文件是否存在 - 对比百度端期望大小与本地实际大小 - 若大小不一致,判定为“下载不完整”,触发下载重试,不进入上传阶段 3. **本地缓存复用** - 若 `download/` 中已有文件且大小与百度端一致,则直接复用本地文件,不重复下载 4. **并发唯一文件处理** - 对 `to_upload` 做 `set()` 去重并排序 - 每个并发 worker 只处理一个完整文件流程,不会多个并发重复处理相同文件 5. **防止定时任务重叠执行** - `scheduler.py` 新增 `_job_lock` - 若上一次同步尚未结束,本次定时触发直接跳过,并打印提示:`上一次同步仍在执行,跳过本次触发` 6. **额外合理优化** - `bypy` 执行超时从 300 秒提高到 1800 秒,减少大文件/大量文件时的超时误判 7. **校验** - 使用 `py -3 -m py_compile` 校验 `sync_manager.py / scheduler.py / baidu_pan.py`,通过 ### 关键决策和解决方案 - 将“下载重试”和“上传重试”拆开,避免一次失败把两段流程反复混在一起重试,减少无效失败次数。 - 用文件大小作为下载完整性判据,简单直接,适合当前 bypy + AList 架构。 - 用调度锁阻止重叠任务,避免大批量同步未完成时再次启动新一轮同步造成雪崩。 ### 使用的技术栈 - Python threading / Lock - ThreadPoolExecutor 并发控制 - 本地文件大小校验 ### 修改了哪些文件 - `src/sync_manager.py` - `src/scheduler.py` - `src/baidu_pan.py` ---