-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy path__init__.py
More file actions
147 lines (112 loc) Β· 6.33 KB
/
__init__.py
File metadata and controls
147 lines (112 loc) Β· 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import importlib
import inspect
import os
import re
import traceback
# Directory containing node wrapper modules relative to this __init__.py
WRAPPER_DIR = "node_wrappers"
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
print("\033[93m" + "[ComfyUI_RealtimeNodes] Loading nodes...")
def load_nodes_from_directory(package_path):
"""Dynamically loads nodes from Python files in a directory."""
loaded_nodes = {}
loaded_display_names = {}
# Calculate absolute path to the package directory
package_abs_path = os.path.join(os.path.dirname(__file__), *package_path.split("."))
if not os.path.isdir(package_abs_path):
print(f"\033[91m" + f"[ComfyUI_RealtimeNodes] Warning: Directory not found: {package_abs_path}")
return loaded_nodes, loaded_display_names
print(f"\033[92m" + f"[ComfyUI_RealtimeNodes] Searching for nodes in: {package_abs_path}")
for filename in os.listdir(package_abs_path):
if filename.endswith(".py") and not filename.startswith("__"):
module_name = filename[:-3]
full_module_path = f".{package_path}.{module_name}" # Relative import path
try:
module = importlib.import_module(full_module_path, package=__name__)
# Find classes defined in the module
for name, obj in inspect.getmembers(module):
if inspect.isclass(obj):
# Check if it's a ComfyUI node (heuristic: has INPUT_TYPES)
if hasattr(obj, "INPUT_TYPES") and callable(obj.INPUT_TYPES):
# Exclude base classes/mixins if they are explicitly named or lack a CATEGORY
if "Base" not in name and not name.endswith("Mixin") and hasattr(obj, "CATEGORY"):
loaded_nodes[name] = obj
# Generate display name (similar to original logic)
display_name = " ".join(
word.capitalize() for word in re.findall(r"[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\d|\W|$)|\d+", name)
)
# Add prefix if defined
if hasattr(obj, "NAME_PREFIX"):
display_name = f"{obj.NAME_PREFIX} {display_name}"
# Add suffix if defined
if hasattr(obj, "NAME_SUFFIX"):
display_name = f"{display_name} {obj.NAME_SUFFIX}"
# Add the realtime suffix
suffix = " ππ
‘π
£π
"
if not display_name.endswith(suffix):
display_name += suffix
loaded_display_names[name] = display_name
print(f"\033[94m" + f"[ComfyUI_RealtimeNodes] - Loaded node: {name} -> {display_name}")
except ImportError as e:
print(f"\033[91m" + f"[ComfyUI_RealtimeNodes] Error importing module {full_module_path}: {e}")
traceback.print_exc()
except Exception as e:
print(f"\033[91m" + f"[ComfyUI_RealtimeNodes] Error processing module {full_module_path}: {e}")
traceback.print_exc()
return loaded_nodes, loaded_display_names
# --- Main Loading Logic ---
# Get base path for the node_wrappers directory
base_dir_path = os.path.join(os.path.dirname(__file__), WRAPPER_DIR)
# Recursively scan all directories and subdirectories
def scan_for_modules(base_path, base_package):
"""Recursively scan directories for module files"""
try:
for item in os.listdir(base_path):
item_path = os.path.join(base_path, item)
# Skip __pycache__ and files/dirs starting with __
if item.startswith("__"):
continue
if os.path.isdir(item_path):
# Handle subdirectory
subdir_package = f"{base_package}.{item}"
# First load .py files in this directory
try:
nodes, display_names = load_nodes_from_directory(subdir_package)
NODE_CLASS_MAPPINGS.update(nodes)
NODE_DISPLAY_NAME_MAPPINGS.update(display_names)
except Exception as e:
print(f"\033[91m" + f"[ComfyUI_RealtimeNodes] Error processing directory {subdir_package}: {e}")
traceback.print_exc()
# Then recursively process subdirectories
subdir_path = os.path.join(base_path, item)
scan_for_modules(subdir_path, subdir_package)
except Exception as e:
print(f"\033[91m" + f"[ComfyUI_RealtimeNodes] Error scanning directory {base_path}: {e}")
traceback.print_exc()
# Start recursive scanning from the base directory
print(f"\033[92m" + f"[ComfyUI_RealtimeNodes] Scanning node_wrappers directory for modules...")
scan_for_modules(base_dir_path, WRAPPER_DIR)
suffix = " ππ
‘π
£π
"
for node_name in NODE_CLASS_MAPPINGS.keys():
# Convert camelCase or snake_case to Title Case
if node_name not in NODE_DISPLAY_NAME_MAPPINGS:
display_name = " ".join(word.capitalize() for word in re.findall(r"[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\d|\W|$)|\d+", node_name))
# Add prefix if defined
node_class = NODE_CLASS_MAPPINGS[node_name]
if hasattr(node_class, "NAME_PREFIX"):
display_name = f"{node_class.NAME_PREFIX} {display_name}"
# Add suffix if defined
if hasattr(node_class, "NAME_SUFFIX"):
display_name = f"{display_name} {node_class.NAME_SUFFIX}"
else:
display_name = NODE_DISPLAY_NAME_MAPPINGS[node_name]
# Add the suffix if it's not already present
if not display_name.endswith(suffix):
display_name += suffix
# Assign the final display name to the mappings
NODE_DISPLAY_NAME_MAPPINGS[node_name] = display_name
# --- Original Web Directory and Export ---
WEB_DIRECTORY = "./web/js" # Adjusted path if needed
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
print("\033[92m" + f"[ComfyUI_RealtimeNodes] Loaded {len(NODE_CLASS_MAPPINGS)} nodes.")