Browse Source

improve: add preemptions for custom nodes

- better nickname displays for badge

fix: If the missing node is included in multiple custom node packs, it reports all the custom node packs.
pull/440/head
dr.lt.data 9 months ago
parent
commit
ef24e2cee6
  1. 42
      __init__.py
  2. 1
      custom-node-list.json
  3. 29
      extension-node-map.json
  4. 16
      js/comfyui-manager.js
  5. 21
      js/custom-nodes-downloader.js
  6. 26
      node_db/new/extension-node-map.json
  7. 2
      scan.sh
  8. 59
      scanner.py

42
__init__.py

@ -29,7 +29,7 @@ except:
print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.")
version = [2, 7, 2]
version = [2, 8]
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
print(f"### Loading: ComfyUI-Manager ({version_str})")
@ -777,9 +777,47 @@ def check_custom_nodes_installed(json_obj, do_fetch=False, do_update_check=True,
print(f"\x1b[2K\rUpdate check done.")
def nickname_filter(json_obj):
preemptions_map = {}
for k, x in json_obj.items():
if 'preemptions' in x[1]:
for y in x[1]['preemptions']:
preemptions_map[y] = k
elif k.endswith("/ComfyUI"):
for y in x[0]:
preemptions_map[y] = k
updates = {}
for k, x in json_obj.items():
removes = set()
for y in x[0]:
k2 = preemptions_map.get(y)
if k2 is not None and k != k2:
removes.add(y)
if len(removes) > 0:
updates[k] = [y for y in x[0] if y not in removes]
for k, v in updates.items():
json_obj[k][0] = v
return json_obj
@server.PromptServer.instance.routes.get("/customnode/getmappings")
async def fetch_customnode_mappings(request):
json_obj = await get_data_by_mode(request.rel_url.query["mode"], 'extension-node-map.json')
mode = request.rel_url.query["mode"]
nickname_mode = False
if mode == "nickname":
mode = "local"
nickname_mode = True
json_obj = await get_data_by_mode(mode, 'extension-node-map.json')
if nickname_mode:
json_obj = nickname_filter(json_obj)
all_nodes = set()
patterns = []

1
custom-node-list.json

@ -1896,6 +1896,7 @@
"https://github.com/Ttl/ComfyUi_NNLatentUpscale"
],
"install_type": "git-clone",
"preemptions": ["NNLatentUpscale"],
"description": "Nodes:NNLatentUpscale, A custom ComfyUI node designed for rapid latent upscaling using a compact neural network, eliminating the need for VAE-based decoding and encoding."
},
{

29
extension-node-map.json

@ -247,15 +247,6 @@
"title_aux": "AnimateDiff"
}
],
"https://github.com/AuroBit/ComfyUI-OOTDiffusion": [
[
"LoadOOTDPipeline",
"OOTDGenerate"
],
{
"title_aux": "ComfyUI OOTDiffusion"
}
],
"https://github.com/AustinMroz/ComfyUI-SpliceTools": [
[
"LogSigmas",
@ -682,7 +673,7 @@
"author": "CRE8IT GmbH",
"description": "This extension offers various nodes.",
"nickname": "cre8Nodes",
"title": "cr8SerialPrompter",
"title": "cr8ImageSizer",
"title_aux": "ComfyUI-Cre8it-Nodes"
}
],
@ -1060,10 +1051,12 @@
],
"https://github.com/Haoming02/comfyui-diffusion-cg": [
[
"Hook Recenter",
"Hook Recenter XL",
"Normalization",
"NormalizationXL",
"Recenter",
"Recenter XL"
"Tensor Debug",
"Unhook Recenter"
],
{
"title_aux": "ComfyUI Diffusion Color Grading"
@ -2015,6 +2008,7 @@
],
"https://github.com/RomanKuschanow/ComfyUI-Advanced-Latent-Control": [
[
"KSamplerMirroring",
"LatentMirror",
"LatentShift"
],
@ -2825,6 +2819,9 @@
"NNLatentUpscale"
],
{
"preemptions": [
"NNLatentUpscale"
],
"title_aux": "ComfyUI Neural Network Latent Upscale"
}
],
@ -4948,14 +4945,14 @@
],
"https://github.com/davask/ComfyUI-MarasIT-Nodes": [
[
"MarasitBusNode",
"MarasitAnyBusNode",
"MarasitBusNode",
"MarasitBusPipeNode",
"MarasitPipeNodeBasic",
"MarasitUniversalBusNode"
],
{
"title_aux": "🐰 MarasIT Nodes"
"title_aux": "\ud83d\udc30 MarasIT Nodes"
}
],
"https://github.com/dave-palt/comfyui_DSP_imagehelpers": [
@ -5516,6 +5513,7 @@
],
"https://github.com/gokayfem/ComfyUI_VLM_nodes": [
[
"AudioLDM2Node",
"CreativeArtPromptGenerator",
"Internlm",
"Joytag",
@ -5531,6 +5529,7 @@
"LLavaSamplerSimple",
"LlavaClipLoader",
"MoonDream",
"PlayMusic",
"PromptGenerateAPI",
"SimpleText",
"Suggester",
@ -8745,4 +8744,4 @@
"title_aux": "SDXLCustomAspectRatio"
}
]
}
}

