feat: add fnOS packaging, storage workflows and release pipeline

This commit is contained in:
2026-08-11 18:05:49 +08:00
parent c5922f9b08
commit 95932f0199
181 changed files with 24024 additions and 1164 deletions
+90 -1
View File
@@ -19,6 +19,9 @@
- [1.1 提取抖音 Cookie](#11-提取抖音-cookie)
- [1.2 提取 `sec_user_id`(个人/指定博主)](#12-提取-sec_user_id个人指定博主)
- [2. 路径映射规则(核心!错配会导致无法访问/数据丢失)](#2-路径映射规则核心错配会导致无法访问数据丢失)
- [2.1 直接同步到 WebDAVAList/OpenList](#21-直接同步到-webdavalistopenlist)
- [2.2 升级后将本地视频迁移到 WebDAV](#22-升级后将本地视频迁移到-webdav)
- [2.3 WebDAV 自动化与真实服务测试](#23-webdav-自动化与真实服务测试)
- [3. 默认账号密码(首次登录用)](#3-默认账号密码首次登录用)
- [4. 运行方式(推荐 Docker Compose](#4-运行方式推荐-docker-compose)
- [镜像版本](#镜像版本)
@@ -80,6 +83,92 @@ Cookie 及 `sec_user_id` 是同步功能的核心,需严格按步骤获取,
---
### 2.1 通过 OpenList 原生 API 同步到远端
`0.2.22` 不再使用 WebDAV 上传新内容。应用先把完整文件写入本地共享中转目录,再调用 OpenList `/api/fs/copy` 在服务端复制,并通过暂存目录、移动和长度校验原子提升到最终路径。OpenList 返回外部云盘签名地址时不会向该域名转发 OpenList Token,避免移动云 Range 校验返回 400,并防止登录凭据跨主机发送。
`0.2.23` 将“检测存储”固定显示在任务中心顶部;存储正常时可随时主动检测,熔断后会自动变为“重新检测存储”。移动端按钮独占一行,不再依赖警告框的操作区域。
`0.2.24` 修复 OpenList 新视频目录尚未创建时被误判为存储故障的问题。应用会继续保留已有目录的服务端真实大小写,并把缺失的尾部路径交给安全传输流程创建。抖音作品列表和媒体连接超时会进行两次带退避的有限重试;切换到 OpenList 后遗留的旧 WebDAV 同步任务会在启动恢复阶段安全终结并隐藏,不删除视频记录或媒体文件。普通同步成功切换存储但旧本地文件清理失败时,任务条目会显示“重试清理旧文件”,再次验证远端主媒体后才执行清理。
`0.2.25` 补齐 OpenList 对象检查的强制刷新分支:远端尚未创建的新视频目录会稳定返回“不存在”并进入下载,不再在 `ExistsAsync` 的第二次检查中误报 `object not found`。新建目录后会进行总计最多约 7.5 秒的有限刷新确认,以兼容远端云盘的可见性延迟;若服务端确实自动改名,仍会停止写入以避免生成重复目录。
当底层云盘目录大小写不敏感时,应用会根据 OpenList 目录列表解析真实名称。例如逻辑路径 `/collect/Kk` 会稳定复用现有 `/collect/KK`,不会再触发 `Kk_日期_时间` 自动改名。任务中心的“修复异常目录”会严格筛选时间后缀候选,逐个检查并等待人工确认;删除前还会复检,只删除空目录。
1. 在 fnOS 或宿主机创建应用可写的本地中转目录。
2. 在 OpenList 中添加一个本地存储驱动,让“源挂载目录”指向同一个物理目录。应用与 OpenList 看到的路径名称可以不同,但内容必须完全对应。
3. 进入“系统配置 → 媒体存储”,选择 **OpenList 原生 API**。地址填写站点根地址,例如 `http://192.168.1.2:5244`,不要填写 `/dav`
4. 填写本地中转目录、OpenList 源挂载目录和目标基础目录,然后执行“测试完整复制链路”。测试会验证登录、本地文件可见、服务端复制、Range 读取和删除。
5. 测试通过后启用 OpenList,再进入“抖音授权”配置收藏、喜欢、关注、合集和短剧路径。这些字段都是目标基础目录之后的相对路径;留空保存时会按账号生成默认值。
注意事项:
- OpenList 账号需要源挂载目录的读取权限,以及目标基础目录的读取、写入、移动、重命名和删除权限。
- 新写入不会调用 `/api/fs/put` 或 WebDAV。服务端复制完成并确认最终文件长度后,本地中转副本才会清理;失败任务会持久化并按退避规则恢复。
- 切换存储模式只影响之后的新同步内容,不会自动移动或删除历史文件。历史 WebDAV 驱动仅用于旧记录继续播放、删除和回滚。
- OpenList 密码使用 Data Protection 加密。密钥位于数据库目录的 `keys` 子目录,因此 Docker 部署必须持续映射并备份 `/app/db`
- 图文和动态视频仍会先在本地完成 FFmpeg 合成,再进入同一 OpenList 中转与服务端复制流程。
### 2.2 升级后将旧视频接管到 OpenList
`0.2.25` 支持从官方 `0.2.x` 原地升级,保留数据库、Cookie、配置、Data Protection 密钥及历史媒体路径。系统配置会分别显示本地、历史 WebDAV、OpenList 和“不在当前存储”的记录数量;旧 WebDAV 迁移任务只保留审计信息,可直接归档隐藏。
> 升级 → 配置并测试 OpenList → 启用 OpenList → 迁移预检 → 手动创建任务 → 后台迁移 → 选择回滚或清理旧文件
1. 安装 `0.2.25 x86_64` FPK 覆盖升级。升级不会自动迁移视频,也不会覆盖 fnOS 数据共享目录;启动前会备份 SQLite、WAL/SHM 和 Data Protection 密钥,并只保留最近三份升级备份。
2. 按上一节配置共享中转目录和 OpenList,完成完整复制链路测试后再启用。此后新同步内容直接写入 OpenList,旧记录仍按原存储类型工作。
3. 打开“系统配置 → 存储迁移”执行预检。页面会统计本地记录、历史 WebDAV、可直接接管、需复制或回源、缺失文件、总字节数、无效 Cookie、未配置路径和目标冲突;存在冲突时不会创建任务。
4. 同一 OpenList 实例中可见且长度匹配的历史 WebDAV 文件会直接改标接管,不会重复复制。其余记录优先读取安全范围内的本地文件;本地主媒体缺失时才尝试记录 URL 和抖音全量列表回源。
5. 选择并发数 `13`(默认 `1`)并手动创建任务。升级、保存配置和启用 OpenList 都不会自动启动迁移。配置地址、源挂载、基础目录或账号变化时,任务会暂停并要求重新预检。
6. 任务支持暂停、恢复、取消和失败项重试;应用重启后会恢复中断项。单条记录只有在远端最终文件通过长度校验且数据库事务成功后才会改为 OpenList,失败项仍指向原存储。
7. 任务结束后可以整批回滚或清理成功项。清理前会再次检查数据库与远端文件;本地来源只删除不再被引用的旧文件,直接接管的 WebDAV 文件不会被误删。清理开始后不再允许回滚。
8. 已结束且无需继续清理或回滚的迁移历史可在系统配置或任务中心隐藏;归档只影响显示,不删除视频、文件或审计条目。
建议在抽样播放确认无误后再清理旧文件,并始终保留 `/app/db` 与原媒体目录的外部备份。
### 2.3 媒体来源 403、429 与重新授权
任务中心会把抖音/CDN 来源错误与 OpenList 存储错误分开显示。任务条目只记录安全的来源域名、HTTP 状态和重试时间,不保存或输出带签名的完整媒体 URL、响应正文与 Cookie。
- 下载会优先尝试所选清晰度,再去重轮换其他清晰度地址;403、404 和 410 会立即切换候选地址。
- 同一抖音授权连续 3 个作品的全部候选地址均返回 403 时,只暂停该授权 15 分钟,其他授权继续同步。冷却结束后后台只用最早的等待条目探测一次。
- 探测成功会自动恢复该授权的其余等待条目;探测仍返回 403 或请求直接返回 401 时,任务中心和“抖音授权”页会提示重新授权。
- 保存新的 Cookie 会清除来源锁并安排一次探测。429 会遵循服务端 `Retry-After` 进入冷却,但不会直接判定 Cookie 失效。
- 404/410 只标记当前作品失败,通常表示作品下架、私密或签名地址已失效,不会暂停整个授权,也不会触发存储熔断。
如果任务中心显示“需要重新授权”,请进入“抖音授权”保留原入口并更新 Cookie;无需修改 OpenList 配置,也不要删除已有视频记录或文件。
### 2.4 关注博主直播监测与邮箱通知
- 在“关注列表”中为每个博主独立开启“直播监测”。开启后会立即检查一次,之后后台每 5 分钟检查;单个博主也可手动刷新,30 秒内重复点击不会再次请求抖音。
- 页面每分钟读取一次本地状态,不会因此额外请求抖音。直播中可直接进入直播间;检查失败时保留上次成功状态并显示失败或过期提示。
- 同一授权账号下的博主串行检查并加入随机间隔;遇到 403、429 或验证响应时按账号进入 15–360 分钟递增冷却,避免持续请求扩大风控影响。
- 在“系统配置 → 邮箱通知”配置 SMTP 地址、端口、安全方式、账号、授权码、发件人和收件人。支持无加密、STARTTLS 和 SSL/TLS,建议优先使用邮箱服务商提供的授权码并先发送测试邮件。
- SMTP 密码使用 Data Protection 加密保存,不会通过读取配置接口返回。密码留空保存表示继续使用原密码;可填写多个收件人,使用逗号、分号或换行分隔。
- 全局邮箱启用并配置完整后,可在每个博主卡片上独立开启“开播邮件”。同一 `web_rid` 或直播房间只通知一次,邮件失败不会覆盖已获取的直播状态,15 分钟后才会重试;检测到下播后才会为下一场直播重新准备通知。
### 2.5 OpenList 自动化与真实服务测试
本地自动化测试覆盖 OpenList Token 缓存与 401 刷新、Unicode 路径、服务端复制、Range 读取、重启恢复、数据库升级,以及历史 WebDAV 兼容行为:
```bash
dotnet test tests/dy.net.Tests/dy.net.Tests.csproj
```
AList 和 OpenList 的历史 WebDAV 兼容实测默认跳过;需要验证旧记录读取与删除时,可分别设置以下环境变量:
| AList | OpenList | 说明 |
|---|---|---|
| `DYSYNC_TEST_ALIST_ENDPOINT` | `DYSYNC_TEST_OPENLIST_ENDPOINT` | WebDAV 地址,例如 `https://host/dav` |
| `DYSYNC_TEST_ALIST_BASE_PATH` | `DYSYNC_TEST_OPENLIST_BASE_PATH` | 专用测试目录,必须是包含 `dysync-test` 的非根路径 |
| `DYSYNC_TEST_ALIST_USERNAME` | `DYSYNC_TEST_OPENLIST_USERNAME` | 测试账号用户名 |
| `DYSYNC_TEST_ALIST_PASSWORD` | `DYSYNC_TEST_OPENLIST_PASSWORD` | 测试账号密码 |
| `DYSYNC_TEST_ALIST_ALLOW_INVALID_CERTIFICATE` | `DYSYNC_TEST_OPENLIST_ALLOW_INVALID_CERTIFICATE` | 可选,仅可信内网自签证书设置为 `true` |
历史兼容测试只会在指定基础目录下创建随机子目录,验证完成后自动删除;不会读取网站中保存的生产配置,也不会输出密码。OpenList 原生写入还依赖应用与 OpenList 共享同一物理中转目录,因此请直接使用“系统配置 → 媒体存储 → 测试完整复制链路”完成部署环境实测。
---
## 3. 默认账号密码(首次登录用)
首次访问后台管理页面时,使用以下默认账号密码:
- **用户名**`douyin`
@@ -301,4 +390,4 @@ services:
## 4. 声明的修改与生效
- 本免责声明的最终解释权归项目开发者所有,开发者保留随时修改本声明的权利。
- 修改后的声明将在项目仓库中更新,建议使用者定期查阅。
- 一旦使用本项目的代码、功能或相关资源,即视为您已充分理解并同意本免责声明的全部条款。如不同意,请立即停止使用。
- 一旦使用本项目的代码、功能或相关资源,即视为您已充分理解并同意本免责声明的全部条款。如不同意,请立即停止使用。