implement: invalid installation handling

- print invalid installation nodes on terminal
(installed by `comfy registryinstall`)

- show only 'reinstall' menu if invalid installation node in gui
(and show INVALID marker)
This commit is contained in:
Dr.Lt.Data 2024-07-31 02:08:30 +09:00
parent 8e1f792cd1
commit cdb400d32b
4 changed files with 104 additions and 6 deletions

View File

@ -55,6 +55,7 @@ def check_comfyui_hash():
check_comfyui_hash() # This is a preparation step for manager_core check_comfyui_hash() # This is a preparation step for manager_core
core.check_invalid_nodes()
def read_downgrade_blacklist(): def read_downgrade_blacklist():

View File

@ -56,6 +56,55 @@ def download_url(url, dest_folder, filename):
custom_nodes_path = os.path.abspath(os.path.join(comfyui_manager_path, '..')) custom_nodes_path = os.path.abspath(os.path.join(comfyui_manager_path, '..'))
invalid_nodes = {}
def check_invalid_nodes():
global invalid_nodes
try:
import folder_paths
node_paths = folder_paths.get_folder_paths("custom_nodes")
except:
try:
sys.path.append(comfy_path)
import folder_paths
except:
raise Exception(f"Invalid COMFYUI_PATH: {comfy_path}")
def check(root):
global invalid_nodes
subdirs = [d for d in os.listdir(root) if os.path.isdir(os.path.join(root, d))]
for subdir in subdirs:
if subdir in ['.disabled', '__pycache__']:
continue
if '@' in subdir:
spec = subdir.split('@')
if spec[1] in ['unknown', 'nightly']:
continue
if not os.path.exists(os.path.join(root, subdir, '.tracking')):
invalid_nodes[spec[0]] = os.path.join(root, subdir)
node_paths = folder_paths.get_folder_paths("custom_nodes")
for x in node_paths:
check(x)
disabled_dir = os.path.join(x, '.disabled')
if os.path.exists(disabled_dir):
check(disabled_dir)
if len(invalid_nodes):
print(f"\n-------------------- ComfyUI-Manager invalid nodes notice ----------------")
print(f"\nNodes requiring reinstallation have been detected:\n(Directly delete the corresponding path and reinstall.)\n")
for x in invalid_nodes.values():
print(x)
print("\n---------------------------------------------------------------------------\n")
comfy_path = os.environ.get('COMFYUI_PATH') comfy_path = os.environ.get('COMFYUI_PATH')
if comfy_path is None: if comfy_path is None:
@ -2368,6 +2417,9 @@ async def get_unified_total_nodes(channel, mode):
updatable = False updatable = False
cnr = unified_manager.cnr_map[cnr_id] cnr = unified_manager.cnr_map[cnr_id]
if cnr_id in invalid_nodes:
v['invalid-installation'] = True
if cnr_id in unified_manager.active_nodes: if cnr_id in unified_manager.active_nodes:
# installed # installed
v['state'] = 'enabled' v['state'] = 'enabled'
@ -2608,4 +2660,3 @@ async def check_need_to_migrate():
print("The following custom nodes were installed using the old management method and require migration:") print("The following custom nodes were installed using the old management method and require migration:")
print(", ".join(legacy_custom_nodes)) print(", ".join(legacy_custom_nodes))
print("---------------------------------------------------------------------------\n") print("---------------------------------------------------------------------------\n")

View File

@ -202,8 +202,7 @@ def print_comfyui_version():
print_comfyui_version() print_comfyui_version()
core.check_invalid_nodes()
def setup_environment(): def setup_environment():
@ -787,6 +786,12 @@ async def get_disabled_versions(request):
return web.Response(status=400) return web.Response(status=400)
@routes.post("/customnode/reinstall")
async def reinstall_custom_node(request):
await uninstall_custom_node(request)
await install_custom_node(request)
@routes.post("/customnode/install") @routes.post("/customnode/install")
async def install_custom_node(request): async def install_custom_node(request):
if not is_allowed_security_level('middle'): if not is_allowed_security_level('middle'):

View File

