fix(plugin): restore compatible history lookup

This commit is contained in:
jxxghp
2026-08-29 08:47:25 +08:00
parent 1fa5b599c7
commit daf67dc71a
2 changed files with 64 additions and 29 deletions

View File

@@ -9,7 +9,7 @@ from fastapi import Depends, Header, HTTPException, Security
from starlette import status
from starlette.responses import StreamingResponse
from app.adapters.external.market import PluginHelper
from app.adapters.external.market import VERSION_BACKWARD_COMPATIBLE_FLAGS, PluginHelper
from app.adapters.external.server import MoviePilotServerHelper
from app.adapters.web.security.access import (
resource_token_cookie,
@@ -101,33 +101,32 @@ async def _get_market_plugin_from_repo(
force: bool,
) -> Optional[_SchemaPlugin]:
"""
只读取指定插件仓库的市场元数据,避免单插件详情触发全部市场刷新。
"""
market_plugins = await plugin_manager.async_get_plugins_from_market(
repo_url, get_api_runtime_config_snapshot().version_flag, force
)
market_plugin = next(
(
plugin
for plugin in market_plugins or []
if plugin.id == plugin_id
),
None,
)
if market_plugin or not get_api_runtime_config_snapshot().version_flag:
return market_plugin
按当前代际、向后兼容代际和基础索引顺序读取指定仓库的市场元数据。
compatible_plugins = await plugin_manager.async_get_plugins_from_market(
repo_url, None, force
)
return next(
(
plugin
for plugin in compatible_plugins or []
if plugin.id == plugin_id
),
None,
)
单插件详情只访问可信绑定仓库,避免触发全部市场刷新;代际顺序必须与
全量插件目录保持一致,否则仅存在于 package.v2.json 的插件会丢失历史说明。
"""
version_flag = get_api_runtime_config_snapshot().version_flag
package_versions = [version_flag] if version_flag else []
package_versions.extend(VERSION_BACKWARD_COMPATIBLE_FLAGS.get(version_flag, []))
package_versions.append(None)
for package_version in dict.fromkeys(package_versions):
market_plugins = await plugin_manager.async_get_plugins_from_market(
repo_url, package_version, force
)
market_plugin = next(
(
plugin
for plugin in market_plugins or []
if plugin.id == plugin_id
),
None,
)
if market_plugin:
return market_plugin
return None
async def _refresh_plugin_release_versions(plugin_id: str, repo_url: str) -> None:

View File

@@ -286,6 +286,41 @@ def test_plugin_history_merges_remote_metadata():
)
def test_plugin_history_falls_back_to_backward_compatible_package():
"""已绑定来源的插件在当前索引缺失时仍读取向后兼容代际的历史。"""
installed_plugin = schemas.Plugin(
id="DemoPlugin",
plugin_name="Demo Plugin",
plugin_version="1.0.0",
installed=True,
history={},
)
market_plugin = schemas.Plugin(
id="DemoPlugin",
repo_url=SOURCE_URL,
history={"v2.0.0": "兼容代际更新说明"},
)
plugin_manager = MagicMock()
plugin_manager.get_installed_plugins.return_value = [installed_plugin]
plugin_manager.get_local_repo_plugins.return_value = []
plugin_manager.async_get_plugins_from_market = AsyncMock(
side_effect=[[], [market_plugin]]
)
persistence = _persistence(_plugin_identity())
with (
patch("app.api.endpoints.plugin.get_plugin_manager", return_value=plugin_manager),
patch("app.api.endpoints.plugin.get_plugin_persistence", return_value=persistence),
):
result = asyncio.run(plugin_history("DemoPlugin", None, True))
assert result.history == {"v2.0.0": "兼容代际更新说明"}
assert plugin_manager.async_get_plugins_from_market.await_args_list == [
((SOURCE_URL, settings.VERSION_FLAG, True), {}),
((SOURCE_URL, "v2", True), {}),
]
def test_runtime_status_reports_pending_and_terminal_counts():
"""插件页摘要区分后台收敛、准备态和终态失败。"""
plugin_manager = MagicMock()
@@ -506,7 +541,7 @@ def test_plugin_releases_does_not_mutate_cached_release_items(monkeypatch):
def test_plugin_releases_falls_back_to_compatible_base_package(monkeypatch):
"""
当前版本 package 未包含插件时,再读取基础 package 兼容项,不扫描其他市场。
当前版本和向后兼容 package 未包含插件时,再读取基础 package 兼容项。
"""
market_plugin = schemas.Plugin(
id="DemoPlugin",
@@ -516,7 +551,7 @@ def test_plugin_releases_falls_back_to_compatible_base_package(monkeypatch):
)
plugin_manager = MagicMock()
plugin_manager.async_get_plugins_from_market = AsyncMock(
side_effect=[[], [market_plugin]]
side_effect=[[], [], [market_plugin]]
)
plugin_manager.get_local_plugin_version.return_value = None
plugin_helper = MagicMock()
@@ -534,6 +569,7 @@ def test_plugin_releases_falls_back_to_compatible_base_package(monkeypatch):
assert result["latest_version"] == "1.2.3"
assert plugin_manager.async_get_plugins_from_market.await_args_list == [
(("https://github.com/demo/plugins", settings.VERSION_FLAG, False), {}),
(("https://github.com/demo/plugins", "v2", False), {}),
(("https://github.com/demo/plugins", None, False), {}),
]