mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-20 18:51:26 -03:00
feat(other-models): announce the feature only when folders are available
Other Models management is opt-in and its folders come from folder_paths.get_folder_paths(). In plugin mode ComfyUI registers vae, upscale_models, text_encoders, clip_vision and controlnet out of the box, so enabling the feature works immediately. Standalone only knows the keys present in settings.json.folder_paths, and that file is edited by hand - there is no UI for those keys - so a standalone user who followed the announcement banner reached "Enable Other Models" and then an empty page. Gate the announcement on the capability instead of on how the process was started: - Config.get_other_models_availability() probes every canonical other key (legacy clip collapses into text_encoders where the host exposes map_legacy) and reports which sub_types resolve to a folder that exists on disk. It deliberately ignores enable_other_models: the question is "could this work here at all?". An empty folder counts, because CivitAI downloads can target it. - /api/lm/settings exposes it as the derived, non-persisted other_models_paths_available flag; a probe failure yields null and the banner fails open. - BannerService only registers the announcement when the flag is not false. `=== false` (not falsy) keeps a cached/older payload working, and nothing is written to dismissed_banners, so the banner can return once folders exist. - The Other page grows an "enabled but nothing to scan" empty state driven by config.other_roots, showing the settings.json snippet for standalone and a pointer to ComfyUI model paths otherwise, plus an Open Settings action. It also covers the corner where only a non-default sub_type has a folder. Translate the six other.noPaths.* keys into all nine locales and record the new "folder key" / "on disk" terminology in the i18n guidelines. Backend tests and pytest tests/i18n could not run in this environment (no pytest/platformdirs); the probe was exercised against a stubbed folder_paths. Frontend: 120 files / 1101 JS tests passed.
This commit is contained in:
@@ -1494,6 +1494,54 @@ class Config:
|
||||
self.other_roots = self._init_other_paths()
|
||||
self._rebuild_preview_roots()
|
||||
|
||||
def get_other_models_availability(self) -> Dict[str, Any]:
|
||||
"""Report the other-model folders the host can actually expose.
|
||||
|
||||
Independent of the opt-in ``enable_other_models`` toggle: this answers
|
||||
"could Other Models management work here at all?". ComfyUI mode almost
|
||||
always has these folder keys registered, while standalone mode only
|
||||
knows the keys present in ``settings.json.folder_paths`` - so the UI
|
||||
uses this to decide whether announcing the feature would be actionable.
|
||||
|
||||
Returns:
|
||||
``{"available": bool, "sub_types": {sub_type: [existing roots]}}``.
|
||||
A folder only counts when it exists on disk; an empty folder still
|
||||
counts because CivitAI downloads can target it.
|
||||
"""
|
||||
sub_types: Dict[str, List[str]] = {}
|
||||
try:
|
||||
keys = self._collapse_legacy_folder_keys(
|
||||
list(OTHER_MODEL_FOLDER_SUBTYPES.keys())
|
||||
)
|
||||
except Exception: # pragma: no cover - defensive
|
||||
keys = list(OTHER_MODEL_FOLDER_SUBTYPES.keys())
|
||||
|
||||
for key in keys:
|
||||
sub_type = OTHER_MODEL_FOLDER_SUBTYPES.get(key)
|
||||
if not sub_type:
|
||||
continue
|
||||
try:
|
||||
raw_paths = folder_paths.get_folder_paths(key)
|
||||
except Exception as exc:
|
||||
logger.debug("Error probing folder paths for '%s': %s", key, exc)
|
||||
continue
|
||||
|
||||
bucket = sub_types.setdefault(sub_type, [])
|
||||
for root in sorted(
|
||||
self._dedupe_existing_paths(raw_paths or []).values(),
|
||||
key=lambda path: path.lower(),
|
||||
):
|
||||
if root not in bucket:
|
||||
bucket.append(root)
|
||||
|
||||
available_sub_types = {
|
||||
sub_type: roots for sub_type, roots in sub_types.items() if roots
|
||||
}
|
||||
return {
|
||||
"available": bool(available_sub_types),
|
||||
"sub_types": available_sub_types,
|
||||
}
|
||||
|
||||
def get_preview_static_url(self, preview_path: str) -> str:
|
||||
if not preview_path:
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user