comfyuiManager_v012 / scanner.py
Outimus's picture
Upload 19 files
f4ee4c3
raw
history blame
5.93 kB
import re
import os
import json
from git import Repo
from torchvision.datasets.utils import download_url
def scan_in_file(filename):
try:
with open(filename, encoding='utf-8') as file:
code = file.read()
except UnicodeDecodeError:
with open(filename, encoding='cp949') as file:
code = file.read()
pattern = r"NODE_CLASS_MAPPINGS\s*=\s*{([^}]*)}"
regex = re.compile(pattern, re.MULTILINE | re.DOTALL)
nodes = set()
class_dict = {}
pattern2 = r'NODE_CLASS_MAPPINGS\["(.*?)"\]'
keys = re.findall(pattern2, code)
for key in keys:
nodes.add(key)
matches = regex.findall(code)
for match in matches:
dict_text = match
key_value_pairs = re.findall(r"\"([^\"]*)\"\s*:\s*([^,\n]*)", dict_text)
for key, value in key_value_pairs:
class_dict[key] = value.strip()
for key, value in class_dict.items():
nodes.add(key)
update_pattern = r"NODE_CLASS_MAPPINGS.update\s*\({([^}]*)}\)"
update_match = re.search(update_pattern, code)
if update_match:
update_dict_text = update_match.group(1)
update_key_value_pairs = re.findall(r"\"([^\"]*)\"\s*:\s*([^,\n]*)", update_dict_text)
for key, value in update_key_value_pairs:
class_dict[key] = value.strip()
nodes.add(key)
return nodes
def get_py_file_paths(dirname):
file_paths = []
for root, dirs, files in os.walk(dirname):
if ".git" in root or "__pycache__" in root:
continue
for file in files:
if file.endswith(".py"):
file_path = os.path.join(root, file)
file_paths.append(file_path)
return file_paths
def get_nodes(target_dir):
py_files = []
directories = []
for item in os.listdir(target_dir):
if ".git" in item or "__pycache__" in item:
continue
path = os.path.abspath(os.path.join(target_dir, item))
if os.path.isfile(path) and item.endswith(".py"):
py_files.append(path)
elif os.path.isdir(path):
directories.append(path)
return py_files, directories
def get_git_urls_from_json(json_file):
with open(json_file) as file:
data = json.load(file)
custom_nodes = data.get('custom_nodes', [])
git_clone_files = []
for node in custom_nodes:
if node.get('install_type') == 'git-clone':
files = node.get('files', [])
if files:
git_clone_files.append(files[0])
return git_clone_files
def get_py_urls_from_json(json_file):
with open(json_file) as file:
data = json.load(file)
custom_nodes = data.get('custom_nodes', [])
py_files = []
for node in custom_nodes:
if node.get('install_type') == 'copy':
files = node.get('files', [])
if files:
py_files.append(files[0])
return py_files
def clone_or_pull_git_repository(git_url):
repo_name = git_url.split("/")[-1].split(".")[0]
repo_dir = os.path.join(os.getcwd(), ".tmp", repo_name)
if os.path.exists(repo_dir):
try:
repo = Repo(repo_dir)
origin = repo.remote(name="origin")
origin.pull()
repo.git.submodule('update', '--init', '--recursive')
print(f"Pulling {repo_name}...")
except Exception as e:
print(f"Pulling {repo_name} failed: {e}")
else:
try:
repo = Repo.clone_from(git_url, repo_dir, recursive=True)
print(f"Cloning {repo_name}...")
except Exception as e:
print(f"Cloning {repo_name} failed: {e}")
def update_custom_nodes():
tmp_dir = os.path.join(os.getcwd(), ".tmp")
if not os.path.exists(tmp_dir):
os.makedirs(tmp_dir)
node_info = {}
git_urls = get_git_urls_from_json('custom-node-list.json')
for url in git_urls:
name = os.path.basename(url)
if name.endswith(".git"):
name = name[:-4]
node_info[name] = url
clone_or_pull_git_repository(url)
py_urls = get_py_urls_from_json('custom-node-list.json')
for url in py_urls:
name = os.path.basename(url)
if name.endswith(".py"):
node_info[name] = url
try:
download_url(url, ".tmp")
except:
print(f"[ERROR] Cannot download '{url}'")
return node_info
def gen_json(node_info):
node_files, node_dirs = get_nodes(".tmp")
data = {}
for dirname in node_dirs:
py_files = get_py_file_paths(dirname)
nodes = set()
for py in py_files:
nodes.update(scan_in_file(py))
dirname = os.path.basename(dirname)
if len(nodes) > 0:
nodes = list(nodes)
nodes.sort()
if dirname in node_info:
git_url = node_info[dirname]
data[git_url] = nodes
else:
print(f"WARN: {dirname} is removed from custom-node-list.json")
for file in node_files:
nodes = scan_in_file(file)
if len(nodes) > 0:
nodes = list(nodes)
nodes.sort()
file = os.path.basename(file)
if file in node_info:
url = node_info[file]
data[url] = nodes
else:
print(f"Missing info: {url}")
json_path = f"extension-node-map.json"
with open(json_path, "w") as file:
json.dump(data, file, indent=4, sort_keys=True)
print("### ComfyUI Manager Node Scanner ###")
print("\n# Updating extensions\n")
updated_node_info = update_custom_nodes()
print("\n# 'extension-node-map.json' file is generated.\n")
gen_json(updated_node_info)