Files
MoviePilot/app/startup/composition/plugin.py

74 lines
2.4 KiB
Python

"""插件市场技术依赖的唯一启动组合 owner。"""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Callable, Optional
from app.adapters.external.plugin.client import (
PluginMarketClient,
PluginMarketTransport,
PluginPackageSourceClient,
)
from app.adapters.system.plugin.dependency import PluginDependencyInstaller
from app.adapters.system.plugin.health import PluginRuntimeHealth
from app.adapters.system.plugin.package import PluginPackageManager
from app.runtime.settings import get_runtime_setting
@dataclass(frozen=True, slots=True)
class PluginMarketComposition:
"""保存插件市场相关 Transport、Client、Package 和 Dependency owner。"""
transport: PluginMarketTransport
client: PluginMarketClient
package: PluginPackageManager
health: PluginRuntimeHealth
dependency: PluginDependencyInstaller
_market_client: Optional[PluginMarketClient] = None
def compose_plugin_market(
*,
installed_plugins_provider: Callable[[], list[str]],
) -> PluginMarketComposition:
"""一次性构造插件市场技术依赖,供同一 lifespan 内所有用例复用。"""
global _market_client
root_path = Path(get_runtime_setting("ROOT_PATH"))
plugin_root = root_path / "app" / "plugins"
transport = PluginMarketTransport.get_existing_instance() or PluginMarketTransport()
client = PluginMarketClient(transport)
health = PluginRuntimeHealth()
composition = PluginMarketComposition(
transport=transport,
client=client,
package=PluginPackageManager(
source=PluginPackageSourceClient(transport),
plugin_root=plugin_root,
),
dependency=PluginDependencyInstaller(
health,
installed_plugins_provider=installed_plugins_provider,
plugin_dir=plugin_root,
),
health=health,
)
_market_client = client
return composition
def get_composed_plugin_market_client() -> PluginMarketClient:
"""返回当前 lifespan 由组合根构造的唯一插件市场 Client。"""
if _market_client is None:
raise RuntimeError("插件市场 Client 尚未由启动组合根装配")
return _market_client
def reset_plugin_market_composition() -> None:
"""撤销当前 lifespan 的插件市场 Client 投影。"""
global _market_client
_market_client = None