feat: TransferSu 统一文件传输工具

- 多后端: rsync(断点续传) / rclone(并行) / pv+tar
- CLI/TUI 双模式, 未指定 --mode cli 时默认 TUI
- TUI 四栏布局: 进度条/速度曲线/文件日志/错误日志 + 底部交互输入栏
- 冲突策略: --overwrite/--skip/--ask, y/n/a/s/q 交互决策
- 实时日志滚动保留 20 个, 纳秒时间戳排序
- 37 个单元测试 (pytest)
This commit is contained in:
AskaEth committed 2026-08-22 13:25:47 +08:00
commit f7b10f3ee3
4 files changed
+1341

No files matched your search

+102
View File
@@ -0,0 +1,102 @@
# TransferSu - 统一文件传输工具
基于 rsync / rclone / pv+tar 的统一拷贝管理工具,CLI/TUI 双模式,实时日志轮转。
## 特性
- **多后端**: rsync(推荐, 断点续传)/ rclone(并行)/ pv+tar(零依赖)
- **CLI/TUI 双模式**: 未显式 `--mode cli` 时默认 TUI 启动
- **TUI 四栏布局**:
- 上栏: 总进度条 + 单文件进度条
- 中栏: 速度曲线可视化(最近 80 秒采样)
- 下栏: 文件日志 + 错误日志 双面板
- 底部: 交互输入栏(可空启动后设定任务)
- **实时日志**: 写入本地目录, 滚动保留最近 N 个(默认 20), 文件名含纳秒时间戳
- **可控性**: 限速 / 断点续传 / 校验 / 并行数 全部可配
## 安装
```bash
pip install -i https://mirrors.aliyun.com/pypi/simple/ pytest textual
```
## 用法
```bash
# TUI 模式 (默认): 空启动后在底部输入栏设定任务
python3 transfer.py
# TUI 模式带预设任务
python3 transfer.py /src /dst --bwlimit 30000
# CLI 模式 (显式指定)
python3 transfer.py --mode cli /src/ /dst/ --backend rclone --bwlimit 8M
```
### TUI 输入栏命令
```
/src /dst --backend rclone --bwlimit 8M --transfers 4 # 启动传输任务
help # 帮助
clear # 清空日志面板
quit # 退出
```
### 参数
| 参数 | 默认 | 说明 |
|---|---|---|
| `--backend` | rsync | rsync / rclone / tar |
| `--bwlimit` | 30000 | 限速 (rsync: KB/s, rclone: 如 8M) |
| `--transfers` | 4 | rclone 并行传输数 |
| `--resume` / `--no-resume` | 开 | rsync 断点续传 |
| `--checksum` | 关 | rsync 校验模式 |
| `--verify` | 关 | 完成后校验 |
| `--mode` | tui | cli / tui |
| `--keep-logs` | 20 | 日志滚动保留数 |
| `--logdir` | ~/logs | 日志目录 |
## 日志
- 目录: `--logdir` 指定(默认 `~/logs`)
- 文件名: `{时间戳}_{后端}_{源名}.log`(时间戳开头保证排序即时间序)
- 滚动: 超过 `--keep-logs` 个自动删除最旧
## 测试
```bash
python3 -m pytest tests/ -q
```
## 冲突策略(覆盖/跳过)
传输前可用参数预设策略,或中途逐项决策:
| 参数 | 行为 |
|---|---|
| `--overwrite` | 覆盖已存在文件(默认) |
| `--skip` | 跳过已存在文件(`--ignore-existing`) |
| `--ask` | 逐项询问(扫描冲突后交互) |
**ask 交互选项**(CLI 与 TUI 一致):
```
y = 覆盖当前项 n = 跳过当前项
a = 全部覆盖 s = 全部跳过
q = 中止传输
```
- **CLI**:预扫描后逐项提示,输入 y/n/a/s/q
- **TUI**:扫描完成后在底部输入栏逐项交互(stats 栏显示当前冲突文件)
- **仅当前/后续同步**:y/n 只作用于当前文件;a/s 一次决定后续所有冲突
- rsync 覆盖场景自动禁用 `--append`(追加模式会阻止重写),保留 `--partial`
- rclone 的 `--ask` 使用原生 `--interactive`(y/n/s);tar 后端不支持 ask/skip
```bash
# CLI 示例: ask 交互
python3 transfer.py --mode cli --policy ask /src/ /dst/
# TUI 输入栏示例
/src /dst --policy ask
/src /dst --skip
```