mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-02 05:56:47 +08:00
refactor: unify module runtime settings
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
from typing import Tuple, Union
|
||||
|
||||
from app.runtime.config import settings
|
||||
from app.application.database import get_database_governance
|
||||
from app.modules import _ModuleBase
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
from app.schemas.types import ModuleType, OtherModulesType
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
|
||||
|
||||
class PostgreSQLModule(_ModuleBase):
|
||||
"""
|
||||
@@ -12,10 +14,12 @@ class PostgreSQLModule(_ModuleBase):
|
||||
"""
|
||||
|
||||
def init_module(self) -> None:
|
||||
"""PostgreSQL 连接由数据库 adapter 管理,无需模块级初始化。"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_name() -> str:
|
||||
"""返回模块展示名称。"""
|
||||
return "PostgreSQL"
|
||||
|
||||
@staticmethod
|
||||
@@ -40,9 +44,11 @@ class PostgreSQLModule(_ModuleBase):
|
||||
return 0
|
||||
|
||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||
"""数据库类型由部署配置决定,不声明独立模块开关。"""
|
||||
pass
|
||||
|
||||
def stop(self) -> None:
|
||||
"""连接池由数据库生命周期释放,本模块无独立资源。"""
|
||||
pass
|
||||
|
||||
def test(self):
|
||||
|
||||
@@ -4,9 +4,9 @@ from typing import Set, Tuple, Optional, Union, List, Dict
|
||||
from qbittorrentapi import TorrentFilesList
|
||||
|
||||
from app.schemas.dashboard import DownloaderInfo as _SchemaDownloaderInfo
|
||||
from app.runtime.config import settings
|
||||
from app.domain.metainfo import MetaInfo
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
from app.modules._base import _DownloaderModuleBase
|
||||
from app.modules.qbittorrent.qbittorrent import Qbittorrent
|
||||
from app.schemas.transfer import DownloaderTorrent
|
||||
@@ -21,6 +21,8 @@ from app.foundation import size as size_tools
|
||||
from app.foundation import temporal as time_tools
|
||||
from app.foundation import text as text_tools
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
|
||||
_QBITTORRENT_DOWNLOADING_STATES = {
|
||||
"allocating",
|
||||
"checkingdl",
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from typing import Tuple, Union
|
||||
|
||||
from app.runtime.config import settings
|
||||
from app.adapters.cache.redis import RedisHelper
|
||||
from app.modules import _ModuleBase
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
from app.schemas.types import ModuleType, OtherModulesType
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
|
||||
|
||||
class RedisModule(_ModuleBase):
|
||||
"""
|
||||
@@ -12,10 +14,12 @@ class RedisModule(_ModuleBase):
|
||||
"""
|
||||
|
||||
def init_module(self) -> None:
|
||||
"""Redis 客户端由缓存 adapter 惰性管理,无需模块级初始化。"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_name() -> str:
|
||||
"""返回模块展示名称。"""
|
||||
return "Redis缓存"
|
||||
|
||||
@staticmethod
|
||||
@@ -40,9 +44,11 @@ class RedisModule(_ModuleBase):
|
||||
return 0
|
||||
|
||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||
"""缓存后端由部署配置决定,不声明独立模块开关。"""
|
||||
pass
|
||||
|
||||
def stop(self) -> None:
|
||||
"""缓存 adapter 负责连接释放,本模块无独立资源。"""
|
||||
pass
|
||||
|
||||
def test(self):
|
||||
|
||||
@@ -2,9 +2,9 @@ from pathlib import Path
|
||||
from typing import Set, Tuple, Optional, Union, List, Dict
|
||||
|
||||
from app.schemas.dashboard import DownloaderInfo as _SchemaDownloaderInfo
|
||||
from app.runtime.config import settings
|
||||
from app.domain.metainfo import MetaInfo
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
from app.modules._base import _DownloaderModuleBase
|
||||
from app.modules.rtorrent.rtorrent import Rtorrent
|
||||
from app.schemas.transfer import DownloaderTorrent
|
||||
@@ -19,8 +19,12 @@ from app.foundation import size as size_tools
|
||||
from app.foundation import temporal as time_tools
|
||||
from app.foundation import text as text_tools
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
|
||||
|
||||
class RtorrentModule(_DownloaderModuleBase[Rtorrent]):
|
||||
"""rTorrent 下载器模块,负责任务添加、标签和文件状态转换。"""
|
||||
|
||||
def init_module(self) -> None:
|
||||
"""
|
||||
初始化模块
|
||||
@@ -31,6 +35,7 @@ class RtorrentModule(_DownloaderModuleBase[Rtorrent]):
|
||||
|
||||
@staticmethod
|
||||
def get_name() -> str:
|
||||
"""返回模块展示名称。"""
|
||||
return "Rtorrent"
|
||||
|
||||
@staticmethod
|
||||
@@ -55,9 +60,11 @@ class RtorrentModule(_DownloaderModuleBase[Rtorrent]):
|
||||
return 3
|
||||
|
||||
def stop(self):
|
||||
"""下载器客户端由服务基类管理,本模块无额外停止动作。"""
|
||||
pass
|
||||
|
||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||
"""下载器实例由系统配置管理,不声明独立模块开关。"""
|
||||
pass
|
||||
|
||||
def download(
|
||||
|
||||
@@ -4,9 +4,9 @@ from typing import Set, Tuple, Optional, Union, List, Dict
|
||||
from transmission_rpc import File
|
||||
|
||||
from app.schemas.dashboard import DownloaderInfo as _SchemaDownloaderInfo
|
||||
from app.runtime.config import settings
|
||||
from app.domain.metainfo import MetaInfo
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import RuntimeSettingsCompat
|
||||
from app.modules._base import _DownloaderModuleBase
|
||||
from app.modules.transmission.transmission import Transmission
|
||||
from app.schemas.transfer import DownloaderTorrent
|
||||
@@ -20,6 +20,8 @@ from app.schemas.types import (
|
||||
from app.foundation import size as size_tools
|
||||
from app.foundation import temporal as time_tools
|
||||
|
||||
settings = RuntimeSettingsCompat()
|
||||
|
||||
_TRANSMISSION_DOWNLOADING_STATES = {
|
||||
"download_pending",
|
||||
"downloading",
|
||||
@@ -30,6 +32,7 @@ _TRANSMISSION_PAUSED_STATES = {
|
||||
|
||||
|
||||
class TransmissionModule(_DownloaderModuleBase[Transmission]):
|
||||
"""Transmission 下载器模块,负责任务添加、标签和文件选择。"""
|
||||
|
||||
def init_module(self) -> None:
|
||||
"""
|
||||
@@ -40,6 +43,7 @@ class TransmissionModule(_DownloaderModuleBase[Transmission]):
|
||||
|
||||
@staticmethod
|
||||
def get_name() -> str:
|
||||
"""返回模块展示名称。"""
|
||||
return "Transmission"
|
||||
|
||||
@staticmethod
|
||||
@@ -64,9 +68,11 @@ class TransmissionModule(_DownloaderModuleBase[Transmission]):
|
||||
return 2
|
||||
|
||||
def stop(self):
|
||||
"""下载器客户端由服务基类管理,本模块无额外停止动作。"""
|
||||
pass
|
||||
|
||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||
"""下载器实例由系统配置管理,不声明独立模块开关。"""
|
||||
pass
|
||||
|
||||
def download(self, content: Union[Path, str, bytes], download_dir: Path, cookie: str,
|
||||
|
||||
@@ -96,6 +96,9 @@
|
||||
concrete `PluginManager`,不改变 V1/V2/V3 插件加载与自由响应 API。
|
||||
Command 的 API 消费点也已完成原计划迁移:WebAgent 查询和站点认证后的刷新统一使用
|
||||
`app.application.commands`,只有 startup 组合根注册 concrete Command;门面保留原命令对象与插件命令语义。
|
||||
宿主 Module 的部署配置读取也已统一到 `RuntimeSettingsCompat`:PostgreSQL、Redis、qBittorrent、
|
||||
rTorrent 和 Transmission 不再直接导入全局 Settings,模块目录由架构测试保持零直连;兼容代理仍保留
|
||||
启动早期与旧插件/测试的动态 Settings 注入语义。
|
||||
|
||||
### P2:中长期可演进性债务
|
||||
|
||||
|
||||
@@ -10,16 +10,11 @@
|
||||
"root": "app"
|
||||
},
|
||||
"settings_imports": {
|
||||
"count": 8,
|
||||
"count": 3,
|
||||
"files": [
|
||||
"app/db/base.py",
|
||||
"app/db/engine.py",
|
||||
"app/db/session.py",
|
||||
"app/modules/postgresql/__init__.py",
|
||||
"app/modules/qbittorrent/__init__.py",
|
||||
"app/modules/redis/__init__.py",
|
||||
"app/modules/rtorrent/__init__.py",
|
||||
"app/modules/transmission/__init__.py"
|
||||
"app/db/session.py"
|
||||
]
|
||||
},
|
||||
"system_config_oper_constructions": {
|
||||
|
||||
+6
-6
@@ -14,7 +14,7 @@
|
||||
"workflow_to_db": []
|
||||
},
|
||||
"edge_count": 6499,
|
||||
"edge_sha256": "f21eea0878e60d4b955a87da15cf0653eaecf07d147dc43e9eabc9f9573bb793",
|
||||
"edge_sha256": "54ddd2d6cd5669354a2d1303b24c95e573368e145fdd74e4240b01bb8ef1f687",
|
||||
"edges": [
|
||||
"app -> app.runtime",
|
||||
"app -> app.runtime.compat",
|
||||
@@ -4808,7 +4808,7 @@
|
||||
"app.modules.postgresql -> app.application.database",
|
||||
"app.modules.postgresql -> app.modules",
|
||||
"app.modules.postgresql -> app.runtime",
|
||||
"app.modules.postgresql -> app.runtime.config",
|
||||
"app.modules.postgresql -> app.runtime.settings",
|
||||
"app.modules.postgresql -> app.schemas",
|
||||
"app.modules.postgresql -> app.schemas.types",
|
||||
"app.modules.qbittorrent -> app.domain",
|
||||
@@ -4821,8 +4821,8 @@
|
||||
"app.modules.qbittorrent -> app.modules._base",
|
||||
"app.modules.qbittorrent -> app.modules.qbittorrent.qbittorrent",
|
||||
"app.modules.qbittorrent -> app.runtime",
|
||||
"app.modules.qbittorrent -> app.runtime.config",
|
||||
"app.modules.qbittorrent -> app.runtime.log",
|
||||
"app.modules.qbittorrent -> app.runtime.settings",
|
||||
"app.modules.qbittorrent -> app.schemas",
|
||||
"app.modules.qbittorrent -> app.schemas.dashboard",
|
||||
"app.modules.qbittorrent -> app.schemas.transfer",
|
||||
@@ -4879,7 +4879,7 @@
|
||||
"app.modules.redis -> app.adapters.cache.redis",
|
||||
"app.modules.redis -> app.modules",
|
||||
"app.modules.redis -> app.runtime",
|
||||
"app.modules.redis -> app.runtime.config",
|
||||
"app.modules.redis -> app.runtime.settings",
|
||||
"app.modules.redis -> app.schemas",
|
||||
"app.modules.redis -> app.schemas.types",
|
||||
"app.modules.rtorrent -> app.domain",
|
||||
@@ -4892,8 +4892,8 @@
|
||||
"app.modules.rtorrent -> app.modules._base",
|
||||
"app.modules.rtorrent -> app.modules.rtorrent.rtorrent",
|
||||
"app.modules.rtorrent -> app.runtime",
|
||||
"app.modules.rtorrent -> app.runtime.config",
|
||||
"app.modules.rtorrent -> app.runtime.log",
|
||||
"app.modules.rtorrent -> app.runtime.settings",
|
||||
"app.modules.rtorrent -> app.schemas",
|
||||
"app.modules.rtorrent -> app.schemas.dashboard",
|
||||
"app.modules.rtorrent -> app.schemas.transfer",
|
||||
@@ -5248,8 +5248,8 @@
|
||||
"app.modules.transmission -> app.modules._base",
|
||||
"app.modules.transmission -> app.modules.transmission.transmission",
|
||||
"app.modules.transmission -> app.runtime",
|
||||
"app.modules.transmission -> app.runtime.config",
|
||||
"app.modules.transmission -> app.runtime.log",
|
||||
"app.modules.transmission -> app.runtime.settings",
|
||||
"app.modules.transmission -> app.schemas",
|
||||
"app.modules.transmission -> app.schemas.dashboard",
|
||||
"app.modules.transmission -> app.schemas.transfer",
|
||||
|
||||
@@ -926,6 +926,21 @@ def test_runtime_consumers_use_command_application_facade():
|
||||
assert violations == {}
|
||||
|
||||
|
||||
def test_modules_read_deployment_settings_through_runtime_port():
|
||||
"""宿主 Module 不得绕过 runtime 配置端口直接依赖 Settings 实例。"""
|
||||
violations: list[str] = []
|
||||
for path in (APP_ROOT / "modules").rglob("*.py"):
|
||||
tree = ast.parse(path.read_text(encoding="utf-8-sig"), filename=str(path))
|
||||
for node in ast.walk(tree):
|
||||
if not isinstance(node, ast.ImportFrom) or node.module != "app.runtime.config":
|
||||
continue
|
||||
if any(alias.name == "settings" for alias in node.names):
|
||||
violations.append(path.relative_to(PROJECT_ROOT).as_posix())
|
||||
break
|
||||
|
||||
assert violations == []
|
||||
|
||||
|
||||
def test_api_does_not_import_factory():
|
||||
"""装配器(factory)只允许 app.main 使用,HTTP 端点不得回引。"""
|
||||
violations: dict[str, set[str]] = {}
|
||||
|
||||
@@ -13,8 +13,16 @@ def _load_downloader_base():
|
||||
app_module.__path__ = []
|
||||
helper_module = types.ModuleType("app.helper")
|
||||
helper_module.__path__ = []
|
||||
runtime_module = types.ModuleType("app.runtime")
|
||||
runtime_module.__path__ = []
|
||||
runtime_extensions_module = types.ModuleType("app.runtime.extensions")
|
||||
runtime_extensions_module.__path__ = []
|
||||
service_module = types.ModuleType("app.runtime.extensions.service_config")
|
||||
log_module = types.ModuleType("app.runtime.log")
|
||||
schemas_module = types.ModuleType("app.schemas")
|
||||
schemas_module.__path__ = []
|
||||
schema_message_module = types.ModuleType("app.schemas.message")
|
||||
schema_system_module = types.ModuleType("app.schemas.system")
|
||||
schema_types_module = types.ModuleType("app.schemas.types")
|
||||
utils_module = types.ModuleType("app.utils")
|
||||
utils_module.__path__ = []
|
||||
@@ -27,6 +35,13 @@ def _load_downloader_base():
|
||||
class _ConfigReloadMixin:
|
||||
pass
|
||||
|
||||
class _Logger:
|
||||
"""隔离模块基类加载时使用的无副作用日志桩。"""
|
||||
|
||||
def error(self, *_args, **_kwargs):
|
||||
"""忽略测试范围外的错误日志输出。"""
|
||||
pass
|
||||
|
||||
class _ServiceConfigHelper:
|
||||
@staticmethod
|
||||
def get_downloader_configs():
|
||||
@@ -59,24 +74,37 @@ def _load_downloader_base():
|
||||
)
|
||||
|
||||
service_module.ServiceConfigHelper = _ServiceConfigHelper
|
||||
log_module.logger = _Logger()
|
||||
mixins_module.ConfigReloadMixin = _ConfigReloadMixin
|
||||
schemas_module.Message = object
|
||||
schemas_module.NotificationConf = object
|
||||
schemas_module.MediaServerConf = object
|
||||
schemas_module.DownloaderConf = object
|
||||
schema_message_module.Message = object
|
||||
schema_system_module.NotificationConf = object
|
||||
schema_system_module.MediaServerConf = object
|
||||
schema_system_module.DownloaderConf = object
|
||||
|
||||
app_module.helper = helper_module
|
||||
app_module.runtime = runtime_module
|
||||
app_module.schemas = schemas_module
|
||||
app_module.utils = utils_module
|
||||
helper_module.service = service_module
|
||||
runtime_module.extensions = runtime_extensions_module
|
||||
runtime_module.log = log_module
|
||||
runtime_module.reload = mixins_module
|
||||
runtime_extensions_module.service_config = service_module
|
||||
schemas_module.message = schema_message_module
|
||||
schemas_module.system = schema_system_module
|
||||
schemas_module.types = schema_types_module
|
||||
utils_module.mixins = mixins_module
|
||||
|
||||
stub_modules = {
|
||||
"app": app_module,
|
||||
"app.helper": helper_module,
|
||||
"app.runtime": runtime_module,
|
||||
"app.runtime.extensions": runtime_extensions_module,
|
||||
"app.runtime.extensions.service_config": service_module,
|
||||
"app.runtime.log": log_module,
|
||||
"app.schemas": schemas_module,
|
||||
"app.schemas.message": schema_message_module,
|
||||
"app.schemas.system": schema_system_module,
|
||||
"app.schemas.types": schema_types_module,
|
||||
"app.utils": utils_module,
|
||||
"app.runtime.reload": mixins_module,
|
||||
@@ -108,7 +136,10 @@ def _load_transmission_module():
|
||||
torrent_rules_module = types.ModuleType("app.domain.torrent")
|
||||
size_tools_module = types.ModuleType("app.foundation.size")
|
||||
temporal_tools_module = types.ModuleType("app.foundation.temporal")
|
||||
runtime_module = types.ModuleType("app.runtime")
|
||||
runtime_module.__path__ = []
|
||||
cache_module = types.ModuleType("app.runtime.cache")
|
||||
runtime_settings_module = types.ModuleType("app.runtime.settings")
|
||||
base_module = types.ModuleType("app.modules._base")
|
||||
modules_module = types.ModuleType("app.modules")
|
||||
modules_module.__path__ = []
|
||||
@@ -116,6 +147,9 @@ def _load_transmission_module():
|
||||
transmission_package_module.__path__ = []
|
||||
transmission_client_module = types.ModuleType("app.modules.transmission.transmission")
|
||||
schemas_module = types.ModuleType("app.schemas")
|
||||
schemas_module.__path__ = []
|
||||
schema_dashboard_module = types.ModuleType("app.schemas.dashboard")
|
||||
schema_transfer_module = types.ModuleType("app.schemas.transfer")
|
||||
schema_types_module = types.ModuleType("app.schemas.types")
|
||||
config_module = types.ModuleType("app.runtime.config")
|
||||
metainfo_module = types.ModuleType("app.domain.metainfo")
|
||||
@@ -225,12 +259,19 @@ def _load_transmission_module():
|
||||
def get(self, *_args, **_kwargs):
|
||||
return None
|
||||
|
||||
class _RuntimeSettingsCompat:
|
||||
"""隔离测试用动态配置代理,保持生产模块的兼容读取语义。"""
|
||||
|
||||
def __getattr__(self, key):
|
||||
"""从测试提供的旧 Settings 桩读取配置项。"""
|
||||
return getattr(config_module.settings, key)
|
||||
|
||||
transmission_client_module.Transmission = object
|
||||
cache_module.FileCache = _FileCache
|
||||
schemas_module.TransferTorrent = _TransferTorrent
|
||||
schemas_module.DownloadingTorrent = _DownloadingTorrent
|
||||
schemas_module.DownloaderTorrent = _DownloaderTorrent
|
||||
schemas_module.DownloaderInfo = object
|
||||
schema_transfer_module.TransferTorrent = _TransferTorrent
|
||||
schema_transfer_module.DownloadingTorrent = _DownloadingTorrent
|
||||
schema_transfer_module.DownloaderTorrent = _DownloaderTorrent
|
||||
schema_dashboard_module.DownloaderInfo = object
|
||||
schema_types_module.TorrentStatus = TorrentStatus
|
||||
schema_types_module.TorrentQueryStatus = TorrentQueryStatus
|
||||
schema_types_module.DownloadTaskState = DownloadTaskState
|
||||
@@ -239,6 +280,7 @@ def _load_transmission_module():
|
||||
"DownloaderType", {"Transmission": "Transmission"}
|
||||
)
|
||||
config_module.settings = SimpleNamespace(TORRENT_TAG="moviepilot-tag")
|
||||
runtime_settings_module.RuntimeSettingsCompat = _RuntimeSettingsCompat
|
||||
metainfo_module.MetaInfo = _MetaInfo
|
||||
log_module.logger = _Logger()
|
||||
modules_module._ModuleBase = _ModuleBase
|
||||
@@ -257,6 +299,7 @@ def _load_transmission_module():
|
||||
app_module.domain = domain_module
|
||||
app_module.foundation = foundation_module
|
||||
app_module.modules = modules_module
|
||||
app_module.runtime = runtime_module
|
||||
app_module.schemas = schemas_module
|
||||
domain_module.torrent = torrent_rules_module
|
||||
foundation_module.size = size_tools_module
|
||||
@@ -264,8 +307,14 @@ def _load_transmission_module():
|
||||
core_module.cache = cache_module
|
||||
core_module.config = config_module
|
||||
core_module.metainfo = metainfo_module
|
||||
runtime_module.cache = cache_module
|
||||
runtime_module.config = config_module
|
||||
runtime_module.log = log_module
|
||||
runtime_module.settings = runtime_settings_module
|
||||
modules_module.transmission = transmission_package_module
|
||||
transmission_package_module.transmission = transmission_client_module
|
||||
schemas_module.dashboard = schema_dashboard_module
|
||||
schemas_module.transfer = schema_transfer_module
|
||||
schemas_module.types = schema_types_module
|
||||
torrentool_module.torrent = torrentool_torrent_module
|
||||
|
||||
@@ -279,13 +328,17 @@ def _load_transmission_module():
|
||||
"app.foundation.temporal": temporal_tools_module,
|
||||
"app.runtime.cache": cache_module,
|
||||
"app.runtime.config": config_module,
|
||||
"app.runtime": runtime_module,
|
||||
"app.domain.metainfo": metainfo_module,
|
||||
"app.runtime.log": log_module,
|
||||
"app.runtime.settings": runtime_settings_module,
|
||||
"app.modules": modules_module,
|
||||
"app.modules._base": base_module,
|
||||
"app.modules.transmission": transmission_package_module,
|
||||
"app.modules.transmission.transmission": transmission_client_module,
|
||||
"app.schemas": schemas_module,
|
||||
"app.schemas.dashboard": schema_dashboard_module,
|
||||
"app.schemas.transfer": schema_transfer_module,
|
||||
"app.schemas.types": schema_types_module,
|
||||
"transmission_rpc": transmission_rpc_module,
|
||||
"torrentool": torrentool_module,
|
||||
|
||||
@@ -26,11 +26,17 @@ def _load_qbittorrent_modules():
|
||||
modules_module.__path__ = []
|
||||
qbittorrent_package_module = types.ModuleType("app.modules.qbittorrent")
|
||||
qbittorrent_package_module.__path__ = []
|
||||
runtime_module = types.ModuleType("app.runtime")
|
||||
runtime_module.__path__ = []
|
||||
log_module = types.ModuleType("app.runtime.log")
|
||||
cache_module = types.ModuleType("app.runtime.cache")
|
||||
config_module = types.ModuleType("app.runtime.config")
|
||||
runtime_settings_module = types.ModuleType("app.runtime.settings")
|
||||
metainfo_module = types.ModuleType("app.domain.metainfo")
|
||||
schemas_module = types.ModuleType("app.schemas")
|
||||
schemas_module.__path__ = []
|
||||
schema_dashboard_module = types.ModuleType("app.schemas.dashboard")
|
||||
schema_transfer_module = types.ModuleType("app.schemas.transfer")
|
||||
schema_types_module = types.ModuleType("app.schemas.types")
|
||||
torrentool_module = types.ModuleType("torrentool")
|
||||
torrentool_module.__path__ = []
|
||||
@@ -78,6 +84,13 @@ def _load_qbittorrent_modules():
|
||||
def get(self, *_args, **_kwargs):
|
||||
return None
|
||||
|
||||
class _RuntimeSettingsCompat:
|
||||
"""隔离测试用动态配置代理,保持生产模块的兼容读取语义。"""
|
||||
|
||||
def __getattr__(self, key):
|
||||
"""从测试提供的旧 Settings 桩读取配置项。"""
|
||||
return getattr(config_module.settings, key)
|
||||
|
||||
class _MetaInfo:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
@@ -160,11 +173,12 @@ def _load_qbittorrent_modules():
|
||||
log_module.logger = _Logger()
|
||||
cache_module.FileCache = _FileCache
|
||||
config_module.settings = types.SimpleNamespace(TORRENT_TAG="moviepilot-tag")
|
||||
runtime_settings_module.RuntimeSettingsCompat = _RuntimeSettingsCompat
|
||||
metainfo_module.MetaInfo = _MetaInfo
|
||||
schemas_module.DownloaderInfo = object
|
||||
schemas_module.TransferTorrent = object
|
||||
schemas_module.DownloadingTorrent = object
|
||||
schemas_module.DownloaderTorrent = _DownloaderTorrent
|
||||
schema_dashboard_module.DownloaderInfo = object
|
||||
schema_transfer_module.TransferTorrent = object
|
||||
schema_transfer_module.DownloadingTorrent = object
|
||||
schema_transfer_module.DownloaderTorrent = _DownloaderTorrent
|
||||
schema_types_module.TorrentStatus = TorrentStatus
|
||||
schema_types_module.TorrentQueryStatus = TorrentQueryStatus
|
||||
schema_types_module.DownloadTaskState = DownloadTaskState
|
||||
@@ -195,6 +209,7 @@ def _load_qbittorrent_modules():
|
||||
app_module.foundation = foundation_module
|
||||
app_module.log = log_module
|
||||
app_module.modules = modules_module
|
||||
app_module.runtime = runtime_module
|
||||
app_module.schemas = schemas_module
|
||||
domain_module.torrent = torrent_rules_module
|
||||
foundation_module.size = size_tools_module
|
||||
@@ -204,6 +219,12 @@ def _load_qbittorrent_modules():
|
||||
core_module.cache = cache_module
|
||||
core_module.config = config_module
|
||||
core_module.metainfo = metainfo_module
|
||||
runtime_module.cache = cache_module
|
||||
runtime_module.config = config_module
|
||||
runtime_module.log = log_module
|
||||
runtime_module.settings = runtime_settings_module
|
||||
schemas_module.dashboard = schema_dashboard_module
|
||||
schemas_module.transfer = schema_transfer_module
|
||||
schemas_module.types = schema_types_module
|
||||
modules_module.qbittorrent = qbittorrent_package_module
|
||||
torrentool_module.torrent = torrentool_torrent_module
|
||||
@@ -220,12 +241,16 @@ def _load_qbittorrent_modules():
|
||||
"app.foundation.url": url_tools_module,
|
||||
"app.runtime.cache": cache_module,
|
||||
"app.runtime.config": config_module,
|
||||
"app.runtime": runtime_module,
|
||||
"app.domain.metainfo": metainfo_module,
|
||||
"app.runtime.log": log_module,
|
||||
"app.runtime.settings": runtime_settings_module,
|
||||
"app.modules": modules_module,
|
||||
"app.modules._base": base_module,
|
||||
"app.modules.qbittorrent": qbittorrent_package_module,
|
||||
"app.schemas": schemas_module,
|
||||
"app.schemas.dashboard": schema_dashboard_module,
|
||||
"app.schemas.transfer": schema_transfer_module,
|
||||
"app.schemas.types": schema_types_module,
|
||||
"qbittorrentapi": qbittorrentapi_module,
|
||||
"qbittorrentapi.client": qbittorrentapi_client_module,
|
||||
|
||||
Reference in New Issue
Block a user