16
js/comfyui-manager.js vendored

@ -147,13 +147,13 @@ docStyle.innerHTML = `
}
.cm-notice-board > ul {
display: block;
list-style-type: disc;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
padding-inline-start: 40px;
display: block;
list-style-type: disc;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
padding-inline-start: 40px;
}
.cm-conflicted-nodes-text {
@ -378,7 +378,7 @@ await init_badge_mode();
await init_share_option();
async function fetchNicknames() {
const response1 = await api.fetchApi(`/customnode/getmappings?mode=local`);
const response1 = await api.fetchApi(`/customnode/getmappings?mode=nickname`);
const mappings = await response1.json();
let result = {};

21
js/custom-nodes-downloader.js

@ -154,7 +154,6 @@ export class CustomNodesInstaller extends ComfyDialog {
async filter_missing_node(data) {
const mappings = await getCustomnodeMappings();
// build regex->url map
const regex_to_url = [];
for (let i in data) {
@ -165,11 +164,17 @@ export class CustomNodesInstaller extends ComfyDialog {
}
// build name->url map
const name_to_url = {};
const name_to_urls = {};
for (const url in mappings) {
const names = mappings[url];
for(const name in names[0]) {
name_to_url[names[0][name]] = url;
let v = name_to_urls[names[0][name]];
if(v == undefined) {
v = [];
name_to_urls[names[0][name]] = v;
}
v.push(url);
}
}
@ -194,9 +199,11 @@ export class CustomNodesInstaller extends ComfyDialog {
continue;
if (!registered_nodes.has(node_type)) {
const url = name_to_url[node_type.trim()];
if(url)
missing_nodes.add(url);
const urls = name_to_urls[node_type.trim()];
if(urls)
urls.forEach(url => {
missing_nodes.add(url);
});
else {
for(let j in regex_to_url) {
if(regex_to_url[j].regex.test(node_type)) {
@ -210,7 +217,7 @@ export class CustomNodesInstaller extends ComfyDialog {
let unresolved_nodes = await getUnresolvedNodesInComponent();
for (let i in unresolved_nodes) {
let node_type = unresolved_nodes[i];
const url = name_to_url[node_type];
const url = name_to_urls[node_type];
if(url)
missing_nodes.add(url);
}

26
node_db/new/extension-node-map.json

@ -247,15 +247,6 @@
"title_aux": "AnimateDiff"
}
],
"https://github.com/AuroBit/ComfyUI-OOTDiffusion": [
[
"LoadOOTDPipeline",
"OOTDGenerate"
],
{
"title_aux": "ComfyUI OOTDiffusion"
}
],
"https://github.com/AustinMroz/ComfyUI-SpliceTools": [
[
"LogSigmas",
@ -682,7 +673,7 @@
"author": "CRE8IT GmbH",
"description": "This extension offers various nodes.",
"nickname": "cre8Nodes",
"title": "cr8SerialPrompter",
"title": "cr8ImageSizer",
"title_aux": "ComfyUI-Cre8it-Nodes"
}
],
@ -1060,10 +1051,12 @@
],
"https://github.com/Haoming02/comfyui-diffusion-cg": [
[
"Hook Recenter",
"Hook Recenter XL",
"Normalization",
"NormalizationXL",
"Recenter",
"Recenter XL"
"Tensor Debug",
"Unhook Recenter"
],
{
"title_aux": "ComfyUI Diffusion Color Grading"
@ -2015,6 +2008,7 @@
],
"https://github.com/RomanKuschanow/ComfyUI-Advanced-Latent-Control": [
[
"KSamplerMirroring",
"LatentMirror",
"LatentShift"
],
@ -2825,6 +2819,9 @@
"NNLatentUpscale"
],
{
"preemptions": [
"NNLatentUpscale"
],
"title_aux": "ComfyUI Neural Network Latent Upscale"
}
],
@ -4948,13 +4945,14 @@
],
"https://github.com/davask/ComfyUI-MarasIT-Nodes": [
[
"MarasitAnyBusNode",
"MarasitBusNode",
"MarasitBusPipeNode",
"MarasitPipeNodeBasic",
"MarasitUniversalBusNode"
],
{
"title_aux": "MarasIT Nodes"
"title_aux": "\ud83d\udc30 MarasIT Nodes"
}
],
"https://github.com/dave-palt/comfyui_DSP_imagehelpers": [
@ -5515,6 +5513,7 @@
],
"https://github.com/gokayfem/ComfyUI_VLM_nodes": [
[
"AudioLDM2Node",
"CreativeArtPromptGenerator",
"Internlm",
"Joytag",
@ -5530,6 +5529,7 @@
"LLavaSamplerSimple",
"LlavaClipLoader",
"MoonDream",
"PlayMusic",
"PromptGenerateAPI",
"SimpleText",
"Suggester",

2
scan.sh

@ -1,6 +1,6 @@
#!/bin/bash
rm ~/.tmp/default/*.py > /dev/null 2>&1
python scanner.py ~/.tmp/default
python scanner.py ~/.tmp/default $@
cp extension-node-map.json node_db/new/.
echo Integrity check

59
scanner.py

@ -20,6 +20,8 @@ else:
if not os.path.exists(temp_dir):
os.makedirs(temp_dir)
skip_update = '--skip-update' in sys.argv
print(f"TEMP DIR: {temp_dir}")
@ -159,9 +161,9 @@ def get_git_urls_from_json(json_file):
if node.get('install_type') == 'git-clone':
files = node.get('files', [])
if files:
git_clone_files.append((files[0], node.get('title'), node.get('nodename_pattern')))
git_clone_files.append((files[0], node.get('title'), node.get('preemptions'), node.get('nodename_pattern')))
git_clone_files.append(("https://github.com/comfyanonymous/ComfyUI", "ComfyUI", None))
git_clone_files.append(("https://github.com/comfyanonymous/ComfyUI", "ComfyUI", None, None))
return git_clone_files
@ -176,7 +178,7 @@ def get_py_urls_from_json(json_file):
if node.get('install_type') == 'copy':
files = node.get('files', [])
if files:
py_files.append((files[0], node.get('title'), node.get('nodename_pattern')))
py_files.append((files[0], node.get('title'), node.get('preemptions'), node.get('nodename_pattern')))
return py_files
@ -208,27 +210,31 @@ def update_custom_nodes():
node_info = {}
git_url_titles = get_git_urls_from_json('custom-node-list.json')
git_url_titles_preemptions = get_git_urls_from_json('custom-node-list.json')
def process_git_url_title(url, title, preemptions, node_pattern):
if 'Jovimetrix' in title:
pass
def process_git_url_title(url, title, node_pattern):
name = os.path.basename(url)
if name.endswith(".git"):
name = name[:-4]
node_info[name] = (url, title, node_pattern)
clone_or_pull_git_repository(url)
node_info[name] = (url, title, preemptions, node_pattern)
if not skip_update:
clone_or_pull_git_repository(url)
with concurrent.futures.ThreadPoolExecutor(10) as executor:
for url, title, node_pattern in git_url_titles:
executor.submit(process_git_url_title, url, title, node_pattern)
for url, title, preemptions, node_pattern in git_url_titles_preemptions:
executor.submit(process_git_url_title, url, title, preemptions, node_pattern)
py_url_titles_and_pattern = get_py_urls_from_json('custom-node-list.json')
def download_and_store_info(url_title_and_pattern):
url, title, node_pattern = url_title_and_pattern
def download_and_store_info(url_title_preemptions_and_pattern):
url, title, preemptions, node_pattern = url_title_preemptions_and_pattern
name = os.path.basename(url)
if name.endswith(".py"):
node_info[name] = (url, title, node_pattern)
node_info[name] = (url, title, preemptions, node_pattern)
try:
download_url(url, temp_dir)
@ -262,15 +268,24 @@ def gen_json(node_info):
dirname = os.path.basename(dirname)
if len(nodes) > 0 or (dirname in node_info and node_info[dirname][2] is not None):
if 'Jovimetrix' in dirname:
pass
if len(nodes) > 0 or (dirname in node_info and node_info[dirname][3] is not None):
nodes = list(nodes)
nodes.sort()
if dirname in node_info:
git_url, title, node_pattern = node_info[dirname]
git_url, title, preemptions, node_pattern = node_info[dirname]
metadata['title_aux'] = title
if preemptions is not None:
metadata['preemptions'] = preemptions
if node_pattern is not None:
metadata['nodename_pattern'] = node_pattern
data[git_url] = (nodes, metadata)
else:
print(f"WARN: {dirname} is removed from custom-node-list.json")
@ -278,17 +293,22 @@ def gen_json(node_info):
for file in node_files:
nodes, metadata = scan_in_file(file)
if len(nodes) > 0 or (dirname in node_info and node_info[dirname][2] is not None):
if len(nodes) > 0 or (dirname in node_info and node_info[dirname][3] is not None):
nodes = list(nodes)
nodes.sort()
file = os.path.basename(file)
if file in node_info:
url, title, node_pattern = node_info[file]
url, title, preemptions, node_pattern = node_info[file]
metadata['title_aux'] = title
if preemptions is not None:
metadata['preemptions'] = preemptions
if node_pattern is not None:
metadata['nodename_pattern'] = node_pattern
data[url] = (nodes, metadata)
else:
print(f"Missing info: {file}")
@ -299,7 +319,7 @@ def gen_json(node_info):
for extension in extensions:
node_list_json_path = os.path.join(temp_dir, extension, 'node_list.json')
if os.path.exists(node_list_json_path):
git_url, title, node_pattern = node_info[extension]
git_url, title, preemptions, node_pattern = node_info[extension]
with open(node_list_json_path, 'r', encoding='utf-8') as f:
node_list_json = json.load(f)
@ -315,8 +335,13 @@ def gen_json(node_info):
nodes.add(x.strip())
metadata_in_url['title_aux'] = title
if preemptions is not None:
metadata['preemptions'] = preemptions
if node_pattern is not None:
metadata_in_url['nodename_pattern'] = node_pattern
nodes = list(nodes)
nodes.sort()
data[git_url] = (nodes, metadata_in_url)

Loading…
Cancel
Save