Delete .github/scripts/generate_helpers_cache.py

This commit is contained in:
MacRimi
2026-03-14 18:03:51 +01:00
committed by GitHub
parent 8f5df889ab
commit b30b6a062a

View File

@@ -1,224 +0,0 @@
#!/usr/bin/env python3
import json
import re
import sys
from pathlib import Path
from typing import Any
import requests
SCRIPT_BASE = "https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main"
POCKETBASE_BASE = "https://db.community-scripts.org/api/collections"
SCRIPT_COLLECTION_URL = f"{POCKETBASE_BASE}/script_scripts/records"
CATEGORY_COLLECTION_URL = f"{POCKETBASE_BASE}/script_categories/records"
REPO_ROOT = Path(__file__).resolve().parents[2]
OUTPUT_FILE = REPO_ROOT / "json" / "helpers_cache.json"
OUTPUT_FILE.parent.mkdir(parents=True, exist_ok=True)
TYPE_TO_PATH_PREFIX = {
"lxc": "ct",
"vm": "vm",
"addon": "tools/addon",
"pve": "tools/pve",
}
def to_mirror_url(raw_url: str) -> str:
m = re.match(r"^https://raw\.githubusercontent\.com/([^/]+)/([^/]+)/([^/]+)/(.+)$", raw_url or "")
if not m:
return ""
org, repo, branch, path = m.groups()
if org.lower() != "community-scripts" or repo != "ProxmoxVE":
return ""
return f"https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/{branch}/{path}"
def fetch_json(url: str, *, params: dict[str, Any] | None = None) -> dict[str, Any]:
r = requests.get(url, params=params, timeout=60)
r.raise_for_status()
data = r.json()
if not isinstance(data, dict):
raise RuntimeError(f"Unexpected response from {url}: expected object")
return data
def fetch_all_records(url: str, *, expand: str | None = None, per_page: int = 500) -> list[dict[str, Any]]:
page = 1
items: list[dict[str, Any]] = []
while True:
params: dict[str, Any] = {"page": page, "perPage": per_page}
if expand:
params["expand"] = expand
data = fetch_json(url, params=params)
page_items = data.get("items", [])
if not isinstance(page_items, list):
raise RuntimeError(f"Unexpected items list from {url}")
items.extend(page_items)
total_pages = data.get("totalPages", page)
if not isinstance(total_pages, int) or page >= total_pages:
break
page += 1
return items
def normalize_os_variants(install_methods_json: list[dict[str, Any]]) -> list[str]:
os_values: list[str] = []
for item in install_methods_json:
if not isinstance(item, dict):
continue
resources = item.get("resources", {})
if not isinstance(resources, dict):
continue
os_name = resources.get("os")
if isinstance(os_name, str) and os_name.strip():
normalized = os_name.strip().lower()
if normalized not in os_values:
os_values.append(normalized)
return os_values
def build_script_path(type_name: str, slug: str) -> str:
type_name = (type_name or "").strip().lower()
slug = (slug or "").strip()
if type_name == "turnkey":
return "turnkey/turnkey.sh"
prefix = TYPE_TO_PATH_PREFIX.get(type_name)
if not prefix or not slug:
return ""
return f"{prefix}/{slug}.sh"
def main() -> int:
try:
scripts = fetch_all_records(SCRIPT_COLLECTION_URL, expand="type,categories")
categories = fetch_all_records(CATEGORY_COLLECTION_URL)
except Exception as e:
print(f"ERROR: Unable to fetch PocketBase data: {e}", file=sys.stderr)
return 1
category_map: dict[str, dict[str, Any]] = {}
for category in categories:
category_id = category.get("id")
if isinstance(category_id, str) and category_id:
category_map[category_id] = category
cache: list[dict[str, Any]] = []
print(f"Fetched {len(scripts)} scripts and {len(category_map)} categories")
for idx, raw in enumerate(scripts, start=1):
if not isinstance(raw, dict):
continue
slug = raw.get("slug")
name = raw.get("name", "")
desc = raw.get("description", "")
if not isinstance(slug, str) or not slug.strip():
continue
expand = raw.get("expand", {}) if isinstance(raw.get("expand"), dict) else {}
type_expanded = expand.get("type", {}) if isinstance(expand.get("type"), dict) else {}
type_name = type_expanded.get("type", "") if isinstance(type_expanded.get("type"), str) else ""
script_path = build_script_path(type_name, slug)
if not script_path:
print(f"[{idx:03d}] WARNING: Unable to build script path for slug={slug} type={type_name!r}", file=sys.stderr)
continue
full_script_url = f"{SCRIPT_BASE}/{script_path}"
script_url_mirror = to_mirror_url(full_script_url)
install_methods_json = raw.get("install_methods_json", [])
if not isinstance(install_methods_json, list):
install_methods_json = []
notes_json = raw.get("notes_json", [])
if not isinstance(notes_json, list):
notes_json = []
notes = [
note.get("text", "")
for note in notes_json
if isinstance(note, dict) and isinstance(note.get("text"), str) and note.get("text", "").strip()
]
category_ids = raw.get("categories", [])
if not isinstance(category_ids, list):
category_ids = []
expanded_categories = expand.get("categories", []) if isinstance(expand.get("categories"), list) else []
category_names: list[str] = []
for cat in expanded_categories:
if isinstance(cat, dict):
cat_name = cat.get("name")
if isinstance(cat_name, str) and cat_name.strip():
category_names.append(cat_name.strip())
if not category_names:
for cat_id in category_ids:
cat = category_map.get(cat_id, {})
cat_name = cat.get("name")
if isinstance(cat_name, str) and cat_name.strip():
category_names.append(cat_name.strip())
entry: dict[str, Any] = {
"name": name,
"slug": slug,
"desc": desc,
"script": script_path,
"script_url": full_script_url,
"script_url_mirror": script_url_mirror,
"type": type_name,
"type_id": raw.get("type", ""),
"categories": category_ids,
"category_names": category_names,
"notes": notes,
"os": normalize_os_variants(install_methods_json),
"install_methods_json": install_methods_json,
"port": raw.get("port", 0),
"website": raw.get("website", ""),
"documentation": raw.get("documentation", ""),
"logo": raw.get("logo", ""),
"updateable": bool(raw.get("updateable", False)),
"privileged": bool(raw.get("privileged", False)),
"has_arm": bool(raw.get("has_arm", False)),
"is_dev": bool(raw.get("is_dev", False)),
"execute_in": raw.get("execute_in", []),
"config_path": raw.get("config_path", ""),
}
default_user = raw.get("default_user")
default_passwd = raw.get("default_passwd")
if (isinstance(default_user, str) and default_user.strip()) or (isinstance(default_passwd, str) and default_passwd.strip()):
entry["default_credentials"] = {
"username": default_user if isinstance(default_user, str) else "",
"password": default_passwd if isinstance(default_passwd, str) else "",
}
cache.append(entry)
os_label = ",".join(entry["os"]) if entry["os"] else "n/a"
print(f"[{len(cache):03d}] {slug:<24}{script_path:<28} type={type_name:<7} os={os_label}")
cache.sort(key=lambda x: (x.get("slug") or "", x.get("script") or ""))
with OUTPUT_FILE.open("w", encoding="utf-8") as f:
json.dump(cache, f, ensure_ascii=False, indent=2)
print(f"\n✅ helpers_cache.json → {OUTPUT_FILE}")
print(f" Guardados: {len(cache)}")
return 0
if __name__ == "__main__":
sys.exit(main())