Commit Graph

946 Commits

Author SHA1 Message Date
jxxghp
e9f0c693e2 fix(torrent): retry transient downloads and shorten empty-content cooldown 2026-10-10 00:05:22 +08:00
jxxghp
9924e5e7ff fix(workflow): satisfy architecture gates for issue 6931 2026-10-09 23:58:33 +08:00
freeman
f3ad81b39e style: apply safe ruff auto-fixes and exempt startup late imports
Run `ruff check app tests scripts --fix` with the configured rule set
(E4/E7/E9/F/I): import sorting (I001), f-strings without placeholders
(F541), lambda/variable/unused-import cleanups that ruff marks safe.
Nine files whose only ruff debt sits next to pre-existing pylint
import-resolution errors (lazy exports, sys.path script imports) or
whose "unused" imports are reached through attribute access by tests are
left untouched so the changed-file pylint gate and the benchmark tests
stay green; their diagnostics remain in the baseline.

app/startup/lifecycle/__init__.py and app/main.py import business
modules after cache composition, import-path and stdio setup on purpose
(the source comments document the contract), so declare E402
per-file-ignores for them instead of adding per-line noqa.

Ruff ratchet watermark drops from 498 to 100; sync the baseline fixture
and the optimization checklist figure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 13:29:09 +08:00
jxxghp
1c1db41222 Merge pull request #6926 from cwd0204/test/optional-downloader-stubs 2026-10-09 13:05:13 +08:00
jxxghp
233be41b49 Merge pull request #6925 from cwd0204/fix/login-throttle 2026-10-09 13:04:40 +08:00
freeman
2165475dd0 fix(security): throttle password login after repeated failures
The access-token endpoint accepted unlimited password attempts; the
only existing rate limiters are single-instance helpers for outbound
site requests. Add app/application/security/throttle.py, an in-memory
LoginThrottle keyed by (client address, normalized username) that locks
for 30s after five consecutive failures and doubles the lockout up to
15 minutes. The endpoint answers 429 with Retry-After while locked,
counts only real credential failures (an MFA challenge after a correct
password does not count), and clears the record on success.

X-Forwarded-For is deliberately not trusted because there is no
trusted-proxy setting; behind the bundled nginx all requests share one
address, so the key degrades to per-username throttling, which is the
dimension brute-force protection needs. Sync the dependency snapshot
and architecture metrics for the new module.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 12:01:04 +08:00
jxxghp
54f2daba06 fix(subscribe): stop automatic searches and downloads when paused 2026-10-09 12:00:18 +08:00
freeman
88641d4a7a test: stub optional downloader modules only when they are missing
test_chain_rate_limit.py and test_system_notification_dispatch.py
installed a bare qbittorrentapi/transmission_rpc/psutil ModuleType into
sys.modules at import time with sys.modules.setdefault. When either file
is collected before a test that imports the real package in the same
shard (for example tests/test_downloader_add_failure_message.py and its
TorrentDictionary import), the placeholder wins and collection fails
with "cannot import name ... (unknown location)". Any change to the test
file set reshuffles the six CI shards and can surface this.

