From 04963370935449c8a6cf3b4eb4831a6ef45d1974 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 7 Mar 2026 16:51:03 +0000 Subject: [PATCH 1/2] feat(od): proactive notification on download completion via JobQueue Poll undone/done task lists every 30 seconds; when a task transitions from undone to done, send an instant message to admin with file name, size, path, and error info (if any). https://claude.ai/code/session_01HNCfZLiNXHZcchtifn6b5T --- bot.py | 3 ++ module/offline_download/offline_download.py | 38 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/bot.py b/bot.py index d246c58..ded00f6 100644 --- a/bot.py +++ b/bot.py @@ -54,6 +54,9 @@ async def post_init(application: Application): + from module.offline_download.offline_download import check_download_completion + application.job_queue.run_repeating(check_download_completion, interval=30, first=60) + logger.info("已注册离线下载完成通知任务(每 30 秒轮询)") admin_cmd = [ BotCommand("s", "搜索网盘文件"), BotCommand("sb", "搜索种子"), diff --git a/module/offline_download/offline_download.py b/module/offline_download/offline_download.py index 27f84e7..93d2042 100644 --- a/module/offline_download/offline_download.py +++ b/module/offline_download/offline_download.py @@ -17,6 +17,44 @@ DOWNLOAD_CACHE = {} STEP_SELECTING_TOOL = "tool" + +# ─── 下载完成通知 ────────────────────────────────────────────────────────────── +PREV_UNDONE_IDS: set[str] = set() + + +async def check_download_completion(context) -> None: + """定时检查离线下载任务,完成时主动推送通知(JobQueue 回调)""" + global PREV_UNDONE_IDS + try: + undone = await openlist.get_offline_download_undone_task() + done = await openlist.get_offline_download_done_task() + + current_undone_ids: set[str] = set() + if undone.data and isinstance(undone.data, list): + current_undone_ids = {str(t.get("id", "")) for t in undone.data if t.get("id")} + + done_map: dict[str, dict] = {} + if done.data and isinstance(done.data, list): + done_map = {str(t.get("id", "")): t for t in done.data if t.get("id")} + + newly_done = PREV_UNDONE_IDS & done_map.keys() + for task_id in newly_done: + task = done_map[task_id] + name, path = extract_file_info(task.get("name", "")) + size = format_size(task.get("total_bytes", 0)) + err = task.get("error", "") + if err: + text = f"❌ 下载失败\n\n文件: {name}\n路径: {path}\n错误: {err}" + else: + text = f"✅ 下载完成\n\n文件: {name}\n大小: {size}\n路径: {path}" + try: + await context.bot.send_message(chat_id=bot_cfg.admin, text=text) + except Exception as e: + logger.error(f"发送下载通知失败: {e}") + + PREV_UNDONE_IDS = current_undone_ids + except Exception as e: + logger.error(f"check_download_completion 失败: {e}") STEP_BROWSING_PATH = "browse_path" STEP_ENTERING_URL = "url" STEP_CONFIRMING = "confirm" From 2b5546e18cc9c3d4268ad95b38b69f1832f04304 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 7 Mar 2026 17:00:43 +0000 Subject: [PATCH 2/2] docs: update README roadmap to reflect completed features Mark file management (delete/mkdir/upload in /st) and notification system as completed; remove them from planned items. https://claude.ai/code/session_01HNCfZLiNXHZcchtifn6b5T --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7c921ba..96497d1 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ | `/s <关键词>` | 搜索网盘文件(支持类型筛选) | | `/sb <关键词>` | 搜索种子/磁力链接 (Prowlarr) | | `/sm <关键词>` | 通过 TMDB 搜索影视信息 | -| `/st` | 交互式浏览 OpenList 存储文件 | +| `/st` | 交互式浏览 OpenList 存储文件,支持删除、新建文件夹、上传文件 | | `/od` | 提交离线下载任务 | | `/ods` | 查看离线下载进度状态 | | `/cf` | 交互式配置默认下载设置 | @@ -92,12 +92,12 @@ - [x] 自动化链路:一键刷新 OpenList 缓存 + 触发 SmartStrm + 扫描 Jellyfin - [x] 配置管理:支持 YAML 配置文件与交互式修改配置项 - [x] Docker 支持:支持 GHCR 自动构建与多架构部署方案 +- [x] **文件管理增强**:支持在 `/st` 中直接删除文件/文件夹、新建文件夹、上传文件 +- [x] **通知系统**:离线下载完成/失败后通过机器人自动推送通知 ### 计划实现功能 -- [ ] **文件管理增强**:支持在 Telegram 中直接删除 OpenList 里的文件/文件夹 - [ ] **字幕搜索集成**:支持中文字幕搜索功能(拟集成多个字幕库 API) - [ ] **多用户权限管理**:更细粒度的管理员/成员使用权限控制 -- [ ] **通知系统**:离线下载完成后通过机器人自动推送通知 ## 注意事项