Merge branch 'ltdrdata:main' into hangover3832

This commit is contained in:
AlexL 2024-04-02 21:01:31 +02:00 committed by GitHub
commit 0d235d481c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 3700 additions and 291 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ startup-scripts/**
matrix_auth matrix_auth
channels.list channels.list
comfyworkflows_sharekey comfyworkflows_sharekey
github-stats-cache.json

View File

@ -153,7 +153,7 @@ This repository provides Colab notebooks that allow you to install and use Comfy
* Press the "Restore" button to revert to the installation status of the respective snapshot. * Press the "Restore" button to revert to the installation status of the respective snapshot.
* However, for custom nodes not managed by Git, snapshot support is incomplete. * However, for custom nodes not managed by Git, snapshot support is incomplete.
* When you press `Restore`, it will take effect on the next ComfyUI startup. * When you press `Restore`, it will take effect on the next ComfyUI startup.
* The selected snapshot file is saved in `ComfyUI-Manager/startup-scripts/restore-snapshot.json`, and upon restarting ComfyUI, the snapshot is applied and then deleted.
![model-install-dialog](misc/snapshot.jpg) ![model-install-dialog](misc/snapshot.jpg)
@ -272,6 +272,13 @@ NODE_CLASS_MAPPINGS.update({
* `Possible(left) + Copy(right)`: When you Double-Click on the left half of the title, it operates as `Possible Input Connections`, and when you Double-Click on the right half, it operates as `Copy All Connections`. * `Possible(left) + Copy(right)`: When you Double-Click on the left half of the title, it operates as `Possible Input Connections`, and when you Double-Click on the right half, it operates as `Copy All Connections`.
* Prevent downgrade of specific packages
* List the package names in the `downgrade_blacklist` section of the `config.ini` file, separating them with commas.
* e.g
```
downgrade_blacklist = diffusers, kornia
```
## Troubleshooting ## Troubleshooting
* If your `git.exe` is installed in a specific location other than system git, please install ComfyUI-Manager and run ComfyUI. Then, specify the path including the file name in `git_exe = ` in the ComfyUI-Manager/config.ini file that is generated. * If your `git.exe` is installed in a specific location other than system git, please install ComfyUI-Manager and run ComfyUI. Then, specify the path including the file name in `git_exe = ` in the ComfyUI-Manager/config.ini file that is generated.
* If updating ComfyUI-Manager itself fails, please go to the **ComfyUI-Manager** directory and execute the command `git update-ref refs/remotes/origin/main a361cc1 && git fetch --all && git pull`. * If updating ComfyUI-Manager itself fails, please go to the **ComfyUI-Manager** directory and execute the command `git update-ref refs/remotes/origin/main a361cc1 && git fetch --all && git pull`.

View File

@ -17,6 +17,7 @@ import re
import nodes import nodes
import hashlib import hashlib
from datetime import datetime from datetime import datetime
from distutils.version import StrictVersion
try: try:
@ -29,7 +30,7 @@ except:
print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.")
version = [2, 11] version = [2, 13, 1]
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
print(f"### Loading: ComfyUI-Manager ({version_str})") print(f"### Loading: ComfyUI-Manager ({version_str})")
@ -38,19 +39,56 @@ comfy_ui_hash = "-"
cache_lock = threading.Lock() cache_lock = threading.Lock()
pip_map = None
def get_installed_packages():
global pip_map
if pip_map is None:
try:
result = subprocess.check_output([sys.executable, '-m', 'pip', 'list'], universal_newlines=True)
pip_map = {}
for line in result.split('\n'):
x = line.strip()
if x:
y = line.split()
if y[0] == 'Package' or y[0].startswith('-'):
continue
pip_map[y[0]] = y[1]
except subprocess.CalledProcessError as e:
print(f"[ComfyUI-Manager] Failed to retrieve the information of installed pip packages.")
return set()
return pip_map
def clear_pip_cache():
global pip_map
pip_map = None
def is_blacklisted(name): def is_blacklisted(name):
name = name.strip() name = name.strip()
pattern = r'([^<>!=]+)([<>!=]=?)' pattern = r'([^<>!=]+)([<>!=]=?)(.*)'
match = re.search(pattern, name) match = re.search(pattern, name)
if match: if match:
name = match.group(1) name = match.group(1)
if name in cm_global.pip_downgrade_blacklist: if name in cm_global.pip_downgrade_blacklist:
if match is None or match.group(2) in ['<=', '==', '<']: pips = get_installed_packages()
return True
if match is None:
if name in pips:
return True
elif match.group(2) in ['<=', '==', '<']:
if name in pips:
if StrictVersion(pips[name]) >= StrictVersion(match.group(3)):
return True
return False return False
@ -194,7 +232,8 @@ def write_config():
'component_policy': get_config()['component_policy'], 'component_policy': get_config()['component_policy'],
'double_click_policy': get_config()['double_click_policy'], 'double_click_policy': get_config()['double_click_policy'],
'windows_selector_event_loop_policy': get_config()['windows_selector_event_loop_policy'], 'windows_selector_event_loop_policy': get_config()['windows_selector_event_loop_policy'],
'model_download_by_agent': get_config()['model_download_by_agent'] 'model_download_by_agent': get_config()['model_download_by_agent'],
'downgrade_blacklist': get_config()['downgrade_blacklist']
} }
with open(config_path, 'w') as configfile: with open(config_path, 'w') as configfile:
config.write(configfile) config.write(configfile)
@ -219,6 +258,7 @@ def read_config():
'double_click_policy': default_conf['double_click_policy'] if 'double_click_policy' in default_conf else 'copy-all', 'double_click_policy': default_conf['double_click_policy'] if 'double_click_policy' in default_conf else 'copy-all',
'windows_selector_event_loop_policy': default_conf['windows_selector_event_loop_policy'] if 'windows_selector_event_loop_policy' in default_conf else False, 'windows_selector_event_loop_policy': default_conf['windows_selector_event_loop_policy'] if 'windows_selector_event_loop_policy' in default_conf else False,
'model_download_by_agent': default_conf['model_download_by_agent'] if 'model_download_by_agent' in default_conf else False, 'model_download_by_agent': default_conf['model_download_by_agent'] if 'model_download_by_agent' in default_conf else False,
'downgrade_blacklist': default_conf['downgrade_blacklist'] if 'downgrade_blacklist' in default_conf else '',
} }
except Exception: except Exception:
@ -235,6 +275,7 @@ def read_config():
'double_click_policy': 'copy-all', 'double_click_policy': 'copy-all',
'windows_selector_event_loop_policy': False, 'windows_selector_event_loop_policy': False,
'model_download_by_agent': False, 'model_download_by_agent': False,
'downgrade_blacklist': ''
} }
@ -307,7 +348,6 @@ def try_install_script(url, repo_path, install_cmd):
print(f"[ComfyUI-Manager] skip black listed pip installation: '{install_cmd[4]}'") print(f"[ComfyUI-Manager] skip black listed pip installation: '{install_cmd[4]}'")
return True return True
print(f"\n## ComfyUI-Manager: EXECUTE => {install_cmd}") print(f"\n## ComfyUI-Manager: EXECUTE => {install_cmd}")
code = run_script(install_cmd, cwd=repo_path) code = run_script(install_cmd, cwd=repo_path)
@ -581,6 +621,20 @@ async def get_data(uri, silent=False):
json_obj = json.loads(json_text) json_obj = json.loads(json_text)
return json_obj return json_obj
async def populate_github_stats(json_obj, filename, silent=False):
uri = os.path.join(comfyui_manager_path, filename)
with open(uri, "r", encoding='utf-8') as f:
github_stats = json.load(f)
if 'custom_nodes' in json_obj:
for i, node in enumerate(json_obj['custom_nodes']):
url = node['reference']
if url in github_stats:
json_obj['custom_nodes'][i]['stars'] = github_stats[url]['stars']
json_obj['custom_nodes'][i]['last_update'] = github_stats[url]['last_update']
else:
json_obj['custom_nodes'][i]['stars'] = -1
json_obj['custom_nodes'][i]['last_update'] = -1
return json_obj
def setup_js(): def setup_js():
import nodes import nodes
@ -831,6 +885,7 @@ def nickname_filter(json_obj):
return json_obj return json_obj
@server.PromptServer.instance.routes.get("/customnode/getmappings") @server.PromptServer.instance.routes.get("/customnode/getmappings")
async def fetch_customnode_mappings(request): async def fetch_customnode_mappings(request):
mode = request.rel_url.query["mode"] mode = request.rel_url.query["mode"]
@ -903,6 +958,8 @@ async def update_all(request):
return web.json_response(res, status=status, content_type='application/json') return web.json_response(res, status=status, content_type='application/json')
except: except:
return web.Response(status=400) return web.Response(status=400)
finally:
clear_pip_cache()
def convert_markdown_to_html(input_text): def convert_markdown_to_html(input_text):
@ -962,6 +1019,7 @@ async def fetch_customnode_list(request):
channel = get_config()['channel_url'] channel = get_config()['channel_url']
json_obj = await get_data_by_mode(request.rel_url.query["mode"], 'custom-node-list.json') json_obj = await get_data_by_mode(request.rel_url.query["mode"], 'custom-node-list.json')
json_obj = await populate_github_stats(json_obj, "github-stats.json")
def is_ignored_notice(code): def is_ignored_notice(code):
global version global version
@ -1586,6 +1644,8 @@ async def install_custom_node(request):
install_cmd = [sys.executable, "-m", "pip", "install", pname] install_cmd = [sys.executable, "-m", "pip", "install", pname]
try_install_script(json_data['files'][0], ".", install_cmd) try_install_script(json_data['files'][0], ".", install_cmd)
clear_pip_cache()
if res: if res:
print(f"After restarting ComfyUI, please refresh the browser.") print(f"After restarting ComfyUI, please refresh the browser.")
return web.json_response({}, content_type='application/json') return web.json_response({}, content_type='application/json')
@ -1684,6 +1744,8 @@ async def update_custom_node(request):
if install_type == "git-clone": if install_type == "git-clone":
res = gitclone_update(json_data['files']) res = gitclone_update(json_data['files'])
clear_pip_cache()
if res: if res:
print(f"After restarting ComfyUI, please refresh the browser.") print(f"After restarting ComfyUI, please refresh the browser.")
return web.json_response({}, content_type='application/json') return web.json_response({}, content_type='application/json')
@ -2132,6 +2194,7 @@ if hasattr(server.PromptServer.instance, "app"):
cors_middleware = server.create_cors_middleware(args.enable_cors_header) cors_middleware = server.create_cors_middleware(args.enable_cors_header)
app.middlewares.append(cors_middleware) app.middlewares.append(cors_middleware)
@server.PromptServer.instance.routes.post("/manager/set_esheep_workflow_and_images") @server.PromptServer.instance.routes.post("/manager/set_esheep_workflow_and_images")
async def set_esheep_workflow_and_images(request): async def set_esheep_workflow_and_images(request):
json_data = await request.json() json_data = await request.json()
@ -2141,12 +2204,14 @@ async def set_esheep_workflow_and_images(request):
json.dump(json_data, file, indent=4) json.dump(json_data, file, indent=4)
return web.Response(status=200) return web.Response(status=200)
@server.PromptServer.instance.routes.get("/manager/get_esheep_workflow_and_images") @server.PromptServer.instance.routes.get("/manager/get_esheep_workflow_and_images")
async def get_esheep_workflow_and_images(request): async def get_esheep_workflow_and_images(request):
with open(os.path.join(comfyui_manager_path, "esheep_share_message.json"), 'r', encoding='utf-8') as file: with open(os.path.join(comfyui_manager_path, "esheep_share_message.json"), 'r', encoding='utf-8') as file:
data = json.load(file) data = json.load(file)
return web.Response(status=200, text=json.dumps(data)) return web.Response(status=200, text=json.dumps(data))
def set_matrix_auth(json_data): def set_matrix_auth(json_data):
homeserver = json_data['homeserver'] homeserver = json_data['homeserver']
username = json_data['username'] username = json_data['username']
@ -2188,6 +2253,7 @@ def extract_model_file_names(json_data):
recursive_search(json_data) recursive_search(json_data)
return [f for f in list(file_names) if os.path.splitext(f)[1] in model_filename_extensions] return [f for f in list(file_names) if os.path.splitext(f)[1] in model_filename_extensions]
def find_file_paths(base_dir, file_names): def find_file_paths(base_dir, file_names):
"""Find the paths of the files in the base directory.""" """Find the paths of the files in the base directory."""
file_paths = {} file_paths = {}
@ -2201,6 +2267,7 @@ def find_file_paths(base_dir, file_names):
file_paths[file] = os.path.join(root, file) file_paths[file] = os.path.join(root, file)
return file_paths return file_paths
def compute_sha256_checksum(filepath): def compute_sha256_checksum(filepath):
"""Compute the SHA256 checksum of a file, in chunks""" """Compute the SHA256 checksum of a file, in chunks"""
sha256 = hashlib.sha256() sha256 = hashlib.sha256()
@ -2209,6 +2276,7 @@ def compute_sha256_checksum(filepath):
sha256.update(chunk) sha256.update(chunk)
return sha256.hexdigest() return sha256.hexdigest()
@server.PromptServer.instance.routes.post("/manager/share") @server.PromptServer.instance.routes.post("/manager/share")
async def share_art(request): async def share_art(request):
# get json data # get json data

View File

@ -266,16 +266,6 @@
], ],
"description": "CLIPTextEncodeBLIP: This custom node provides a CLIP Encoder that is capable of receiving images as input." "description": "CLIPTextEncodeBLIP: This custom node provides a CLIP Encoder that is capable of receiving images as input."
}, },
{
"author": "Davemane42",
"title": "Visual Area Conditioning / Latent composition",
"reference": "https://github.com/Davemane42/ComfyUI_Dave_CustomNode",
"files": [
"https://github.com/Davemane42/ComfyUI_Dave_CustomNode"
],
"install_type": "git-clone",
"description": "This tool provides custom nodes that allow visualization and configuration of area conditioning and latent composite."
},
{ {
"author": "WASasquatch", "author": "WASasquatch",
"title": "WAS Node Suite", "title": "WAS Node Suite",
@ -3452,6 +3442,16 @@
"install_type": "git-clone", "install_type": "git-clone",
"description": "Unofficial implementation of [a/DepthFM](https://github.com/CompVis/depth-fm) for ComfyUI" "description": "Unofficial implementation of [a/DepthFM](https://github.com/CompVis/depth-fm) for ComfyUI"
}, },
{
"author": "ZHO-ZHO-ZHO",
"title": "ComfyUI-BiRefNet-ZHO",
"reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO",
"files": [
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO"
],
"install_type": "git-clone",
"description": "Better version for [a/BiRefNet](https://github.com/zhengpeng7/birefnet) in ComfyUI | Both img and video"
},
{ {
"author": "kenjiqq", "author": "kenjiqq",
"title": "qq-nodes-comfyui", "title": "qq-nodes-comfyui",
@ -4302,6 +4302,7 @@
"files": [ "files": [
"https://github.com/crystian/ComfyUI-Crystools" "https://github.com/crystian/ComfyUI-Crystools"
], ],
"nodename_pattern": " \\[Crystools\\]$",
"install_type": "git-clone", "install_type": "git-clone",
"description": "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." "description": "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow."
}, },
@ -4506,6 +4507,16 @@
"install_type": "git-clone", "install_type": "git-clone",
"description": "Nodes:3D Pose Editor" "description": "Nodes:3D Pose Editor"
}, },
{
"author": "chaojie",
"title": "ComfyUI-MuseV",
"reference": "https://github.com/chaojie/ComfyUI-MuseV",
"files": [
"https://github.com/chaojie/ComfyUI-MuseV"
],
"install_type": "git-clone",
"description": "ComfyUI MuseV"
},
{ {
"author": "chaojie", "author": "chaojie",
"title": "ComfyUI-AniPortrait", "title": "ComfyUI-AniPortrait",
@ -5798,6 +5809,16 @@
"install_type": "git-clone", "install_type": "git-clone",
"description": "Nodes:Apply Ref UNet, Ref Sampler, Ref Sampler Custom" "description": "Nodes:Apply Ref UNet, Ref Sampler, Ref Sampler Custom"
}, },
{
"author": "logtd",
"title": "ComfyUI-FLATTEN",
"reference": "https://github.com/logtd/ComfyUI-FLATTEN",
"files": [
"https://github.com/logtd/ComfyUI-FLATTEN"
],
"install_type": "git-clone",
"description": "ComfyUI nodes to use [a/FLATTEN: optical FLow-guided ATTENtion for consistent text-to-video editing](https://github.com/yrcong/flatten)."
},
{ {
"author": "Big-Idea-Technology", "author": "Big-Idea-Technology",
"title": "ImageTextOverlay Node for ComfyUI", "title": "ImageTextOverlay Node for ComfyUI",
@ -6698,7 +6719,96 @@
"install_type": "git-clone", "install_type": "git-clone",
"description": "This initiative represents a solo venture dedicated to integrating a stereopsis effect within ComfyUI (Stable Diffusion). Presently, the project is focused on the refinement of node categorization within a unified framework, as it is in the early stages of development. However, it has achieved functionality in a fundamental capacity. By processing a video through the Side-by-Side (SBS) node and applying Frame Delay to one of the inputs, it facilitates the creation of a stereopsis effect. This effect is compatible with any Virtual Reality headset that supports SBS video playback, offering a practical application in immersive media experiences." "description": "This initiative represents a solo venture dedicated to integrating a stereopsis effect within ComfyUI (Stable Diffusion). Presently, the project is focused on the refinement of node categorization within a unified framework, as it is in the early stages of development. However, it has achieved functionality in a fundamental capacity. By processing a video through the Side-by-Side (SBS) node and applying Frame Delay to one of the inputs, it facilitates the creation of a stereopsis effect. This effect is compatible with any Virtual Reality headset that supports SBS video playback, offering a practical application in immersive media experiences."
}, },
{
"author": "nickve28",
"title": "Nich Comfy Utils",
"reference": "https://github.com/nickve28/nich-comfy-utils",
"files": [
"https://github.com/nickve28/nich-comfy-utils"
],
"install_type": "git-clone",
"description": "Nodes:Image from Dir Selector (Nich)"
},
{
"author": "frankchieng",
"title": "ComfyUI_Aniportrait",
"reference": "https://github.com/frankchieng/ComfyUI_Aniportrait",
"files": [
"https://github.com/frankchieng/ComfyUI_Aniportrait"
],
"install_type": "git-clone",
"description": "implementation of [a/Aniportrait](https://github.com/Zejun-Yang/AniPortrait)'s self driven,audio driven and Face reenacment in ComfyUI"
},
{
"author": "BlakeOne",
"title": "ComfyUI SchedulerMixer",
"reference": "https://github.com/BlakeOne/ComfyUI-SchedulerMixer",
"files": [
"https://github.com/BlakeOne/ComfyUI-SchedulerMixer"
],
"install_type": "git-clone",
"description": "Create a custom scheduler from a weighted average of the built-in schedulers"
},
{
"author": "BlakeOne",
"title": "ComfyUI FastImageListToImageBatch",
"reference": "https://github.com/BlakeOne/ComfyUI-FastImageListToImageBatch",
"files": [
"https://github.com/BlakeOne/ComfyUI-FastImageListToImageBatch"
],
"install_type": "git-clone",
"description": "Quickly convert a list of images to a batch of images. All images must be the same size. Great for long videos."
},
{
"author": "kale4eat",
"title": "ComfyUI_demucus",
"reference": "https://github.com/kale4eat/ComfyUI-path-util",
"files": [
"https://github.com/kale4eat/ComfyUI-path-util"
],
"install_type": "git-clone",
"description": "Path utility for ComfyUI"
},
{
"author": "kale4eat",
"title": "ComfyUI-string-util",
"reference": "https://github.com/kale4eat/ComfyUI-string-util",
"files": [
"https://github.com/kale4eat/ComfyUI-string-util"
],
"install_type": "git-clone",
"description": "String utility for ComfyUI"
},
{
"author": "kale4eat",
"title": "ComfyUI-text-file-util",
"reference": "https://github.com/kale4eat/ComfyUI-text-file-util",
"files": [
"https://github.com/kale4eat/ComfyUI-text-file-util"
],
"install_type": "git-clone",
"description": "Text file utility for ComfyUI"
},
{
"author": "kijai",
"title": "ComfyUI-APISR",
"reference": "https://github.com/kijai/ComfyUI-APISR",
"files": [
"https://github.com/kijai/ComfyUI-APISR"
],
"install_type": "git-clone",
"description": "Node to use [a/APISR](https://github.com/Kiteretsu77/APISR) upscale models in ComfyUI"
},
{
"author": "DrMWeigand",
"title": "ComfyUI Color Detection Nodes",
"reference": "https://github.com/DrMWeigand/ComfyUI_ColorImageDetection",
"files": [
"https://github.com/DrMWeigand/ComfyUI_ColorImageDetection"
],
"install_type": "git-clone",
"description": "A collection of nodes for detecting color in images, leveraging RGB and LAB color spaces. These nodes aim to distinguish colored images from black and white, including those with color tints."
},

View File

@ -328,6 +328,7 @@
"Load Images Pair Batch", "Load Images Pair Batch",
"Merge Tag", "Merge Tag",
"Move Tag To Top", "Move Tag To Top",
"Reserve Tag",
"Save Images Pair" "Save Images Pair"
], ],
{ {
@ -554,6 +555,22 @@
"title_aux": "ComfyUI-Path-Helper" "title_aux": "ComfyUI-Path-Helper"
} }
], ],
"https://github.com/BlakeOne/ComfyUI-FastImageListToImageBatch": [
[
"FastImageListToImageBatch"
],
{
"title_aux": "ComfyUI FastImageListToImageBatch"
}
],
"https://github.com/BlakeOne/ComfyUI-SchedulerMixer": [
[
"SchedulerMixer"
],
{
"title_aux": "ComfyUI SchedulerMixer"
}
],
"https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb": [ "https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb": [
[ [
"BNK_AddCLIPSDXLParams", "BNK_AddCLIPSDXLParams",
@ -766,6 +783,7 @@
"PrimereStyleLoader", "PrimereStyleLoader",
"PrimereStylePile", "PrimereStylePile",
"PrimereTextOutput", "PrimereTextOutput",
"PrimereUpscaleModel",
"PrimereVAE", "PrimereVAE",
"PrimereVAELoader", "PrimereVAELoader",
"PrimereVAESelector", "PrimereVAESelector",
@ -793,18 +811,6 @@
"title_aux": "ComfyUI-ComfyCouple" "title_aux": "ComfyUI-ComfyCouple"
} }
], ],
"https://github.com/Davemane42/ComfyUI_Dave_CustomNode": [
[
"ABGRemover",
"ConditioningStretch",
"ConditioningUpscale",
"MultiAreaConditioning",
"MultiLatentComposite"
],
{
"title_aux": "Visual Area Conditioning / Latent composition"
}
],
"https://github.com/Derfuu/Derfuu_ComfyUI_ModdedNodes": [ "https://github.com/Derfuu/Derfuu_ComfyUI_ModdedNodes": [
[ [
"Absolute value", "Absolute value",
@ -864,6 +870,15 @@
"title_aux": "ComfyUI-Cre8it-Nodes" "title_aux": "ComfyUI-Cre8it-Nodes"
} }
], ],
"https://github.com/DrMWeigand/ComfyUI_ColorImageDetection": [
[
"LABColorDetection",
"RGBColorDetection"
],
{
"title_aux": "ComfyUI Color Detection Nodes"
}
],
"https://github.com/Electrofried/ComfyUI-OpenAINode": [ "https://github.com/Electrofried/ComfyUI-OpenAINode": [
[ [
"OpenAINode" "OpenAINode"
@ -1022,6 +1037,7 @@
[ [
"EmptyMotionData", "EmptyMotionData",
"ExportSMPLTo3DSoftware", "ExportSMPLTo3DSoftware",
"Export_SMPLMultipleSubjects_To_3DSoftware",
"Human4D_Img2SMPL", "Human4D_Img2SMPL",
"Humans4DLoader", "Humans4DLoader",
"MotionCLIPTextEncode", "MotionCLIPTextEncode",
@ -1030,6 +1046,7 @@
"MotionDiffSimpleSampler", "MotionDiffSimpleSampler",
"RenderMultipleSubjectsSMPLMesh", "RenderMultipleSubjectsSMPLMesh",
"RenderSMPLMesh", "RenderSMPLMesh",
"Render_OpenPose_From_SMPL_Mesh_Multiple_Subjects",
"SMPLLoader", "SMPLLoader",
"SMPLShapeParameters", "SMPLShapeParameters",
"SaveSMPL", "SaveSMPL",
@ -1333,6 +1350,10 @@
"Moondream Interrogator" "Moondream Interrogator"
], ],
{ {
"author": "AlexL",
"description": "An implementation of the moondream visual LLM",
"nickname": "Hangover-Moondream",
"title": "ComfyUI-Hangover-Moondream",
"title_aux": "ComfyUI-Hangover-Moondream" "title_aux": "ComfyUI-Hangover-Moondream"
} }
], ],
@ -1344,6 +1365,10 @@
"Save Image w/o Metadata" "Save Image w/o Metadata"
], ],
{ {
"author": "AlexL",
"description": "Scales an input image into a given box size, whereby the aspect ratio keeps retained.",
"nickname": "Hangover-Image_Scale_Bouning_Box",
"title": "ComfyUI-Hangover-Image_Scale_Bouning_Box",
"title_aux": "ComfyUI-Hangover-Nodes" "title_aux": "ComfyUI-Hangover-Nodes"
} }
], ],
@ -1352,6 +1377,10 @@
"Recognize Anything Model (RAM++)" "Recognize Anything Model (RAM++)"
], ],
{ {
"author": "AlexL",
"description": "An implementation of the Recognize Anything Model (RAM++) for ComfyUI. The counterpart of Segment Anything Model (SAM).",
"nickname": "Hangover-Recognize_Anything",
"title": "ComfyUI-Hangover-Recognize_Anything",
"title_aux": "Recognize Anything Model (RAM++) for ComfyUI" "title_aux": "Recognize Anything Model (RAM++) for ComfyUI"
} }
], ],
@ -1665,6 +1694,7 @@
"ACN_ControlNetLoaderWithLoraAdvanced", "ACN_ControlNetLoaderWithLoraAdvanced",
"ACN_DefaultUniversalWeights", "ACN_DefaultUniversalWeights",
"ACN_ReferenceControlNet", "ACN_ReferenceControlNet",
"ACN_ReferenceControlNetFinetune",
"ACN_ReferencePreprocessor", "ACN_ReferencePreprocessor",
"ACN_SparseCtrlIndexMethodNode", "ACN_SparseCtrlIndexMethodNode",
"ACN_SparseCtrlLoaderAdvanced", "ACN_SparseCtrlLoaderAdvanced",
@ -2157,6 +2187,7 @@
"DoubleClipTextEncode", "DoubleClipTextEncode",
"HashText", "HashText",
"IndoorBackgrounds", "IndoorBackgrounds",
"IntFloatDict",
"LandscapeBackgrounds", "LandscapeBackgrounds",
"NatureColours", "NatureColours",
"OptimalCrop", "OptimalCrop",
@ -2547,9 +2578,10 @@
"OneTimeMultiplyTransform", "OneTimeMultiplyTransform",
"OneTimeShiftTransform", "OneTimeShiftTransform",
"ShiftTransform", "ShiftTransform",
"TSamplerWithTransform", "TransformHijack",
"TransformOffset", "TransformOffset",
"TransformSampler", "TransformSampler",
"TransformSamplerAdvanced",
"TransformsCombine" "TransformsCombine"
], ],
{ {
@ -3981,16 +4013,6 @@
"title_aux": "MergeBlockWeighted_fo_ComfyUI" "title_aux": "MergeBlockWeighted_fo_ComfyUI"
} }
], ],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-APISR": [
[
"APISR_Lterative_Zho",
"APISR_ModelLoader_Zho",
"APISR_Zho"
],
{
"title_aux": "APISR IN COMFYUI"
}
],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-ArtGallery": [ "https://github.com/ZHO-ZHO-ZHO/ComfyUI-ArtGallery": [
[ [
"ArtGallery_Zho", "ArtGallery_Zho",
@ -4013,6 +4035,15 @@
"title_aux": "ComfyUI-BRIA_AI-RMBG" "title_aux": "ComfyUI-BRIA_AI-RMBG"
} }
], ],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO": [
[
"BiRefNet_ModelLoader_Zho",
"BiRefNet_Zho"
],
{
"title_aux": "ComfyUI-BiRefNet-ZHO"
}
],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-DepthFM": [ "https://github.com/ZHO-ZHO-ZHO/ComfyUI-DepthFM": [
[ [
"DepthFM_Literative_Zho", "DepthFM_Literative_Zho",
@ -4188,6 +4219,7 @@
"AudioToFFTs", "AudioToFFTs",
"BatchAmplitudeSchedule", "BatchAmplitudeSchedule",
"ClipAmplitude", "ClipAmplitude",
"FloatArrayToGraph",
"GateNormalizedAmplitude", "GateNormalizedAmplitude",
"LoadAudio", "LoadAudio",
"NormalizeAmplitude", "NormalizeAmplitude",
@ -5252,6 +5284,15 @@
"title_aux": "ComfyUI-MotionCtrl-SVD" "title_aux": "ComfyUI-MotionCtrl-SVD"
} }
], ],
"https://github.com/chaojie/ComfyUI-MuseV": [
[
"MuseVRun"
],
{
"author": "infguo",
"title_aux": "ComfyUI-MuseV"
}
],
"https://github.com/chaojie/ComfyUI-Open-Sora": [ "https://github.com/chaojie/ComfyUI-Open-Sora": [
[ [
"OpenSoraLoader", "OpenSoraLoader",
@ -5923,6 +5964,17 @@
"title_aux": "Cozy Reference Pose Generator" "title_aux": "Cozy Reference Pose Generator"
} }
], ],
"https://github.com/crystian/ComfyUI-Crystools": [
[],
{
"author": "Crystian",
"description": "Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia",
"nickname": "Crystools",
"nodename_pattern": " \\[Crystools\\]$",
"title": "Crystools",
"title_aux": "Crystools"
}
],
"https://github.com/cubiq/ComfyUI_FaceAnalysis": [ "https://github.com/cubiq/ComfyUI_FaceAnalysis": [
[ [
"FaceAnalysisModels", "FaceAnalysisModels",
@ -6693,6 +6745,20 @@
"title_aux": "RF Nodes" "title_aux": "RF Nodes"
} }
], ],
"https://github.com/frankchieng/ComfyUI_Aniportrait": [
[
"AniPortrait_Audio2Video",
"AniPortrait_Audio_Path",
"AniPortrait_Generate_Ref_Pose",
"AniPortrait_LoadVideoPath",
"AniPortrait_Pose_Gen_Video",
"AniPortrait_Ref_Image_Path",
"AniPortrait_Video_Gen_Pose"
],
{
"title_aux": "ComfyUI_Aniportrait"
}
],
"https://github.com/gemell1/ComfyUI_GMIC": [ "https://github.com/gemell1/ComfyUI_GMIC": [
[ [
"GmicCliWrapper", "GmicCliWrapper",
@ -7322,6 +7388,60 @@
"title_aux": "ComfyUI-Transformers" "title_aux": "ComfyUI-Transformers"
} }
], ],
"https://github.com/kale4eat/ComfyUI-path-util": [
[
"path_util_PathAbspath",
"path_util_PathBasename",
"path_util_PathDirname",
"path_util_PathExists",
"path_util_PathIsdir",
"path_util_PathIsfile",
"path_util_PathJoin",
"path_util_PathRelpath",
"path_util_PathSplitext"
],
{
"title_aux": "ComfyUI_demucus"
}
],
"https://github.com/kale4eat/ComfyUI-string-util": [
[
"string_util_Str",
"string_util_StrConcat",
"string_util_StrCount",
"string_util_StrEndsWith",
"string_util_StrEqual",
"string_util_StrFind",
"string_util_StrFormat",
"string_util_StrJoin",
"string_util_StrLen",
"string_util_StrLower",
"string_util_StrLstrip",
"string_util_StrNotEqual",
"string_util_StrReplace",
"string_util_StrRstrip",
"string_util_StrSlice",
"string_util_StrSplit",
"string_util_StrStartsWith",
"string_util_StrStrip",
"string_util_StrUpper"
],
{
"title_aux": "ComfyUI-string-util"
}
],
"https://github.com/kale4eat/ComfyUI-text-file-util": [
[
"text_file_util_ReadAllLines",
"text_file_util_ReadAllText",
"text_file_util_WriteText",
"text_file_util_WriteTextLines",
"text_file_util_WriteTextWithSequentialNumbering"
],
{
"title_aux": "ComfyUI-text-file-util"
}
],
"https://github.com/kenjiqq/qq-nodes-comfyui": [ "https://github.com/kenjiqq/qq-nodes-comfyui": [
[ [
"Any List", "Any List",
@ -7370,6 +7490,16 @@
"title_aux": "Animatediff MotionLoRA Trainer" "title_aux": "Animatediff MotionLoRA Trainer"
} }
], ],
"https://github.com/kijai/ComfyUI-APISR": [
[
"APISR_Lterative_Zho",
"APISR_ModelLoader_Zho",
"APISR_Zho"
],
{
"title_aux": "ComfyUI-APISR"
}
],
"https://github.com/kijai/ComfyUI-CCSR": [ "https://github.com/kijai/ComfyUI-CCSR": [
[ [
"CCSR_Model_Select", "CCSR_Model_Select",
@ -7768,6 +7898,19 @@
"title_aux": "comfyui-easyapi-nodes" "title_aux": "comfyui-easyapi-nodes"
} }
], ],
"https://github.com/logtd/ComfyUI-FLATTEN": [
[
"ApplyFlattenAttentionNode",
"CreateFlowNoiseNode",
"FlattenCheckpointLoaderNode",
"KSamplerFlattenNode",
"TrajectoryNode",
"UnsamplerFlattenNode"
],
{
"title_aux": "ComfyUI-FLATTEN"
}
],
"https://github.com/logtd/ComfyUI-InstanceDiffusion": [ "https://github.com/logtd/ComfyUI-InstanceDiffusion": [
[ [
"ApplyScaleUModelNode", "ApplyScaleUModelNode",
@ -7835,8 +7978,7 @@
], ],
"https://github.com/longgui0318/comfyui-oms-diffusion": [ "https://github.com/longgui0318/comfyui-oms-diffusion": [
[ [
"Additional Features With Attention", "Additional Features With Attention"
"Extract Features With Unet"
], ],
{ {
"title_aux": "comfyui-oms-diffusion" "title_aux": "comfyui-oms-diffusion"
@ -8402,6 +8544,7 @@
"CreateMaskWithCanvas", "CreateMaskWithCanvas",
"CreateRegionalPNGMask", "CreateRegionalPNGMask",
"EightFloats", "EightFloats",
"EvenOrOdd",
"FloatMultiplication", "FloatMultiplication",
"FourBooleanTrigger", "FourBooleanTrigger",
"FourFloats", "FourFloats",
@ -8492,6 +8635,14 @@
"title_aux": "ComfyUI-NegiTools" "title_aux": "ComfyUI-NegiTools"
} }
], ],
"https://github.com/nickve28/nich-comfy-utils": [
[
"Image from Dir Selector (Nich)"
],
{
"title_aux": "Nich Comfy Utils"
}
],
"https://github.com/nicolai256/comfyUI_Nodes_nicolai256/raw/main/yugioh-presets.py": [ "https://github.com/nicolai256/comfyUI_Nodes_nicolai256/raw/main/yugioh-presets.py": [
[ [
"yugioh_Presets" "yugioh_Presets"
@ -9743,6 +9894,7 @@
"https://github.com/toyxyz/ComfyUI_toyxyz_test_nodes": [ "https://github.com/toyxyz/ComfyUI_toyxyz_test_nodes": [
[ [
"CaptureWebcam", "CaptureWebcam",
"ImageResize_Padding",
"LatentDelay", "LatentDelay",
"LoadWebcamImage", "LoadWebcamImage",
"SaveImagetoPath" "SaveImagetoPath"
@ -10234,6 +10386,7 @@
"easy if", "easy if",
"easy imageInsetCrop", "easy imageInsetCrop",
"easy imagePixelPerfect", "easy imagePixelPerfect",
"easy imageRatio",
"easy imageRemBg", "easy imageRemBg",
"easy imageRemoveBG", "easy imageRemoveBG",
"easy imageSave", "easy imageSave",

2674
github-stats.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -109,6 +109,9 @@ export class CustomNodesInstaller extends ComfyDialog {
this.manager_dialog = manager_dialog; this.manager_dialog = manager_dialog;
this.search_keyword = ''; this.search_keyword = '';
this.element = $el("div.comfy-modal", { parent: document.body }, []); this.element = $el("div.comfy-modal", { parent: document.body }, []);
this.currentSortProperty = ''; // The property currently being sorted
this.currentSortAscending = true; // The direction of the current sort
} }
startInstall(target) { startInstall(target) {
@ -367,76 +370,165 @@ export class CustomNodesInstaller extends ComfyDialog {
} }
} }
sortData(property, ascending = true) {
this.data.sort((a, b) => {
// Check if either value is -1 and handle accordingly
if (a[property] === -1) return 1; // Always put a at the end if its value is -1
if (b[property] === -1) return -1; // Always put b at the end if its value is -1
// And be careful here, (-1<'2024-01-01') and (-1>'2024-01-01') are both false! So I handle -1 seperately.
if (a[property] < b[property]) return ascending ? -1 : 1;
if (a[property] > b[property]) return ascending ? 1 : -1;
return 0;
});
}
resetHeaderStyles() {
const headers = ['th_stars', 'th_last_update']; // Add the IDs of all your sortable headers here
headers.forEach(headerId => {
const header = this.element.querySelector(`#${headerId}`);
if (header) {
header.style.backgroundColor = ''; // Reset to default background color
// Add other style resets if necessary
}
});
}
toggleSort(property) {
// If currently sorted by this property, toggle the direction; else, sort ascending
if (this.currentSortProperty === property) {
this.currentSortAscending = !this.currentSortAscending;
} else {
this.currentSortAscending = false;
}
this.currentSortProperty = property;
this.resetHeaderStyles(); // Reset styles of all sortable headers
// Determine the ID of the header based on the property
let headerId = '';
if (property === 'stars') {
headerId = 'th_stars';
} else if (property === 'last_update') {
headerId = 'th_last_update';
}
// If we have a valid headerId, change its style to indicate it's the active sort column
if (headerId) {
const activeHeader = this.element.querySelector(`#${headerId}`);
if (activeHeader) {
activeHeader.style.backgroundColor = '#222';
// Slightly brighter. Add other style changes if necessary.
}
}
// Call sortData with the current property and direction
this.sortData(property, this.currentSortAscending);
// Refresh the grid to display sorted data
this.createGrid();
this.apply_searchbox(this.data);
}
async createGrid() { async createGrid() {
var grid = document.createElement('table'); // Remove existing table if present
grid.setAttribute('id', 'custom-nodes-grid'); var grid = this.element.querySelector('#custom-nodes-grid');
var panel;
this.grid_rows = {};
let self = this; let self = this;
if (grid) {
grid.querySelector('tbody').remove();
panel = grid.parentNode;
} else {
grid = document.createElement('table');
grid.setAttribute('id', 'custom-nodes-grid');
var thead = document.createElement('thead'); this.grid_rows = {};
var thead = document.createElement('thead');
var headerRow = document.createElement('tr');
thead.style.position = "sticky";
thead.style.top = "0px";
thead.style.borderCollapse = "collapse";
thead.style.tableLayout = "fixed";
var header0 = document.createElement('th');
header0.style.width = "20px";
this.checkbox_all = $el("input",{type:'checkbox', id:'check_all'},[]);
header0.appendChild(this.checkbox_all);
this.checkbox_all.checked = false;
this.checkbox_all.disabled = true;
this.checkbox_all.addEventListener('change', function() { self.check_all.call(self, self.checkbox_all.checked); });
var header1 = document.createElement('th');
header1.innerHTML = '&nbsp;&nbsp;ID&nbsp;&nbsp;';
header1.style.width = "20px";
var header2 = document.createElement('th');
header2.innerHTML = 'Author';
header2.style.width = "150px";
var header3 = document.createElement('th');
header3.innerHTML = 'Name';
header3.style.width = "20%";
var header4 = document.createElement('th');
header4.innerHTML = 'Description';
header4.style.width = "60%";
// header4.classList.add('expandable-column');
var header5 = document.createElement('th');
header5.innerHTML = 'GitHub Stars';
header5.style.width = "130px";
header5.setAttribute('id', 'th_stars');
header5.style.cursor = 'pointer';
header5.onclick = () => this.toggleSort('stars');
var header6 = document.createElement('th');
header6.innerHTML = 'Last Update';
header6.style.width = "130px";
header6.setAttribute('id', 'th_last_update');
header6.style.cursor = 'pointer';
header6.onclick = () => this.toggleSort('last_update');
var header7 = document.createElement('th');
header7.innerHTML = 'Install';
header7.style.width = "130px";
header0.style.position = "sticky";
header0.style.top = "0px";
header1.style.position = "sticky";
header1.style.top = "0px";
header2.style.position = "sticky";
header2.style.top = "0px";
header3.style.position = "sticky";
header3.style.top = "0px";
header4.style.position = "sticky";
header4.style.top = "0px";
header5.style.position = "sticky";
header5.style.top = "0px";
header6.style.position = "sticky";
header6.style.top = "0px";
header7.style.position = "sticky";
header7.style.top = "0px";
thead.appendChild(headerRow);
headerRow.appendChild(header0);
headerRow.appendChild(header1);
headerRow.appendChild(header2);
headerRow.appendChild(header3);
headerRow.appendChild(header4);
headerRow.appendChild(header5);
headerRow.appendChild(header6);
headerRow.appendChild(header7);
headerRow.style.backgroundColor = "Black";
headerRow.style.color = "White";
headerRow.style.textAlign = "center";
headerRow.style.width = "100%";
headerRow.style.padding = "0";
grid.appendChild(thead);
panel = document.createElement('div');
panel.style.width = "100%";
panel.appendChild(grid);
this.element.appendChild(panel);
}
var tbody = document.createElement('tbody'); var tbody = document.createElement('tbody');
var headerRow = document.createElement('tr');
thead.style.position = "sticky";
thead.style.top = "0px";
thead.style.borderCollapse = "collapse";
thead.style.tableLayout = "fixed";
var header0 = document.createElement('th');
header0.style.width = "20px";
this.checkbox_all = $el("input",{type:'checkbox', id:'check_all'},[]);
header0.appendChild(this.checkbox_all);
this.checkbox_all.checked = false;
this.checkbox_all.disabled = true;
this.checkbox_all.addEventListener('change', function() { self.check_all.call(self, self.checkbox_all.checked); });
var header1 = document.createElement('th');
header1.innerHTML = '&nbsp;&nbsp;ID&nbsp;&nbsp;';
header1.style.width = "20px";
var header2 = document.createElement('th');
header2.innerHTML = 'Author';
header2.style.width = "150px";
var header3 = document.createElement('th');
header3.innerHTML = 'Name';
header3.style.width = "20%";
var header4 = document.createElement('th');
header4.innerHTML = 'Description';
header4.style.width = "60%";
// header4.classList.add('expandable-column');
var header5 = document.createElement('th');
header5.innerHTML = 'Install';
header5.style.width = "130px";
header0.style.position = "sticky";
header0.style.top = "0px";
header1.style.position = "sticky";
header1.style.top = "0px";
header2.style.position = "sticky";
header2.style.top = "0px";
header3.style.position = "sticky";
header3.style.top = "0px";
header4.style.position = "sticky";
header4.style.top = "0px";
header5.style.position = "sticky";
header5.style.top = "0px";
thead.appendChild(headerRow);
headerRow.appendChild(header0);
headerRow.appendChild(header1);
headerRow.appendChild(header2);
headerRow.appendChild(header3);
headerRow.appendChild(header4);
headerRow.appendChild(header5);
headerRow.style.backgroundColor = "Black";
headerRow.style.color = "White";
headerRow.style.textAlign = "center";
headerRow.style.width = "100%";
headerRow.style.padding = "0";
grid.appendChild(thead);
grid.appendChild(tbody); grid.appendChild(tbody);
if(this.data) if(this.data)
@ -499,8 +591,27 @@ export class CustomNodesInstaller extends ComfyDialog {
} }
var data5 = document.createElement('td'); var data5 = document.createElement('td');
data5.style.maxWidth = "100px";
data5.className = "cm-node-stars"
data5.textContent = `${data.stars}`;
data5.style.whiteSpace = "nowrap";
data5.style.overflow = "hidden";
data5.style.textOverflow = "ellipsis";
data5.style.textAlign = "center"; data5.style.textAlign = "center";
var lastUpdateDate = new Date();
var data6 = document.createElement('td');
data6.style.maxWidth = "100px";
data6.className = "cm-node-last-update"
data6.textContent = `${data.last_update}`.split(' ')[0];
data6.style.whiteSpace = "nowrap";
data6.style.overflow = "hidden";
data6.style.textOverflow = "ellipsis";
data6.style.textAlign = "center";
var data7 = document.createElement('td');
data7.style.textAlign = "center";
var installBtn = document.createElement('button'); var installBtn = document.createElement('button');
installBtn.className = "cm-btn-install"; installBtn.className = "cm-btn-install";
var installBtn2 = null; var installBtn2 = null;
@ -587,7 +698,7 @@ export class CustomNodesInstaller extends ComfyDialog {
install_checked_custom_node(self.grid_rows, j, CustomNodesInstaller.instance, 'update'); install_checked_custom_node(self.grid_rows, j, CustomNodesInstaller.instance, 'update');
}); });
data5.appendChild(installBtn2); data7.appendChild(installBtn2);
} }
if(installBtn3 != null) { if(installBtn3 != null) {
@ -596,7 +707,7 @@ export class CustomNodesInstaller extends ComfyDialog {
install_checked_custom_node(self.grid_rows, j, CustomNodesInstaller.instance, 'toggle_active'); install_checked_custom_node(self.grid_rows, j, CustomNodesInstaller.instance, 'toggle_active');
}); });
data5.appendChild(installBtn3); data7.appendChild(installBtn3);
} }
if(installBtn4 != null) { if(installBtn4 != null) {
@ -605,7 +716,7 @@ export class CustomNodesInstaller extends ComfyDialog {
install_checked_custom_node(self.grid_rows, j, CustomNodesInstaller.instance, 'fix'); install_checked_custom_node(self.grid_rows, j, CustomNodesInstaller.instance, 'fix');
}); });
data5.appendChild(installBtn4); data7.appendChild(installBtn4);
} }
installBtn.style.width = "120px"; installBtn.style.width = "120px";
@ -621,7 +732,7 @@ export class CustomNodesInstaller extends ComfyDialog {
}); });
if(!data.author.startsWith('#NOTICE')){ if(!data.author.startsWith('#NOTICE')){
data5.appendChild(installBtn); data7.appendChild(installBtn);
} }
if(data.installed == 'Fail' || data.author.startsWith('#NOTICE')) if(data.installed == 'Fail' || data.author.startsWith('#NOTICE'))
@ -637,6 +748,8 @@ export class CustomNodesInstaller extends ComfyDialog {
dataRow.appendChild(data3); dataRow.appendChild(data3);
dataRow.appendChild(data4); dataRow.appendChild(data4);
dataRow.appendChild(data5); dataRow.appendChild(data5);
dataRow.appendChild(data6);
dataRow.appendChild(data7);
tbody.appendChild(dataRow); tbody.appendChild(dataRow);
let buttons = []; let buttons = [];
@ -653,10 +766,6 @@ export class CustomNodesInstaller extends ComfyDialog {
this.grid_rows[i] = {data:data, buttons:buttons, checkbox:checkbox, control:dataRow}; this.grid_rows[i] = {data:data, buttons:buttons, checkbox:checkbox, control:dataRow};
} }
const panel = document.createElement('div');
panel.style.width = "100%";
panel.appendChild(grid);
function handleResize() { function handleResize() {
const parentHeight = self.element.clientHeight; const parentHeight = self.element.clientHeight;
const gridHeight = parentHeight - 200; const gridHeight = parentHeight - 200;
@ -672,7 +781,6 @@ export class CustomNodesInstaller extends ComfyDialog {
grid.style.overflowY = "scroll"; grid.style.overflowY = "scroll";
this.element.style.height = "85%"; this.element.style.height = "85%";
this.element.style.width = "80%"; this.element.style.width = "80%";
this.element.appendChild(panel);
handleResize(); handleResize();
} }

View File

@ -9,6 +9,26 @@
"description": "If you see this message, your ComfyUI-Manager is outdated.\nDev channel provides only the list of the developing nodes. If you want to find the complete node list, please go to the Default channel." "description": "If you see this message, your ComfyUI-Manager is outdated.\nDev channel provides only the list of the developing nodes. If you want to find the complete node list, please go to the Default channel."
}, },
{
"author": "Jiffies-64",
"title": "ComfyUI-SaveImagePlus",
"reference": "https://github.com/Jiffies-64/ComfyUI-SaveImagePlus",
"files": [
"https://github.com/Jiffies-64/ComfyUI-SaveImagePlus"
],
"install_type": "git-clone",
"description": "Nodes:SaveImagePlus"
},
{
"author": "kadirnar",
"title": "ComfyUI-Adapter [WIP]",
"reference": "https://github.com/kadirnar/ComfyUI-Adapter",
"files": [
"https://github.com/kadirnar/ComfyUI-Adapter"
],
"install_type": "git-clone",
"description": "WIP"
},
{ {
"author": "Beinsezii", "author": "Beinsezii",
"title": "comfyui-amd-go-fast", "title": "comfyui-amd-go-fast",
@ -229,16 +249,6 @@
"install_type": "git-clone", "install_type": "git-clone",
"description": "I made these nodes for experimenting so it's far from perfect but at least it is entertaining!\nIt uses cosine similarities or smallest euclidean distances to find the closest tokens." "description": "I made these nodes for experimenting so it's far from perfect but at least it is entertaining!\nIt uses cosine similarities or smallest euclidean distances to find the closest tokens."
}, },
{
"author": "logtd",
"title": "ComfyUI-FLATTEN",
"reference": "https://github.com/logtd/ComfyUI-FLATTEN",
"files": [
"https://github.com/logtd/ComfyUI-FLATTEN"
],
"install_type": "git-clone",
"description": "Load Checkpoint with FLATTEN model, KSampler (Flatten), Unsampler (Flatten), Sample Trajectories"
},
{ {
"author": "shadowcz007", "author": "shadowcz007",
"title": "comfyui-llamafile [WIP]", "title": "comfyui-llamafile [WIP]",

View File

@ -9,6 +9,16 @@
"description": "If you see this message, your ComfyUI-Manager is outdated.\nLegacy channel provides only the list of the deprecated nodes. If you want to find the complete node list, please go to the Default channel." "description": "If you see this message, your ComfyUI-Manager is outdated.\nLegacy channel provides only the list of the deprecated nodes. If you want to find the complete node list, please go to the Default channel."
}, },
{
"author": "Davemane42",
"title": "Visual Area Conditioning / Latent composition [DEPRECATED]",
"reference": "https://github.com/Davemane42/ComfyUI_Dave_CustomNode",
"files": [
"https://github.com/Davemane42/ComfyUI_Dave_CustomNode"
],
"install_type": "git-clone",
"description": "This tool provides custom nodes that allow visualization and configuration of area conditioning and latent composite."
},
{ {
"author": "laksjdjf", "author": "laksjdjf",
"title": "LoRA-Merger-ComfyUI [DEPRECATED]", "title": "LoRA-Merger-ComfyUI [DEPRECATED]",

View File

@ -10,6 +10,126 @@
}, },
{
"author": "chaojie",
"title": "ComfyUI-MuseV",
"reference": "https://github.com/chaojie/ComfyUI-MuseV",
"files": [
"https://github.com/chaojie/ComfyUI-MuseV"
],
"install_type": "git-clone",
"description": "ComfyUI MuseV"
},
{
"author": "DrMWeigand",
"title": "ComfyUI Color Detection Nodes",
"reference": "https://github.com/DrMWeigand/ComfyUI_ColorImageDetection",
"files": [
"https://github.com/DrMWeigand/ComfyUI_ColorImageDetection"
],
"install_type": "git-clone",
"description": "A collection of nodes for detecting color in images, leveraging RGB and LAB color spaces. These nodes aim to distinguish colored images from black and white, including those with color tints."
},
{
"author": "kijai",
"title": "ComfyUI-APISR",
"reference": "https://github.com/kijai/ComfyUI-APISR",
"files": [
"https://github.com/kijai/ComfyUI-APISR"
],
"install_type": "git-clone",
"description": "Node to use [a/APISR](https://github.com/Kiteretsu77/APISR) upscale models in ComfyUI"
},
{
"author": "logtd",
"title": "ComfyUI-FLATTEN",
"reference": "https://github.com/logtd/ComfyUI-FLATTEN",
"files": [
"https://github.com/logtd/ComfyUI-FLATTEN"
],
"install_type": "git-clone",
"description": "ComfyUI nodes to use [a/FLATTEN: optical FLow-guided ATTENtion for consistent text-to-video editing](https://github.com/yrcong/flatten)."
},
{
"author": "BlakeOne",
"title": "ComfyUI SchedulerMixer",
"reference": "https://github.com/BlakeOne/ComfyUI-SchedulerMixer",
"files": [
"https://github.com/BlakeOne/ComfyUI-SchedulerMixer"
],
"install_type": "git-clone",
"description": "Create a custom scheduler from a weighted average of the built-in schedulers"
},
{
"author": "BlakeOne",
"title": "ComfyUI FastImageListToImageBatch",
"reference": "https://github.com/BlakeOne/ComfyUI-FastImageListToImageBatch",
"files": [
"https://github.com/BlakeOne/ComfyUI-FastImageListToImageBatch"
],
"install_type": "git-clone",
"description": "Quickly convert a list of images to a batch of images. All images must be the same size. Great for long videos."
},
{
"author": "frankchieng",
"title": "ComfyUI_Aniportrait",
"reference": "https://github.com/frankchieng/ComfyUI_Aniportrait",
"files": [
"https://github.com/frankchieng/ComfyUI_Aniportrait"
],
"install_type": "git-clone",
"description": "implementation of [a/Aniportrait](https://github.com/Zejun-Yang/AniPortrait)'s self driven,audio driven and Face reenacment in ComfyUI"
},
{
"author": "ZHO-ZHO-ZHO",
"title": "ComfyUI-BiRefNet-ZHO",
"reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO",
"files": [
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO"
],
"install_type": "git-clone",
"description": "Better version for [a/BiRefNet](https://github.com/zhengpeng7/birefnet) in ComfyUI | Both img and video"
},
{
"author": "kale4eat",
"title": "ComfyUI_demucus",
"reference": "https://github.com/kale4eat/ComfyUI-path-util",
"files": [
"https://github.com/kale4eat/ComfyUI-path-util"
],
"install_type": "git-clone",
"description": "Path utility for ComfyUI"
},
{
"author": "kale4eat",
"title": "ComfyUI-string-util",
"reference": "https://github.com/kale4eat/ComfyUI-string-util",
"files": [
"https://github.com/kale4eat/ComfyUI-string-util"
],
"install_type": "git-clone",
"description": "String utility for ComfyUI"
},
{
"author": "kale4eat",
"title": "ComfyUI-text-file-util",
"reference": "https://github.com/kale4eat/ComfyUI-text-file-util",
"files": [
"https://github.com/kale4eat/ComfyUI-text-file-util"
],
"install_type": "git-clone",
"description": "Text file utility for ComfyUI"
},
{
"author": "nickve28",
"title": "Nich Comfy Utils",
"reference": "https://github.com/nickve28/nich-comfy-utils",
"files": [
"https://github.com/nickve28/nich-comfy-utils"
],
"install_type": "git-clone",
"description": "Nodes:Image from Dir Selector (Nich)"
},
{ {
"author": "Hangover3832", "author": "Hangover3832",
"title": "Recognize Anything Model (RAM++) for ComfyUI", "title": "Recognize Anything Model (RAM++) for ComfyUI",
@ -571,126 +691,6 @@
], ],
"install_type": "git-clone", "install_type": "git-clone",
"description": "DragAnything" "description": "DragAnything"
},
{
"author": "chaojie",
"title": "ComfyUI-Trajectory",
"reference": "https://github.com/chaojie/ComfyUI-Trajectory",
"files": [
"https://github.com/chaojie/ComfyUI-Trajectory"
],
"install_type": "git-clone",
"description": "ComfyUI Trajectory"
},
{
"author": "olduvai-jp",
"title": "ComfyUI-HfLoader",
"reference": "https://github.com/olduvai-jp/ComfyUI-HfLoader",
"files": [
"https://github.com/olduvai-jp/ComfyUI-HfLoader"
],
"install_type": "git-clone",
"description": "Nodes:Lora Loader From HF"
},
{
"author": "AiMiDi",
"title": "ComfyUI-Aimidi-nodes",
"reference": "https://github.com/AiMiDi/ComfyUI-Aimidi-nodes",
"files": [
"https://github.com/AiMiDi/ComfyUI-Aimidi-nodes"
],
"install_type": "git-clone",
"description": "Nodes:Merge Tag, Clear Tag, Add Tag, Load Images Pair Batch, Save Images Pair"
},
{
"author": "vsevolod-oparin",
"title": "Kandinsky 2.2 ComfyUI Plugin",
"reference": "https://github.com/vsevolod-oparin/comfyui-kandinsky22",
"files": [
"https://github.com/vsevolod-oparin/comfyui-kandinsky22"
],
"install_type": "git-clone",
"description": "Nodes provide an options to combine prior and decoder models of Kandinsky 2.2."
},
{
"author": "Xyem",
"title": "Xycuno Oobabooga",
"reference": "https://github.com/Xyem/Xycuno-Oobabooga",
"files": [
"https://github.com/Xyem/Xycuno-Oobabooga"
],
"install_type": "git-clone",
"description": "Xycuno Oobabooga provides custom nodes for ComfyUI, for sending requests to an [a/Oobabooga](https://github.com/oobabooga/text-generation-webui) instance to assist in creating prompt texts."
},
{
"author": "CozyMantis",
"title": "Cozy Reference Pose Generator",
"reference": "https://github.com/cozymantis/pose-generator-comfyui-node",
"files": [
"https://github.com/cozymantis/pose-generator-comfyui-node"
],
"install_type": "git-clone",
"description": "Generate OpenPose face/body reference poses in ComfyUI with ease. Made with 💚 by the CozyMantis squad."
},
{
"author": "CozyMantis",
"title": "Cozy Utils",
"reference": "https://github.com/cozymantis/cozy-utils-comfyui-nodes",
"files": [
"https://github.com/cozymantis/cozy-utils-comfyui-nodes"
],
"install_type": "git-clone",
"description": "Various cozy nodes, made with 💚 by the CozyMantis squad."
},
{
"author": "Chan-0312",
"title": "ComfyUI-EasyDeforum",
"reference": "https://github.com/Chan-0312/ComfyUI-EasyDeforum",
"files": [
"https://github.com/Chan-0312/ComfyUI-EasyDeforum"
],
"install_type": "git-clone",
"description": "Nodes:Easy2DDeforum (Chan)"
},
{
"author": "if-ai",
"title": "ComfyUI-IF_AI_tools",
"reference": "https://github.com/if-ai/ComfyUI-IF_AI_tools",
"files": [
"https://github.com/if-ai/ComfyUI-IF_AI_tools"
],
"install_type": "git-clone",
"description": "Various AI tools to use in Comfy UI. Starting with VL and prompt making tools using Ollma as backend will evolve as I find time."
},
{
"author": "shi3z",
"title": "ComfyUI_Memeplex_DALLE",
"reference": "https://github.com/shi3z/ComfyUI_Memeplex_DALLE",
"files": [
"https://github.com/shi3z/ComfyUI_Memeplex_DALLE"
],
"install_type": "git-clone",
"description": "You can use memeplex and DALL-E thru ComfyUI. You need API keys."
},
{
"author": "cdb-boop",
"title": "ComfyUI Bringing Old Photos Back to Life",
"reference": "https://github.com/cdb-boop/ComfyUI-Bringing-Old-Photos-Back-to-Life",
"files": [
"https://github.com/cdb-boop/ComfyUI-Bringing-Old-Photos-Back-to-Life"
],
"install_type": "git-clone",
"description": "Enhance old or low-quality images in ComfyUI. Optional features include automatic scratch removal and face enhancement. Based on Microsoft's Bringing-Old-Photos-Back-to-Life. Requires installing models, so see instructions here: https://github.com/cdb-boop/ComfyUI-Bringing-Old-Photos-Back-to-Life."
},
{
"author": "kingzcheung",
"title": "ComfyUI_kkTranslator_nodes",
"reference": "https://github.com/AIGCTeam/ComfyUI_kkTranslator_nodes",
"files": [
"https://github.com/AIGCTeam/ComfyUI_kkTranslator_nodes"
],
"install_type": "git-clone",
"description": "These nodes are mainly used to translate prompt words from other languages into English. PromptTranslateToText implements prompt word translation based on Helsinki NLP translation model.It doesn't require internet connection。"
} }
] ]
} }

View File

@ -328,6 +328,7 @@
"Load Images Pair Batch", "Load Images Pair Batch",
"Merge Tag", "Merge Tag",
"Move Tag To Top", "Move Tag To Top",
"Reserve Tag",
"Save Images Pair" "Save Images Pair"
], ],
{ {
@ -554,6 +555,22 @@
"title_aux": "ComfyUI-Path-Helper" "title_aux": "ComfyUI-Path-Helper"
} }
], ],
"https://github.com/BlakeOne/ComfyUI-FastImageListToImageBatch": [
[
"FastImageListToImageBatch"
],
{
"title_aux": "ComfyUI FastImageListToImageBatch"
}
],
"https://github.com/BlakeOne/ComfyUI-SchedulerMixer": [
[
"SchedulerMixer"
],
{
"title_aux": "ComfyUI SchedulerMixer"
}
],
"https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb": [ "https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb": [
[ [
"BNK_AddCLIPSDXLParams", "BNK_AddCLIPSDXLParams",
@ -766,6 +783,7 @@
"PrimereStyleLoader", "PrimereStyleLoader",
"PrimereStylePile", "PrimereStylePile",
"PrimereTextOutput", "PrimereTextOutput",
"PrimereUpscaleModel",
"PrimereVAE", "PrimereVAE",
"PrimereVAELoader", "PrimereVAELoader",
"PrimereVAESelector", "PrimereVAESelector",
@ -793,18 +811,6 @@
"title_aux": "ComfyUI-ComfyCouple" "title_aux": "ComfyUI-ComfyCouple"
} }
], ],
"https://github.com/Davemane42/ComfyUI_Dave_CustomNode": [
[
"ABGRemover",
"ConditioningStretch",
"ConditioningUpscale",
"MultiAreaConditioning",
"MultiLatentComposite"
],
{
"title_aux": "Visual Area Conditioning / Latent composition"
}
],
"https://github.com/Derfuu/Derfuu_ComfyUI_ModdedNodes": [ "https://github.com/Derfuu/Derfuu_ComfyUI_ModdedNodes": [
[ [
"Absolute value", "Absolute value",
@ -864,6 +870,15 @@
"title_aux": "ComfyUI-Cre8it-Nodes" "title_aux": "ComfyUI-Cre8it-Nodes"
} }
], ],
"https://github.com/DrMWeigand/ComfyUI_ColorImageDetection": [
[
"LABColorDetection",
"RGBColorDetection"
],
{
"title_aux": "ComfyUI Color Detection Nodes"
}
],
"https://github.com/Electrofried/ComfyUI-OpenAINode": [ "https://github.com/Electrofried/ComfyUI-OpenAINode": [
[ [
"OpenAINode" "OpenAINode"
@ -1022,6 +1037,7 @@
[ [
"EmptyMotionData", "EmptyMotionData",
"ExportSMPLTo3DSoftware", "ExportSMPLTo3DSoftware",
"Export_SMPLMultipleSubjects_To_3DSoftware",
"Human4D_Img2SMPL", "Human4D_Img2SMPL",
"Humans4DLoader", "Humans4DLoader",
"MotionCLIPTextEncode", "MotionCLIPTextEncode",
@ -1030,6 +1046,7 @@
"MotionDiffSimpleSampler", "MotionDiffSimpleSampler",
"RenderMultipleSubjectsSMPLMesh", "RenderMultipleSubjectsSMPLMesh",
"RenderSMPLMesh", "RenderSMPLMesh",
"Render_OpenPose_From_SMPL_Mesh_Multiple_Subjects",
"SMPLLoader", "SMPLLoader",
"SMPLShapeParameters", "SMPLShapeParameters",
"SaveSMPL", "SaveSMPL",
@ -1333,6 +1350,10 @@
"Moondream Interrogator" "Moondream Interrogator"
], ],
{ {
"author": "AlexL",
"description": "An implementation of the moondream visual LLM",
"nickname": "Hangover-Moondream",
"title": "ComfyUI-Hangover-Moondream",
"title_aux": "ComfyUI-Hangover-Moondream" "title_aux": "ComfyUI-Hangover-Moondream"
} }
], ],
@ -1344,6 +1365,10 @@
"Save Image w/o Metadata" "Save Image w/o Metadata"
], ],
{ {
"author": "AlexL",
"description": "Scales an input image into a given box size, whereby the aspect ratio keeps retained.",
"nickname": "Hangover-Image_Scale_Bouning_Box",
"title": "ComfyUI-Hangover-Image_Scale_Bouning_Box",
"title_aux": "ComfyUI-Hangover-Nodes" "title_aux": "ComfyUI-Hangover-Nodes"
} }
], ],
@ -1352,6 +1377,10 @@
"Recognize Anything Model (RAM++)" "Recognize Anything Model (RAM++)"
], ],
{ {
"author": "AlexL",
"description": "An implementation of the Recognize Anything Model (RAM++) for ComfyUI. The counterpart of Segment Anything Model (SAM).",
"nickname": "Hangover-Recognize_Anything",
"title": "ComfyUI-Hangover-Recognize_Anything",
"title_aux": "Recognize Anything Model (RAM++) for ComfyUI" "title_aux": "Recognize Anything Model (RAM++) for ComfyUI"
} }
], ],
@ -1665,6 +1694,7 @@
"ACN_ControlNetLoaderWithLoraAdvanced", "ACN_ControlNetLoaderWithLoraAdvanced",
"ACN_DefaultUniversalWeights", "ACN_DefaultUniversalWeights",
"ACN_ReferenceControlNet", "ACN_ReferenceControlNet",
"ACN_ReferenceControlNetFinetune",
"ACN_ReferencePreprocessor", "ACN_ReferencePreprocessor",
"ACN_SparseCtrlIndexMethodNode", "ACN_SparseCtrlIndexMethodNode",
"ACN_SparseCtrlLoaderAdvanced", "ACN_SparseCtrlLoaderAdvanced",
@ -2157,6 +2187,7 @@
"DoubleClipTextEncode", "DoubleClipTextEncode",
"HashText", "HashText",
"IndoorBackgrounds", "IndoorBackgrounds",
"IntFloatDict",
"LandscapeBackgrounds", "LandscapeBackgrounds",
"NatureColours", "NatureColours",
"OptimalCrop", "OptimalCrop",
@ -2547,9 +2578,10 @@
"OneTimeMultiplyTransform", "OneTimeMultiplyTransform",
"OneTimeShiftTransform", "OneTimeShiftTransform",
"ShiftTransform", "ShiftTransform",
"TSamplerWithTransform", "TransformHijack",
"TransformOffset", "TransformOffset",
"TransformSampler", "TransformSampler",
"TransformSamplerAdvanced",
"TransformsCombine" "TransformsCombine"
], ],
{ {
@ -3981,16 +4013,6 @@
"title_aux": "MergeBlockWeighted_fo_ComfyUI" "title_aux": "MergeBlockWeighted_fo_ComfyUI"
} }
], ],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-APISR": [
[
"APISR_Lterative_Zho",
"APISR_ModelLoader_Zho",
"APISR_Zho"
],
{
"title_aux": "APISR IN COMFYUI"
}
],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-ArtGallery": [ "https://github.com/ZHO-ZHO-ZHO/ComfyUI-ArtGallery": [
[ [
"ArtGallery_Zho", "ArtGallery_Zho",
@ -4013,6 +4035,15 @@
"title_aux": "ComfyUI-BRIA_AI-RMBG" "title_aux": "ComfyUI-BRIA_AI-RMBG"
} }
], ],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO": [
[
"BiRefNet_ModelLoader_Zho",
"BiRefNet_Zho"
],
{
"title_aux": "ComfyUI-BiRefNet-ZHO"
}
],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-DepthFM": [ "https://github.com/ZHO-ZHO-ZHO/ComfyUI-DepthFM": [
[ [
"DepthFM_Literative_Zho", "DepthFM_Literative_Zho",
@ -4188,6 +4219,7 @@
"AudioToFFTs", "AudioToFFTs",
"BatchAmplitudeSchedule", "BatchAmplitudeSchedule",
"ClipAmplitude", "ClipAmplitude",
"FloatArrayToGraph",
"GateNormalizedAmplitude", "GateNormalizedAmplitude",
"LoadAudio", "LoadAudio",
"NormalizeAmplitude", "NormalizeAmplitude",
@ -5252,6 +5284,15 @@
"title_aux": "ComfyUI-MotionCtrl-SVD" "title_aux": "ComfyUI-MotionCtrl-SVD"
} }
], ],
"https://github.com/chaojie/ComfyUI-MuseV": [
[
"MuseVRun"
],
{
"author": "infguo",
"title_aux": "ComfyUI-MuseV"
}
],
"https://github.com/chaojie/ComfyUI-Open-Sora": [ "https://github.com/chaojie/ComfyUI-Open-Sora": [
[ [
"OpenSoraLoader", "OpenSoraLoader",
@ -5923,6 +5964,17 @@
"title_aux": "Cozy Reference Pose Generator" "title_aux": "Cozy Reference Pose Generator"
} }
], ],
"https://github.com/crystian/ComfyUI-Crystools": [
[],
{
"author": "Crystian",
"description": "Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia",
"nickname": "Crystools",
"nodename_pattern": " \\[Crystools\\]$",
"title": "Crystools",
"title_aux": "Crystools"
}
],
"https://github.com/cubiq/ComfyUI_FaceAnalysis": [ "https://github.com/cubiq/ComfyUI_FaceAnalysis": [
[ [
"FaceAnalysisModels", "FaceAnalysisModels",
@ -6693,6 +6745,20 @@
"title_aux": "RF Nodes" "title_aux": "RF Nodes"
} }
], ],
"https://github.com/frankchieng/ComfyUI_Aniportrait": [
[
"AniPortrait_Audio2Video",
"AniPortrait_Audio_Path",
"AniPortrait_Generate_Ref_Pose",
"AniPortrait_LoadVideoPath",
"AniPortrait_Pose_Gen_Video",
"AniPortrait_Ref_Image_Path",
"AniPortrait_Video_Gen_Pose"
],
{
"title_aux": "ComfyUI_Aniportrait"
}
],
"https://github.com/gemell1/ComfyUI_GMIC": [ "https://github.com/gemell1/ComfyUI_GMIC": [
[ [
"GmicCliWrapper", "GmicCliWrapper",
@ -7322,6 +7388,60 @@
"title_aux": "ComfyUI-Transformers" "title_aux": "ComfyUI-Transformers"
} }
], ],
"https://github.com/kale4eat/ComfyUI-path-util": [
[
"path_util_PathAbspath",
"path_util_PathBasename",
"path_util_PathDirname",
"path_util_PathExists",
"path_util_PathIsdir",
"path_util_PathIsfile",
"path_util_PathJoin",
"path_util_PathRelpath",
"path_util_PathSplitext"
],
{
"title_aux": "ComfyUI_demucus"
}
],
"https://github.com/kale4eat/ComfyUI-string-util": [
[
"string_util_Str",
"string_util_StrConcat",
"string_util_StrCount",
"string_util_StrEndsWith",
"string_util_StrEqual",
"string_util_StrFind",
"string_util_StrFormat",
"string_util_StrJoin",
"string_util_StrLen",
"string_util_StrLower",
"string_util_StrLstrip",
"string_util_StrNotEqual",
"string_util_StrReplace",
"string_util_StrRstrip",
"string_util_StrSlice",
"string_util_StrSplit",
"string_util_StrStartsWith",
"string_util_StrStrip",
"string_util_StrUpper"
],
{
"title_aux": "ComfyUI-string-util"
}
],
"https://github.com/kale4eat/ComfyUI-text-file-util": [
[
"text_file_util_ReadAllLines",
"text_file_util_ReadAllText",
"text_file_util_WriteText",
"text_file_util_WriteTextLines",
"text_file_util_WriteTextWithSequentialNumbering"
],
{
"title_aux": "ComfyUI-text-file-util"
}
],
"https://github.com/kenjiqq/qq-nodes-comfyui": [ "https://github.com/kenjiqq/qq-nodes-comfyui": [
[ [
"Any List", "Any List",
@ -7370,6 +7490,16 @@
"title_aux": "Animatediff MotionLoRA Trainer" "title_aux": "Animatediff MotionLoRA Trainer"
} }
], ],
"https://github.com/kijai/ComfyUI-APISR": [
[
"APISR_Lterative_Zho",
"APISR_ModelLoader_Zho",
"APISR_Zho"
],
{
"title_aux": "ComfyUI-APISR"
}
],
"https://github.com/kijai/ComfyUI-CCSR": [ "https://github.com/kijai/ComfyUI-CCSR": [
[ [
"CCSR_Model_Select", "CCSR_Model_Select",
@ -7768,6 +7898,19 @@
"title_aux": "comfyui-easyapi-nodes" "title_aux": "comfyui-easyapi-nodes"
} }
], ],
"https://github.com/logtd/ComfyUI-FLATTEN": [
[
"ApplyFlattenAttentionNode",
"CreateFlowNoiseNode",
"FlattenCheckpointLoaderNode",
"KSamplerFlattenNode",
"TrajectoryNode",
"UnsamplerFlattenNode"
],
{
"title_aux": "ComfyUI-FLATTEN"
}
],
"https://github.com/logtd/ComfyUI-InstanceDiffusion": [ "https://github.com/logtd/ComfyUI-InstanceDiffusion": [
[ [
"ApplyScaleUModelNode", "ApplyScaleUModelNode",
@ -7835,8 +7978,7 @@
], ],
"https://github.com/longgui0318/comfyui-oms-diffusion": [ "https://github.com/longgui0318/comfyui-oms-diffusion": [
[ [
"Additional Features With Attention", "Additional Features With Attention"
"Extract Features With Unet"
], ],
{ {
"title_aux": "comfyui-oms-diffusion" "title_aux": "comfyui-oms-diffusion"
@ -8402,6 +8544,7 @@
"CreateMaskWithCanvas", "CreateMaskWithCanvas",
"CreateRegionalPNGMask", "CreateRegionalPNGMask",
"EightFloats", "EightFloats",
"EvenOrOdd",
"FloatMultiplication", "FloatMultiplication",
"FourBooleanTrigger", "FourBooleanTrigger",
"FourFloats", "FourFloats",
@ -8492,6 +8635,14 @@
"title_aux": "ComfyUI-NegiTools" "title_aux": "ComfyUI-NegiTools"
} }
], ],
"https://github.com/nickve28/nich-comfy-utils": [
[
"Image from Dir Selector (Nich)"
],
{
"title_aux": "Nich Comfy Utils"
}
],
"https://github.com/nicolai256/comfyUI_Nodes_nicolai256/raw/main/yugioh-presets.py": [ "https://github.com/nicolai256/comfyUI_Nodes_nicolai256/raw/main/yugioh-presets.py": [
[ [
"yugioh_Presets" "yugioh_Presets"
@ -9743,6 +9894,7 @@
"https://github.com/toyxyz/ComfyUI_toyxyz_test_nodes": [ "https://github.com/toyxyz/ComfyUI_toyxyz_test_nodes": [
[ [
"CaptureWebcam", "CaptureWebcam",
"ImageResize_Padding",
"LatentDelay", "LatentDelay",
"LoadWebcamImage", "LoadWebcamImage",
"SaveImagetoPath" "SaveImagetoPath"
@ -10234,6 +10386,7 @@
"easy if", "easy if",
"easy imageInsetCrop", "easy imageInsetCrop",
"easy imagePixelPerfect", "easy imagePixelPerfect",
"easy imageRatio",
"easy imageRemBg", "easy imageRemBg",
"easy imageRemoveBG", "easy imageRemoveBG",
"easy imageSave", "easy imageSave",

View File

@ -9,6 +9,13 @@ import locale
import platform import platform
try:
from distutils.version import StrictVersion
except:
print(f"[ComfyUI-Manager] Missing `distutils`. Try install...")
subprocess.check_output([sys.executable, '-m', 'pip', 'install', 'distutils'])
from distutils.version import StrictVersion
glob_path = os.path.join(os.path.dirname(__file__), "glob") glob_path = os.path.join(os.path.dirname(__file__), "glob")
sys.path.append(glob_path) sys.path.append(glob_path)
@ -292,6 +299,26 @@ else:
print("** Log path: file logging is disabled") print("** Log path: file logging is disabled")
def read_downgrade_blacklist():
try:
import configparser
config_path = os.path.join(os.path.dirname(__file__), "config.ini")
config = configparser.ConfigParser()
config.read(config_path)
default_conf = config['default']
if 'downgrade_blacklist' in default_conf:
items = default_conf['downgrade_blacklist'].split(',')
items = [x.strip() for x in items if x != '']
cm_global.pip_downgrade_blacklist += items
cm_global.pip_downgrade_blacklist = list(set(cm_global.pip_downgrade_blacklist))
except:
pass
read_downgrade_blacklist()
def check_bypass_ssl(): def check_bypass_ssl():
try: try:
import configparser import configparser
@ -314,21 +341,30 @@ check_bypass_ssl()
# Perform install # Perform install
processed_install = set() processed_install = set()
script_list_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "startup-scripts", "install-scripts.txt") script_list_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "startup-scripts", "install-scripts.txt")
pip_list = None pip_map = None
def get_installed_packages(): def get_installed_packages():
global pip_list global pip_map
if pip_list is None: if pip_map is None:
try: try:
result = subprocess.check_output([sys.executable, '-m', 'pip', 'list'], universal_newlines=True) result = subprocess.check_output([sys.executable, '-m', 'pip', 'list'], universal_newlines=True)
pip_list = set([line.split()[0].lower() for line in result.split('\n') if line.strip()])
pip_map = {}
for line in result.split('\n'):
x = line.strip()
if x:
y = line.split()
if y[0] == 'Package' or y[0].startswith('-'):
continue
pip_map[y[0]] = y[1]
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print(f"[ComfyUI-Manager] Failed to retrieve the information of installed pip packages.") print(f"[ComfyUI-Manager] Failed to retrieve the information of installed pip packages.")
return set() return set()
return pip_list return pip_map
def is_installed(name): def is_installed(name):
@ -337,16 +373,23 @@ def is_installed(name):
if name.startswith('#'): if name.startswith('#'):
return True return True
pattern = r'([^<>!=]+)([<>!=]=?)' pattern = r'([^<>!=]+)([<>!=]=?)(.*)'
match = re.search(pattern, name) match = re.search(pattern, name)
if match: if match:
name = match.group(1) name = match.group(1)
if name in cm_global.pip_downgrade_blacklist: if name in cm_global.pip_downgrade_blacklist:
if match is None or match.group(2) in ['<=', '==', '<']: pips = get_installed_packages()
print(f"[ComfyUI-Manager] skip black listed pip installation: '{name}'")
return True if match is None:
if name in pips:
return True
elif match.group(2) in ['<=', '==', '<']:
if name in pips:
if StrictVersion(pips[name]) >= StrictVersion(match.group(3)):
print(f"[ComfyUI-Manager] skip black listed pip installation: '{name}'")
return True
return name.lower() in get_installed_packages() return name.lower() in get_installed_packages()
@ -499,7 +542,7 @@ if os.path.exists(script_list_path):
print("#######################################################################\n") print("#######################################################################\n")
del processed_install del processed_install
del pip_list del pip_map
def check_windows_event_loop_policy(): def check_windows_event_loop_policy():

View File

@ -1,4 +1,5 @@
GitPython GitPython
PyGithub
matrix-client==0.4.0 matrix-client==0.4.0
transformers transformers
huggingface-hub>0.20 huggingface-hub>0.20

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
rm ~/.tmp/default/*.py > /dev/null 2>&1 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/. cp extension-node-map.json node_db/new/.
echo Integrity check echo Integrity check

View File

@ -5,11 +5,16 @@ import json
from git import Repo from git import Repo
from torchvision.datasets.utils import download_url from torchvision.datasets.utils import download_url
import concurrent import concurrent
import datetime
builtin_nodes = set() builtin_nodes = set()
import sys import sys
from urllib.parse import urlparse
from github import Github
g = Github(os.environ.get('GITHUB_TOKEN'))
# prepare temp dir # prepare temp dir
if len(sys.argv) > 1: if len(sys.argv) > 1:
@ -213,9 +218,6 @@ def update_custom_nodes():
git_url_titles_preemptions = 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): def process_git_url_title(url, title, preemptions, node_pattern):
if 'Jovimetrix' in title:
pass
name = os.path.basename(url) name = os.path.basename(url)
if name.endswith(".git"): if name.endswith(".git"):
name = name[:-4] name = name[:-4]
@ -224,7 +226,76 @@ def update_custom_nodes():
if not skip_update: if not skip_update:
clone_or_pull_git_repository(url) clone_or_pull_git_repository(url)
with concurrent.futures.ThreadPoolExecutor(10) as executor: def process_git_stats(git_url_titles_preemptions):
GITHUB_STATS_CACHE_FILENAME = 'github-stats-cache.json'
GITHUB_STATS_FILENAME = 'github-stats.json'
github_stats = {}
try:
with open(GITHUB_STATS_CACHE_FILENAME, 'r', encoding='utf-8') as file:
github_stats = json.load(file)
except FileNotFoundError:
pass
def is_rate_limit_exceeded():
return g.rate_limiting[0] == 0
if is_rate_limit_exceeded():
print(f"GitHub API Rate Limit Exceeded: remained - {(g.rate_limiting_resettime - datetime.datetime.now().timestamp())/60:.2f} min")
else:
def renew_stat(url):
if is_rate_limit_exceeded():
return
# Parsing the URL
parsed_url = urlparse(url)
domain = parsed_url.netloc
path = parsed_url.path
path_parts = path.strip("/").split("/")
if len(path_parts) >= 2 and domain == "github.com":
owner_repo = "/".join(path_parts[-2:])
repo = g.get_repo(owner_repo)
last_update = repo.pushed_at.strftime("%Y-%m-%d %H:%M:%S") if repo.pushed_at else 'N/A'
github_stats[url] = {
"stars": repo.stargazers_count,
"last_update": last_update,
"cached_time": datetime.datetime.now().timestamp(),
}
with open(GITHUB_STATS_CACHE_FILENAME, 'w', encoding='utf-8') as file:
json.dump(github_stats, file, ensure_ascii=False, indent=4)
else:
print(f"Invalid URL format for GitHub repository: {url}")
# resolve unresolved urls
for url, title, preemptions, node_pattern in git_url_titles_preemptions:
if url not in github_stats:
renew_stat(url)
# renew outdated cache
outdated_urls = []
for k, v in github_stats.items():
if (datetime.datetime.now().timestamp() - v['cached_time']) > 60*60*3: # 3 hours
outdated_urls += k
for url in outdated_urls:
renew_stat(url)
with open(GITHUB_STATS_FILENAME, 'w', encoding='utf-8') as file:
for v in github_stats.values():
if "cached_time" in v:
del v["cached_time"]
json.dump(github_stats, file, ensure_ascii=False, indent=4)
print(f"Successfully written to {GITHUB_STATS_FILENAME}, removing {GITHUB_STATS_CACHE_FILENAME}.")
# try:
# os.remove(GITHUB_STATS_CACHE_FILENAME) # This cache file is just for avoiding failure of GitHub API fetch, so it is safe to remove.
# except:
# pass
with concurrent.futures.ThreadPoolExecutor(11) as executor:
executor.submit(process_git_stats, git_url_titles_preemptions) # One single thread for `process_git_stats()`. Runs concurrently with `process_git_url_title()`.
for url, title, preemptions, node_pattern in git_url_titles_preemptions: for url, title, preemptions, node_pattern in git_url_titles_preemptions:
executor.submit(process_git_url_title, url, title, preemptions, node_pattern) executor.submit(process_git_url_title, url, title, preemptions, node_pattern)