@ -253,6 +253,11 @@ const pageCss = `
color: white; color: white;
} }
.cn-manager .cn-btn-reinstall {
background-color: #993333;
color: white;
}
.cn-manager .cn-btn-switch { .cn-manager .cn-btn-switch {
background-color: #448833; background-color: #448833;
color: white; color: white;
@ -587,18 +592,26 @@ export class CustomNodesManager {
mode: "fix" mode: "fix"
}, },
"reinstall": {
label: "Reinstall",
mode: "reinstall"
},
"install": { "install": {
label: "Install", label: "Install",
mode: "install" mode: "install"
}, },
"try-install": { "try-install": {
label: "Try install", label: "Try install",
mode: "install" mode: "install"
}, },
"uninstall": { "uninstall": {
label: "Uninstall", label: "Uninstall",
mode: "uninstall" mode: "uninstall"
}, },
"switch": { "switch": {
label: "Switch", label: "Switch",
mode: "switch" mode: "switch"
@ -611,7 +624,8 @@ export class CustomNodesManager {
"import-fail": ["try-fix", "switch", "disable", "uninstall"], "import-fail": ["try-fix", "switch", "disable", "uninstall"],
"enabled": ["try-update", "switch", "disable", "uninstall"], "enabled": ["try-update", "switch", "disable", "uninstall"],
"not-installed": ["install"], "not-installed": ["install"],
'unknown': ["try-install"] 'unknown': ["try-install"],
"invalid-installation": ["reinstall"],
} }
if (!manager_instance.update_check_checkbox.checked) { if (!manager_instance.update_check_checkbox.checked) {
@ -887,8 +901,16 @@ export class CustomNodesManager {
maxWidth: 500, maxWidth: 500,
classMap: 'cn-node-name', classMap: 'cn-node-name',
formatter: (title, rowItem, columnItem) => { formatter: (title, rowItem, columnItem) => {
return `${rowItem.action === 'import-fail' ? '<font color="red"><B>(IMPORT FAILED)</B></font>' : ''} var prefix = '';
<a href=${rowItem.reference} target="_blank"><b>${title}</b></a>`; if(rowItem.action === 'invalid-installation') {
prefix = '<font color="red"><B>(INVALID)</B></font>';
}
else if(rowItem.action === 'import-fail') {
prefix = '<font color="red"><B>(IMPORT FAILED)</B></font>';
}
return `${prefix}<a href=${rowItem.reference} target="_blank"><b>${title}</b></a>`;
} }
}, { }, {
id: 'version', id: 'version',
@ -1189,6 +1211,13 @@ export class CustomNodesManager {
} }
} }
if(mode === "reinstall") {
title = title || `${list.length} custom nodes`;
if (!confirm(`Are you sure reinstall ${title}?`)) {
return;
}
}
target.classList.add("cn-btn-loading"); target.classList.add("cn-btn-loading");
this.showError(""); this.showError("");
@ -1228,6 +1257,10 @@ export class CustomNodesManager {
api_mode = 'install'; api_mode = 'install';
} }
if(install_mode == 'reinstall') {
api_mode = 'reinstall';
}
const res = await api.fetchApi(`/customnode/${api_mode}`, { const res = await api.fetchApi(`/customnode/${api_mode}`, {
method: 'POST', method: 'POST',
body: JSON.stringify(data) body: JSON.stringify(data)
@ -1538,6 +1571,10 @@ export class CustomNodesManager {
nodeItem.action = nodeItem.state; nodeItem.action = nodeItem.state;
} }
if(nodeItem['invalid-installation']) {
nodeItem.action = 'invalid-installation';
}
const filterTypes = new Set(); const filterTypes = new Set();
this.filterList.forEach(filterItem => { this.filterList.forEach(filterItem => {
const { value, hashMap } = filterItem; const { value, hashMap } = filterItem;
@ -1586,6 +1623,10 @@ export class CustomNodesManager {
if(nodeItem['import-fail']) { if(nodeItem['import-fail']) {
filterTypes.add("import-fail"); filterTypes.add("import-fail");
} }
if(nodeItem['invalid-installation']) {
filterTypes.add("invalid-installation");
}
} }
}); });