| 1 | # Bilibili CLI 设计 |
| 2 | |
| 3 | 日期:2026-03-25 |
| 4 | |
| 5 | ## 概要 |
| 6 | |
| 7 | 这份设计要把 `bilibili` 挂到 `sau` 下面,用户侧体验尽量和现在的 `douyin`、`kuaishou` 保持一致。 |
| 8 | |
| 9 | 核心约束只有两个: |
| 10 | |
| 11 | - 用户不需要自己安装 `biliup` |
| 12 | - 外部统一走 `sau bilibili ...` |
| 13 | |
| 14 | 程序会把 `biliup` 当作内部运行时依赖来处理: |
| 15 | |
| 16 | - `sau bilibili ...` 是唯一公开入口 |
| 17 | - 本地没有 `biliup` 时自动下载 |
| 18 | - 每次运行都检查 GitHub Release 最新版本 |
| 19 | - 如果发现有更新,先自动更新,再继续执行当前命令 |
| 20 | |
| 21 | 这份设计刻意保持轻量,不重新发明一套 B 站上传语义,而是直接复用仓库里现有的 B 站上传模型。 |
| 22 | |
| 23 | ## 目标 |
| 24 | |
| 25 | - 让 `sau bilibili ...` 和 `sau douyin ...`、`sau kuaishou ...` 保持统一心智 |
| 26 | - 隐藏 `biliup` 的安装细节,降低用户使用成本 |
| 27 | - 复用项目里已经存在的账号文件、`VideoZoneTypes`、定时发布等能力 |
| 28 | - 不做过度封装 |
| 29 | |
| 30 | ## 非目标 |
| 31 | |
| 32 | - 第一版不把 `biliup` 二进制直接提交进仓库 |
| 33 | - 第一版不维护本地 release manifest |
| 34 | - 第一版不做 B 站图文发布 |
| 35 | - 第一版不重做现有的 B 站上传领域模型 |
| 36 | |
| 37 | ## 当前项目基础 |
| 38 | |
| 39 | 仓库里已经有 B 站上传能力: |
| 40 | |
| 41 | - `uploader/bilibili_uploader/main.py` 目前直接封装了 `biliup.plugins.bili_webup` |
| 42 | - `examples/upload_video_to_bilibili.py` 已经在使用现有上传参数 |
| 43 | - `utils/constant.py` 已经定义了完整的 `VideoZoneTypes` |
| 44 | |
| 45 | 也就是说,你现在项目里的 B 站上传语义已经很明确,核心就是: |
| 46 | |
| 47 | - `file` |
| 48 | - `title` |
| 49 | - `desc` |
| 50 | - `tid` |
| 51 | - `tags` |
| 52 | - `dtime` |
| 53 | |
| 54 | 所以第一版 CLI 不需要重新造模型,直接沿用这套。 |
| 55 | |
| 56 | ## 用户侧 CLI 设计 |
| 57 | |
| 58 | ### 支持的命令 |
| 59 | |
| 60 | - `sau bilibili login` |
| 61 | - `sau bilibili check` |
| 62 | - `sau bilibili upload-video` |
| 63 | |
| 64 | ### 命令契约 |
| 65 | |
| 66 | #### `sau bilibili login` |
| 67 | |
| 68 | 作用: |
| 69 | |
| 70 | - 自动准备 `biliup` |
| 71 | - 如果有更新则先升级 |
| 72 | - 然后调用 `biliup` 完成登录 |
| 73 | - 将账号数据按项目自己的账号文件规则保存下来 |
| 74 | |
| 75 | 第一版行为: |
| 76 | |
| 77 | - 本地没有 `biliup` 时自动下载最新 release |
| 78 | - 本地已有但上游有更新时自动升级 |
| 79 | - 升级完成后继续执行登录流程 |
| 80 | |
| 81 | #### `sau bilibili check` |
| 82 | |
| 83 | 作用: |
| 84 | |
| 85 | - 自动准备 `biliup` |
| 86 | - 检查当前账号是否可用 |
| 87 | |
| 88 | 第一版行为: |
| 89 | |
| 90 | - 结合本地账号文件存在性和 `biliup` 实际可用性来判断 |
| 91 | - 输出风格和其他平台保持一致: |
| 92 | - `valid` |
| 93 | - `invalid` |
| 94 | |
| 95 | #### `sau bilibili upload-video` |
| 96 | |
| 97 | 作用: |
| 98 | |
| 99 | - 自动准备 `biliup` |
| 100 | - 走项目当前已有的 B 站上传参数体系完成视频上传 |
| 101 | |
| 102 | 第一版参数: |
| 103 | |
| 104 | - `--account` 必填 |
| 105 | - `--file` 必填 |
| 106 | - `--title` 必填 |
| 107 | - `--desc` 必填 |
| 108 | - `--tid` 必填 |
| 109 | - `--tags` 选填 |
| 110 | - `--schedule` 选填 |
| 111 | |
| 112 | 明确决定: |
| 113 | |
| 114 | - `tid` 在第一版里必须传 |
| 115 | - 不给默认分区,避免猜测和隐式错误 |
| 116 | |
| 117 | ## 运行时依赖策略 |
| 118 | |
| 119 | ### 选定方案 |
| 120 | |
| 121 | `biliup` 不提交进仓库,也不要求用户手工安装。 |
| 122 | |
| 123 | `sau bilibili ...` 在运行时自动处理它: |
| 124 | |
| 125 | 1. 查找本地是否已有 `biliup` |
| 126 | 2. 检查 GitHub Release 最新版本 |
| 127 | 3. 如果缺失或过期,则自动下载最新版本 |
| 128 | 4. 替换本地运行时副本 |
| 129 | 5. 继续执行本次命令 |
| 130 | |
| 131 | ### 选择这个方案的原因 |
| 132 | |
| 133 | - 仓库体积更干净 |
| 134 | - 用户不需要自己找 release、自己下载 |
| 135 | - 对外仍然只有一个统一入口 `sau` |
| 136 | - 不需要使用 `git submodule` |
| 137 | |
| 138 | ### 接受的代价 |
| 139 | |
| 140 | 这套方案明确接受一个现实: |
| 141 | |
| 142 | - 每次运行都会检查上游 release |
| 143 | - 上游如果改 CLI 行为,可能会影响这层适配 |
| 144 | |
| 145 | 所以这里的应对方式不是做重封装,而是保持 wrapper 很薄,减少被动维护成本。 |
| 146 | |
| 147 | ## 存储与解析 |
| 148 | |
| 149 | `biliup` 应该存放在本地运行时缓存目录中,而不是源码目录中。 |
| 150 | |
| 151 | 缓存目录只需要满足: |
| 152 | |
| 153 | - 当前用户可写 |
| 154 | - 可跨命令复用 |
| 155 | - 不进入 git 管理 |
| 156 | |
| 157 | 解析器的职责应当是: |
| 158 | |
| 159 | - 识别当前操作系统 |
| 160 | - 选择对应平台的 release asset |
| 161 | - 下载并替换可执行文件 |
| 162 | - 返回最终可执行路径 |
| 163 | |
| 164 | ## 轻量封装边界 |
| 165 | |
| 166 | 为了避免过度封装,第一版只建议拆成 3 个很薄的部分。 |
| 167 | |
| 168 | ### 1. Resolver |
| 169 | |
| 170 | 职责: |
| 171 | |
| 172 | - 判断本地是否已有 `biliup` |
| 173 | - 检查 GitHub Release 最新版本 |
| 174 | - 下载或更新可执行文件 |
| 175 | - 返回最终可执行文件路径 |
| 176 | |
| 177 | ### 2. Runner |
| 178 | |
| 179 | 职责: |
| 180 | |
| 181 | - 调用解析出来的 `biliup` |
| 182 | - 收集退出码、标准输出、标准错误 |
| 183 | - 对明显的进程级错误做一层项目内友好的报错转换 |
| 184 | |
| 185 | ### 3. `sau_cli.py` 中的 bilibili 子命令 |
| 186 | |
| 187 | 职责: |
| 188 | |
| 189 | - 解析 `sau bilibili ...` 参数 |
| 190 | - 把这些参数翻译成底层运行逻辑 |
| 191 | - 让帮助信息风格和其他平台一致 |
| 192 | |
| 193 | 第一版不需要更多层,也不需要再抽一套很重的统一框架。 |
| 194 | |
| 195 | ## 与现有项目概念的映射 |
| 196 | |
| 197 | ### 账号文件 |
| 198 | |
| 199 | B 站也继续沿用现在项目的账号别名机制: |
| 200 | |
| 201 | - 用户传 `--account <name>` |
| 202 | - 程序解析成对应的账号文件路径 |
| 203 | |
| 204 | ### 分区 |
| 205 | |
| 206 | `tid` 保持为一等参数。 |
| 207 | |
| 208 | `VideoZoneTypes` 继续保留并服务于: |
| 209 | |
| 210 | - example |
| 211 | - 文档 |
| 212 | - 后续可能的辅助工具 |
| 213 | |
| 214 | ### 定时发布 |
| 215 | |
| 216 | `--schedule` 保持和当前 `sau` 其他平台一致的使用方式: |
| 217 | |
| 218 | - 不传就是立即发布 |
| 219 | - 传了就是定时发布 |
| 220 | |
| 221 | 具体如何映射到底层 B 站执行逻辑,由 adapter 负责,不暴露给用户。 |
| 222 | |
| 223 | ## 错误处理 |
| 224 | |
| 225 | 第一版错误处理保持直接,不做花哨包装: |
| 226 | |
| 227 | - 下载失败:明确告诉用户自动下载 `biliup` 失败 |
| 228 | - 更新失败:明确告诉用户最新 release 准备失败 |
| 229 | - 登录失败:保留 `biliup` 登录失败上下文 |
| 230 | - 检查失败:输出 `invalid` |
| 231 | - 上传失败:返回非零退出码,并展示上游错误摘要 |
| 232 | |
| 233 | 第一版不追求把所有 `biliup` 错误文本都重新翻译一遍。 |
| 234 | |
| 235 | ## 文档影响范围 |
| 236 | |
| 237 | 实现完成后,至少需要补齐这些地方: |
| 238 | |
| 239 | - `README.md` |
| 240 | - `docs/CLI.md` |
| 241 | - 安装与更新文档 |
| 242 | - 一套对应的 Bilibili skill |
| 243 | - Bilibili example 脚本 |
| 244 | |
| 245 | 对外表达应当统一成: |
| 246 | |
| 247 | - 用户使用的是 `sau bilibili ...` |
| 248 | - `biliup` 由程序自动准备 |
| 249 | |
| 250 | ## 测试策略 |
| 251 | |
| 252 | 第一版最少需要验证这些路径: |
| 253 | |
| 254 | - `sau bilibili login --account <name>` |
| 255 | - `sau bilibili check --account <name>` |
| 256 | - `sau bilibili upload-video ...` |
| 257 | - 本地没有 `biliup` 时能自动下载 |
| 258 | - 本地已有旧版本时能先升级再执行 |
| 259 | - 本地已有最新版本时能直接复用 |
| 260 | |
| 261 | 因为登录和上传涉及真实外部平台,第一版以手工验证为主是可以接受的。 |
| 262 | |
| 263 | ## 推荐实现顺序 |
| 264 | |
| 265 | 1. 在 `sau_cli.py` 中加入 `bilibili` 子命令 |
| 266 | 2. 增加一个最小可用的 `biliup` resolver |
| 267 | 3. 增加一个最小可用的 `biliup` runner |
| 268 | 4. 接上 `login / check / upload-video` |
| 269 | 5. 补文档、example、skill |
| 270 | |
| 271 | ## 最终结论 |
| 272 | |
| 273 | - 对外入口固定为 `sau bilibili ...` |
| 274 | - 第一版支持 `login`、`check`、`upload-video` |
| 275 | - `tid` 必填 |
| 276 | - `biliup` 不需要用户手动安装 |
| 277 | - 每次运行都检查 GitHub Release |
| 278 | - 有新版本时先自动更新,再继续执行 |
| 279 | - 整体实现保持轻量,不做过度封装 |
| 280 |