Commit Graph

288 Commits

Author SHA1 Message Date
Estrella Pan
87e23eea2d fix(plugins): 处理 Codex 对插件市场的审查意见
- 安装请求带上用户确认的版本,目录已换版本时后端拒绝
- 目录刷新换了条目时关闭确认栏,重新确认权限
- 是否有更新由后端按 PEP 440 判断(update_available)
- 插件改动后的同步失败不再算作操作失败
- KeepAlive 再次进入时重新加载失败,下次进入会再试
- 手机详情页的返回只在上一条历史是列表时后退
2026-10-09 15:39:17 +02:00
Estrella Pan
c67a63267f fix(webui): 处理市场页与内置插件文案的审查意见
- 设置页与市场页通过 pluginSetVersion 在再次进入时互相同步;刷新逻辑合并为 refreshPluginState
- 安装成功后本地更新 installed_version,不再重新下载目录
- 选中的插件变化时关闭确认栏,避免装错插件
- 本机版本比目录新时不提示更新
- 内置插件文案只用于 source 为 builtin 的插件
- README:链接中的行内代码、段落中的“2024.”、分隔线、标题中的“C#”
2026-10-09 15:34:31 +02:00
Estrella Pan
7ace0581e0 fix(webui): 市场页再次进入时同步安装状态;手机底栏用短标签 2026-10-09 15:27:01 +02:00
Estrella Pan
1fc10b16eb Merge branch 'fix/4.0-builtin-plugin-i18n' into feat/4.0-plugin-market-ui
# Conflicts:
#	webui/src/i18n/en.json
#	webui/src/i18n/zh-CN.json
#	webui/src/utils/id-label.ts
2026-10-09 13:37:41 +02:00
Estrella Pan
42bccb964b fix(webui): i18n 文案在构建后是消息函数,hasKey 一并识别 2026-10-09 13:35:19 +02:00
Estrella Pan
56ac06db2a feat(webui): 插件市场页面
- 新增 /market 与 /market/:id:列表 + 详情双栏,手机上点行进入整屏详情,
  主操作固定在底部;侧栏与手机导航加入口
- 按扩展点归类的分类标签、安装状态筛选与搜索;签名目录获取成功后缓存,
  目录不可达时显示上次的目录并禁用安装/更新
- 安装/更新前的确认步骤:来源与审查、权限声明、前端、同进程警告;
  更新显示版本与权限差异,权限变多须勾选确认
