mirror of
https://git.datalinker.icu/ltdrdata/ComfyUI-Manager
synced 2025-12-09 14:14:54 +08:00
import fail check
notice board built-in node check node conflict check
This commit is contained in:
parent
7c82317201
commit
6fada254ea
@ -192,14 +192,14 @@ NODE_CLASS_MAPPINGS.update({
|
||||
|
||||
## Roadmap
|
||||
|
||||
- [ ] System displaying information about failed custom nodes import.
|
||||
- [ ] Guide for missing nodes in ComfyUI vanilla nodes.
|
||||
- [x] System displaying information about failed custom nodes import.
|
||||
- [x] Guide for missing nodes in ComfyUI vanilla nodes.
|
||||
- [x] Collision checking system for nodes with the same ID across extensions.
|
||||
- [ ] Auto migration for custom nodes with changed structures.
|
||||
- [ ] Version control feature for nodes.
|
||||
- [ ] List of currently used custom nodes.
|
||||
- [ ] Template sharing system.
|
||||
- [ ] 3rd party API system.
|
||||
- [ ] Collision checking system for nodes with the same ID across extensions.
|
||||
|
||||
|
||||
# Disclaimer
|
||||
|
||||
55
__init__.py
55
__init__.py
@ -13,8 +13,10 @@ from tqdm.auto import tqdm
|
||||
import concurrent
|
||||
import ssl
|
||||
from urllib.parse import urlparse
|
||||
import http.client
|
||||
import re
|
||||
|
||||
version = "V1.3"
|
||||
version = "V1.4"
|
||||
print(f"### Loading: ComfyUI-Manager ({version})")
|
||||
|
||||
|
||||
@ -84,6 +86,7 @@ from torchvision.datasets.utils import download_url
|
||||
|
||||
comfy_ui_required_revision = 1240
|
||||
comfy_ui_revision = "Unknown"
|
||||
comfy_ui_commit_date = ""
|
||||
|
||||
comfy_path = os.path.dirname(folder_paths.__file__)
|
||||
custom_nodes_path = os.path.join(comfy_path, 'custom_nodes')
|
||||
@ -244,6 +247,8 @@ def try_install_script(url, repo_path, install_cmd):
|
||||
|
||||
def print_comfyui_version():
|
||||
global comfy_ui_revision
|
||||
global comfy_ui_commit_date
|
||||
|
||||
try:
|
||||
repo = git.Repo(os.path.dirname(folder_paths.__file__))
|
||||
|
||||
@ -257,10 +262,11 @@ def print_comfyui_version():
|
||||
except:
|
||||
pass
|
||||
|
||||
comfy_ui_commit_date = repo.head.commit.committed_datetime.date()
|
||||
if current_branch == "master":
|
||||
print(f"### ComfyUI Revision: {comfy_ui_revision} [{git_hash[:8]}] | Released on '{repo.head.commit.committed_datetime.date()}'")
|
||||
print(f"### ComfyUI Revision: {comfy_ui_revision} [{git_hash[:8]}] | Released on '{comfy_ui_commit_date}'")
|
||||
else:
|
||||
print(f"### ComfyUI Revision: {comfy_ui_revision} on '{current_branch}' [{git_hash[:8]}] | Released on '{repo.head.commit.committed_datetime.date()}'")
|
||||
print(f"### ComfyUI Revision: {comfy_ui_revision} on '{current_branch}' [{git_hash[:8]}] | Released on '{comfy_ui_commit_date}'")
|
||||
except:
|
||||
print("### ComfyUI Revision: UNKNOWN (The currently installed ComfyUI is not a Git repository)")
|
||||
|
||||
@ -531,10 +537,15 @@ def check_a_custom_node_installed(item, do_fetch=False, do_update_check=True, do
|
||||
try:
|
||||
if do_update_check and git_repo_has_updates(dir_path, do_fetch, do_update):
|
||||
item['installed'] = 'Update'
|
||||
elif sys.__comfyui_manager_is_import_failed_extension(dir_name):
|
||||
item['installed'] = 'Fail'
|
||||
else:
|
||||
item['installed'] = 'True'
|
||||
except:
|
||||
item['installed'] = 'True'
|
||||
if sys.__comfyui_manager_is_import_failed_extension(dir_name):
|
||||
item['installed'] = 'Fail'
|
||||
else:
|
||||
item['installed'] = 'True'
|
||||
|
||||
elif os.path.exists(dir_path + ".disabled"):
|
||||
item['installed'] = 'Disabled'
|
||||
@ -554,7 +565,10 @@ def check_a_custom_node_installed(item, do_fetch=False, do_update_check=True, do
|
||||
|
||||
file_path = os.path.join(base_path, dir_name)
|
||||
if os.path.exists(file_path):
|
||||
item['installed'] = 'True'
|
||||
if sys.__comfyui_manager_is_import_failed_extension(dir_name):
|
||||
item['installed'] = 'Fail'
|
||||
else:
|
||||
item['installed'] = 'True'
|
||||
elif os.path.exists(file_path + ".disabled"):
|
||||
item['installed'] = 'Disabled'
|
||||
else:
|
||||
@ -1421,6 +1435,37 @@ async def channel_url_list(request):
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@server.PromptServer.instance.routes.get("/manager/notice")
|
||||
async def get_notice(request):
|
||||
url = "github.com"
|
||||
path = "/ltdrdata/ltdrdata.github.io/wiki/News"
|
||||
|
||||
conn = http.client.HTTPSConnection(url)
|
||||
conn.request("GET", path)
|
||||
|
||||
response = conn.getresponse()
|
||||
|
||||
try:
|
||||
if response.status == 200:
|
||||
html_content = response.read().decode('utf-8')
|
||||
|
||||
pattern = re.compile(r'<div class="markdown-body">([\s\S]*?)</div>')
|
||||
match = pattern.search(html_content)
|
||||
|
||||
if match:
|
||||
markdown_content = match.group(1)
|
||||
markdown_content += f"<HR>ComfyUI: {comfy_ui_revision} ({comfy_ui_commit_date})"
|
||||
markdown_content += f"<BR>Manager: {version}"
|
||||
return web.Response(text=markdown_content, status=200)
|
||||
else:
|
||||
return web.Response(text="Unable to retrieve Notice", status=200)
|
||||
else:
|
||||
return web.Response(text="Unable to retrieve Notice", status=200)
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_matrix_auth():
|
||||
if not os.path.exists(os.path.join(folder_paths.base_path, "matrix_auth")):
|
||||
return None
|
||||
|
||||
@ -2565,6 +2565,138 @@
|
||||
"title_aux": "comfy-nodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/comfyanonymous/ComfyUI": [
|
||||
[
|
||||
"BasicScheduler",
|
||||
"CLIPLoader",
|
||||
"CLIPMergeSimple",
|
||||
"CLIPSave",
|
||||
"CLIPSetLastLayer",
|
||||
"CLIPTextEncode",
|
||||
"CLIPTextEncodeSDXL",
|
||||
"CLIPTextEncodeSDXLRefiner",
|
||||
"CLIPVisionEncode",
|
||||
"CLIPVisionLoader",
|
||||
"Canny",
|
||||
"CheckpointLoader",
|
||||
"CheckpointLoaderSimple",
|
||||
"CheckpointSave",
|
||||
"ConditioningAverage",
|
||||
"ConditioningCombine",
|
||||
"ConditioningConcat",
|
||||
"ConditioningSetArea",
|
||||
"ConditioningSetAreaPercentage",
|
||||
"ConditioningSetMask",
|
||||
"ConditioningSetTimestepRange",
|
||||
"ConditioningZeroOut",
|
||||
"ControlNetApply",
|
||||
"ControlNetApplyAdvanced",
|
||||
"ControlNetLoader",
|
||||
"CropMask",
|
||||
"DiffControlNetLoader",
|
||||
"DiffusersLoader",
|
||||
"DualCLIPLoader",
|
||||
"EmptyImage",
|
||||
"EmptyLatentImage",
|
||||
"ExponentialScheduler",
|
||||
"FeatherMask",
|
||||
"FlipSigmas",
|
||||
"FreeU",
|
||||
"FreeU_V2",
|
||||
"GLIGENLoader",
|
||||
"GLIGENTextBoxApply",
|
||||
"GrowMask",
|
||||
"HyperTile",
|
||||
"HypernetworkLoader",
|
||||
"ImageBatch",
|
||||
"ImageBlend",
|
||||
"ImageBlur",
|
||||
"ImageColorToMask",
|
||||
"ImageCompositeMasked",
|
||||
"ImageCrop",
|
||||
"ImageInvert",
|
||||
"ImageOnlyCheckpointLoader",
|
||||
"ImagePadForOutpaint",
|
||||
"ImageQuantize",
|
||||
"ImageScale",
|
||||
"ImageScaleBy",
|
||||
"ImageScaleToTotalPixels",
|
||||
"ImageSharpen",
|
||||
"ImageToMask",
|
||||
"ImageUpscaleWithModel",
|
||||
"InvertMask",
|
||||
"JoinImageWithAlpha",
|
||||
"KSampler",
|
||||
"KSamplerAdvanced",
|
||||
"KSamplerSelect",
|
||||
"KarrasScheduler",
|
||||
"LatentAdd",
|
||||
"LatentBlend",
|
||||
"LatentComposite",
|
||||
"LatentCompositeMasked",
|
||||
"LatentCrop",
|
||||
"LatentFlip",
|
||||
"LatentFromBatch",
|
||||
"LatentInterpolate",
|
||||
"LatentMultiply",
|
||||
"LatentRotate",
|
||||
"LatentSubtract",
|
||||
"LatentUpscale",
|
||||
"LatentUpscaleBy",
|
||||
"LoadImage",
|
||||
"LoadImageMask",
|
||||
"LoadLatent",
|
||||
"LoraLoader",
|
||||
"LoraLoaderModelOnly",
|
||||
"MaskComposite",
|
||||
"MaskToImage",
|
||||
"ModelMergeAdd",
|
||||
"ModelMergeBlocks",
|
||||
"ModelMergeSimple",
|
||||
"ModelMergeSubtract",
|
||||
"ModelSamplingContinuousEDM",
|
||||
"ModelSamplingDiscrete",
|
||||
"PatchModelAddDownscale",
|
||||
"PolyexponentialScheduler",
|
||||
"PorterDuffImageComposite",
|
||||
"PreviewImage",
|
||||
"RebatchLatents",
|
||||
"RepeatImageBatch",
|
||||
"RepeatLatentBatch",
|
||||
"RescaleCFG",
|
||||
"SVD_img2vid_Conditioning",
|
||||
"SamplerCustom",
|
||||
"SamplerDPMPP_2M_SDE",
|
||||
"SamplerDPMPP_SDE",
|
||||
"SaveAnimatedPNG",
|
||||
"SaveAnimatedWEBP",
|
||||
"SaveImage",
|
||||
"SaveLatent",
|
||||
"SetLatentNoiseMask",
|
||||
"SolidMask",
|
||||
"SplitImageWithAlpha",
|
||||
"SplitSigmas",
|
||||
"StyleModelApply",
|
||||
"StyleModelLoader",
|
||||
"TomePatchModel",
|
||||
"UNETLoader",
|
||||
"UpscaleModelLoader",
|
||||
"VAEDecode",
|
||||
"VAEDecodeTiled",
|
||||
"VAEEncode",
|
||||
"VAEEncodeForInpaint",
|
||||
"VAEEncodeTiled",
|
||||
"VAELoader",
|
||||
"VAESave",
|
||||
"VPScheduler",
|
||||
"VideoLinearCFGGuidance",
|
||||
"unCLIPCheckpointLoader",
|
||||
"unCLIPConditioning"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI"
|
||||
}
|
||||
],
|
||||
"https://github.com/comfyanonymous/ComfyUI_experiments": [
|
||||
[
|
||||
"ModelMergeBlockNumber",
|
||||
@ -4274,6 +4406,7 @@
|
||||
[
|
||||
"Auto Merge Block Weighted",
|
||||
"CLIPMergeSimple",
|
||||
"CheckpointSave",
|
||||
"ModelMergeBlocks",
|
||||
"ModelMergeSimple"
|
||||
],
|
||||
|
||||
@ -28,6 +28,16 @@ docStyle.innerHTML = `
|
||||
text-align: center;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.cm-notice-board {
|
||||
width: 250px;
|
||||
height: 130px;
|
||||
overflow: auto;
|
||||
color: var(--input-text);
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
overflow-x: hidden;
|
||||
};
|
||||
`;
|
||||
|
||||
document.head.appendChild(docStyle);
|
||||
@ -79,6 +89,14 @@ async function init_badge_mode() {
|
||||
.then(data => { badge_mode = data; })
|
||||
}
|
||||
|
||||
async function init_notice(notice) {
|
||||
api.fetchApi('/manager/notice')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
notice.innerHTML = data;
|
||||
})
|
||||
}
|
||||
|
||||
await init_badge_mode();
|
||||
|
||||
|
||||
@ -436,7 +454,7 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
}
|
||||
|
||||
createControlsRight() {
|
||||
return [
|
||||
const elts = [
|
||||
$el("button", {
|
||||
type: "button",
|
||||
textContent: "ComfyUI Community Manual",
|
||||
@ -514,7 +532,16 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
textContent: "ComfyUI Nodes Info",
|
||||
onclick: () => { window.open("https://ltdrdata.github.io/", "comfyui-node-info"); }
|
||||
}),
|
||||
$el("br", {}, []),
|
||||
];
|
||||
|
||||
var textarea = document.createElement("div");
|
||||
textarea.className = "cm-notice-board";
|
||||
elts.push(textarea);
|
||||
|
||||
init_notice(textarea);
|
||||
|
||||
return elts;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@ -647,6 +674,10 @@ app.registerExtension({
|
||||
if (nicknames[nodeData.name.trim()]) {
|
||||
let nick = nicknames[nodeData.name.trim()];
|
||||
|
||||
if (nick == 'ComfyUI') {
|
||||
nick = "🦊"
|
||||
}
|
||||
|
||||
if (nick.length > 25) {
|
||||
text += nick.substring(0, 23) + "..";
|
||||
}
|
||||
@ -691,6 +722,10 @@ app.registerExtension({
|
||||
if (nicknames[node.type.trim()]) {
|
||||
let nick = nicknames[node.type.trim()];
|
||||
|
||||
if (nick == 'ComfyUI') {
|
||||
nick = "🦊"
|
||||
}
|
||||
|
||||
if (nick.length > 25) {
|
||||
text += nick.substring(0, 23) + "..";
|
||||
}
|
||||
|
||||
@ -29,6 +29,53 @@ async function getCustomnodeMappings() {
|
||||
return data;
|
||||
}
|
||||
|
||||
async function getConflictMappings() {
|
||||
var mode = "url";
|
||||
if(manager_instance.local_mode_checkbox.checked)
|
||||
mode = "local";
|
||||
|
||||
const response = await api.fetchApi(`/customnode/getmappings?mode=${mode}`);
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
let node_to_extensions_map = {};
|
||||
|
||||
for(let k in data) {
|
||||
for(let i in data[k][0]) {
|
||||
let node = data[k][0][i];
|
||||
let l = node_to_extensions_map[node];
|
||||
if(!l) {
|
||||
l = [];
|
||||
node_to_extensions_map[node] = l;
|
||||
}
|
||||
l.push(k);
|
||||
}
|
||||
}
|
||||
|
||||
let conflict_map = {};
|
||||
for(let node in node_to_extensions_map) {
|
||||
if(node_to_extensions_map[node].length > 1) {
|
||||
for(let i in node_to_extensions_map[node]) {
|
||||
let extension = node_to_extensions_map[node][i];
|
||||
let l = conflict_map[extension];
|
||||
|
||||
if(!l) {
|
||||
l = [];
|
||||
conflict_map[extension] = l;
|
||||
}
|
||||
|
||||
for(let j in node_to_extensions_map[node]) {
|
||||
let extension2 = node_to_extensions_map[node][j];
|
||||
if(extension != extension2)
|
||||
l.push([node, extension2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return conflict_map;
|
||||
}
|
||||
|
||||
async function getUnresolvedNodesInComponent() {
|
||||
try {
|
||||
var mode = "url";
|
||||
@ -180,6 +227,8 @@ export class CustomNodesInstaller extends ComfyDialog {
|
||||
// invalidate
|
||||
this.data = (await getCustomNodes()).custom_nodes;
|
||||
|
||||
this.conflict_mappings = await getConflictMappings();
|
||||
|
||||
if(this.is_missing_node_mode)
|
||||
this.data = await this.filter_missing_node(this.data);
|
||||
|
||||
@ -369,6 +418,7 @@ export class CustomNodesInstaller extends ComfyDialog {
|
||||
var data1 = document.createElement('td');
|
||||
data1.style.textAlign = "center";
|
||||
data1.innerHTML = i+1;
|
||||
|
||||
var data2 = document.createElement('td');
|
||||
data2.style.maxWidth = "100px";
|
||||
data2.className = "cm-node-author"
|
||||
@ -376,14 +426,43 @@ export class CustomNodesInstaller extends ComfyDialog {
|
||||
data2.style.whiteSpace = "nowrap";
|
||||
data2.style.overflow = "hidden";
|
||||
data2.style.textOverflow = "ellipsis";
|
||||
|
||||
var data3 = document.createElement('td');
|
||||
data3.style.maxWidth = "200px";
|
||||
data3.style.wordWrap = "break-word";
|
||||
data3.className = "cm-node-name"
|
||||
data3.innerHTML = ` <a href=${data.reference} target="_blank"><font color="skyblue"><b>${data.title}</b></font></a>`;
|
||||
if(data.installed == 'Fail')
|
||||
data3.innerHTML = ' <font color="BLACK"><B>(IMPORT FAILED)</B></font>' + data3.innerHTML;
|
||||
|
||||
var data4 = document.createElement('td');
|
||||
data4.innerHTML = data.description;
|
||||
data4.className = "cm-node-desc"
|
||||
|
||||
let conflicts = this.conflict_mappings[data.files[0]];
|
||||
if(conflicts) {
|
||||
let buf = '<BR><BR><FONT color="#AA3333"><B>Conflicted Nodes:</B><BR>';
|
||||
for(let k in conflicts) {
|
||||
let node_name = conflicts[k][0];
|
||||
|
||||
let extension_name = conflicts[k][1].split('/').pop();
|
||||
if(extension_name.endsWith('/')) {
|
||||
extension_name = extension_name.slice(0, -1);
|
||||
}
|
||||
if(node_name.endsWith('.git')) {
|
||||
extension_name = extension_name.slice(0, -4);
|
||||
}
|
||||
|
||||
buf += `${node_name} [${extension_name}], `;
|
||||
}
|
||||
|
||||
if(buf.endsWith(', ')) {
|
||||
buf = buf.slice(0, -2);
|
||||
}
|
||||
buf += "</FONT>";
|
||||
data4.innerHTML += buf;
|
||||
}
|
||||
|
||||
var data5 = document.createElement('td');
|
||||
data5.style.textAlign = "center";
|
||||
|
||||
@ -424,6 +503,7 @@ export class CustomNodesInstaller extends ComfyDialog {
|
||||
installBtn.innerHTML = 'Uninstall';
|
||||
installBtn.style.backgroundColor = 'red';
|
||||
break;
|
||||
case 'Fail':
|
||||
case 'True':
|
||||
installBtn3 = document.createElement('button');
|
||||
installBtn3.innerHTML = 'Disable';
|
||||
@ -441,7 +521,7 @@ export class CustomNodesInstaller extends ComfyDialog {
|
||||
installBtn.style.color = 'white';
|
||||
break;
|
||||
default:
|
||||
installBtn.innerHTML = 'Try Install';
|
||||
installBtn.innerHTML = `Try Install${data.installed}`;
|
||||
installBtn.style.backgroundColor = 'Gray';
|
||||
installBtn.style.color = 'white';
|
||||
}
|
||||
@ -479,7 +559,10 @@ export class CustomNodesInstaller extends ComfyDialog {
|
||||
|
||||
data5.appendChild(installBtn);
|
||||
|
||||
dataRow.style.backgroundColor = "var(--bg-color)";
|
||||
if(data.installed == 'Fail')
|
||||
dataRow.style.backgroundColor = "#880000";
|
||||
else
|
||||
dataRow.style.backgroundColor = "var(--bg-color)";
|
||||
dataRow.style.color = "var(--fg-color)";
|
||||
dataRow.style.textAlign = "left";
|
||||
|
||||
@ -548,6 +631,7 @@ export class CustomNodesInstaller extends ComfyDialog {
|
||||
{ value:'Update', text:'Filter: update' },
|
||||
{ value:'True', text:'Filter: installed' },
|
||||
{ value:'False', text:'Filter: not-installed' },
|
||||
{ value:'Fail', text:'Filter: import failed' },
|
||||
];
|
||||
|
||||
items.forEach(item => {
|
||||
|
||||
@ -2565,6 +2565,138 @@
|
||||
"title_aux": "comfy-nodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/comfyanonymous/ComfyUI": [
|
||||
[
|
||||
"BasicScheduler",
|
||||
"CLIPLoader",
|
||||
"CLIPMergeSimple",
|
||||
"CLIPSave",
|
||||
"CLIPSetLastLayer",
|
||||
"CLIPTextEncode",
|
||||
"CLIPTextEncodeSDXL",
|
||||
"CLIPTextEncodeSDXLRefiner",
|
||||
"CLIPVisionEncode",
|
||||
"CLIPVisionLoader",
|
||||
"Canny",
|
||||
"CheckpointLoader",
|
||||
"CheckpointLoaderSimple",
|
||||
"CheckpointSave",
|
||||
"ConditioningAverage",
|
||||
"ConditioningCombine",
|
||||
"ConditioningConcat",
|
||||
"ConditioningSetArea",
|
||||
"ConditioningSetAreaPercentage",
|
||||
"ConditioningSetMask",
|
||||
"ConditioningSetTimestepRange",
|
||||
"ConditioningZeroOut",
|
||||
"ControlNetApply",
|
||||
"ControlNetApplyAdvanced",
|
||||
"ControlNetLoader",
|
||||
"CropMask",
|
||||
"DiffControlNetLoader",
|
||||
"DiffusersLoader",
|
||||
"DualCLIPLoader",
|
||||
"EmptyImage",
|
||||
"EmptyLatentImage",
|
||||
"ExponentialScheduler",
|
||||
"FeatherMask",
|
||||
"FlipSigmas",
|
||||
"FreeU",
|
||||
"FreeU_V2",
|
||||
"GLIGENLoader",
|
||||
"GLIGENTextBoxApply",
|
||||
"GrowMask",
|
||||
"HyperTile",
|
||||
"HypernetworkLoader",
|
||||
"ImageBatch",
|
||||
"ImageBlend",
|
||||
"ImageBlur",
|
||||
"ImageColorToMask",
|
||||
"ImageCompositeMasked",
|
||||
"ImageCrop",
|
||||
"ImageInvert",
|
||||
"ImageOnlyCheckpointLoader",
|
||||
"ImagePadForOutpaint",
|
||||
"ImageQuantize",
|
||||
"ImageScale",
|
||||
"ImageScaleBy",
|
||||
"ImageScaleToTotalPixels",
|
||||
"ImageSharpen",
|
||||
"ImageToMask",
|
||||
"ImageUpscaleWithModel",
|
||||
"InvertMask",
|
||||
"JoinImageWithAlpha",
|
||||
"KSampler",
|
||||
"KSamplerAdvanced",
|
||||
"KSamplerSelect",
|
||||
"KarrasScheduler",
|
||||
"LatentAdd",
|
||||
"LatentBlend",
|
||||
"LatentComposite",
|
||||
"LatentCompositeMasked",
|
||||
"LatentCrop",
|
||||
"LatentFlip",
|
||||
"LatentFromBatch",
|
||||
"LatentInterpolate",
|
||||
"LatentMultiply",
|
||||
"LatentRotate",
|
||||
"LatentSubtract",
|
||||
"LatentUpscale",
|
||||
"LatentUpscaleBy",
|
||||
"LoadImage",
|
||||
"LoadImageMask",
|
||||
"LoadLatent",
|
||||
"LoraLoader",
|
||||
"LoraLoaderModelOnly",
|
||||
"MaskComposite",
|
||||
"MaskToImage",
|
||||
"ModelMergeAdd",
|
||||
"ModelMergeBlocks",
|
||||
"ModelMergeSimple",
|
||||
"ModelMergeSubtract",
|
||||
"ModelSamplingContinuousEDM",
|
||||
"ModelSamplingDiscrete",
|
||||
"PatchModelAddDownscale",
|
||||
"PolyexponentialScheduler",
|
||||
"PorterDuffImageComposite",
|
||||
"PreviewImage",
|
||||
"RebatchLatents",
|
||||
"RepeatImageBatch",
|
||||
"RepeatLatentBatch",
|
||||
"RescaleCFG",
|
||||
"SVD_img2vid_Conditioning",
|
||||
"SamplerCustom",
|
||||
"SamplerDPMPP_2M_SDE",
|
||||
"SamplerDPMPP_SDE",
|
||||
"SaveAnimatedPNG",
|
||||
"SaveAnimatedWEBP",
|
||||
"SaveImage",
|
||||
"SaveLatent",
|
||||
"SetLatentNoiseMask",
|
||||
"SolidMask",
|
||||
"SplitImageWithAlpha",
|
||||
"SplitSigmas",
|
||||
"StyleModelApply",
|
||||
"StyleModelLoader",
|
||||
"TomePatchModel",
|
||||
"UNETLoader",
|
||||
"UpscaleModelLoader",
|
||||
"VAEDecode",
|
||||
"VAEDecodeTiled",
|
||||
"VAEEncode",
|
||||
"VAEEncodeForInpaint",
|
||||
"VAEEncodeTiled",
|
||||
"VAELoader",
|
||||
"VAESave",
|
||||
"VPScheduler",
|
||||
"VideoLinearCFGGuidance",
|
||||
"unCLIPCheckpointLoader",
|
||||
"unCLIPConditioning"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI"
|
||||
}
|
||||
],
|
||||
"https://github.com/comfyanonymous/ComfyUI_experiments": [
|
||||
[
|
||||
"ModelMergeBlockNumber",
|
||||
@ -4274,6 +4406,7 @@
|
||||
[
|
||||
"Auto Merge Block Weighted",
|
||||
"CLIPMergeSimple",
|
||||
"CheckpointSave",
|
||||
"ModelMergeBlocks",
|
||||
"ModelMergeSimple"
|
||||
],
|
||||
|
||||
@ -9,6 +9,7 @@ import locale
|
||||
|
||||
|
||||
message_collapses = []
|
||||
import_failed_extensions = set()
|
||||
|
||||
|
||||
def register_message_collapse(f):
|
||||
@ -16,10 +17,16 @@ def register_message_collapse(f):
|
||||
message_collapses.append(f)
|
||||
|
||||
|
||||
def is_import_failed_extension(x):
|
||||
global import_failed_extensions
|
||||
return x in import_failed_extensions
|
||||
|
||||
|
||||
sys.__comfyui_manager_register_message_collapse = register_message_collapse
|
||||
sys.__comfyui_manager_is_import_failed_extension = is_import_failed_extension
|
||||
|
||||
comfyui_manager_path = os.path.dirname(__file__)
|
||||
custom_nodes_path = os.path.join(comfyui_manager_path, "..")
|
||||
custom_nodes_path = os.path.abspath(os.path.join(comfyui_manager_path, ".."))
|
||||
startup_script_path = os.path.join(comfyui_manager_path, "startup-scripts")
|
||||
restore_snapshot_path = os.path.join(startup_script_path, "restore-snapshot.json")
|
||||
git_script_path = os.path.join(comfyui_manager_path, "git_helper.py")
|
||||
@ -78,7 +85,12 @@ try:
|
||||
original_stdout = sys.stdout
|
||||
original_stderr = sys.stderr
|
||||
|
||||
tqdm = r'\d+%.*\[(.*?)\]'
|
||||
pat_tqdm = r'\d+%.*\[(.*?)\]'
|
||||
pat_import_fail = r'seconds \(IMPORT FAILED\):'
|
||||
pat_custom_node = r'[/\\]custom_nodes[/\\](.*)$'
|
||||
|
||||
is_start_mode = True
|
||||
is_import_fail_mode = False
|
||||
|
||||
log_file = open(f"comfyui{postfix}.log", "w", encoding="utf-8")
|
||||
log_lock = threading.Lock()
|
||||
@ -99,11 +111,30 @@ try:
|
||||
raise ValueError("The object does not have a fileno method")
|
||||
|
||||
def write(self, message):
|
||||
global is_start_mode
|
||||
global is_import_fail_mode
|
||||
|
||||
if any(f(message) for f in message_collapses):
|
||||
return
|
||||
|
||||
if is_start_mode:
|
||||
if is_import_fail_mode:
|
||||
match = re.search(pat_custom_node, message)
|
||||
if match:
|
||||
import_failed_extensions.add(match.group(1))
|
||||
is_import_fail_mode = False
|
||||
else:
|
||||
match = re.search(pat_import_fail, message)
|
||||
if match:
|
||||
is_import_fail_mode = True
|
||||
else:
|
||||
is_import_fail_mode = False
|
||||
|
||||
if 'Starting server' in message:
|
||||
is_start_mode = False
|
||||
|
||||
if not self.is_stdout:
|
||||
match = re.search(tqdm, message)
|
||||
match = re.search(pat_tqdm, message)
|
||||
if match:
|
||||
message = re.sub(r'([#|])\d', r'\1▌', message)
|
||||
message = re.sub('#', '█', message)
|
||||
|
||||
28
scanner.py
28
scanner.py
@ -5,9 +5,12 @@ from git import Repo
|
||||
from torchvision.datasets.utils import download_url
|
||||
import concurrent
|
||||
|
||||
builtin_nodes = ["KSampler", "CheckpointSave"]
|
||||
builtin_nodes = set()
|
||||
|
||||
|
||||
def scan_in_file(filename, is_builtin=False):
|
||||
global builtin_nodes
|
||||
|
||||
def scan_in_file(filename):
|
||||
try:
|
||||
with open(filename, encoding='utf-8') as file:
|
||||
code = file.read()
|
||||
@ -63,9 +66,12 @@ def scan_in_file(filename):
|
||||
key, value = line[1:].strip().split(':')
|
||||
metadata[key.strip()] = value.strip()
|
||||
|
||||
for x in builtin_nodes:
|
||||
if x in nodes:
|
||||
nodes.remove(x)
|
||||
if is_builtin:
|
||||
builtin_nodes += set(nodes)
|
||||
else:
|
||||
for x in builtin_nodes:
|
||||
if x in nodes:
|
||||
nodes.remove(x)
|
||||
|
||||
return nodes, metadata
|
||||
|
||||
@ -113,7 +119,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')))
|
||||
git_clone_files.append((files[0], node.get('title')))
|
||||
|
||||
git_clone_files.append(("https://github.com/comfyanonymous/ComfyUI", "ComfyUI"))
|
||||
|
||||
return git_clone_files
|
||||
|
||||
@ -190,7 +198,7 @@ def update_custom_nodes():
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(10) as executor:
|
||||
executor.map(download_and_store_info, py_url_titles)
|
||||
|
||||
|
||||
return node_info
|
||||
|
||||
|
||||
@ -198,6 +206,10 @@ def gen_json(node_info):
|
||||
# scan from .py file
|
||||
node_files, node_dirs = get_nodes(".tmp")
|
||||
|
||||
comfyui_path = os.path.abspath(os.path.join('.tmp', "ComfyUI"))
|
||||
node_dirs.remove(comfyui_path)
|
||||
node_dirs = [comfyui_path] + node_dirs
|
||||
|
||||
data = {}
|
||||
for dirname in node_dirs:
|
||||
py_files = get_py_file_paths(dirname)
|
||||
@ -205,7 +217,7 @@ def gen_json(node_info):
|
||||
|
||||
nodes = set()
|
||||
for py in py_files:
|
||||
nodes_in_file, metadata_in_file = scan_in_file(py)
|
||||
nodes_in_file, metadata_in_file = scan_in_file(py, dirname == "ComfyUI")
|
||||
nodes.update(nodes_in_file)
|
||||
metadata.update(metadata_in_file)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user