feat(p3): add discovery, telegram notifications, and one-click favorites
Implement WBI video search with legacy fallback, classification scoring, candidate pool, permanent seen-aid dedupe, blacklist filtering, and batched Telegram notifications. Add write client for fav deal/sort, target-folder selection, insertion position calculation, read-back verification, fav_action locking, retry on failure, ignore and blacklist actions. Wire discovery, candidate cleanup, Telegram long polling, and new discover/candidates CLI commands into the scheduler. Add migration v3 for candidate duration and index stats.
This commit is contained in:
1 parent
6a21b5d905
commit
d971e718e9
31 files changed
+2886
-55
No files matched your search
+49
-18
@@ -199,28 +199,29 @@ PRAGMA synchronous = NORMAL;
|
||||
│ ├── migrations.py # schema_version 与迁移
|
||||
│ ├── scheduler.py # 内置任务调度
|
||||
│ ├── logging_json.py # 脱敏 JSON 日志
|
||||
│ ├── classify.py # 标题归一化、时长解析与打分
|
||||
│ ├── fav_position.py # 新视频插入位置计算
|
||||
│ ├── timeutil.py # 上海时区与每日时间
|
||||
│ ├── bilibili/
|
||||
│ │ ├── client.py # HTTP、WBI、重试与限速
|
||||
│ │ ├── client.py # 只读 HTTP、重试与限速
|
||||
│ │ ├── write_client.py # deal / sort 写客户端
|
||||
│ │ ├── search.py # WBI 搜索与旧接口降级
|
||||
│ │ ├── provider.py # 凭据变化重建客户端
|
||||
│ │ ├── auth.py # Cookie、设备指纹与请求头工具
|
||||
│ │ ├── auth_flow.py # app.py auth 的扫码与原子写回流程
|
||||
│ │ └── favorite.py # 加入收藏夹与排序定位
|
||||
│ │ └── models.py # 接口响应模型
|
||||
│ ├── services/
|
||||
│ │ ├── discovery.py
|
||||
│ │ ├── discovery.py # 搜索发现与候选池
|
||||
│ │ ├── favorites.py # 收藏 / 忽略 / 拉黑
|
||||
│ │ ├── telegram_poller.py # getUpdates 与回调分发
|
||||
│ │ ├── folder_sync.py
|
||||
│ │ ├── snapshot.py
|
||||
│ │ ├── fans.py
|
||||
│ │ ├── candidates.py
|
||||
│ │ ├── rankings.py
|
||||
│ │ └── maintenance.py
|
||||
│ ├── notify/telegram.py
|
||||
│ └── web/
|
||||
│ ├── notify/telegram.py # Telegram 消息与按钮
|
||||
│ └── web/ # P2 预留
|
||||
│ ├── server.py
|
||||
│ ├── api.py
|
||||
│ └── static/
|
||||
│ ├── index.html
|
||||
│ ├── app.js
|
||||
│ ├── styles.css
|
||||
│ └── vendor/echarts.min.js
|
||||
│
|
||||
├── tests/
|
||||
└── data/ # 本地运行期数据,默认不提交
|
||||
@@ -379,6 +380,14 @@ score >= 2:发送通知
|
||||
score < 0:丢弃
|
||||
```
|
||||
|
||||
P3 实现说明:
|
||||
|
||||
- WBI 密钥来自 `nav.data.wbi_img`,缓存 6 小时;WBI 失败自动降级旧版 `search/type`;
|
||||
- 关键词、页数和时间窗由 `discover` 配置控制;
|
||||
- 同一 aid 在多个关键词/页重复出现时,候选与通知都按 aid 去重;
|
||||
- 已通知但未决策的候选不会重复通知;未通知的候选会在后续发现轮次补发;
|
||||
- 人工把候选加入收藏夹后,收藏夹同步会入库并删除同 aid 候选。
|
||||
|
||||
### 7.3 收藏夹同步
|
||||
|
||||
每小时对所有已配置年度夹执行:
|
||||
@@ -451,6 +460,16 @@ Telegram `callback_data` 只包含短操作 ID,例如 `fav:<id>`;真实 aid
|
||||
|
||||
GET 页面或链接预览只能展示信息,绝不能触发任何写操作。
|
||||
|
||||
P3 实现说明:
|
||||
|
||||
- `callback_data` 使用 `fav:<aid>` / `ign:<aid>` / `blk:<aid>`,真实状态存 `fav_action`;
|
||||
- `begin_fav_action` 把 `pending/failed` 原子切换为 `processing`;并发点击返回 `busy`;
|
||||
- 已在目标夹时直接成功,不重复 `deal`;
|
||||
- 目标夹优先同 UP 在库最早视频所在夹,其次当前自然年夹,最后最新年度夹;
|
||||
- 插入位置由 `fav_position.plan_insertion` 计算;组头需要两次 `sort`;
|
||||
- `deal` 或 `sort` 失败写 `fav_action.state='failed'`,保留候选,用户可再次点击重试;
|
||||
- Telegram 只接受 `chat_id` 与 `from.id` 都等于配置私聊用户的回调。
|
||||
|
||||
---
|
||||
|
||||
## 9. Web API 与页面
|
||||
@@ -608,18 +627,30 @@ uv run python tests/test_moves.py
|
||||
- `favsort.py`:`--verify-every` 必须为正数;`sort` 使用真实资源类型,不再硬编码 `2`;
|
||||
- 配置每 60 秒检查 mtime;调度参数变更需重启。
|
||||
|
||||
### P3:Telegram 与一键加入 ✅
|
||||
|
||||
- long polling、候选通知、收藏/忽略/拉黑;
|
||||
- `deal`、`sort`、回读验证和失败重试;
|
||||
- 对真实写入操作使用独立测试视频完成授权验证后再启用。
|
||||
|
||||
完成情况(2026-10-31):
|
||||
|
||||
- 已实现 `bilibili/search.py`:WBI 签名、密钥缓存 6 小时、旧版搜索降级;
|
||||
- 已实现 `classify.py`:标题归一化、时长解析与打分;
|
||||
- 已实现 `services/discovery.py`:关键词/页数/时间窗过滤、黑名单、候选池、通知批次;
|
||||
- 已实现 `notify/telegram.py` 与 `services/telegram_poller.py`:消息分片、Inline Keyboard、回调授权、offset 推进;
|
||||
- 已实现 `bilibili/write_client.py`、`fav_position.py`、`services/favorites.py`:目标夹选择、`deal`、`sort`、回读校验、失败保留候选;
|
||||
- `app.py` 新增 `discover` / `candidates`;`run` 注册发现与候选清理任务,并启动 Telegram poller;
|
||||
- 真实只读联调:4 次 WBI 搜索、168 条结果、1 条候选(score=6),Telegram 通知发送成功;
|
||||
- 真实 `deal` / `sort` 尚未在收藏夹执行,等待用户点击 Telegram 按钮或授权测试视频后验证;
|
||||
- 自动化测试见 `tests/test_classify.py`、`test_search.py`、`test_candidates.py`、`test_discovery.py`、`test_fav_position.py`、`test_favorites.py`、`test_telegram.py`。
|
||||
|
||||
### P2:本地看板
|
||||
|
||||
- 总览、榜单、详情、UP、粉丝、候选和系统状态页面;
|
||||
- 原生前端和 ECharts;
|
||||
- 本机默认绑定 `127.0.0.1:8080`。
|
||||
|
||||
### P3:Telegram 与一键加入
|
||||
|
||||
- long polling、候选通知、收藏/忽略/拉黑;
|
||||
- `deal`、`sort`、回读验证和失败重试;
|
||||
- 对真实写入操作使用独立测试视频完成授权验证后再启用。
|
||||
|
||||
### P4:可选部署
|
||||
|
||||
- 反向代理、TLS、远程访问鉴权;
|
||||
|
||||
Reference in new issue
Block a user