mirror of
https://git.datalinker.icu/ltdrdata/ComfyUI-Manager
synced 2025-12-08 21:54:26 +08:00
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.
This commit is contained in:
parent
b013eaa7c9
commit
ef24e2cee6
42
__init__.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 = []
|
||||
|
||||
@ -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."
|
||||
},
|
||||
{
|
||||
|
||||
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -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 = {};
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
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
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…
x
Reference in New Issue
Block a user