| """ComfyUI-Koolook node registry. |
| |
| @title: ComfyUI-Koolook |
| @nickname: Kforge Labs |
| @description: Project-kit sidebar plus Koolook nodes for VFX, image, and video workflows. |
| |
| Two layers of resilience guard the import: |
| |
| 1. Duplicate-install guard (#162) — if two Koolook folders exist in |
| ``custom_nodes/``, only the alphabetical winner registers; the loser |
| short-circuits before any heavy imports or route install. |
| 2. Per-group registration (#198 / #183) — each node group is imported |
| independently so a single missing or broken module degrades to "that |
| node absent" instead of taking down the whole pack, and the Kforge Labs |
| snapshot/preset routes install regardless of node-import results. The |
| failure this guards against: a module that ``__init__`` imported but |
| ``dev-sync`` never copied raised ``ImportError`` at startup, which zeroed |
| every node *and* 404'd every snapshot route. |
| """ |
| from __future__ import annotations |
|
|
| import importlib |
| from pathlib import Path |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| try: |
| from .koolook_install_guard import ( |
| build_duplicate_report, |
| detect_duplicate_koolook_installs, |
| ) |
| except ImportError: |
| from koolook_install_guard import ( |
| build_duplicate_report, |
| detect_duplicate_koolook_installs, |
| ) |
|
|
| NODE_CLASS_MAPPINGS: dict = {} |
| NODE_DISPLAY_NAME_MAPPINGS: dict = {} |
|
|
|
|
| def _merge_node_group(label: str, module_name: str) -> None: |
| """Import one node group's mappings, isolating any import failure. |
| |
| A missing module, a broken import inside it, or an absent |
| ``NODE_CLASS_MAPPINGS`` / ``NODE_DISPLAY_NAME_MAPPINGS`` attribute is |
| caught and logged; the rest of the registry (and the route install |
| below) is unaffected. |
| """ |
| try: |
| module = importlib.import_module(module_name, __package__) |
| class_mappings = module.NODE_CLASS_MAPPINGS |
| display_mappings = module.NODE_DISPLAY_NAME_MAPPINGS |
| except (ImportError, AttributeError) as exc: |
| print(f"[Koolook] {label} registry skipped: {exc}") |
| return |
| NODE_CLASS_MAPPINGS.update(class_mappings) |
| NODE_DISPLAY_NAME_MAPPINGS.update(display_mappings) |
|
|
|
|
| _here = Path(__file__).resolve().parent |
| if "__path__" not in globals(): |
| |
| |
| |
| __path__ = [str(_here)] |
| __package__ = __name__ |
| if __spec__ is not None: |
| __spec__.submodule_search_locations = [str(_here)] |
|
|
| |
| |
| |
| |
| |
| _is_winning_install = True |
| try: |
| _siblings = detect_duplicate_koolook_installs(_here) |
| if _siblings: |
| _is_winning_install, _report = build_duplicate_report(_here, _siblings) |
| print(_report) |
| except Exception as _guard_err: |
| print( |
| f"[Koolook] install-guard check failed ({_guard_err!r}); " |
| "registering normally." |
| ) |
| _is_winning_install = True |
|
|
|
|
| if not _is_winning_install: |
| |
| |
| |
| |
| |
| __all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] |
| else: |
| |
| |
| |
| |
| |
| |
| |
| try: |
| from . import koolook_versioning as _context_probe |
| except ImportError as _context_exc: |
| print( |
| f"[Koolook] node registry skipped (non-Comfy import context): " |
| f"{_context_exc}" |
| ) |
| __all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] |
| else: |
| |
| _merge_node_group("Wan 2.2 Easy Prompt", ".k_easy_wan22_prompt") |
| _merge_node_group("Easy Resize", ".k_easy_resize") |
| _merge_node_group("Easy AI Pipeline", ".k_ai_pipeline") |
| _merge_node_group("Easy Image Batch", ".k_easy_image_batch") |
| _merge_node_group("Koolook Camera Loader", ".k_easy_track") |
| _merge_node_group("Easy Pattern", ".k_easy_pattern") |
| _merge_node_group("Easy Utility", ".k_easy_utility") |
| _merge_node_group("Koolook Loop Status", ".k_loop_status") |
| _merge_node_group("Koolook Publish Contract", ".k_publish_contract") |
| |
| |
| |
| _merge_node_group("Easy Load Video", ".k_video_load") |
| _merge_node_group("Easy Video Combine", ".k_video_combine") |
| _merge_node_group("Radiance Koolook VAE", ".forks.radiance_koolook") |
| _merge_node_group("WhatDreamsCost LTX Director", ".forks.whatdreamscost_koolook") |
|
|
| |
| |
| |
| |
| |
| |
| try: |
| from . import koolook_routes |
|
|
| if not koolook_routes.install(): |
| print( |
| "[Koolook] PromptServer unavailable at import time; preset routes " |
| "(/koolook/presets/*) not registered for this session." |
| ) |
| except Exception as _routes_exc: |
| print( |
| f"[Koolook] preset routes import failed; node mappings unaffected: " |
| f"{_routes_exc}" |
| ) |
|
|
| WEB_DIRECTORY = "./web" |
| __all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"] |
|
|