fix(architecture): satisfy ruff/mypy ratchets for media auxiliary

e02418bac 把新导入放在 settings = RuntimeSettingsCompat() 之后,
导致 5 个模块 E402 诊断超出只降不增基线;同时 media_auxiliary
把工厂函数 MetaInfo 误用作返回类型标注。将新增导入移回赋值语句
之前,返回类型修正为 MetaBase。
This commit is contained in:
jxxghp
2026-08-26 14:33:36 +08:00
parent df2ce103e1
commit cdab54254d
6 changed files with 42 additions and 46 deletions
+2 -1
View File
@@ -21,8 +21,9 @@ class MediaAuxiliaryProviderMixin:
def _build_auxiliary_meta(
mediainfo: MediaInfo,
metainfo: Optional[MetaBase] = None,
) -> MetaInfo:
) -> MetaBase:
"""根据主识别结果构造不携带原来源身份的标题查询参数。"""
# MetaInfo 是工厂函数,实际返回 MetaBase 及其子类实例
meta = MetaInfo(mediainfo.title or getattr(metainfo, "name", None) or "")
if not meta.en_name:
meta.en_name = mediainfo.en_title or getattr(metainfo, "en_name", None)
+5 -6
View File
@@ -1,16 +1,15 @@
from typing import List, Optional, Tuple, Union
from app.runtime.settings import RuntimeSettingsCompat
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.runtime.settings import get_runtime_setting
from app.schemas.context import MediaPerson as _SchemaMediaPerson
settings = RuntimeSettingsCompat()
from app.domain.context import MediaInfo
from app.domain.media import is_media_source_enabled
from app.domain.meta.metabase import MetaBase
from app.domain.scraper import MediaScraperHelper
from app.modules import _ModuleBase
from app.modules.anilist.anilist import AniListApi
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.runtime.log import logger
from app.schemas.types import (
MediaRecognizeType,
@@ -78,7 +77,7 @@ class AniListModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param media_source: 请求级识别数据源
:return: 是否启用 AniList 识别
"""
return (media_source or settings.RECOGNIZE_SOURCE) == MediaSource.AniList
return (media_source or get_runtime_setting("RECOGNIZE_SOURCE")) == MediaSource.AniList
@staticmethod
def _media_type(info: dict) -> MediaType:
@@ -571,7 +570,7 @@ class AniListModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param episode: 集号
:return: NFO XML 文本
"""
scrape_source = mediainfo.scrape_source or settings.SCRAP_SOURCE
scrape_source = mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")
if scrape_source != "anilist":
return None
return self.scraper.get_metadata_nfo(mediainfo, season=season, episode=episode)
@@ -590,7 +589,7 @@ class AniListModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param episode: 集号
:return: 图片文件名与下载地址映射
"""
scrape_source = mediainfo.scrape_source or settings.SCRAP_SOURCE
scrape_source = mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")
if scrape_source != "anilist":
return None
return self.scraper.get_metadata_img(mediainfo, season=season, episode=episode)
+7 -8
View File
@@ -1,10 +1,10 @@
from dataclasses import dataclass
from typing import Any, List, Optional, Tuple, Union
from app.runtime.settings import RuntimeSettingsCompat
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.runtime.settings import get_runtime_setting
from app.schemas.context import MediaPerson as _SchemaMediaPerson
settings = RuntimeSettingsCompat()
from app.adapters.network.http import RequestUtils
from app.domain.context import MediaInfo
from app.domain.media import is_media_source_enabled
@@ -12,7 +12,6 @@ from app.domain.meta.metabase import MetaBase
from app.domain.scraper import MediaScraperHelper
from app.modules import _ModuleBase
from app.modules.bangumi.bangumi import BangumiApi
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.runtime.log import logger
from app.schemas.types import (
MediaRecognizeType,
@@ -45,7 +44,7 @@ class BangumiModule(MediaAuxiliaryProviderMixin, _ModuleBase):
"""
初始化Bangumi客户端
"""
self._config = BangumiConfigSnapshot(proxy=settings.PROXY)
self._config = BangumiConfigSnapshot(proxy=get_runtime_setting("PROXY"))
self.bangumiapi = BangumiApi()
self.scraper = MediaScraperHelper()
@@ -127,7 +126,7 @@ class BangumiModule(MediaAuxiliaryProviderMixin, _ModuleBase):
return None
bangumiid = int(media_id) if media_id is not None else None
if not bangumiid and (
not meta or (media_source or settings.RECOGNIZE_SOURCE) != MediaSource.Bangumi
not meta or (media_source or get_runtime_setting("RECOGNIZE_SOURCE")) != MediaSource.Bangumi
):
return None
@@ -176,7 +175,7 @@ class BangumiModule(MediaAuxiliaryProviderMixin, _ModuleBase):
return None
bangumiid = int(media_id) if media_id is not None else None
if not bangumiid and (
not meta or (media_source or settings.RECOGNIZE_SOURCE) != MediaSource.Bangumi
not meta or (media_source or get_runtime_setting("RECOGNIZE_SOURCE")) != MediaSource.Bangumi
):
return None
@@ -317,7 +316,7 @@ class BangumiModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param episode: 集号
:return: NFO XML文本
"""
scrape_source = mediainfo.scrape_source or settings.SCRAP_SOURCE
scrape_source = mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")
if scrape_source != "bangumi":
return None
return self.scraper.get_metadata_nfo(mediainfo, season=season, episode=episode)
@@ -336,7 +335,7 @@ class BangumiModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param episode: 集号
:return: 图片文件名与下载地址映射
"""
scrape_source = mediainfo.scrape_source or settings.SCRAP_SOURCE
scrape_source = mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")
if scrape_source != "bangumi":
return None
return self.scraper.get_metadata_img(mediainfo, season=season, episode=episode)
+7 -8
View File
@@ -3,10 +3,10 @@ from typing import Any, List, Optional, Tuple, Union
import cn2an
from app.runtime.settings import RuntimeSettingsCompat
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.runtime.settings import get_runtime_setting
from app.schemas.context import MediaPerson as _SchemaMediaPerson
settings = RuntimeSettingsCompat()
from app.adapters.network.http import RequestUtils
from app.domain.context import (
MediaInfo,
@@ -21,7 +21,6 @@ from app.foundation.text import convert as zhconv_convert
from app.modules import _ModuleBase
from app.modules.douban.apiv2 import DoubanApi
from app.modules.douban.scraper import DoubanScraper
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.runtime.execution import retry
from app.runtime.log import logger
from app.runtime.rate import rate_limit_exponential
@@ -707,7 +706,7 @@ class DoubanModule(MediaAuxiliaryProviderMixin, _ModuleBase):
if (
meta
and not doubanid
and (kwargs.get("media_source") or settings.RECOGNIZE_SOURCE) != "douban"
and (kwargs.get("media_source") or get_runtime_setting("RECOGNIZE_SOURCE")) != "douban"
):
return None
@@ -778,7 +777,7 @@ class DoubanModule(MediaAuxiliaryProviderMixin, _ModuleBase):
if (
meta
and not doubanid
and (kwargs.get("media_source") or settings.RECOGNIZE_SOURCE) != "douban"
and (kwargs.get("media_source") or get_runtime_setting("RECOGNIZE_SOURCE")) != "douban"
):
return None
@@ -1685,7 +1684,7 @@ class DoubanModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param mediainfo: 媒体信息
:param season: 季号
"""
if (mediainfo.scrape_source or settings.SCRAP_SOURCE) != "douban":
if (mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")) != "douban":
return None
return self.scraper.get_metadata_nfo(mediainfo=mediainfo, season=season)
@@ -1696,7 +1695,7 @@ class DoubanModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param season: 季号
:param episode: 集号
"""
if (mediainfo.scrape_source or settings.SCRAP_SOURCE) != "douban":
if (mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")) != "douban":
return None
return self.scraper.get_metadata_img(mediainfo=mediainfo, season=season, episode=episode)
@@ -1707,7 +1706,7 @@ class DoubanModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param mediainfo: 媒体信息
:return: None 表示不处理,MediaInfo 表示继续处理
"""
if mediainfo.media_source != MediaSource.Douban and settings.RECOGNIZE_SOURCE != "douban":
if mediainfo.media_source != MediaSource.Douban and get_runtime_setting("RECOGNIZE_SOURCE") != "douban":
return None
if not mediainfo.douban_id:
return None
+14 -15
View File
@@ -3,19 +3,18 @@ from typing import Dict, List, Optional, Tuple, Union
import cn2an
from app.runtime.settings import RuntimeSettingsCompat
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.runtime.settings import get_runtime_setting
from app.schemas.context import MediaPerson as _SchemaMediaPerson
from app.schemas.tmdb import TmdbEpisode as _SchemaTmdbEpisode
from app.schemas.tmdb import TmdbSeason as _SchemaTmdbSeason
settings = RuntimeSettingsCompat()
from app.adapters.network.http import RequestUtils
from app.domain.context import MediaInfo
from app.domain.media import is_media_source_enabled, is_media_source_selected
from app.domain.meta.metabase import MetaBase
from app.foundation.text import convert as zhconv_convert
from app.modules import _ModuleBase
from app.modules._base.media_auxiliary import MediaAuxiliaryProviderMixin
from app.modules.themoviedb.category import CategoryHelper
from app.modules.themoviedb.scraper import TmdbScraper
from app.modules.themoviedb.tmdb_cache import TmdbCache
@@ -95,13 +94,13 @@ class TheMovieDbModule(MediaAuxiliaryProviderMixin, _ModuleBase):
"""
测试模块连接性
"""
ret = RequestUtils(ua=settings.NORMAL_USER_AGENT, proxies=settings.PROXY).get_res(
f"https://{settings.TMDB_API_DOMAIN}/3/movie/550?api_key={settings.TMDB_API_KEY}")
ret = RequestUtils(ua=get_runtime_setting("NORMAL_USER_AGENT"), proxies=get_runtime_setting("PROXY")).get_res(
f"https://{get_runtime_setting("TMDB_API_DOMAIN")}/3/movie/550?api_key={get_runtime_setting("TMDB_API_KEY")}")
if ret and ret.status_code == 200:
return True, ""
elif ret:
return False, f"无法连接 {settings.TMDB_API_DOMAIN},错误码:{ret.status_code}"
return False, f"{settings.TMDB_API_DOMAIN} 网络连接失败"
return False, f"无法连接 {get_runtime_setting("TMDB_API_DOMAIN")},错误码:{ret.status_code}"
return False, f"{get_runtime_setting("TMDB_API_DOMAIN")} 网络连接失败"
def init_setting(self) -> Tuple[str, Union[str, bool]]:
pass
@@ -123,7 +122,7 @@ class TheMovieDbModule(MediaAuxiliaryProviderMixin, _ModuleBase):
if not tmdbid and not meta:
return False
selected_source = normalize_media_source(media_source or settings.RECOGNIZE_SOURCE)
selected_source = normalize_media_source(media_source or get_runtime_setting("RECOGNIZE_SOURCE"))
if meta and not tmdbid and selected_source != MediaSource.TMDB:
return False
@@ -974,7 +973,7 @@ class TheMovieDbModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param season: 季号
:param episode: 集号
"""
if (mediainfo.scrape_source or settings.SCRAP_SOURCE) != "themoviedb":
if (mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")) != "themoviedb":
return None
return self.scraper.get_metadata_nfo(meta=meta, mediainfo=mediainfo, season=season, episode=episode)
@@ -986,7 +985,7 @@ class TheMovieDbModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param season: 季号
:param episode: 集号
"""
if (mediainfo.scrape_source or settings.SCRAP_SOURCE) != "themoviedb":
if (mediainfo.scrape_source or get_runtime_setting("SCRAP_SOURCE")) != "themoviedb":
return None
return self.scraper.get_metadata_img(mediainfo=mediainfo, season=season, episode=episode)
@@ -1107,7 +1106,7 @@ class TheMovieDbModule(MediaAuxiliaryProviderMixin, _ModuleBase):
:param mediainfo: 媒体信息
:return: None 表示不处理,MediaInfo 表示继续处理
"""
if mediainfo.media_source != "themoviedb" and settings.RECOGNIZE_SOURCE != "themoviedb":
if mediainfo.media_source != "themoviedb" and get_runtime_setting("RECOGNIZE_SOURCE") != "themoviedb":
return None
if not mediainfo.tmdb_id:
return mediainfo
@@ -1148,15 +1147,15 @@ class TheMovieDbModule(MediaAuxiliaryProviderMixin, _ModuleBase):
# 背景图
if not mediainfo.backdrop_path:
if image_path := cls._pick_best_tmdb_image(images.get("backdrops")):
mediainfo.backdrop_path = settings.TMDB_IMAGE_URL(image_path)
mediainfo.backdrop_path = get_runtime_setting("TMDB_IMAGE_URL")(image_path)
# 标志
if not mediainfo.logo_path:
if image_path := cls._pick_best_tmdb_image(images.get("logos")):
mediainfo.logo_path = settings.TMDB_IMAGE_URL(image_path)
mediainfo.logo_path = get_runtime_setting("TMDB_IMAGE_URL")(image_path)
# 海报
if not mediainfo.poster_path:
if image_path := cls._pick_best_tmdb_image(images.get("posters")):
mediainfo.poster_path = settings.TMDB_IMAGE_URL(image_path)
mediainfo.poster_path = get_runtime_setting("TMDB_IMAGE_URL")(image_path)
return mediainfo
def obtain_images(self, mediainfo: MediaInfo) -> Optional[MediaInfo]:
@@ -1246,7 +1245,7 @@ class TheMovieDbModule(MediaAuxiliaryProviderMixin, _ModuleBase):
image_path = seasoninfo.get(image_type.value)
if image_path:
return settings.TMDB_IMAGE_URL(image_path, image_prefix)
return get_runtime_setting("TMDB_IMAGE_URL")(image_path, image_prefix)
return None
def tmdb_movie_similar(self, tmdbid: int) -> List[MediaInfo]:
+7 -8
View File
@@ -1,15 +1,14 @@
from threading import Lock
from typing import Optional, Tuple, Union, cast
from app.runtime.settings import RuntimeSettingsCompat
settings = RuntimeSettingsCompat()
from app.domain.context import MediaInfo
from app.domain.media import is_media_source_enabled
from app.domain.meta.metabase import MetaBase
from app.runtime.execution import run_in_threadpool
from app.runtime.settings import get_runtime_setting
from app.modules import _ModuleBase
from app.modules.thetvdb import tvdb_v4_official
from app.runtime.execution import run_in_threadpool
from app.runtime.log import logger
from app.schemas.types import (
MediaRecognizeType,
@@ -39,11 +38,11 @@ class TheTvDbModule(_ModuleBase):
action = "刷新" if is_retry else "创建"
logger.info(f"开始{action}TVDB登录会话...")
try:
if not settings.TVDB_V4_API_KEY:
if not get_runtime_setting("TVDB_V4_API_KEY"):
raise ConnectionError("TVDB API Key 未配置,无法初始化会话。")
self.tvdb = tvdb_v4_official.TVDB(apikey=settings.TVDB_V4_API_KEY,
pin=settings.TVDB_V4_API_PIN,
proxy=settings.PROXY,
self.tvdb = tvdb_v4_official.TVDB(apikey=get_runtime_setting("TVDB_V4_API_KEY"),
pin=get_runtime_setting("TVDB_V4_API_PIN"),
proxy=get_runtime_setting("PROXY"),
timeout=self.__timeout)
if self.tvdb:
logger.info(f"TVDB登录会话{action}成功。")