mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
fix(ci): isolate plugin market snapshot generator
This commit is contained in:
@@ -4,23 +4,71 @@
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from app.adapters.external.market import extract_plugin_market_repos_from_wiki
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
OFFICIAL_PLUGIN_MARKET = "https://github.com/jxxghp/MoviePilot-Plugins"
|
||||
PLUGIN_MARKET_WIKI_START = "<!-- plugin-market-repos:start -->"
|
||||
PLUGIN_MARKET_WIKI_END = "<!-- plugin-market-repos:end -->"
|
||||
PLUGIN_MARKET_REPO_PATTERN = re.compile(
|
||||
r"https?://github\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+(?:\.git)?/?",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
|
||||
def _parse_args(args: Optional[list[str]] = None) -> argparse.Namespace:
|
||||
"""解析独立构建脚本需要的 Wiki 和配置文件路径。"""
|
||||
parser = argparse.ArgumentParser(description="生成插件市场发版默认值")
|
||||
parser.add_argument("--wiki-file", type=Path, required=True)
|
||||
parser.add_argument("--config-file", type=Path, required=True)
|
||||
return parser.parse_args(args)
|
||||
|
||||
|
||||
def _normalize_plugin_market_repo_url(repo_url: str) -> Optional[str]:
|
||||
"""规范化 GitHub 插件仓库地址,供清单解析阶段去重。"""
|
||||
repo_url = (repo_url or "").strip().rstrip("/").removesuffix(".git")
|
||||
if not repo_url:
|
||||
return None
|
||||
parsed_url = urlparse(repo_url)
|
||||
if parsed_url.scheme not in {"http", "https"}:
|
||||
return None
|
||||
if (parsed_url.hostname or "").lower() != "github.com":
|
||||
return None
|
||||
paths = [item for item in parsed_url.path.split("/") if item]
|
||||
if len(paths) < 2:
|
||||
return None
|
||||
return f"https://github.com/{paths[0]}/{paths[1]}"
|
||||
|
||||
|
||||
def _extract_plugin_market_repos_from_wiki(markdown: str) -> list[str]:
|
||||
"""从唯一且有序的 Wiki 标记区域读取插件仓库清单。"""
|
||||
start_count = markdown.count(PLUGIN_MARKET_WIKI_START)
|
||||
end_count = markdown.count(PLUGIN_MARKET_WIKI_END)
|
||||
start_index = markdown.find(PLUGIN_MARKET_WIKI_START)
|
||||
end_index = markdown.find(PLUGIN_MARKET_WIKI_END)
|
||||
if start_count != 1 or end_count != 1 or start_index >= end_index:
|
||||
raise ValueError("Wiki 插件仓库清单必须包含唯一且有序的开始和结束标记")
|
||||
|
||||
content = markdown[
|
||||
start_index + len(PLUGIN_MARKET_WIKI_START):end_index
|
||||
]
|
||||
repos: list[str] = []
|
||||
seen_repos: set[str] = set()
|
||||
for item in PLUGIN_MARKET_REPO_PATTERN.findall(content):
|
||||
normalized_repo = _normalize_plugin_market_repo_url(item)
|
||||
identity = normalized_repo.lower() if normalized_repo else ""
|
||||
if not normalized_repo or identity in seen_repos:
|
||||
continue
|
||||
repos.append(normalized_repo)
|
||||
seen_repos.add(identity)
|
||||
return repos
|
||||
|
||||
|
||||
def _find_plugin_market_assignment(source: str) -> tuple[int, int, str]:
|
||||
"""定位 ConfigModel 中插件市场默认值对应的源码范围。"""
|
||||
tree = ast.parse(source)
|
||||
source_lines = source.splitlines(keepends=True)
|
||||
for node in tree.body:
|
||||
@@ -41,6 +89,7 @@ def _find_plugin_market_assignment(source: str) -> tuple[int, int, str]:
|
||||
|
||||
|
||||
def _format_plugin_market_assignment(repos: list[str], indent: str) -> str:
|
||||
"""按配置文件现有缩进格式生成插件市场默认值源码。"""
|
||||
lines = [f"{indent}PLUGIN_MARKET: str = (\n"]
|
||||
for index, repo in enumerate(repos):
|
||||
suffix = "," if index < len(repos) - 1 else ""
|
||||
@@ -50,8 +99,9 @@ def _format_plugin_market_assignment(repos: list[str], indent: str) -> str:
|
||||
|
||||
|
||||
def _generate_plugin_market_default(wiki_file: Path, config_file: Path) -> list[str]:
|
||||
"""读取 Wiki 清单并原地更新配置文件中的插件市场默认值。"""
|
||||
markdown = wiki_file.read_text(encoding="utf-8")
|
||||
repos = extract_plugin_market_repos_from_wiki(markdown, require_markers=True)
|
||||
repos = _extract_plugin_market_repos_from_wiki(markdown)
|
||||
if not repos:
|
||||
raise ValueError("Wiki 插件仓库清单为空")
|
||||
if OFFICIAL_PLUGIN_MARKET not in repos:
|
||||
|
||||
Reference in New Issue
Block a user