手上有两个云盘:115 网盘存了大量影视资源,123 云盘有不错的带宽和直链能力。日常需求很简单——让 媒体库的文件,可以通过 115 和 123 的通道播放和下载。
很多工具都是之前已经实现的零碎任务,这次结合核心诉求,把下面的问题整合起来:
- 两个平台的 API 风格完全不同,一个 OAuth2 PKCE,一个 clientId + clientSecret
- 文件需要在两边做匹配,靠的是 SHA1 而不是文件名
- 想做增量同步,就得维护一份文件索引
- 生成媒体库的 strm 文件,还要写入远程 NAS
- 最后需要一个下载服务,能把 123 的直链能力用起来
一个个手动操作太累了,于是有了 CloudPanBridge。
架构总览
整个项目分为三层:
1 | ┌─────────────────────────────────────────────┐ |
最底层是 SDK 层,分别封装了两个平台的完整开放 API;中间是 CLI 工具层,把业务逻辑编排成一个个命令;上层是 运维层,靠一个 shell 脚本编排定时任务。
数据库是整个系统的核心枢纽,所有信息流经它串联——文件索引、云盘匹配关系、同步任务状态,全部落库管理。
核心工作流
整个自动化管线按照 1→2→3→4→5 的顺序执行:
1. 文件导出
把云盘上的文件列表完整拉到数据库,这是后续一切操作的基础。
115 的导出做了三阶段设计:先分页拉取文件列表(不拉目录信息),再批量调用目录信息 API 构建路径,最后回填数据库。增量模式下,拉到比上次更新时间更旧的文件就自动停止,效率很高。
123 的导出用了 UPSERT 批量写入(5000 条一批),支持并发扫描子目录,还有指数退避的限流保护。回收站里的文件自动跳过。
这部分在代码里是最复杂的——要处理分页、限流、断点续传、增量同步、多用户隔离。
2. 重复文件检测
同一目录下,通过文件大小 + SHA1(或 MD5、ETag)判断重复。特别针对网盘场景做了 --detect-suffix 支持——匹配文件名末尾的 (1) 或 (1) 这类后缀,配合 --delete 可以安全批量清理。
3. 跨云盘匹配
匹配逻辑没有在 Python 里做循环,而是直接生成 SQL,在数据库服务端完成 JOIN:
1 | SELECT f115.*, f123.* |
匹配结果通过临时表 + 单条 UPDATE 批量写入,100 万级数据分分钟搞定(1C1G的垃圾服务器)。全程数据库服务端计算,Python 只收结果,内存零压力。
4. 生成 strm 文件
为媒体播放器生成 .strm 文件(本质是一个指向 HTTP URL 的文本文件),内容形如:
1 | http://172.16.16.170:8808/sha1/{sha1}/size/{size}/{encoded_name} |
支持两种模式:本地写入和远程 SFTP 写入。我用的是 --ssh-password 参数直接写入 NAS 上的目录。47 万个文件,8 线程并行写入,大约 8 分钟跑完。
5. 同步与下载服务
同步(115 → 123) 基于 123 云盘的 SHA1 秒传接口,文件不需要下载再上传,服务端直接复制。大文件优先处理,已匹配的文件自动跳过。并发数通过 -c 参数控制。
下载服务 基于 FastAPI + uvicorn 构建,支持两种模式:
- 302 重定向模式:查询直链后 302 跳转,服务端不接触文件数据
- 代理缓存模式(
--proxy):文件边下边转,支持 HTTP Range 断点续传,缓存到本地磁盘
代理模式做了一些有意思的优化:
1 | # 多线程分段下载:123 的文件用 2 个线程同时拉 |
最妙的是 SHA1 秒传兜底机制——所有常规下载路径都失败时,自动触发 123 的 SHA1 秒传接口完成兜底,并更新数据库关联供后续复用。
技术亮点
双数据库后端的优雅抽象
项目同时支持 SQLite 和 MySQL,但不是用 ORM,而是自己做了抽象层:
1 | DatabaseBackend (抽象基类) |
环境变量一键切换:
1 | export CLOUDPAN_DB_TYPE=mysql |
Mark-and-Sweep 增量清理
每次导出生成唯一的 sync_id,写入每条记录时标记 last_sync_id = sync_id。导出完成后,清理该云盘下 last_sync_id != sync_id 的记录——这就是云盘上已被删除的文件。增量模式下不执行清理,防止误删。
授权管理
115 用的是 PKCE 扫码授权(比传统授权码模式更安全),Token 刷新后旧的立即作废。123 则是 clientId + clientSecret 直接获取 access_token,30 天有效期。缓存统一存放在 ~/.cloudpan/auth_cache.json。
生产部署
日常运维通过一个 shell 脚本编排:
1 | # 每 4 小时:导出 → 去重 → 匹配 → 生成 strm |
脚本加了日志、PID 管理、命令可用性检测,放在 crontab 里基本不用管。
项目结构
1 | CloudPanBridge/ |
platform_115 和 platform_123 是纯粹的 SDK 封装,cli/ 目录才是真正的业务逻辑所在。这种分层让 SDK 可以独立复用——即使不用这套自动化管线,单纯想调 115 或 123 的 API,也可以直接 pip install 后 import 使用。
写在最后
这个项目不是一个大而全的框架,而是一组解决具体问题的工具集合。每个命令单独拿出来都能用,组合起来就形成了一条完整的自动化管线。
如果你也有类似的场景——管理多个云盘、做媒体库自动化、或者单纯想研究网盘 API 的封装方式,希望对你有参考价值。

