115 lines
4.9 KiB
Markdown
115 lines
4.9 KiB
Markdown
---
|
||
description: 百度备份 - 打包当前项目所有文件并上传到百度网盘指定目录
|
||
---
|
||
|
||
# 上传项目到百度网盘
|
||
|
||
用户提供百度网盘目标目录路径(如 `/2026/0517`),将当前工作区所有文件打包为 zip 并上传。
|
||
|
||
## 百度网盘凭证
|
||
|
||
- AppID: 121939687
|
||
- AppKey: z3gemBZfg7KYj6U3eHNfIzTs7uYS9OMh
|
||
- SecretKey: ptCKj2DfxL0KtGR1pM08c9KO2t2UC7SR
|
||
- Token缓存文件: ~/.baidu_pan_token.json
|
||
|
||
## 步骤
|
||
|
||
1. 获取用户输入的百度网盘目标目录,如 `/2026/0517`。如果用户未输入,使用当前日期生成默认路径 `/年份/月日`。
|
||
|
||
2. 打包当前工作区根目录的 **所有文件**(包括二进制、配置、文档等),仅排除 `.git` 目录。用友好进度展示:
|
||
// turbo
|
||
```bash
|
||
cd <工作区父目录> && zip -r /tmp/<项目名>.zip <项目文件夹名> -x "<项目文件夹名>/.git/*" 2>&1 | tail -1 && ls -lh /tmp/<项目名>.zip | awk '{print "✅ 打包完成:", $5}'
|
||
```
|
||
|
||
3. **检查 Token 缓存**:读取 `~/.baidu_pan_token.json`,检查是否有有效的 access_token(未过期)。
|
||
- 如果文件存在且 token 未过期(当前时间 < expires_at):直接使用缓存的 access_token,**跳过步骤 4-5 的授权流程**。
|
||
- 如果文件存在但 token 已过期:使用 refresh_token 刷新:
|
||
// turbo
|
||
```bash
|
||
curl -s -X POST "https://openapi.baidu.com/oauth/2.0/token" \
|
||
-d "grant_type=refresh_token&refresh_token=<cached_refresh_token>&client_id=z3gemBZfg7KYj6U3eHNfIzTs7uYS9OMh&client_secret=ptCKj2DfxL0KtGR1pM08c9KO2t2UC7SR"
|
||
```
|
||
刷新成功后更新缓存文件,跳过步骤 4-5。
|
||
- 如果文件不存在或刷新失败:执行步骤 4-5 进行设备授权。
|
||
|
||
4. (仅首次或刷新失败时)获取百度网盘设备授权码:
|
||
// turbo
|
||
```bash
|
||
curl -s -X POST "https://openapi.baidu.com/oauth/2.0/device/code" \
|
||
-d "response_type=device_code&client_id=z3gemBZfg7KYj6U3eHNfIzTs7uYS9OMh&scope=basic,netdisk"
|
||
```
|
||
告知用户授权地址和用户码,等待确认。
|
||
|
||
5. (仅首次或刷新失败时)用户确认授权后,获取 access_token:
|
||
// turbo
|
||
```bash
|
||
curl -s -X POST "https://openapi.baidu.com/oauth/2.0/token" \
|
||
-d "grant_type=device_token&code=<device_code>&client_id=z3gemBZfg7KYj6U3eHNfIzTs7uYS9OMh&client_secret=ptCKj2DfxL0KtGR1pM08c9KO2t2UC7SR"
|
||
```
|
||
获取成功后,将 access_token、refresh_token、expires_at(当前时间+expires_in秒)保存到 `~/.baidu_pan_token.json`:
|
||
```json
|
||
{"access_token":"xxx","refresh_token":"xxx","expires_at":1234567890}
|
||
```
|
||
|
||
6. **创建远程目录**(确保目标目录存在):
|
||
// turbo
|
||
```bash
|
||
curl -s "https://pan.baidu.com/rest/2.0/xpan/file?method=create&access_token=<access_token>" \
|
||
-d "path=<目标目录>&size=0&isdir=1"
|
||
```
|
||
忽略目录已存在的错误(errno=-8),只要不是其他错误即可。
|
||
|
||
7. 预创建文件(precreate),用分片方式处理大文件:
|
||
// turbo
|
||
```bash
|
||
FILE_SIZE=$(stat -f%z /tmp/<项目名>.zip)
|
||
BLOCK_SIZE=$((4*1024*1024))
|
||
BLOCKS=$(( (FILE_SIZE + BLOCK_SIZE - 1) / BLOCK_SIZE ))
|
||
# 生成 block_list(每片用占位符 md5)
|
||
BLOCK_LIST=$(python3 -c "import json; print(json.dumps(['0'*32]*$BLOCKS))")
|
||
curl -s "https://pan.baidu.com/rest/2.0/xpan/file?method=precreate&access_token=<access_token>" \
|
||
-d "path=<目标目录>/<项目名>.zip&size=$FILE_SIZE&isdir=0&autoinit=1&block_list=$BLOCK_LIST"
|
||
```
|
||
从返回中提取 `uploadid`。
|
||
|
||
8. **分片上传**,使用一个 shell 脚本完成,脚本内显示友好的进度信息(百分比、已传/总量、预计剩余时间):
|
||
// turbo
|
||
```bash
|
||
# 创建上传脚本 /tmp/baidu_upload.sh 并执行
|
||
# 脚本逻辑:
|
||
# - 按 4MB 分片 dd 切割文件
|
||
# - 逐片上传到 superfile2 接口
|
||
# - 每上传一片输出一行进度:[=====> ] 23/259 (8.9%) | 已传92MB/1034MB | 速度: 2.1MB/s
|
||
# - 收集每片返回的 md5
|
||
# - 全部完成后输出汇总
|
||
bash /tmp/baidu_upload.sh
|
||
```
|
||
|
||
9. 合并创建文件(create):
|
||
// turbo
|
||
```bash
|
||
curl -s "https://pan.baidu.com/rest/2.0/xpan/file?method=create&access_token=<access_token>" \
|
||
-d "path=<目标目录>/<项目名>.zip&size=$FILE_SIZE&isdir=0&uploadid=<uploadid>&block_list=[<所有分片md5>]"
|
||
```
|
||
确认返回 `errno: 0` 表示成功。
|
||
|
||
10. 清理临时文件:
|
||
// turbo
|
||
```bash
|
||
rm -f /tmp/<项目名>.zip /tmp/baidu_upload.sh /tmp/chunk_*
|
||
```
|
||
|
||
11. 输出最终结果(友好格式):
|
||
```
|
||
╔══════════════════════════════════════╗
|
||
║ 📦 百度网盘备份完成! ║
|
||
╠══════════════════════════════════════╣
|
||
║ 📁 路径: /2026/0517/GovAI.zip ║
|
||
║ 📊 大小: 1034 MB ║
|
||
║ ⏱️ 耗时: 5分32秒 ║
|
||
║ ✅ 状态: 上传成功 ║
|
||
╚══════════════════════════════════════╝
|
||
```
|