Skip to content

powerfullz/netdisk-backup-util

Repository files navigation

netdisk-backup-util

Working In Progress....

这个仓库内置了一个通过 OpenAPI Generator 生成的百度网盘(xpan)Python SDK(目录 openapi_client/)。

目前提供一个可直接运行的示例:

  • 通过 Device Code(设备码) 完成 OAuth 登录,拿到 access_token/refresh_token
  • 通过 precreate -> upload -> create 上传一个文件到网盘

为什么推荐设备码登录?

  • 命令行/脚本/服务器环境更方便
  • 不需要搭建回调地址(redirect_uri)

1) 准备:创建百度网盘应用

在百度网盘开放平台创建应用并获取:

  • API Key(对应本项目 BAIDU_APP_KEY
  • Secret Key(对应本项目 BAIDU_SECRET_KEY

同时确认你的应用已开通/申请了需要的权限(scope),本示例默认使用:

  • basic,netdisk

2) 配置:填写 .env

项目根目录已提供 .env 占位(不要把真实密钥提交到 git):

  • BAIDU_APP_KEY
  • BAIDU_SECRET_KEY
  • BAIDU_APP_NAME

关于 BAIDU_APP_NAME

  • 上传路径会写到 /apps/<APP_NAME>/...
  • 这是百度网盘给第三方应用的“沙盒目录”风格路径

3) 登录:Device Code 获取 token

运行登录:

  • python main.py login

脚本会打印:

  • verification_url:在浏览器打开
  • user_code:在页面输入并授权
  • (可选)qrcode_url:二维码授权

授权成功后,会在项目根目录写入 token 缓存文件(默认 .token.json,可用 BAIDU_TOKEN_CACHE 改路径)。

4) 上传:上传一个本地文件

运行上传:

  • python main.py upload --local demo/uploadtestdata/a.txt --remote a.txt

可选参数:

  • --concurrency:分片并发上传数(默认 3)。

说明:

  • --local 是本地文件路径
  • --remote 如果是相对路径(例如 a.txt),脚本会自动拼成:
    • /apps/<BAIDU_APP_NAME>/a.txt
  • 如果你直接传绝对路径(以 / 开头),脚本会按原样使用

上传流程对应百度网盘 xpan 的标准三步:

  1. xpanfileprecreate:预上传,得到 uploadid
  2. pcssuperfile2:按 4MB 分片上传(小文件也按单分片处理)
  3. xpanfilecreate:合并分片并创建最终文件

并发说明:

  • 并发指同时上传多个分片(例如 --concurrency 3 表示同一时间最多 3 个分片并行上传)。
  • 不是“一个分片用多个线程上传”。每个分片对应一次上传请求。

4.1) 加密上传与解密

本工具支持 AES-128 分片加密上传,以及 文件名/路径加密(混淆)

准备:在 .env 设置加密密码:

  • FILE_ENCRYPTION_PASSWORD

加密上传(仅内容加密):

  • python main.py upload --local demo/uploadtestdata/a.txt --remote a.txt --encrypt

加密上传(内容与文件名同时加密):

  • python main.py upload --local demo/uploadtestdata/a.txt --remote a.txt --encrypt --encrypt-filename

解密文件/目录:

  • python main.py decrypt --input a.txt.encrypted
  • python main.py decrypt --input /path/to/encrypted_dir --delete-source

说明:

  • 启用了文件名加密的文件在网盘中会以 NDB64_ 开头命名。
  • 解密时若提供密码,程序会自动尝试还原混淆后的原始文件名。
  • 加密过程采用确定性算法,同一密码下同一原始文件名始终映射到相同的加密名,确保增量备份正常运行。

Go 解密器(高性能)

目录:decryptor/

构建:

  • go build

用法(单文件):

  • decryptor -i <input.encrypted> -p <password>
  • decryptor -i <input.encrypted> -o <output> -p <password>
  • decryptor -i <input.encrypted> -p <password> -d

用法(目录递归):

  • decryptor -i <input_dir> -p <password> -r
  • decryptor -i <input_dir> -o <output_dir> -p <password> -r
  • decryptor -i <input_dir> -p <password> -r -d

