refactor(chain): chain 与 module 仅经 run_module 契约互联,实现模块内容封闭

- mTorrent 字幕链接解析下沉为 IndexerModule.site_subtitle_links,subtitle 模块自行跳过 API 站点
- TMDB/MusicBrainz 识别缓存管理改为模块方法(tmdb_cache_*/music_cache_*)经 run_module 分发
- WechatClawBot 客户端查找/临时客户端/缓存迁移内聚为 wechatclawbot_* 模块方法,
  chain 移除 WechatClawBot 类与 ModuleManager 内省
- LISTENBRAINZ_* 常量迁至 schemas/types.py,模块与链层再导入保持兼容
- TMDbException 升为 schemas/exception.py 跨层契约,vendored 异常保持类身份一致
- 架构守护测试新增 test_chain_does_not_import_module_internals(共 18 项)
- 文档同步:chain->module 仅允许 run_module 分发,直接导入禁止
This commit is contained in:
jxxghp
2026-08-16 05:25:28 +08:00
parent 02f0dd0b9a
commit 4345fcfa22
21 changed files with 241 additions and 131 deletions
+1 -14
View File
@@ -29,10 +29,7 @@ from app.domain.metainfo import MetaInfo
from app.db.oper.downloadfailure import DownloadFailureOper
from app.db.oper.downloadhistory import DownloadHistoryOper
from app.db.oper.mediaserver import MediaServerOper
from app.db.oper.site import SiteOper
from app.application.directory import DirectoryHelper, validate_download_save_path
from app.application.site.sites import SitesHelper # pylint: disable=no-name-in-module
from app.modules.indexer.spider.mtorrent import MTorrentSpider
from app.runtime.thread import ThreadHelper
from app.application.torrent import TorrentHelper
from app.runtime.log import logger
@@ -554,18 +551,8 @@ class DownloadChain(ChainBase):
def _site_subtitle_links(self, context: Context) -> Optional[List[str]]:
"""
解析站点详情页的字幕下载链接,API 站点直接调用对应爬虫,
普通站点通过模块分发解析页面代码
解析站点详情页的字幕下载链接,模块内部自行区分页面解析与API站点
"""
torrent = context.torrent_info
if torrent.site is not None:
site = SiteOper().get(torrent.site)
if indexer := SitesHelper().get_indexer(site.domain):
if indexer.get("parser") == "mTorrent":
return MTorrentSpider(indexer).get_subtitle_links(
torrent.page_url
)
# TODO 其它采用API访问的站点
return self.run_module("site_subtitle_links", context=context)
def download_site_subtitles(