mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-07 08:26:53 +08:00
refactor: route monitor and resource settings through runtime
This commit is contained in:
@@ -20,8 +20,8 @@ from app.adapters.system.plugin.manifest import (
|
||||
PluginDependencyManifestError,
|
||||
load_dependency_manifest,
|
||||
)
|
||||
from app.runtime.config import settings
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -52,7 +52,7 @@ class PluginDependencyInstaller:
|
||||
self._helper = helper
|
||||
self._installed_plugins_provider = installed_plugins_provider or (lambda: [])
|
||||
self._plugin_dir = plugin_dir or (
|
||||
Path(settings.ROOT_PATH) / "app" / "plugins"
|
||||
Path(get_runtime_setting("ROOT_PATH")) / "app" / "plugins"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -11,8 +11,8 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from app.adapters.external.market import PluginHelper as _PluginHelper
|
||||
from app.runtime.config import settings
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
@@ -37,7 +37,9 @@ class PluginPackageManager:
|
||||
@staticmethod
|
||||
def _plugin_dir(plugin_id: str) -> Path:
|
||||
"""解析插件运行目录并拒绝越出宿主插件根目录的标识。"""
|
||||
plugins_root = (Path(settings.ROOT_PATH) / "app" / "plugins").resolve()
|
||||
plugins_root = (
|
||||
Path(get_runtime_setting("ROOT_PATH")) / "app" / "plugins"
|
||||
).resolve()
|
||||
plugin_dir = (plugins_root / plugin_id.lower()).resolve()
|
||||
if plugin_dir == plugins_root or not plugin_dir.is_relative_to(plugins_root):
|
||||
raise ValueError(f"非法插件ID:{plugin_id}")
|
||||
@@ -47,7 +49,7 @@ class PluginPackageManager:
|
||||
"""在包变更前创建独立快照,供后续提交或补偿恢复。"""
|
||||
plugin_dir = self._plugin_dir(plugin_id)
|
||||
transaction_dir = (
|
||||
Path(settings.TEMP_PATH)
|
||||
Path(get_runtime_setting("TEMP_PATH"))
|
||||
/ "plugin_transactions"
|
||||
/ f"{plugin_id.lower()}-{uuid.uuid4().hex}"
|
||||
)
|
||||
|
||||
@@ -4,11 +4,16 @@ import sys
|
||||
from pathlib import Path
|
||||
from typing import Callable
|
||||
|
||||
from app.runtime.config import settings
|
||||
from app.runtime import config as _runtime_config
|
||||
from app.runtime.log import logger
|
||||
from app.adapters.network.http import RequestUtils
|
||||
from app.foundation.version import compare_version
|
||||
from app.adapters.system.host import SystemUtils
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
# 保留模块级旧 Settings 入口,旧插件和测试可能仍会对其做运行时覆盖;实现读取统一走 runtime 端口。
|
||||
settings = _runtime_config.settings
|
||||
|
||||
|
||||
ResourceVersionProvider = Callable[[], tuple[str, str]]
|
||||
@@ -33,11 +38,11 @@ class ResourceHelper:
|
||||
检测和更新资源包
|
||||
"""
|
||||
|
||||
_base_dir: Path = settings.ROOT_PATH
|
||||
_base_dir: Path = get_runtime_setting("ROOT_PATH")
|
||||
_resource_target = Path("app/application/site")
|
||||
_version_flag = settings.RESOURCE_VERSION_FLAG
|
||||
_version_flag = get_runtime_setting("RESOURCE_VERSION_FLAG")
|
||||
_repo = (
|
||||
f"{settings.GITHUB_PROXY}https://raw.githubusercontent.com/"
|
||||
f"{get_runtime_setting('GITHUB_PROXY')}https://raw.githubusercontent.com/"
|
||||
f"jxxghp/MoviePilot-Resources/main/package.{_version_flag}.json"
|
||||
)
|
||||
_files_api = (
|
||||
@@ -48,7 +53,11 @@ class ResourceHelper:
|
||||
@property
|
||||
def proxies(self):
|
||||
"""返回访问 GitHub 资源时应使用的代理配置。"""
|
||||
return None if settings.GITHUB_PROXY else settings.PROXY
|
||||
return (
|
||||
None
|
||||
if get_runtime_setting("GITHUB_PROXY")
|
||||
else get_runtime_setting("PROXY")
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _get_python_version_tag() -> str:
|
||||
@@ -86,7 +95,7 @@ class ResourceHelper:
|
||||
"""读取 V3 资源清单。"""
|
||||
response = RequestUtils(
|
||||
proxies=self.proxies,
|
||||
headers=settings.GITHUB_HEADERS,
|
||||
headers=get_runtime_setting("GITHUB_HEADERS"),
|
||||
timeout=10,
|
||||
).get_res(self._repo)
|
||||
return response if response and response.status_code == 200 else None
|
||||
@@ -104,7 +113,7 @@ class ResourceHelper:
|
||||
:param indexer_version: 当前已加载的站点索引资源版本;省略时使用组合根注入值
|
||||
:return: 是否成功安装了需要由上层处理重启的新资源
|
||||
"""
|
||||
if not settings.AUTO_UPDATE_RESOURCE:
|
||||
if not get_runtime_setting("AUTO_UPDATE_RESOURCE"):
|
||||
return False
|
||||
if SystemUtils.is_frozen():
|
||||
return False
|
||||
@@ -159,8 +168,8 @@ class ResourceHelper:
|
||||
if need_updates:
|
||||
# 下载文件信息列表
|
||||
r = RequestUtils(
|
||||
proxies=settings.PROXY,
|
||||
headers=settings.GITHUB_HEADERS,
|
||||
proxies=get_runtime_setting("PROXY"),
|
||||
headers=get_runtime_setting("GITHUB_HEADERS"),
|
||||
timeout=30,
|
||||
).get_res(self._files_api)
|
||||
if r and not r.ok:
|
||||
@@ -186,11 +195,11 @@ class ResourceHelper:
|
||||
if item.get("download_url"):
|
||||
logger.info(f"开始更新资源文件:{file_name} ...")
|
||||
download_url = (
|
||||
f"{settings.GITHUB_PROXY}{item.get('download_url')}"
|
||||
f"{get_runtime_setting('GITHUB_PROXY')}{item.get('download_url')}"
|
||||
)
|
||||
res = RequestUtils(
|
||||
proxies=self.proxies,
|
||||
headers=settings.GITHUB_HEADERS,
|
||||
headers=get_runtime_setting("GITHUB_HEADERS"),
|
||||
timeout=180,
|
||||
).get_res(download_url)
|
||||
if not res:
|
||||
|
||||
@@ -6,7 +6,6 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from app.chain.transfer import TransferChain
|
||||
from app.runtime.cache import TTLCache
|
||||
from app.runtime.config import settings
|
||||
from app.application.directory import DirectoryHelper
|
||||
from app.application.history import (
|
||||
HistoryGateAction,
|
||||
@@ -21,6 +20,7 @@ from app.runtime.log import logger
|
||||
from app.adapters.system.fsproxy import fsproxy
|
||||
from app.schemas.workflow import FileItem
|
||||
from app.schemas.types import MediaType
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
class TransferDispatcher:
|
||||
@@ -39,7 +39,10 @@ class TransferDispatcher:
|
||||
:param cache: 去重缓存,默认使用 10 秒 TTL 缓存
|
||||
"""
|
||||
self.all_exts = all_exts if all_exts is not None else (
|
||||
settings.RMT_MEDIAEXT + settings.RMT_SUBEXT + settings.RMT_AUDIOEXT)
|
||||
get_runtime_setting("RMT_MEDIAEXT")
|
||||
+ get_runtime_setting("RMT_SUBEXT")
|
||||
+ get_runtime_setting("RMT_AUDIOEXT")
|
||||
)
|
||||
self._cache = cache if cache is not None else TTLCache(region="monitor", maxsize=1024, ttl=10)
|
||||
self._lock = Lock()
|
||||
# 历史查询失败待重试的文件
|
||||
@@ -76,7 +79,7 @@ class TransferDispatcher:
|
||||
"""
|
||||
判断监控事件路径是否需要进入整理链。
|
||||
"""
|
||||
if self._has_suffix_in(file_path, settings.DOWNLOAD_TMPEXT):
|
||||
if self._has_suffix_in(file_path, get_runtime_setting("DOWNLOAD_TMPEXT")):
|
||||
return False
|
||||
return self._has_suffix_in(file_path, self.all_exts)
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
|
||||
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
|
||||
from app.runtime.config import settings
|
||||
from app.application.directory import DirectoryHelper
|
||||
from app.application.messaging.message import MessageHelper
|
||||
from app.runtime.log import logger
|
||||
@@ -21,6 +20,7 @@ from app.schemas.types import SystemConfigKey
|
||||
from app.runtime.reload import ConfigReloadMixin
|
||||
from app.foundation.singleton import SingletonClass
|
||||
from app.adapters.system.host import SystemUtils
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
@@ -172,7 +172,7 @@ class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
logger.info(f"找到 {len(monitor_dirs)} 个目录监控配置")
|
||||
|
||||
# 启动定时服务进程
|
||||
self._scheduler = BackgroundScheduler(timezone=settings.TZ)
|
||||
self._scheduler = BackgroundScheduler(timezone=get_runtime_setting("TZ"))
|
||||
|
||||
mon_storages: Dict[str, List[Path]] = {}
|
||||
# 本地监控启动结果计数,用于输出真实的启动总结
|
||||
@@ -285,7 +285,7 @@ class Monitor(ConfigReloadMixin, metaclass=SingletonClass):
|
||||
# 网络/FUSE 挂载轮询降频,减少监控自身对挂载后端的持续 stat 压力
|
||||
poll_delay_ms = None
|
||||
if use_polling and SystemUtils.is_network_filesystem(mon_path):
|
||||
poll_delay_ms = (settings.MONITOR_POLL_DELAY_NETWORK
|
||||
poll_delay_ms = (get_runtime_setting("MONITOR_POLL_DELAY_NETWORK")
|
||||
or LocalDirectoryWatcher.POLL_DELAY_NETWORK_MS)
|
||||
logger.info(f"检测到网络文件系统,轮询扫描间隔调整为 {poll_delay_ms}ms: {mon_path}")
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import time
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from app.runtime.cache import FileCache
|
||||
from app.runtime.config import settings
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
class SnapshotStore:
|
||||
@@ -18,7 +18,9 @@ class SnapshotStore:
|
||||
初始化快照存储。
|
||||
:param cache: 快照文件缓存,默认使用 CACHE_PATH/snapshots
|
||||
"""
|
||||
self._cache = cache if cache is not None else FileCache(base=settings.CACHE_PATH / "snapshots")
|
||||
self._cache = cache if cache is not None else FileCache(
|
||||
base=get_runtime_setting("CACHE_PATH") / "snapshots"
|
||||
)
|
||||
|
||||
def save(self, storage: str, snapshot: Dict, file_count: int = 0,
|
||||
last_snapshot_time: Optional[float] = None,
|
||||
|
||||
@@ -2,9 +2,9 @@ import platform
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from app.runtime.config import settings
|
||||
from app.runtime.log import logger
|
||||
from app.adapters.system.host import SystemUtils
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
def count_directory_entries(directory: Path, max_check: int = 10000) -> Tuple[int, int]:
|
||||
@@ -123,7 +123,7 @@ def decide_monitor_mode(directory: Path,
|
||||
|
||||
# 检查网络文件系统
|
||||
if SystemUtils.is_network_filesystem(directory):
|
||||
if not settings.MONITOR_NETWORK_FAST_MODE:
|
||||
if not get_runtime_setting("MONITOR_NETWORK_FAST_MODE"):
|
||||
return True, "检测到网络文件系统,建议使用兼容模式", None, None
|
||||
# 用户已确认该挂载支持 inotify,继续走快速模式的系统限制检查
|
||||
logger.info(f"检测到网络文件系统,但已配置允许快速模式: {directory}")
|
||||
|
||||
@@ -7,8 +7,8 @@ from typing import Any, Optional
|
||||
|
||||
from watchfiles import Change, DefaultFilter, watch
|
||||
|
||||
from app.runtime.config import settings
|
||||
from app.runtime.log import logger
|
||||
from app.runtime.settings import get_runtime_setting
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -285,7 +285,9 @@ class LocalDirectoryWatcher:
|
||||
配置,配置热更新后无需重建监控线程即可生效;解析失败或未配置时回退默认值。
|
||||
:return: 重扫轮次延迟秒数元组
|
||||
"""
|
||||
return self._parse_rescan_delays(getattr(settings, "MONITOR_RESCAN_DELAYS", None))
|
||||
return self._parse_rescan_delays(
|
||||
get_runtime_setting("MONITOR_RESCAN_DELAYS")
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _parse_rescan_delays(cls, raw: Optional[str]) -> tuple[int, ...]:
|
||||
|
||||
Reference in New Issue
Block a user