Use app.testing.bootstrap.ensure_optional_stub, which keeps the real
module when it is installed, and convert both unittest.TestCase files to
pytest-native functions as the testing guide requires when touching a
TestCase file. Record the resulting lower Ruff watermark.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 11:58:51 +08:00
jxxghp
35d5cac84f fix(subscribe): validate TMDB conversion and sync architecture facts 2026-10-08 21:22:17 +08:00
jxxghp
70811b551e feat(music): optionally simplify written lyrics 2026-10-08 18:40:16 +08:00
jxxghp
6758633e01 docs(architecture): sync metrics for Milkie adapter 2026-10-08 17:56:07 +08:00
jxxghp
656e2852f7 fix(indexer): paginate keyword results without server page support
Refs #6911
2026-10-08 13:46:57 +08:00
jxxghp
11303a8e88 fix(transfer): suppress completion events without target items 2026-10-08 13:42:08 +08:00
jxxghp
cf889ba7a0 fix(telegram): report persistent polling failures 2026-10-08 13:23:58 +08:00
jxxghp
f0b34cf9f5 fix(search): restore concurrent progressive manual paging 2026-10-08 11:57:10 +08:00
jxxghp
32d37fa8b4 feat(music): preserve per-task CUE recognition policy 2026-10-08 08:51:01 +08:00
jxxghp
6ba8bc027d fix(deps): update audited runtime dependencies 2026-10-08 07:27:25 +08:00
ChantXu64
e5e2558585 feat(search): 订阅补全逐页搜索、断点续搜与资源页手动分页 (#6907) 2026-10-07 14:40:55 +08:00
jxxghp
6c9ebd01f3 fix(agent): close owned LLM clients with their lifecycle
Refs #6901
2026-10-07 09:18:40 +08:00
jxxghp
e51fd44964 fix(agent): resolve alternative QQ and Feishu user bindings
Keep strict binding lookup as the default and explicitly match alternative channel identifiers for the Agent API gateway. Reject ambiguous active-user matches and cover single-field bindings with database-backed tests.

Refs #6905
2026-10-07 09:16:33 +08:00
Freeman
4c994c993f docs(download): document directory aliases for save_path
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 15:30:29 +08:00
jxxghp
791bcc00c0 fix(subscribe): persist cleared optional settings
Preserve explicit empty values for recognition words, keywords, paths, episode groups, downloaders, and audio thresholds. Add endpoint and persisted transaction regression coverage and document the update contract.

Refs #6894
2026-10-05 17:54:29 +08:00
jxxghp
fb652c74f4 fix(music): 支持关闭 CUE 识别整理分轨音频 2026-10-05 17:15:14 +08:00
jxxghp
ad4c92da9e Merge branch 'v3' into fix/media-scrape-manage-permission 2026-10-05 16:38:08 +08:00
LIN student
873c4c7087 fix(media): 刮削接口要求管理权限,与手动整理和文件管理保持一致
POST /api/v1/media/scrape/{storage} 只依赖 verify_token,任何登录用户都可
调用。该接口以 overwrite=True 调用刮削链,会覆盖目标目录已有的海报、背景图
和 NFO,音频文件还会改写标签;存储与路径完全由请求提供。

同类写操作 /transfer/manual、/transfer/manual/target-path、/storage/* 以及
整理记录的写操作都要求 manage 权限;前端只在文件管理页(需 manage 权限)
调用该接口,Agent 策略也已把 media.scrape 定为管理员操作。

现改为依赖 get_current_active_manage_user。_scrape_impl 内部没有使用令牌
载荷,去掉其中未使用的 Depends 参数。API_TOKEN/apikey 调用解析为 SUPERUSER
对应的超级管理员,行为不变。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 15:42:29 +08:00
LIN student
75d8b2e441 fix(system): 公开设置不再返回存储的连接配置
/system/setting/public/{key} 只要求登录用户,白名单中的 Storages 原样返回
整个存储列表,每项的 config 保存着各存储的连接配置和凭据(SMB 用户名密码、
alist 账号、115 token 等)。设置合同已将 Storages 标记为 sensitive,
/system/settings 默认会脱敏,只有这个公开接口直接返回原值。

前端 v3 已改用 /storage/options 读取存储名称和类型,公开接口的 Storages
目前只剩 Agent 的 config.public.get 和旧版前端页面会用到,它们只需要
name、type。因此保留该 key,改为与 /storage/options 相同的投影:只返回
name(缺省时取 type)和 type,跳过没有 type 的项。所有调用者返回相同
结果,超级管理员仍可通过 /system/setting/Storages 读取完整配置。

白名单内其他配置(目录、站点范围、集数定位规则、默认订阅规则、Follow
订阅者)不含连接凭据,保持原值返回。同步更新 docs/mcp-api.md 的接口说明。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 15:42:28 +08:00
jxxghp
fa5fa33db1 fix(lyrics): normalize LRCLIB music metadata 2026-10-05 13:10:10 +08:00
LIN student
3bdf09dc6f fix(site): 非超级管理员读取订阅站点和域名详情时不返回认证字段
/site/rss 与 /site/domain/{site_url} 只依赖 verify_token,直接返回完整的
Site 模型,其中包含 cookie、apikey、token、rss。同模块的 /site/agent 已经
对非超级管理员剔除这些字段,/site/ 列表也要求 manage 权限,两个接口与之
不一致。

前端订阅编辑和工作流「获取种子」动作只用到站点的 id、name、is_active,
因此非超级管理员改为复用 _project_agent_site(include_secrets=False) 投影,
超级管理员保持原有完整字段。

read_rss_sites 的返回标注由 List[dict] 改为实际的 Site 或投影字典,site.py
的 mypy 债务减少 2(return-value、type-arg 各 1),已固化低水位并同步文档
指标。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 19:01:22 +08:00
jxxghp
c8869d4b89 fix(api): classify notification image transport route 2026-10-04 16:33:11 +08:00
jxxghp
03a285a2a6 fix(wechat): proxy douban notification images 2026-10-04 16:19:58 +08:00
jxxghp
3f206171e7 fix(feishu): apply image referer and proxy policy
Refs #6879
2026-10-04 12:23:08 +08:00
jxxghp
e21d68496f fix(torrents): use incremental cache for M-Team by default
Refs #6878
2026-10-04 10:46:49 +08:00
jxxghp
823423b2c9 fix(download): refresh expired signed torrent links
Refs #6878
2026-10-04 10:27:28 +08:00
jxxghp
d8031e29a8 fix(agent): guide captcha OCR failures to browser vision 2026-10-04 09:19:29 +08:00
jxxghp
4d74d4c2e9 fix(agent): route API calls to the local backend (#6875) 2026-10-04 09:05:33 +08:00
jxxghp
fcf12a1e2f docs(architecture): sync music normalization dependency count 2026-10-04 09:04:09 +08:00
jxxghp
754da97d97 fix(music): apply simplified metadata to manual transfers
Normalize album details and final music template fields while preserving local edition evidence, multi-artist credits and source objects. Refs #6870.
2026-10-04 08:47:15 +08:00
InfinityPacer
6e295d5d2f fix(subscribe): preserve accepted searches for paused subscriptions 2026-10-04 00:22:57 +08:00
Cat
2a31b51687 fix(transfer): 整理规划的业务拒绝不再按系统错误告警 (#6868) 2026-10-03 23:03:15 +08:00
ChantXu64
3c56f0bfdc fix(llm): 允许温度留空以省略不兼容的请求参数 (#6865) 2026-10-03 19:55:43 +08:00
jxxghp
afa6a42a55 docs(architecture): sync mypy debt metric 2026-10-03 09:03:56 +08:00
jxxghp
118e2ef933 fix(notification): align scoped recipient routing 2026-10-03 01:00:21 +08:00
jxxghp
1ba2f28c94 chore(transfer): remove unrelated fork sync changes 2026-10-02 22:08:10 +08:00
jxxghp
b33053e10f Merge remote-tracking branch 'origin/v3' into codex/optimize-pr-6849
# Conflicts:
#	docs/architecture-overview.md
#	docs/refactor/optimization-checklist.md
#	tests/fixtures/architecture/dependency-baseline.json
2026-10-02 22:06:27 +08:00
jxxghp
5f596484b4 fix(classification): prepare policy-specific facts and refine defaults 2026-10-02 14:14:09 +08:00
jxxghp
da932158bb docs: sync system version query type debt metrics 2026-10-02 14:11:26 +08:00
jxxghp
a8b0870ef9 fix(cli): force sync remote tags during updates 2026-10-02 11:21:54 +08:00
jxxghp
e7852dd8a0 refactor(agent): 优化提示词并完善 Issue 反馈交互 2026-10-02 10:35:37 +08:00
jxxghp
bdbc801e83 fix(agent): steer active channel conversations into new replies 2026-10-02 09:12:21 +08:00
jxxghp
27a9ca4d66 feat(agent): install CJK history tokenizer for Docker and CLI 2026-10-01 23:26:10 +08:00