- README 用安全的 Markdown 子集渲染(先转义 HTML,链接只允许 http(s))
- 设置页的插件目录区换成「打开插件市场」入口
- 后端 CatalogEntry 补上 sdk 与 path 字段
2026-10-09 13:34:38 +02:00
Estrella Pan
40a525ecdc fix(webui): idLabel 识别预编译的 i18n 消息
构建时 unplugin-vue-i18n 把 i18n/*.json 的文案编译成消息函数,
idLabel 只认字符串,扩展点、权限与重命名方式在应用里一直显示原始 id。
2026-10-09 13:33:48 +02:00
Estrella Pan
49a499d417 fix(webui): 内置插件的名称、描述与配置字段支持英文
内置插件的清单与 config_model 只有中文,英文界面里直接显示中文。前端在
builtin_plugins.<id> 下为 4 个内置插件配齐中英文案,按插件 id 查找,查不到
(第三方插件)时仍显示后端文字。插件的停用原因改为代码(not_enabled、
unsigned_blocked),由前端翻译;“未启用”不再重复显示为提示框。
2026-10-09 13:14:33 +02:00
Estrella Pan
5fc7f749d7 Merge remote-tracking branch 'origin/4.0-dev' into feat/4.0-plugin-market 2026-10-09 13:00:21 +02:00
Estrella Pan
ee3ee0a6ab fix(webui): 4.0 界面审查第二轮修复
- 通知渠道列表测试:已保存且未改动的行按下标测试后端保存的配置(掩码密钥
  不再导致失败,插件渠道的自带字段得以保留),未保存的行按当前配置测试;
  后端下标改为对应完整渠道列表(含停用项)
- 插件配置表单:草稿深拷贝 options,编辑嵌套行后保存按钮可用
- 插件配置表单:数字字段清空后保持空白,Optional 字段清空为 null
- 标签输入:失焦(focusout)时添加未确认的输入;输入法组字时的回车不添加标签
- 下载器:切回已保存的类型时恢复保存的配置,不再清空凭据
- 插件挂载点加载失败时改为刷新页面,提示文案同步
- 移动端导航:同一插件只显示一个入口,导航项不收缩、可横向滚动
- 插件页面无匹配挂载点时标题回退为插件 id
2026-10-09 12:11:30 +02:00
Estrella Pan
5e15c5cf17 fix(webui): 4.0 界面审查修复
按 4.0 UI 审查确认的问题修复(设计规范、状态与流程、无障碍与手机端、文案):
- 插件卡片:加载失败可重试、未保存标记、开关与保存分开忙碌状态、停用或卸载
  仍在使用的插件前确认、扩展点与权限显示为译名、tags 字段改用 ab-tags-input
- 插件表单:必填与范围校验、删除非空行前确认、清空数字恢复默认值、稳定的行 key
- 插件页面与挂载点:加载骨架、失败原因与重试;手机底栏可进入插件页面
- 下载器:按类型显示字段、切换类型重置选项、id 规则提示、类型名称
- 通知:测试结果按列表 / 对话框分开、插件渠道提示、rename_skipped 显示方法名
- 规则编辑与添加 RSS:高级区改用 ab-field / ab-select,补充可访问名称
2026-10-09 10:23:16 +02:00
Estrella Pan
eb1598c21e feat(plugins): 插件市场索引与签名发布流水线
- plugins/registry/<id>.toml 指向作者仓库的固定 commit(repo、commit、path)
- scripts/plugin_registry.py:check 在 PR 上校验改动的条目、运行作者测试、
  从 web-src/ 构建前端并写审查摘要;build 在合并后增量打包(commit 未变的
  条目复用已发布的 zip)
- plugin-registry.yml:check / build 不读 secret,sign 只用 PLUGIN_SIGNING_KEY
  签名,不运行作者代码;发布到 release plugins 并删除下架的资源
- 插件目录改用独立的插件公钥 ab_plugin_pubkey.pem,与在线更新密钥分开
- catalog 条目新增 authors、permissions、has_web、repo、commit、readme
- 6 个示例插件上架;上架文档(中 / 英 / 日)、PR 模板与 CODEOWNERS
2026-10-09 10:13:30 +02:00
Estrella Pan
56fa95f51f refactor(4.0): 删除前端 experimental_openai 时代遗留的 OpenAIModel / OpenAIType 类型
P0 已删除后端的 experimental_openai 配置段,这两个类型没有任何引用。
2026-10-08 17:21:35 +02:00
Estrella Pan
c05c2b1727 fix(4.0): 种子批量操作按实例汇总结果、按实例区分选择,下载器页按任一已配置实例判断
- perInstance 对所有实例并发执行,任一实例异常或返回 status: false 都按失败处理并提示,不被其它实例的成功掩盖;无论成败都刷新列表
- 选择键改为 downloader_id:hash,同一 hash 存在于多个实例时只操作选中的那一个
- 下载器页「未配置」判断改为没有任一已配置实例;插件下载器无 host 字段时视为已配置
2026-10-08 17:06:53 +02:00
Estrella Pan
d8dabe4c4c fix(4.0): 插件卡片刷新 allow_unsigned、保留其它卡片未保存的草稿,整数枚举下拉保留原类型
- 卡片操作后同步刷新 config store 的 plugins.allow_unsigned,全局保存不再用旧值回退该开关
- apply() 只重建服务端配置或 schema 变化的插件草稿,切换某个插件不再丢弃其它卡片的未保存编辑
- 枚举下拉以 {label, value} 传入候选值,整数枚举保存为数字而非字符串
2026-10-08 17:06:53 +02:00
Estrella Pan
ee5704eef0 feat(4.0): 设置页新增签名插件目录的浏览、安装、更新与卸载
- 插件卡片下方新增「插件目录」区:点击后才请求 GET /plugins/catalog(silent),失败时在区内显示后端原因并可刷新
- 条目按已装版本显示安装 / 更新 / 已安装;安装成功后刷新卡片、Provider 下拉与前端挂载点
- 卸载只对来源为 catalog 的插件开放,经危险确认框;与后端卸载前提为同一条件,LLM 插件不受影响
- 卡片标出已签名 / 未签名
- 修复前端缺少 catalog 来源类型与 source_catalog 文案
- 同步签名与分发文档(中 / 英 / 日)、设计文档第 0 节与 CHANGELOG
2026-10-08 15:38:52 +02:00
Estrella Pan
34d51dd711 fix(4.0-P6): 嵌套秘密字段掩码、未启用插件 schema 刷新、custom element 归属校验 2026-10-08 14:05:56 +02:00
Estrella Pan
91e01f716f feat(4.0-P6): WebUI 插件挂载点、AbHost 宿主实现与示例插件「手动选种」
- PluginSlot:导入插件模块并在 Shadow DOM 中挂载 custom element,host / context 先于插入设置;加载失败、元素未定义或运行时报错只让该插件的挂载点显示「插件组件加载失败」
- AbHost:api 限定在 /api/v1/plugins/<id>/ 与只读 GET 的宿主 API;i18n、主题、toast;events.on 订阅 SSE 新增的 bus 帧(后端把总线事件转发给前端)
- 五个挂载点:设置分区、番剧详情标签、卡片操作、侧边栏页面 /plugins/:id、首页小组件
- 未启用的内置 / 已允许的插件也能取得配置 schema,首次启用前即可填写配置
- Schema 表单支持对象数组(hardlink 的 path_map)
- hardlink 插件自带 settings.section 元素「链接已有文件」,调用补链路由并显示计数
- examples/plugins/manual-pick:详情页标签示例,含插件路由与事件订阅
- 设计文档第 0 节记录调整,第 10 节标记 P6 已完成
2026-10-08 13:50:46 +02:00
Estrella Pan
bf1c8db08c feat(4.0-P6): 前端插件后端与 plugin-ui 工作区包
- 清单 [[plugin.ui]]:五个挂载点、ab-plugin- 元素名与 web/ 入口校验
- GET /plugins/ui 列出已启用插件的挂载点;GET /plugins/{id}/web/{path} 提供静态资源(防路径穿越、JS MIME、需登录)
- SPA 文档加 CSP script-src 'self',内联深色模式脚本移到 theme-init.js
- webui/packages/plugin-ui:AbHost 类型、--ab-* 主题变量、Vite 库模式模板
- 设计文档第 0 节记录第一部分的调整
2026-10-08 13:31:03 +02:00
Estrella Pan
7af2c781aa fix(4.0-P2.5): 部分更新规则时保持原下载器实例,编辑器打开时才请求实例列表
- update_rule 在请求未带 downloader_id 时沿用规则原来的实例,不再按默认实例重算保存目录
- 下载器设置的实例行改用 ab-button
- 规则编辑与添加订阅在每次打开时请求实例列表(组件常驻,创建时请求会拿到旧列表)
2026-10-08 12:45:22 +02:00
Estrella Pan
d0e357a603 feat(4.0-P2.5): WebUI 管理多个下载器实例,规则与订阅可选下载器,种子列表标注实例
- 下载器设置列出所有实例:添加、编辑、删除、设为默认,类型下拉框含插件下载器
- 规则编辑与添加订阅新增下载器选择(留空跟随默认实例,只有一个实例时不显示)
- 下载器页与种子列表在多实例时标出种子所在实例,批量暂停 / 恢复 / 删除按实例分别请求
- 插件卡片保存后只刷新 plugins.enabled / options,不再覆盖未保存的实例与 slots 修改
- 添加订阅时保存 downloader_id
2026-10-08 12:37:06 +02:00
Estrella Pan
e442d35c76 feat(4.0-P2.5): 下载器改为 plugins.instances 实例,slots 选择 Provider,新增 3.3 配置迁移器
- 运行时模型移除 downloader 配置节:下载器是 plugins.instances 中的实例(id / point / provider / options),plugins.slots.downloader 指向默认实例;Config.downloader 改为只读视图
- 重命名方式、文件分类、版本冲突策略按 plugins.slots 选择,未登记时退回 none / default / hold;冲突策略改为 core 的 hold / replace 两个 Provider,ConflictRequest 删除 configured,ab_sdk 升至 0.5.0
- module/update/v4.py:迁移 downloader、rename_method(normal 改为 none)、revision_conflict_policy;先备份为 config.json.v3.bak,失败时恢复备份并拒绝启动;在 Settings 读写配置前运行
- module.update 包初始化不再 import 子模块,避免 module.conf 引用迁移器时循环 import
- AB_DOWNLOADER_* 等环境变量与设置向导写入默认实例
- 数据库迁移 v26:bangumi / movie / rssitem / torrent 增加 downloader_id,存量行为 default
- WebUI:下载器设置编辑默认实例,重命名方式与版本冲突策略绑定 plugins.slots
2026-10-08 12:07:53 +02:00
Estrella Pan
a0ebfff0e1 feat(4.0-P4): 内置插件 rename 提供 pn / advance / template 重命名方式
- pn / advance 从 core 移入内置插件 rename(默认启用),输出与 3.x 逐字节一致;
  宿主只保留 none,插件停用时按 none 处理。
- template:Jinja2 沙箱模板(StrictUndefined + pad 过滤器)渲染文件名主体,
  字幕自动追加语言与扩展名。保存配置时编译并试渲染示例,不合法返回 422;
  运行时渲染失败、结果为空或含路径分隔符时抛出 RenameSkipped,文件保留原名并
  通知,绝不退回 pn。
- 设置页重命名方式下拉框并入插件提供的方式;通知中心支持 rename_skipped。
- 测试环境默认登记内置 rename 插件,与生产默认启用一致。
2026-10-08 10:37:58 +02:00
Estrella Pan
58f3b40599 Merge branch 'refactor/4.0-p2-extension-points' into refactor/4.0-p3-ingest
# Conflicts:
#	backend/src/module/plugin/host.py
#	webui/src/hooks/usePluginProviders.ts
2026-10-08 09:00:59 +02:00
Estrella Pan
0c5563f8c8 fix(4.0-P2): 修复评审发现的插件隔离与掩码问题
- 插件清单拒绝保留 id "core",避免插件与宿主内置 Provider 共享归属
- 新增 host.provider_impls():搜索站点与 LLM 扩展适配器逐个调用工厂,出错的跳过并记录
- 插件代码未加载(无 schema)时,掩码/还原把全部配置项按秘密处理
- 定时任务桥接:ScheduledTask 字段读取纳入异常保护并计入熔断;enabled 每轮读取,异常计入熔断
- 通知渠道先按原样匹配 type,再按小写兼容,支持含大写的插件渠道 id
- WebUI:插件启停/保存后刷新插件 Provider 候选列表
2026-10-08 08:55:34 +02:00
Claude
9b7ef00c2e feat(4.0-P3): ingest 流水线扩展点与内置种子过滤插件
- 钩子:torrent.filter(排除过滤之后,fail-open)、title.parsed(准入判定前)、
  torrent.adding(save_path / category / tags,ab:<id> 标签强制保留)、
  http.request(GET 请求头)
- Provider:metadata_provider,mikan / tmdb 以 core 登记,按 RSSItem.parser 选择,
  行为与 3.x 一致;插件元数据源走超时与熔断
- SDK 0.3.0:新增 ab_sdk.ingest(冻结快照 TorrentInfo / BangumiInfo / AddRequest /
  HttpRequest / Metadata)
- host.get_runner()/hook_runner():AppContext 构建时设置 runner,无钩子时零开销
- 内置插件 ingest-filters:全局包含过滤,默认启用、留空不生效
- WebUI:添加订阅的解析器下拉框并入插件元数据源
- 文档:插件开发指南新增各扩展点;设计文档 P3 调整

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EoBUPFw7Ty1epuPESdELs1
2026-10-08 06:31:23 +00:00
Claude
332fb451c4 feat(4.0-P2): 下载器/通知/LLM/搜索/定时任务扩展点与插件管理界面
- ab_sdk 0.2:新增 points、downloader(自 module/downloader/base.py 迁入)、
  llm(自 providers/base.py 迁入)、notify、search、tasks 契约与
  secret_field();原路径保留重新导出
- module/plugin/host:进程级扩展注册表,内置 qB/aria2/mock 与各通知渠道以
  core 身份登记;DownloadClient、NotificationManager、LLM 注册表、搜索站点
  均改为按 id 从注册表解析
- 插件定时任务随插件加载/重载/停用同步进调度器,失败计入熔断
- 插件变更后重建通知渠道、清理 LLM 解析器缓存;下载器客户端缓存键包含
  Provider 登记项,插件重载后自动换新
- /api/v1/plugins:总览(schema + 掩码配置)、启停、配置(按模型校验)、
  allow_unsigned、Provider 列表;/config 读写同样掩码/还原插件秘密字段
- WebUI:设置页「插件」卡片与 JSON Schema 表单;下载器与通知下拉框并入插件
  Provider;插件保存后刷新 config store 的 plugins 段,避免全局保存覆盖
- 修复:/search/provider 读取导入时的站点快照,新站点需重启才出现
- 文档:开发者指南 → 插件开发

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EoBUPFw7Ty1epuPESdELs1
2026-10-08 05:59:07 +00:00
Claude
94da8fa741 feat(4.0-P1): 插件运行时与 SDK 骨架
- ab_sdk:Plugin[ConfigT] 基类、@hook / @provider / @subscribe、只读的
  PluginContext 协议、事件基类,以及插件单测辅助 ab_sdk.testing;SDK 不依赖
  module.*(有边界测试)
- module/plugin:plugin.toml 清单校验(含 sdk 版本范围),内置 / 本地目录 /
  pip entry point 三种来源的发现与加载(ab_plugin_<id> 包名、支持相对导入、
  vendor 纯 Python 依赖、拒绝原生扩展)
- 扩展点注册表;HookRunner 负责 filter / transform 钩子的优先级与 hook_order
  排序、超时、fail-open / fail-closed,以及按插件熔断
- EventBus:每个订阅者独立的有序队列,失败与超时隔离,计入熔断
- PluginManager:失败时回滚注册;配置变更只重载受影响的插件;失败插件在其
  配置变化后才重试;熔断后自动禁用并发布 PluginDisabled
- 插件私有 KV 存储(plugin_kv 表,迁移 v25)、plugins 配置段、
  GET /api/v1/plugins
- 插件随进程 lifespan 启停,reload_settings 时重新应用插件配置

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EoBUPFw7Ty1epuPESdELs1
2026-10-08 04:37:57 +00:00
Claude
8ccacb6060 refactor(4.0-P0): 清理死代码与 3.x 兼容层
- 4.0 只支持从 3.3.x 升级:version_check 改为完整 semver 比较,数据低于 3.3
  或残留 2.x data.json 时抛 UnsupportedUpgradeError 中止启动;删除 3.0→3.2
  跨版本迁移、data.json 迁移和 Database.migrate()
- 删除 3.2 兼容的 GET 控制端点与 GET /auth/refresh_token
- 删除旧 JWT 与内存会话实现,密码哈希移到 security/password.py
- 删除 experimental_openai 配置节、通知单 provider 旧字段、3.1 配置字段改名迁移
  与 DEFAULT_SETTINGS;normal 重命名方式迁移为 none
- 删除约 70 处无调用方的函数、方法、模型及未使用的 qB API 封装
- CI 新增 vulture 死代码检查(配置见 pyproject.toml 与 vulture_whitelist.py)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EoBUPFw7Ty1epuPESdELs1
2026-10-08 04:19:53 +00:00
Estrella Pan
520873f035 test(e2e): align standalone movie contract (#1080) 2026-07-15 15:33:36 +02:00
Estrella Pan
9d5b1c3998 fix(renamer): safely replace higher revisions (#1078) 2026-07-13 01:36:17 +02:00
Estrella Pan
32dcbc53df fix(webui): type template event handlers 2026-07-12 21:07:33 +02:00
Estrella Pan
e8bcece42f feat(parser): add selectable preview engine 2026-07-12 21:07:33 +02:00
Estrella Pan
be8d23c319 fix(webui): hide archived anime from calendar 2026-07-11 12:36:50 +02:00
Estrella Pan
86e39811d1 fix(ci): track e2e fixture and sync beta lock 2026-07-10 14:12:00 +02:00
Estrella Pan
7680514a1b test: verify real downloader release flow 2026-07-10 13:50:51 +02:00
Estrella Pan
57d071b2c9 test: cover issue-driven ui regressions 2026-07-10 13:50:36 +02:00
Estrella Pan
8df50b65eb test: add browser auth e2e coverage 2026-07-10 13:50:15 +02:00
Estrella Pan
81cfa41c26 fix: address authentication review findings 2026-07-10 11:56:42 +02:00
Estrella Pan
42ccb7611b feat: persist multi-user authentication 2026-07-10 00:52:39 +02:00
Estrella Pan
b279295515 Merge pull request #1070 from EstrellaXD/fix/issues-1067-1068 2026-07-09 15:42:56 +02:00
Estrella Pan
9586513f6f fix: address recent issue regressions 2026-07-09 14:28:33 +02:00
Estrella Pan
59ed2d926e feat(searcher): add AniBT as a built-in search provider
Add anibt.net as a first-class default search provider alongside
mikan/nyaa/dmhy, using its RSS search endpoint
(https://anibt.net/rss/magnets.xml?q=%s) with the tmdb parser.

load_provider() now merges newly added built-in sites into an
already-saved config/search_provider.json, so existing installs pick
up new default providers on restart while keeping user-customized
URLs and parsers untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YUaTRVgAxPq6zEiwJHnbiC
2026-07-08 11:27:43 +02:00
Estrella Pan
4aa2cfb858 fix(webui): stop leaked search streams duplicating results and spinning
open() never closed the previous EventSource, so re-searching leaked
the old stream: it kept appending the same results (duplicate
variants/tags in the list), its onerror closed the NEW stream's
handle, and the leaked stream auto-reconnected forever — an idle
spinner even with an empty input.

- close the previous stream before opening a new one
- stale-stream handlers close themselves and never touch shared state
- de-duplicate appended results by rss_link as a safety net
- clearing the input stops an in-flight search
- eventSource must be a shallowRef: ref() proxies the EventSource and
  breaks the same-stream identity check

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pz1EmcTPzjgEpkGQWzb8AQ
2026-07-07 22:15:52 +02:00
Estrella Pan
618464a450 feat(config): user-configurable TMDB API key + Network settings panel (#975, #1042)
Backend: add network.tmdb_api_key (empty = fall back to the built-in
shared key, read live like tmdb_base_url); the config API masks it
automatically.

WebUI: the network section existed backend-only since #1042 — expose
it as a Network settings panel (TMDB API URL, TMDB API key,
Bangumi API URL) with types, initConfig defaults, i18n, and mocks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pz1EmcTPzjgEpkGQWzb8AQ
2026-07-07 18:05:53 +02:00
Estrella Pan
1b928ee326 feat(rss): setting to disable orphan-torrent tracking
New bangumi_manage.track_orphans toggle (default on = current
behavior). When off, refresh_rss no longer persists unmatched torrents
(bangumi_id NULL orphan records): they are re-matched in memory each
tick (cheap, no network — the analyser dedups via bangumi rules, not
torrent records), and a rule added later can retroactively pick up
episodes still in the feed, which persisted orphans used to block
forever. Season-collect flows still persist their NULL records for
feed dedup and are not gated.

WebUI: "Track Unmatched Torrents" switch in Settings -> Manage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pz1EmcTPzjgEpkGQWzb8AQ
2026-07-07 12:15:06 +02:00
Estrella Pan
d91686486b refactor(webui): rework torrent-management UI to Soft Ink ab-* layer
Post-rebase rework addressing review findings on #1051 (the branch
predated the component-system migration):

- Replace retired ab-popup confirm with the useConfirm() promise hook
- Replace NButton and bare <button> with ab-button / ab-icon-button;
  badge pills with ab-tag / ab-badge marks; empty state with ab-empty;
  drop hardcoded colors for theme variables
- Make the per-bangumi page's route param reactive with a NaN guard,
  and remount the list on param change
- Add a "View torrents" entry point in the rule edit dialog
- Reload the torrent list in finally so partial batch-delete failures
  don't leave stale rows
- Align the orphan card title across locales; regenerate dts files

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pz1EmcTPzjgEpkGQWzb8AQ
2026-07-07 10:58:58 +02:00
Estrella Pan
679bd2621c feat: manage bangumi torrents and orphan torrents (port of #1020)
Port zhushanwen321's torrent-management feature (#1020) from the 3.2 sync
architecture to the 3.3 async design.

Backend:
- TorrentDatabase: search_orphans / count_orphans / delete_orphans / delete_obj
- bangumi API: list/delete endpoints for per-bangumi torrents and orphan
  torrents (bangumi_id IS NULL); literal /torrents/orphans routes registered
  before /{bangumi_id}/torrents

WebUI:
- Others card on the bangumi list with orphan count badge
- Torrent list pages (per-bangumi and orphans) with multi-select,
  batch delete, and clear-all confirm dialog

The PR's mikan_parser and rss/analyser fixes are not ported: 3.3-dev
already handles failed poster downloads and missing elements.

Co-authored-by: zhushanwen321 <zhushanwen321@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs
2026-07-07 10:48:07 +02:00
Estrella Pan
a9839e0725 Merge pull request #1056 from EstrellaXD/feat/nexusphp-pt-provider
feat(webui): NexusPHP PT-site preset for search providers
2026-07-07 10:45:52 +02:00
Estrella Pan
77e50484f3 fix(webui): correct NexusPHP category format and validate input
Review findings on #1056, verified against upstream NexusPHP source:

- torrentrss.php only recognizes per-category flags (cat402=1); the
  bare cat=402 form was silently ignored. Emit cat<ID>=1 and accept
  comma-separated IDs.
- Validate that category IDs are numeric, with a warning and Apply
  gating in the dialog.
- Stock NexusPHP hardcodes $searchstr = null (search unsupported), so
  the template only filters on sites/forks that kept search support —
  the hint now tells users to verify this on their site instead of
  implying it always works.
- Mask the passkey in the dialog's URL preview (stored URL unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pz1EmcTPzjgEpkGQWzb8AQ
2026-07-07 10:42:53 +02:00