73e4fc005e
Server UI gains Update on stack cards, ComfyUI Models tab with workflow scan and downloads, and centralized comfyui_config. Model catalog and download scripts move from stacks/comfyui to server-ui so ComfyUI stays a minimal Docker wrapper for easier image updates.
66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
"""Index ComfyUI-Manager model-list.json for filename → download URL lookup."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from comfyui_config import host_custom_nodes_dir
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
MANAGER_REL_PATHS = (
|
|
"custom_nodes/ComfyUI-Manager/model-list.json",
|
|
"custom_nodes/ComfyUI-Manager/node_db/new/model-list.json",
|
|
)
|
|
|
|
|
|
def _manager_list_paths(data_root: Path) -> list[Path]:
|
|
base = host_custom_nodes_dir(data_root).parent
|
|
paths: list[Path] = []
|
|
for rel in MANAGER_REL_PATHS:
|
|
path = base / rel
|
|
if path.is_file():
|
|
paths.append(path)
|
|
return paths
|
|
|
|
|
|
def _score_entry(entry: dict[str, Any]) -> tuple[int, int]:
|
|
"""Prefer entries with URL and shorter save_path."""
|
|
has_url = 0 if entry.get("url") else 1
|
|
save_path = str(entry.get("save_path") or "")
|
|
return (has_url, len(save_path))
|
|
|
|
|
|
def load_manager_index(data_root: Path) -> dict[str, dict[str, Any]]:
|
|
"""Build filename → best matching ComfyUI-Manager entry."""
|
|
index: dict[str, dict[str, Any]] = {}
|
|
for list_path in _manager_list_paths(data_root):
|
|
try:
|
|
with list_path.open(encoding="utf-8") as fh:
|
|
data = json.load(fh)
|
|
except (OSError, json.JSONDecodeError) as exc:
|
|
log.warning("Failed to read ComfyUI-Manager list %s: %s", list_path, exc)
|
|
continue
|
|
models = data.get("models") if isinstance(data, dict) else None
|
|
if not isinstance(models, list):
|
|
continue
|
|
for entry in models:
|
|
if not isinstance(entry, dict):
|
|
continue
|
|
filename = entry.get("filename")
|
|
if not isinstance(filename, str) or not filename:
|
|
continue
|
|
existing = index.get(filename)
|
|
if existing is None or _score_entry(entry) < _score_entry(existing):
|
|
index[filename] = entry
|
|
return index
|
|
|
|
|
|
def lookup_manager_entry(
|
|
data_root: Path, filename: str
|
|
) -> dict[str, Any] | None:
|
|
return load_manager_index(data_root).get(filename)
|