说明:

  • -o 可选,省略时默认输出到源目录。
  • 目录模式仅处理 .encrypted 文件,并保持相对路径结构。
  • 若提供了正确的密码,Go 解密器同样支持还原被混淆(加密)的文件名。
  • -d 会在解密成功后删除源文件。

4.2) 目录监控自动上传(inotify)

准备:使用 JSON 配置文件(推荐)

启动监控:

  • JSON 配置(默认读取):python main.py watch
  • JSON 配置(显式指定):python main.py watch --config backup_plan.json
  • 单目录(可选):python main.py watch --dir D:/Backup/Photos

JSON 配置示例:

{
	"watch": [
		{
			"local": "D:/Backup/Photos",
			"remote": "photos",
			"exclude": ["./photos/thumbnails"],
			"encrypt": true,
			"encrypt_filename": true
		}
	]
}

说明:

  • local:本地目录(必填)
  • remote:远端相对路径(可选)。为空时默认使用目录名作为远端根
  • exclude:排除路径(可选,支持文件或目录;相对 local 的路径)
  • encrypt:是否加密文件内容(针对该目录)
  • encrypt_filename:是否加密文件名(针对该目录)
  • 远端路径会保持本地相对路径结构,根目录对应 /apps/<BAIDU_APP_NAME>/...
  • 新建文件:自动上传
  • 修改文件:自动覆盖(同路径)
  • 删除文件:忽略

可选参数:

  • --concurrency:分片并发上传数(默认 3)。

4.3) 一致性校验(check)

用于手动对账本地与远端文件一致性(不上传、不删除),适合周期性巡检。

运行示例:

  • 使用 JSON 配置:python main.py check --config backup_plan.json
  • 单目录模式:python main.py check --dir D:/Backup/Photos --remote photos

启用 checksum 校验(优先使用远端 md5 字段):

  • python main.py check --config backup_plan.json --checksum

说明:

  • 校验使用百度网盘 fileinfo 接口的返回字段(如 size/server_mtime/md5)。
  • 若远端未返回 md5 字段,会回退为 size + server_mtime 的一致性判断。
  • 启用 --encrypt 时会按 .encrypted 规则对账。
  • 启用 --encrypt-filename 时会自动进行文件名解密后比对。
  • 如果启用 --checksum,会对加密后的字节流与远端 MD5 做校验。
  • 不修改状态文件,旧状态文件不受影响(平滑兼容)。

5) Docker Compose 运行(推荐)

准备:

  • .env 填写:BAIDU_APP_KEYBAIDU_SECRET_KEYBAIDU_APP_NAME
  • 如需加密上传,添加 FILE_ENCRYPTION_PASSWORD
  • 准备待监控目录(默认挂载 ./watch
  • 根据需要调整 backup_plan.json(容器内映射到 /app/backup_plan.json

启动:

  • docker compose up -d

查看日志:

  • docker compose logs -f

停止:

  • docker compose down

说明:

  • 容器工作目录为 /app
  • ./data 会挂载到 /app/data,token 与状态文件可持久化
  • 监控目录挂载到 /watch(可在 docker-compose.yml 调整)
  • 如需加密上传,将 docker-compose.ymlcommand 改为 ["watch", "--encrypt"]

6) 常见问题排查

7) 测试

默认测试入口:

  • python -m unittest

也可显式发现并运行:

  • python -m unittest discover -s tests -p "test_*.py"

401 / invalid_access_token

  • access_token 过期:脚本会优先用 refresh_token 自动刷新
  • refresh_token 也失效:重新运行 python main.py login

precreate 返回 errno != 0

  • 检查 --remote 路径是否符合第三方应用目录规则(一般要在 /apps/<appname>/ 下)
  • 检查 scope 是否包含 netdisk

上传分片失败

  • 网络问题:重试通常可恢复
  • 文件过大:默认分片 4MB,脚本通过 --chunk-size 可调整(一般不建议改)

About

加密备份本地内容到百度网盘。

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors