mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-01-30 16:00:15 +08:00
Merge branch 'ltdrdata:main' into main
This commit is contained in:
commit
938dbe7a76
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,3 +12,4 @@ matrix_auth
|
|||||||
channels.list
|
channels.list
|
||||||
comfyworkflows_sharekey
|
comfyworkflows_sharekey
|
||||||
github-stats-cache.json
|
github-stats-cache.json
|
||||||
|
pip_overrides.json
|
||||||
34
README.md
34
README.md
@ -5,10 +5,9 @@
|
|||||||

|

|
||||||
|
|
||||||
## NOTICE
|
## NOTICE
|
||||||
* 🏆 Join us for the [ComfyUI Workflow Contest](https://contest.openart.ai/), hosted by OpenArt AI (11.27.2023 - 12.15.2023). Our esteemed judge panel includes Scott E. Detweiler, Olivio Sarikas, MERJIC麦橘, among others. We're also thrilled to have the authors of ComfyUI Manager and AnimateDiff as our special guests!
|
* V2.21 [cm-cli](docs/en/cm-cli.md) tool is added.
|
||||||
* If you wish to hide the "Share" button, click "Manager" and choose "Share: None" option.
|
* V2.18 to V2.18.3 is not functioning due to a severe bug. Users on these versions are advised to promptly update to V2.18.4. Please navigate to the `ComfyUI/custom_nodes/ComfyUI-Manager` directory and execute `git pull` to update.
|
||||||
* You can see whole nodes info on [ComfyUI Nodes Info](https://ltdrdata.github.io/) page.
|
* You can see whole nodes info on [ComfyUI Nodes Info](https://ltdrdata.github.io/) page.
|
||||||
* Versions prior to V0.22.2 will no longer detect missing nodes unless using a local database. Please update ComfyUI-Manager to the latest version.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -35,7 +34,7 @@ To install ComfyUI-Manager in addition to an existing installation of ComfyUI, y
|
|||||||
### Installation[method3] (Installation for linux+venv: ComfyUI + ComfyUI-Manager)
|
### Installation[method3] (Installation for linux+venv: ComfyUI + ComfyUI-Manager)
|
||||||
|
|
||||||
To install ComfyUI with ComfyUI-Manager on Linux using a venv environment, you can follow these steps:
|
To install ComfyUI with ComfyUI-Manager on Linux using a venv environment, you can follow these steps:
|
||||||
prerequisite: python-is-python3, python3-venv
|
* **prerequisite: python-is-python3, python3-venv**
|
||||||
|
|
||||||
1. Download [scripts/install-comfyui-venv-linux.sh](https://github.com/ltdrdata/ComfyUI-Manager/raw/main/scripts/install-comfyui-venv-linux.sh) into empty install directory
|
1. Download [scripts/install-comfyui-venv-linux.sh](https://github.com/ltdrdata/ComfyUI-Manager/raw/main/scripts/install-comfyui-venv-linux.sh) into empty install directory
|
||||||
- ComfyUI will be installed in the subdirectory of the specified directory, and the directory will contain the generated executable script.
|
- ComfyUI will be installed in the subdirectory of the specified directory, and the directory will contain the generated executable script.
|
||||||
@ -63,6 +62,7 @@ This repository provides Colab notebooks that allow you to install and use Comfy
|
|||||||
* Support for automatically installing dependencies of custom nodes upon restarting Colab notebooks.
|
* Support for automatically installing dependencies of custom nodes upon restarting Colab notebooks.
|
||||||
|
|
||||||
## Changes
|
## Changes
|
||||||
|
* **2.21** [cm-cli](docs/en/cm-cli.md) tool is added.
|
||||||
* **2.4** Copy the connections of the nearest node by double-clicking.
|
* **2.4** Copy the connections of the nearest node by double-clicking.
|
||||||
* **2.2.3** Support Components System
|
* **2.2.3** Support Components System
|
||||||
* **0.29** Add `Update all` feature
|
* **0.29** Add `Update all` feature
|
||||||
@ -157,6 +157,12 @@ This repository provides Colab notebooks that allow you to install and use Comfy
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
## cm-cli: command line tools for power user
|
||||||
|
* A tool is provided that allows you to use the features of ComfyUI-Manager without running ComfyUI.
|
||||||
|
* For more details, please refer to the [cm-cli documentation](docs/en/cm-cli.md).
|
||||||
|
|
||||||
|
|
||||||
## How to register your custom node into ComfyUI-Manager
|
## How to register your custom node into ComfyUI-Manager
|
||||||
|
|
||||||
* Add an entry to `custom-node-list.json` located in the root of ComfyUI-Manager and submit a Pull Request.
|
* Add an entry to `custom-node-list.json` located in the root of ComfyUI-Manager and submit a Pull Request.
|
||||||
@ -279,6 +285,26 @@ NODE_CLASS_MAPPINGS.update({
|
|||||||
downgrade_blacklist = diffusers, kornia
|
downgrade_blacklist = diffusers, kornia
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Custom pip mapping
|
||||||
|
* When you create the `pip_overrides.json` file, it changes the installation of specific pip packages to installations defined by the user.
|
||||||
|
* Please refer to the `pip_overrides.json.template` file.
|
||||||
|
|
||||||
|
|
||||||
|
## Scanner
|
||||||
|
When you run the `scan.sh` script:
|
||||||
|
|
||||||
|
* It updates the `extension-node-map.json`.
|
||||||
|
* To do this, it pulls or clones the custom nodes listed in `custom-node-list.json` into `~/.tmp/default`.
|
||||||
|
* To skip this step, add the `--skip-update` option.
|
||||||
|
* If you want to specify a different path instead of `~/.tmp/default`, run `python scanner.py [path]` directly instead of `scan.sh`.
|
||||||
|
|
||||||
|
* It updates the `github-stats.json`.
|
||||||
|
* This uses the GitHub API, so set your token with `export GITHUB_TOKEN=your_token_here` to avoid quickly reaching the rate limit and malfunctioning.
|
||||||
|
* To skip this step, add the `--skip-update-stat` option.
|
||||||
|
|
||||||
|
* The `--skip-all` option applies both `--skip-update` and `--skip-stat-update`.
|
||||||
|
|
||||||
|
|
||||||
## 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`.
|
||||||
|
|||||||
2530
__init__.py
2530
__init__.py
File diff suppressed because it is too large
Load Diff
508
cm-cli.py
Normal file
508
cm-cli.py
Normal file
@ -0,0 +1,508 @@
|
|||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
import json
|
||||||
|
import asyncio
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
sys.path.append(os.path.dirname(__file__))
|
||||||
|
sys.path.append(os.path.join(os.path.dirname(__file__), "glob"))
|
||||||
|
import manager_core as core
|
||||||
|
import cm_global
|
||||||
|
import git
|
||||||
|
|
||||||
|
|
||||||
|
print(f"\n-= ComfyUI-Manager CLI ({core.version_str}) =-\n")
|
||||||
|
|
||||||
|
|
||||||
|
if not (len(sys.argv) == 2 and sys.argv[1] in ['save-snapshot', 'restore-dependencies', 'clear']) and len(sys.argv) < 3:
|
||||||
|
print(f"\npython cm-cli.py [OPTIONS]\n\n"
|
||||||
|
f"OPTIONS:\n"
|
||||||
|
f" [install|reinstall|uninstall|update|disable|enable|fix] node_name ... ?[--channel <channel name>] ?[--mode [remote|local|cache]]\n"
|
||||||
|
f" [update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]\n"
|
||||||
|
f" [simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]\n"
|
||||||
|
f" save-snapshot\n"
|
||||||
|
f" restore-snapshot <snapshot>\n"
|
||||||
|
f" cli-only-mode [enable|disable]\n"
|
||||||
|
f" restore-dependencies\n"
|
||||||
|
f" clear\n")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
|
comfyui_manager_path = os.path.dirname(__file__)
|
||||||
|
comfy_path = os.environ.get('COMFYUI_PATH')
|
||||||
|
|
||||||
|
if comfy_path is None:
|
||||||
|
print(f"WARN: The `COMFYUI_PATH` environment variable is not set. Assuming `custom_nodes/ComfyUI-Manager/../../` as the ComfyUI path.\n", file=sys.stderr)
|
||||||
|
comfy_path = os.path.abspath(os.path.join(comfyui_manager_path, '..', '..'))
|
||||||
|
|
||||||
|
startup_script_path = os.path.join(comfyui_manager_path, "startup-scripts")
|
||||||
|
custom_nodes_path = os.path.join(comfy_path, 'custom_nodes')
|
||||||
|
|
||||||
|
script_path = os.path.join(startup_script_path, "install-scripts.txt")
|
||||||
|
restore_snapshot_path = os.path.join(startup_script_path, "restore-snapshot.json")
|
||||||
|
pip_overrides_path = os.path.join(comfyui_manager_path, "pip_overrides.json")
|
||||||
|
git_script_path = os.path.join(comfyui_manager_path, "git_helper.py")
|
||||||
|
|
||||||
|
cm_global.pip_downgrade_blacklist = ['torch', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||||
|
cm_global.pip_overrides = {}
|
||||||
|
if os.path.exists(pip_overrides_path):
|
||||||
|
with open(pip_overrides_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
|
||||||
|
cm_global.pip_overrides = json.load(json_file)
|
||||||
|
|
||||||
|
|
||||||
|
processed_install = set()
|
||||||
|
|
||||||
|
|
||||||
|
def post_install(url):
|
||||||
|
try:
|
||||||
|
repository_name = url.split("/")[-1].strip()
|
||||||
|
repo_path = os.path.join(custom_nodes_path, repository_name)
|
||||||
|
repo_path = os.path.abspath(repo_path)
|
||||||
|
|
||||||
|
requirements_path = os.path.join(repo_path, 'requirements.txt')
|
||||||
|
install_script_path = os.path.join(repo_path, 'install.py')
|
||||||
|
|
||||||
|
if os.path.exists(requirements_path):
|
||||||
|
with (open(requirements_path, 'r', encoding="UTF-8", errors="ignore") as file):
|
||||||
|
for line in file:
|
||||||
|
package_name = core.remap_pip_package(line.strip())
|
||||||
|
if package_name and not core.is_installed(package_name):
|
||||||
|
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||||
|
output = subprocess.check_output(install_cmd, cwd=repo_path, text=True)
|
||||||
|
for msg_line in output.split('\n'):
|
||||||
|
if 'Requirement already satisfied:' in msg_line:
|
||||||
|
print('.', end='')
|
||||||
|
else:
|
||||||
|
print(msg_line)
|
||||||
|
|
||||||
|
if os.path.exists(install_script_path) and f'{repo_path}/install.py' not in processed_install:
|
||||||
|
processed_install.add(f'{repo_path}/install.py')
|
||||||
|
install_cmd = [sys.executable, install_script_path]
|
||||||
|
output = subprocess.check_output(install_cmd, cwd=repo_path, text=True)
|
||||||
|
for msg_line in output.split('\n'):
|
||||||
|
if 'Requirement already satisfied:' in msg_line:
|
||||||
|
print('.', end='')
|
||||||
|
else:
|
||||||
|
print(msg_line)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
print(f"ERROR: Restoring '{url}' is failed.")
|
||||||
|
|
||||||
|
|
||||||
|
def restore_dependencies():
|
||||||
|
node_paths = [os.path.join(custom_nodes_path, name) for name in os.listdir(custom_nodes_path)
|
||||||
|
if os.path.isdir(os.path.join(custom_nodes_path, name)) and not name.endswith('.disabled')]
|
||||||
|
|
||||||
|
total = len(node_paths)
|
||||||
|
i = 1
|
||||||
|
for x in node_paths:
|
||||||
|
print(f"----------------------------------------------------------------------------------------------------")
|
||||||
|
print(f"Restoring [{i}/{total}]: {x}")
|
||||||
|
post_install(x)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
|
def restore_snapshot(snapshot_name):
|
||||||
|
global processed_install
|
||||||
|
|
||||||
|
snapshot_path = os.path.join(core.comfyui_manager_path, 'snapshots', snapshot_name)
|
||||||
|
if not os.path.exists(snapshot_path):
|
||||||
|
print(f"ERROR: `{snapshot_path}` is not exists.")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
cloned_repos = []
|
||||||
|
checkout_repos = []
|
||||||
|
skipped_repos = []
|
||||||
|
enabled_repos = []
|
||||||
|
disabled_repos = []
|
||||||
|
is_failed = False
|
||||||
|
|
||||||
|
def extract_infos(msg_lines):
|
||||||
|
nonlocal is_failed
|
||||||
|
|
||||||
|
for x in msg_lines:
|
||||||
|
if x.startswith("CLONE: "):
|
||||||
|
cloned_repos.append(x[7:])
|
||||||
|
elif x.startswith("CHECKOUT: "):
|
||||||
|
checkout_repos.append(x[10:])
|
||||||
|
elif x.startswith("SKIPPED: "):
|
||||||
|
skipped_repos.append(x[9:])
|
||||||
|
elif x.startswith("ENABLE: "):
|
||||||
|
enabled_repos.append(x[8:])
|
||||||
|
elif x.startswith("DISABLE: "):
|
||||||
|
disabled_repos.append(x[9:])
|
||||||
|
elif 'APPLY SNAPSHOT: False' in x:
|
||||||
|
is_failed = True
|
||||||
|
|
||||||
|
print(f"Restore snapshot.")
|
||||||
|
cmd_str = [sys.executable, git_script_path, '--apply-snapshot', snapshot_path]
|
||||||
|
output = subprocess.check_output(cmd_str, cwd=custom_nodes_path, text=True)
|
||||||
|
msg_lines = output.split('\n')
|
||||||
|
extract_infos(msg_lines)
|
||||||
|
|
||||||
|
for url in cloned_repos:
|
||||||
|
post_install(url)
|
||||||
|
|
||||||
|
# print summary
|
||||||
|
for x in cloned_repos:
|
||||||
|
print(f"[ INSTALLED ] {x}")
|
||||||
|
for x in checkout_repos:
|
||||||
|
print(f"[ CHECKOUT ] {x}")
|
||||||
|
for x in enabled_repos:
|
||||||
|
print(f"[ ENABLED ] {x}")
|
||||||
|
for x in disabled_repos:
|
||||||
|
print(f"[ DISABLED ] {x}")
|
||||||
|
|
||||||
|
if is_failed:
|
||||||
|
print("ERROR: Failed to restore snapshot.")
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
print("ERROR: Failed to restore snapshot.")
|
||||||
|
traceback.print_exc()
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
|
def check_comfyui_hash():
|
||||||
|
repo = git.Repo(comfy_path)
|
||||||
|
core.comfy_ui_revision = len(list(repo.iter_commits('HEAD')))
|
||||||
|
|
||||||
|
comfy_ui_hash = repo.head.commit.hexsha
|
||||||
|
cm_global.variables['comfyui.revision'] = core.comfy_ui_revision
|
||||||
|
|
||||||
|
core.comfy_ui_commit_datetime = repo.head.commit.committed_datetime
|
||||||
|
|
||||||
|
|
||||||
|
check_comfyui_hash()
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
channel = 'default'
|
||||||
|
mode = 'remote'
|
||||||
|
nodes = set()
|
||||||
|
|
||||||
|
|
||||||
|
def load_custom_nodes():
|
||||||
|
channel_dict = core.get_channel_dict()
|
||||||
|
if channel not in channel_dict:
|
||||||
|
print(f"ERROR: Invalid channel is specified `--channel {channel}`", file=sys.stderr)
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
if mode not in ['remote', 'local', 'cache']:
|
||||||
|
print(f"ERROR: Invalid mode is specified `--mode {mode}`", file=sys.stderr)
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
channel_url = channel_dict[channel]
|
||||||
|
|
||||||
|
res = {}
|
||||||
|
json_obj = asyncio.run(core.get_data_by_mode(mode, 'custom-node-list.json', channel_url=channel_url))
|
||||||
|
for x in json_obj['custom_nodes']:
|
||||||
|
for y in x['files']:
|
||||||
|
if 'github.com' in y and not (y.endswith('.py') or y.endswith('.js')):
|
||||||
|
repo_name = y.split('/')[-1]
|
||||||
|
res[repo_name] = x
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def process_args():
|
||||||
|
global channel
|
||||||
|
global mode
|
||||||
|
|
||||||
|
i = 2
|
||||||
|
while i < len(sys.argv):
|
||||||
|
if sys.argv[i] == '--channel':
|
||||||
|
if i+1 < len(sys.argv):
|
||||||
|
channel = sys.argv[i+1]
|
||||||
|
i += 1
|
||||||
|
elif sys.argv[i] == '--mode':
|
||||||
|
if i+1 < len(sys.argv):
|
||||||
|
mode = sys.argv[i+1]
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
nodes.add(sys.argv[i])
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
|
process_args()
|
||||||
|
custom_node_map = load_custom_nodes()
|
||||||
|
|
||||||
|
|
||||||
|
def lookup_node_path(node_name):
|
||||||
|
# Currently, the node_name is used directly as the node_path, but in the future, I plan to allow nicknames.
|
||||||
|
|
||||||
|
if '..' in node_name:
|
||||||
|
print(f"ERROR: invalid node name '{node_name}'")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
if node_name in custom_node_map:
|
||||||
|
node_path = os.path.join(custom_nodes_path, node_name)
|
||||||
|
return node_path, custom_node_map[node_name]
|
||||||
|
|
||||||
|
print(f"ERROR: invalid node name '{node_name}'")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
|
||||||
|
def install_node(node_name, is_all=False, cnt_msg=''):
|
||||||
|
node_path, node_item = lookup_node_path(node_name)
|
||||||
|
|
||||||
|
if os.path.exists(node_path):
|
||||||
|
if not is_all:
|
||||||
|
print(f"{cnt_msg} [ SKIPPED ] {node_name:50} => Already installed")
|
||||||
|
elif os.path.exists(node_path+'.disabled'):
|
||||||
|
enable_node(node_name)
|
||||||
|
else:
|
||||||
|
res = core.gitclone_install(node_item['files'], instant_execution=True, msg_prefix=f"[{cnt_msg}] ")
|
||||||
|
if not res:
|
||||||
|
print(f"ERROR: An error occurred while installing '{node_name}'.")
|
||||||
|
else:
|
||||||
|
print(f"{cnt_msg} [INSTALLED] {node_name:50}")
|
||||||
|
|
||||||
|
|
||||||
|
def reinstall_node(node_name, is_all=False, cnt_msg=''):
|
||||||
|
node_path, node_item = lookup_node_path(node_name)
|
||||||
|
|
||||||
|
if os.path.exists(node_path):
|
||||||
|
shutil.rmtree(node_path)
|
||||||
|
if os.path.exists(node_path+'.disabled'):
|
||||||
|
shutil.rmtree(node_path+'.disabled')
|
||||||
|
|
||||||
|
install_node(node_name, is_all=is_all, cnt_msg=cnt_msg)
|
||||||
|
|
||||||
|
|
||||||
|
def fix_node(node_name, is_all=False, cnt_msg=''):
|
||||||
|
node_path, node_item = lookup_node_path(node_name)
|
||||||
|
if os.path.exists(node_path):
|
||||||
|
print(f"{cnt_msg} [ FIXING ]: {node_name:50} => Disabled")
|
||||||
|
res = core.gitclone_fix(node_item['files'], instant_execution=True)
|
||||||
|
if not res:
|
||||||
|
print(f"ERROR: An error occurred while fixing '{node_name}'.")
|
||||||
|
elif not is_all and os.path.exists(node_path+'.disabled'):
|
||||||
|
print(f"{cnt_msg} [ SKIPPED ]: {node_name:50} => Disabled")
|
||||||
|
elif not is_all:
|
||||||
|
print(f"{cnt_msg} [ SKIPPED ]: {node_name:50} => Not installed")
|
||||||
|
|
||||||
|
|
||||||
|
def uninstall_node(node_name, is_all=False, cnt_msg=''):
|
||||||
|
node_path, node_item = lookup_node_path(node_name)
|
||||||
|
if os.path.exists(node_path) or os.path.exists(node_path+'.disabled'):
|
||||||
|
res = core.gitclone_uninstall(node_item['files'])
|
||||||
|
if not res:
|
||||||
|
print(f"ERROR: An error occurred while uninstalling '{node_name}'.")
|
||||||
|
else:
|
||||||
|
print(f"{cnt_msg} [UNINSTALLED] {node_name:50}")
|
||||||
|
else:
|
||||||
|
print(f"{cnt_msg} [ SKIPPED ]: {node_name:50} => Not installed")
|
||||||
|
|
||||||
|
|
||||||
|
def update_node(node_name, is_all=False, cnt_msg=''):
|
||||||
|
node_path, node_item = lookup_node_path(node_name)
|
||||||
|
res = core.gitclone_update(node_item['files'], skip_script=True, msg_prefix=f"[{cnt_msg}] ")
|
||||||
|
post_install(node_path)
|
||||||
|
if not res:
|
||||||
|
print(f"ERROR: An error occurred while uninstalling '{node_name}'.")
|
||||||
|
|
||||||
|
|
||||||
|
def enable_node(node_name, is_all=False, cnt_msg=''):
|
||||||
|
if node_name == 'ComfyUI-Manager':
|
||||||
|
return
|
||||||
|
|
||||||
|
node_path, _ = lookup_node_path(node_name)
|
||||||
|
|
||||||
|
if os.path.exists(node_path+'.disabled'):
|
||||||
|
current_name = node_path+'.disabled'
|
||||||
|
os.rename(current_name, node_path)
|
||||||
|
print(f"{cnt_msg} [ENABLED] {node_name:50}")
|
||||||
|
elif os.path.exists(node_path):
|
||||||
|
print(f"{cnt_msg} [SKIPPED] {node_name:50} => Already enabled")
|
||||||
|
elif not is_all:
|
||||||
|
print(f"{cnt_msg} [SKIPPED] {node_name:50} => Not installed")
|
||||||
|
|
||||||
|
|
||||||
|
def disable_node(node_name, is_all=False, cnt_msg=''):
|
||||||
|
if node_name == 'ComfyUI-Manager':
|
||||||
|
return
|
||||||
|
|
||||||
|
node_path, _ = lookup_node_path(node_name)
|
||||||
|
|
||||||
|
if os.path.exists(node_path):
|
||||||
|
current_name = node_path
|
||||||
|
new_name = node_path+'.disabled'
|
||||||
|
os.rename(current_name, new_name)
|
||||||
|
print(f"{cnt_msg} [DISABLED] {node_name:50}")
|
||||||
|
elif os.path.exists(node_path+'.disabled'):
|
||||||
|
print(f"{cnt_msg} [ SKIPPED] {node_name:50} => Already disabled")
|
||||||
|
elif not is_all:
|
||||||
|
print(f"{cnt_msg} [ SKIPPED] {node_name:50} => Not installed")
|
||||||
|
|
||||||
|
|
||||||
|
def show_list(kind, simple=False):
|
||||||
|
for k, v in custom_node_map.items():
|
||||||
|
node_path = os.path.join(custom_nodes_path, k)
|
||||||
|
|
||||||
|
states = set()
|
||||||
|
if os.path.exists(node_path):
|
||||||
|
prefix = '[ ENABLED ] '
|
||||||
|
states.add('installed')
|
||||||
|
states.add('enabled')
|
||||||
|
states.add('all')
|
||||||
|
elif os.path.exists(node_path+'.disabled'):
|
||||||
|
prefix = '[ DISABLED ] '
|
||||||
|
states.add('installed')
|
||||||
|
states.add('disabled')
|
||||||
|
states.add('all')
|
||||||
|
else:
|
||||||
|
prefix = '[ NOT INSTALLED ] '
|
||||||
|
states.add('not-installed')
|
||||||
|
states.add('all')
|
||||||
|
|
||||||
|
if kind in states:
|
||||||
|
if simple:
|
||||||
|
print(f"{k:50}")
|
||||||
|
else:
|
||||||
|
print(f"{prefix} {k:50}(author: {v['author']})")
|
||||||
|
|
||||||
|
|
||||||
|
def show_snapshot(simple_mode=False):
|
||||||
|
json_obj = core.get_current_snapshot()
|
||||||
|
|
||||||
|
if simple_mode:
|
||||||
|
print(f"[{json_obj['comfyui']}] comfyui")
|
||||||
|
for k, v in json_obj['git_custom_nodes'].items():
|
||||||
|
print(f"[{v['hash']}] {k}")
|
||||||
|
for v in json_obj['file_custom_nodes']:
|
||||||
|
print(f"[ N/A ] {v['filename']}")
|
||||||
|
|
||||||
|
else:
|
||||||
|
formatted_json = json.dumps(json_obj, ensure_ascii=False, indent=4)
|
||||||
|
print(formatted_json)
|
||||||
|
|
||||||
|
|
||||||
|
def show_snapshot_list(simple_mode=False):
|
||||||
|
path = os.path.join(comfyui_manager_path, 'snapshots')
|
||||||
|
|
||||||
|
files = os.listdir(path)
|
||||||
|
json_files = [x for x in files if x.endswith('.json')]
|
||||||
|
for x in sorted(json_files):
|
||||||
|
print(x)
|
||||||
|
|
||||||
|
|
||||||
|
def cancel():
|
||||||
|
if os.path.exists(script_path):
|
||||||
|
os.remove(script_path)
|
||||||
|
|
||||||
|
if os.path.exists(restore_snapshot_path):
|
||||||
|
os.remove(restore_snapshot_path)
|
||||||
|
|
||||||
|
|
||||||
|
def for_each_nodes(act, allow_all=True):
|
||||||
|
global nodes
|
||||||
|
|
||||||
|
is_all = False
|
||||||
|
if allow_all and 'all' in nodes:
|
||||||
|
is_all = True
|
||||||
|
nodes = [x for x in custom_node_map.keys() if os.path.exists(os.path.join(custom_nodes_path, x)) or os.path.exists(os.path.join(custom_nodes_path, x)+'.disabled')]
|
||||||
|
|
||||||
|
total = len(nodes)
|
||||||
|
i = 1
|
||||||
|
for x in nodes:
|
||||||
|
try:
|
||||||
|
act(x, is_all=is_all, cnt_msg=f'{i}/{total}')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
|
i+=1
|
||||||
|
|
||||||
|
|
||||||
|
op = sys.argv[1]
|
||||||
|
|
||||||
|
|
||||||
|
if op == 'install':
|
||||||
|
for_each_nodes(install_node)
|
||||||
|
|
||||||
|
elif op == 'reinstall':
|
||||||
|
for_each_nodes(reinstall_node)
|
||||||
|
|
||||||
|
elif op == 'uninstall':
|
||||||
|
for_each_nodes(uninstall_node)
|
||||||
|
|
||||||
|
elif op == 'update':
|
||||||
|
for_each_nodes(update_node, allow_all=True)
|
||||||
|
|
||||||
|
elif op == 'disable':
|
||||||
|
for_each_nodes(disable_node, allow_all=True)
|
||||||
|
|
||||||
|
elif op == 'enable':
|
||||||
|
for_each_nodes(enable_node, allow_all=True)
|
||||||
|
|
||||||
|
elif op == 'fix':
|
||||||
|
for_each_nodes(fix_node, allow_all=True)
|
||||||
|
|
||||||
|
elif op == 'show':
|
||||||
|
if sys.argv[2] == 'snapshot':
|
||||||
|
show_snapshot()
|
||||||
|
elif sys.argv[2] == 'snapshot-list':
|
||||||
|
show_snapshot_list()
|
||||||
|
else:
|
||||||
|
show_list(sys.argv[2])
|
||||||
|
|
||||||
|
elif op == 'simple-show':
|
||||||
|
if sys.argv[2] == 'snapshot':
|
||||||
|
show_snapshot(True)
|
||||||
|
elif sys.argv[2] == 'snapshot-list':
|
||||||
|
show_snapshot_list(True)
|
||||||
|
else:
|
||||||
|
show_list(sys.argv[2], True)
|
||||||
|
|
||||||
|
elif op == 'cli-only-mode':
|
||||||
|
cli_mode_flag = os.path.join(os.path.dirname(__file__), '.enable-cli-only-mode')
|
||||||
|
if sys.argv[2] == 'enable':
|
||||||
|
with open(cli_mode_flag, 'w') as file:
|
||||||
|
pass
|
||||||
|
print(f"\ncli-only-mode: enabled\n")
|
||||||
|
elif sys.argv[2] == 'disable':
|
||||||
|
if os.path.exists(cli_mode_flag):
|
||||||
|
os.remove(cli_mode_flag)
|
||||||
|
print(f"\ncli-only-mode: disabled\n")
|
||||||
|
else:
|
||||||
|
print(f"\ninvalid value for cli-only-mode: {sys.argv[2]}\n")
|
||||||
|
|
||||||
|
elif op == 'save-snapshot':
|
||||||
|
path = core.save_snapshot_with_postfix('snapshot')
|
||||||
|
print(f"Current snapshot is saved as `{path}`")
|
||||||
|
|
||||||
|
elif op == 'restore-snapshot':
|
||||||
|
restore_snapshot(sys.argv[2])
|
||||||
|
|
||||||
|
elif op == 'restore-dependencies':
|
||||||
|
restore_dependencies()
|
||||||
|
|
||||||
|
elif op == 'clear':
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"\nInvalid command `{op}`")
|
||||||
|
|
||||||
|
print(f"")
|
||||||
@ -42,6 +42,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Nodes: ModelSamplerTonemapNoiseTest, TonemapNoiseWithRescaleCFG, ReferenceOnlySimple, RescaleClassifierFreeGuidanceTest, ModelMergeBlockNumber, ModelMergeSDXL, ModelMergeSDXLTransformers, ModelMergeSDXLDetailedTransformers.[w/NOTE: This is a consolidation of the previously separate custom nodes. Please delete the sampler_tonemap.py, sampler_rescalecfg.py, advanced_model_merging.py, sdxl_model_merging.py, and reference_only.py files installed in custom_nodes before.]"
|
"description": "Nodes: ModelSamplerTonemapNoiseTest, TonemapNoiseWithRescaleCFG, ReferenceOnlySimple, RescaleClassifierFreeGuidanceTest, ModelMergeBlockNumber, ModelMergeSDXL, ModelMergeSDXLTransformers, ModelMergeSDXLDetailedTransformers.[w/NOTE: This is a consolidation of the previously separate custom nodes. Please delete the sampler_tonemap.py, sampler_rescalecfg.py, advanced_model_merging.py, sdxl_model_merging.py, and reference_only.py files installed in custom_nodes before.]"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "Stability-AI",
|
||||||
|
"title": "Stability API nodes for ComfyUI",
|
||||||
|
"reference": "https://github.com/Stability-AI/ComfyUI-SAI_API",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Stability-AI/ComfyUI-SAI_API"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Stability SD3, Stability Outpainting, Stability Search and Replace, Stability Image Core, Stability Inpainting, Stability Remove Background, Stability Creative Upscale.\nAdd API key to environment variable 'SAI_API_KEY'\nAlternatively you can write your API key to file 'sai_platform_key.txt'\nYou can also use and/or override the above by entering your API key in the 'api_key_override' field of each node."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "Stability-AI",
|
"author": "Stability-AI",
|
||||||
"title": "stability-ComfyUI-nodes",
|
"title": "stability-ComfyUI-nodes",
|
||||||
@ -152,6 +162,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "A minimalistic implementation of [a/Robust Video Matting (RVM)](https://github.com/PeterL1n/RobustVideoMatting/) in ComfyUI"
|
"description": "A minimalistic implementation of [a/Robust Video Matting (RVM)](https://github.com/PeterL1n/RobustVideoMatting/) in ComfyUI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "Fannovel16",
|
||||||
|
"title": "ComfyUI-MagickWand",
|
||||||
|
"reference": "https://github.com/Fannovel16/ComfyUI-MagickWand",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Fannovel16/ComfyUI-MagickWand"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Proper implementation of ImageMagick - the famous software suite for editing and manipulating digital images to ComfyUI using [a/wandpy](https://github.com/emcconville/wand).\nNOTE: You need to install ImageMagick, manually."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "biegert",
|
"author": "biegert",
|
||||||
"title": "CLIPSeg",
|
"title": "CLIPSeg",
|
||||||
@ -224,7 +244,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "jags111",
|
"author": "jags111",
|
||||||
"title": "ComfyUI_Jags_VectorMagic",
|
"title": "Jags_VectorMagic",
|
||||||
"reference": "https://github.com/jags111/ComfyUI_Jags_VectorMagic",
|
"reference": "https://github.com/jags111/ComfyUI_Jags_VectorMagic",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/jags111/ComfyUI_Jags_VectorMagic"
|
"https://github.com/jags111/ComfyUI_Jags_VectorMagic"
|
||||||
@ -234,7 +254,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "jags111",
|
"author": "jags111",
|
||||||
"title": "ComfyUI_Jags_Audiotools",
|
"title": "Jags_Audiotools",
|
||||||
"reference": "https://github.com/jags111/ComfyUI_Jags_Audiotools",
|
"reference": "https://github.com/jags111/ComfyUI_Jags_Audiotools",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/jags111/ComfyUI_Jags_Audiotools"
|
"https://github.com/jags111/ComfyUI_Jags_Audiotools"
|
||||||
@ -836,7 +856,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "Suzie1",
|
"author": "Suzie1",
|
||||||
"title": "ComfyUI_Comfyroll_CustomNodes",
|
"title": "Comfyroll Studio",
|
||||||
"reference": "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes",
|
"reference": "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes"
|
"https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes"
|
||||||
@ -2260,7 +2280,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "receyuki",
|
"author": "receyuki",
|
||||||
"title": "comfyui-prompt-reader-node",
|
"title": "SD Prompt Reader",
|
||||||
"reference": "https://github.com/receyuki/comfyui-prompt-reader-node",
|
"reference": "https://github.com/receyuki/comfyui-prompt-reader-node",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/receyuki/comfyui-prompt-reader-node"
|
"https://github.com/receyuki/comfyui-prompt-reader-node"
|
||||||
@ -2399,16 +2419,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Custom AI prompt generator node for ComfyUI."
|
"description": "Custom AI prompt generator node for ComfyUI."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "mlinmg",
|
|
||||||
"title": "LaMa Preprocessor [WIP]",
|
|
||||||
"reference": "https://github.com/mlinmg/ComfyUI-LaMA-Preprocessor",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/mlinmg/ComfyUI-LaMA-Preprocessor"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "A LaMa prerocessor for ComfyUI. This preprocessor finally enable users to generate coherent inpaint and outpaint prompt-free. The best results are given on landscapes, not so much in drawings/animation."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "kijai",
|
"author": "kijai",
|
||||||
"title": "KJNodes for ComfyUI",
|
"title": "KJNodes for ComfyUI",
|
||||||
@ -2522,12 +2532,12 @@
|
|||||||
{
|
{
|
||||||
"author": "kijai",
|
"author": "kijai",
|
||||||
"title": "ComfyUI-APISR",
|
"title": "ComfyUI-APISR",
|
||||||
"reference": "https://github.com/kijai/ComfyUI-APISR",
|
"reference": "https://github.com/kijai/ComfyUI-APISR-KJ",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/kijai/ComfyUI-APISR"
|
"https://github.com/kijai/ComfyUI-APISR-KJ"
|
||||||
],
|
],
|
||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Node to use [a/APISR](https://github.com/Kiteretsu77/APISR) upscale models in ComfyUI"
|
"description": "Node to use [a/APISR](https://github.com/Kiteretsu77/APISR) upscale models in ComfyUI.[w/NOTE: repo name is changed from ComfyUI-APISR -> ComfyUI-APISR-KJ]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "kijai",
|
"author": "kijai",
|
||||||
@ -2539,6 +2549,36 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "This is simplified implementation of the [a/DiffusionLight](https://github.com/DiffusionLight/DiffusionLight) method of creating light probes. You will need the included LoRA, place it in ComfyUI/loras folder like usual, it's converted from the original diffusers one."
|
"description": "This is simplified implementation of the [a/DiffusionLight](https://github.com/DiffusionLight/DiffusionLight) method of creating light probes. You will need the included LoRA, place it in ComfyUI/loras folder like usual, it's converted from the original diffusers one."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "kijai",
|
||||||
|
"title": "ComfyUI-ELLA-wrapper",
|
||||||
|
"reference": "https://github.com/kijai/ComfyUI-ELLA-wrapper",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/kijai/ComfyUI-ELLA-wrapper"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI wrapper nodes to use the Diffusers implementation of ELLA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "kijai",
|
||||||
|
"title": "ComfyUI-LaVi-Bridge-Wrapper",
|
||||||
|
"reference": "https://github.com/kijai/ComfyUI-LaVi-Bridge-Wrapper",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/kijai/ComfyUI-LaVi-Bridge-Wrapper"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI wrapper node to test LaVi-Bridge using Diffusers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "kijai",
|
||||||
|
"title": "ComfyUI-BrushNet-Wrapper",
|
||||||
|
"reference": "https://github.com/kijai/ComfyUI-BrushNet-Wrapper",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/kijai/ComfyUI-BrushNet-Wrapper"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI wrapper nodes to use the Diffusers implementation of BrushNet"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "hhhzzyang",
|
"author": "hhhzzyang",
|
||||||
"title": "Comfyui-Lama",
|
"title": "Comfyui-Lama",
|
||||||
@ -2581,7 +2621,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "avatechai",
|
"author": "avatechai",
|
||||||
"title": "avatar-graph-comfyui",
|
"title": "Avatar Graph",
|
||||||
"reference": "https://github.com/avatechai/avatar-graph-comfyui",
|
"reference": "https://github.com/avatechai/avatar-graph-comfyui",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/avatechai/avatar-graph-comfyui"
|
"https://github.com/avatechai/avatar-graph-comfyui"
|
||||||
@ -3304,7 +3344,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "Danand",
|
"author": "Danand",
|
||||||
"title": "ComfyUI-ComfyCouple",
|
"title": "Comfy Couple",
|
||||||
"reference": "https://github.com/Danand/ComfyUI-ComfyCouple",
|
"reference": "https://github.com/Danand/ComfyUI-ComfyCouple",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/Danand/ComfyUI-ComfyCouple"
|
"https://github.com/Danand/ComfyUI-ComfyCouple"
|
||||||
@ -4114,6 +4154,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "A suite of tools for prompt management. Combining nodes helps the user sequence strings for prompts, also creating logical groupings if necessary. Individual nodes can be chained together in any order."
|
"description": "A suite of tools for prompt management. Combining nodes helps the user sequence strings for prompts, also creating logical groupings if necessary. Individual nodes can be chained together in any order."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "florestefano1975",
|
||||||
|
"title": "ComfyUI StabilityAI Suite",
|
||||||
|
"reference": "https://github.com/florestefano1975/ComfyUI-StabilityAI-Suite",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/florestefano1975/ComfyUI-StabilityAI-Suite"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This fork of the official StabilityAI repository contains a number of enhancements and implementations."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "mozman",
|
"author": "mozman",
|
||||||
"title": "ComfyUI_mozman_nodes",
|
"title": "ComfyUI_mozman_nodes",
|
||||||
@ -4266,7 +4316,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "HarroweD and quadmoon",
|
"author": "HarroweD and quadmoon",
|
||||||
"title": "Harronode",
|
"title": "Harrlogos Prompt Builder Node",
|
||||||
"reference": "https://github.com/NotHarroweD/Harronode",
|
"reference": "https://github.com/NotHarroweD/Harronode",
|
||||||
"nodename_pattern": "Harronode",
|
"nodename_pattern": "Harronode",
|
||||||
"files": [
|
"files": [
|
||||||
@ -4557,6 +4607,26 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Nodes:3D Pose Editor"
|
"description": "Nodes:3D Pose Editor"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "chaojie",
|
||||||
|
"title": "ComfyUI-CameraCtrl-Wrapper",
|
||||||
|
"reference": "https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI-CameraCtrl-Wrapper"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "chaojie",
|
||||||
|
"title": "ComfyUI-EasyAnimate",
|
||||||
|
"reference": "https://github.com/chaojie/ComfyUI-EasyAnimate",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/chaojie/ComfyUI-EasyAnimate"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI-EasyAnimate"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "chaojie",
|
"author": "chaojie",
|
||||||
"title": "ComfyUI_StreamingT2V",
|
"title": "ComfyUI_StreamingT2V",
|
||||||
@ -4787,6 +4857,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "This is an ComfyUI implementation of RAFT to generate motion brush"
|
"description": "This is an ComfyUI implementation of RAFT to generate motion brush"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "chaojie",
|
||||||
|
"title": "ComfyUI-LaVIT",
|
||||||
|
"reference": "https://github.com/chaojie/ComfyUI-LaVIT",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/chaojie/ComfyUI-LaVIT"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:VideoLaVITLoader, VideoLaVITT2V, VideoLaVITI2V, VideoLaVITI2VLong, VideoLaVITT2VLong, VideoLaVITI2I"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "alexopus",
|
"author": "alexopus",
|
||||||
"title": "ComfyUI Image Saver",
|
"title": "ComfyUI Image Saver",
|
||||||
@ -5321,7 +5401,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "Hiero207",
|
"author": "Hiero207",
|
||||||
"title": "ComfyUI-Hiero-Nodes",
|
"title": "Hiero-Nodes",
|
||||||
"reference": "https://github.com/Hiero207/ComfyUI-Hiero-Nodes",
|
"reference": "https://github.com/Hiero207/ComfyUI-Hiero-Nodes",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/Hiero207/ComfyUI-Hiero-Nodes"
|
"https://github.com/Hiero207/ComfyUI-Hiero-Nodes"
|
||||||
@ -5411,7 +5491,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "JerryOrbachJr",
|
"author": "JerryOrbachJr",
|
||||||
"title": "ComfyUI-RandomSize",
|
"title": "Random Size",
|
||||||
"reference": "https://github.com/JerryOrbachJr/ComfyUI-RandomSize",
|
"reference": "https://github.com/JerryOrbachJr/ComfyUI-RandomSize",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/JerryOrbachJr/ComfyUI-RandomSize"
|
"https://github.com/JerryOrbachJr/ComfyUI-RandomSize"
|
||||||
@ -5431,7 +5511,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "mape",
|
"author": "mape",
|
||||||
"title": "mape's ComfyUI Helpers",
|
"title": "mape's helpers",
|
||||||
"reference": "https://github.com/mape/ComfyUI-mape-Helpers",
|
"reference": "https://github.com/mape/ComfyUI-mape-Helpers",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/mape/ComfyUI-mape-Helpers"
|
"https://github.com/mape/ComfyUI-mape-Helpers"
|
||||||
@ -5621,7 +5701,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "dfl",
|
"author": "dfl",
|
||||||
"title": "comfyui-clip-with-break",
|
"title": "CLIP with BREAK syntax",
|
||||||
"reference": "https://github.com/dfl/comfyui-clip-with-break",
|
"reference": "https://github.com/dfl/comfyui-clip-with-break",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/dfl/comfyui-clip-with-break"
|
"https://github.com/dfl/comfyui-clip-with-break"
|
||||||
@ -5639,16 +5719,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "ComfyUI Custom Sampler nodes that implement Zheng et al.'s Trajectory Consistency Distillation based on [a/https://mhh0318.github.io/tcd](https://mhh0318.github.io/tcd)"
|
"description": "ComfyUI Custom Sampler nodes that implement Zheng et al.'s Trajectory Consistency Distillation based on [a/https://mhh0318.github.io/tcd](https://mhh0318.github.io/tcd)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "MarkoCa1",
|
|
||||||
"title": "ComfyUI_Segment_Mask",
|
|
||||||
"reference": "https://github.com/MarkoCa1/ComfyUI_Segment_Mask",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/MarkoCa1/ComfyUI_Segment_Mask"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "Mask cutout based on Segment Anything."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "antrobot",
|
"author": "antrobot",
|
||||||
"title": "antrobots ComfyUI Nodepack",
|
"title": "antrobots ComfyUI Nodepack",
|
||||||
@ -5920,14 +5990,24 @@
|
|||||||
"description": "ComfyUI nodes to use [a/FLATTEN: optical FLow-guided ATTENtion for consistent text-to-video editing](https://github.com/yrcong/flatten)."
|
"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": "logtd",
|
||||||
"title": "ImageTextOverlay Node for ComfyUI",
|
"title": "ComfyUI-RAVE Attention",
|
||||||
"reference": "https://github.com/Big-Idea-Technology/ComfyUI_Image_Text_Overlay",
|
"reference": "https://github.com/logtd/ComfyUI-RAVE_ATTN",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/Big-Idea-Technology/ComfyUI_Image_Text_Overlay"
|
"https://github.com/logtd/ComfyUI-RAVE_ATTN"
|
||||||
],
|
],
|
||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "ImageTextOverlay is a customizable Node for ComfyUI that allows users to easily add text overlays to images within their ComfyUI projects. This Node leverages Python Imaging Library (PIL) and PyTorch to dynamically render text on images, supporting a wide range of customization options including font size, alignment, color, and padding."
|
"description": "ComfyUI nodes to use RAVE attention as a temporal attention mechanism.\nThis differs from other implementations in that it does not concatenate the images together, but within the UNet's Self-Attention mechanism performs the RAVE technique. By not altering the images/latents throughout the UNet, this method does not affect other temporal techniques, style mechanisms, or other UNet modifications.\nFor example, it can be combined with AnimateDiff, ModelScope/ZeroScope, or FLATTEN."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "Big-Idea-Technology",
|
||||||
|
"title": "ComfyUI-Book-Tools Nodes for ComfyUI",
|
||||||
|
"reference": "https://github.com/Big-Idea-Technology/ComfyUI-Book-Tools",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Big-Idea-Technology/ComfyUI-Book-Tools"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI-Book-Tools is a set o new nodes for ComfyUI that allows users to easily add text overlays to images within their ComfyUI projects. This Node leverages Python Imaging Library (PIL) and PyTorch to dynamically render text on images, supporting a wide range of customization options including font size, alignment, color, and padding. Loop with any parameters (*), prompt batch schedule with prompt selector, end queue for automatic ending current queue."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "Big Idea Technology",
|
"author": "Big Idea Technology",
|
||||||
@ -5939,16 +6019,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "The LLM_Node enhances ComfyUI by integrating advanced language model capabilities, enabling a wide range of NLP tasks such as text generation, content summarization, question answering, and more. This flexibility is powered by various transformer model architectures from the transformers library, allowing for the deployment of models like T5, GPT-2, and others based on your project's needs."
|
"description": "The LLM_Node enhances ComfyUI by integrating advanced language model capabilities, enabling a wide range of NLP tasks such as text generation, content summarization, question answering, and more. This flexibility is powered by various transformer model architectures from the transformers library, allowing for the deployment of models like T5, GPT-2, and others based on your project's needs."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "Big Idea Technology",
|
|
||||||
"title": "Image Text Overlay Node for ComfyUI",
|
|
||||||
"reference": "https://github.com/Big-Idea-Technology/ComfyUI_Image_Text_Overlay",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/Big-Idea-Technology/ComfyUI_Image_Text_Overlay"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "ImageTextOverlay is a customizable Node for ComfyUI that allows users to easily add text overlays to images within their ComfyUI projects. This Node leverages Python Imaging Library (PIL) and PyTorch to dynamically render text on images, supporting a wide range of customization options including font size, alignment, color, and padding."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "Guillaume-Fgt",
|
"author": "Guillaume-Fgt",
|
||||||
"title": "ComfyUI-ScenarioPrompt",
|
"title": "ComfyUI-ScenarioPrompt",
|
||||||
@ -5981,7 +6051,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "czcz1024",
|
"author": "czcz1024",
|
||||||
"title": "Comfyui-FaceCompare",
|
"title": "Face Compare",
|
||||||
"reference": "https://github.com/czcz1024/Comfyui-FaceCompare",
|
"reference": "https://github.com/czcz1024/Comfyui-FaceCompare",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/czcz1024/Comfyui-FaceCompare"
|
"https://github.com/czcz1024/Comfyui-FaceCompare"
|
||||||
@ -6399,6 +6469,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "ComfyUI Version of '[a/Visual Style Prompting with Swapping Self-Attention](https://github.com/naver-ai/Visual-Style-Prompting)'"
|
"description": "ComfyUI Version of '[a/Visual Style Prompting with Swapping Self-Attention](https://github.com/naver-ai/Visual-Style-Prompting)'"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "ExponentialML",
|
||||||
|
"title": "ComfyUI_ELLA",
|
||||||
|
"reference": "https://github.com/ExponentialML/ComfyUI_ELLA",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/ExponentialML/ComfyUI_ELLA"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI Implementaion of ELLA: Equip Diffusion Models with LLM for Enhanced Semantic Alignment"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "angeloshredder",
|
"author": "angeloshredder",
|
||||||
"title": "StableCascadeResizer",
|
"title": "StableCascadeResizer",
|
||||||
@ -6489,6 +6569,16 @@
|
|||||||
"install_type": "git-clone",
|
"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."
|
"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": "if-ai",
|
||||||
|
"title": "ComfyUI-IF_AI_WishperSpeechNode",
|
||||||
|
"reference": "https://github.com/if-ai/ComfyUI-IF_AI_WishperSpeechNode",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/if-ai/ComfyUI-IF_AI_WishperSpeechNode"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This repository hosts a Text-to-Speech (TTS) application that leverages Whisper Speech for voice synthesis, allowing users to train a voice model on-the-fly. It is built on ComfyUI and supports rapid training and inference processes."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "dmMaze",
|
"author": "dmMaze",
|
||||||
"title": "Sketch2Manga",
|
"title": "Sketch2Manga",
|
||||||
@ -6549,6 +6639,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Text."
|
"description": "Text."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "MarkoCa1",
|
||||||
|
"title": "ComfyUI_Segment_Mask",
|
||||||
|
"reference": "https://github.com/MarkoCa1/ComfyUI_Segment_Mask",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/MarkoCa1/ComfyUI_Segment_Mask"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Mask cutout based on Segment Anything."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "Shadetail",
|
"author": "Shadetail",
|
||||||
"title": "Eagleshadow Custom Nodes",
|
"title": "Eagleshadow Custom Nodes",
|
||||||
@ -6647,7 +6747,7 @@
|
|||||||
"https://github.com/chaosaiart/Chaosaiart-Nodes"
|
"https://github.com/chaosaiart/Chaosaiart-Nodes"
|
||||||
],
|
],
|
||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "This extension provides various custom nodes to assist in configuring the workflow structure."
|
"description": "LowVRAM Animation : txt2video - img2video - video2video , Frame by Frame, compatible with LowVRAM GPUs\nIncluded : Prompt Switch, Checkpoint Switch, Cache, Number Count by Frame, Ksampler txt2img & img2img ..."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "viperyl",
|
"author": "viperyl",
|
||||||
@ -6691,13 +6791,43 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "hay86",
|
"author": "hay86",
|
||||||
"title": "ComfyUI_AceNodes",
|
"title": "ComfyUI OpenVoice",
|
||||||
|
"reference": "https://github.com/hay86/ComfyUI_OpenVoice",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/hay86/ComfyUI_OpenVoice"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Unofficial implementation of [a/OpenVoice](https://github.com/myshell-ai/OpenVoice) for ComfyUI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "hay86",
|
||||||
|
"title": "ComfyUI DDColor",
|
||||||
|
"reference": "https://github.com/hay86/ComfyUI_DDColor",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/hay86/ComfyUI_DDColor"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Unofficial implementation of [a/DDColor](https://github.com/piddnad/DDColor) for ComfyUI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "hay86",
|
||||||
|
"title": "ComfyUI MiniCPM-V",
|
||||||
|
"reference": "https://github.com/hay86/ComfyUI_MiniCPM-V",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/hay86/ComfyUI_MiniCPM-V"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Unofficial implementation of [a/MiniCPM-V](https://github.com/OpenBMB/MiniCPM-V) for ComfyUI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "hay86",
|
||||||
|
"title": "ComfyUI AceNodes",
|
||||||
"reference": "https://github.com/hay86/ComfyUI_AceNodes",
|
"reference": "https://github.com/hay86/ComfyUI_AceNodes",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/hay86/ComfyUI_AceNodes"
|
"https://github.com/hay86/ComfyUI_AceNodes"
|
||||||
],
|
],
|
||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Nodes:Integer, Float, Text, Seed, Text Concatenate, Text Input Switch (2/4/8 way), Text List, Text Preview, Text Selector, Text To Resolution. Some useful custom nodes that are not included in ComfyUI core yet."
|
"description": "Some useful custom nodes that are not included in ComfyUI core yet."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "shinich39",
|
"author": "shinich39",
|
||||||
@ -6830,7 +6960,7 @@
|
|||||||
"description": "Several utility nodes for use with ComfyUI."
|
"description": "Several utility nodes for use with ComfyUI."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "frankchieng",
|
"author": "FrankChieng",
|
||||||
"title": "ComfyUI_Aniportrait",
|
"title": "ComfyUI_Aniportrait",
|
||||||
"reference": "https://github.com/frankchieng/ComfyUI_Aniportrait",
|
"reference": "https://github.com/frankchieng/ComfyUI_Aniportrait",
|
||||||
"files": [
|
"files": [
|
||||||
@ -6839,6 +6969,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "implementation of [a/AniPortrait](https://github.com/Zejun-Yang/AniPortrait) generating of videos, includes self driven, face reenacment and audio driven with a reference image"
|
"description": "implementation of [a/AniPortrait](https://github.com/Zejun-Yang/AniPortrait) generating of videos, includes self driven, face reenacment and audio driven with a reference image"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "FrankChieng",
|
||||||
|
"title": "ComfyUI_MagicClothing",
|
||||||
|
"reference": "https://github.com/frankchieng/ComfyUI_MagicClothing",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/frankchieng/ComfyUI_MagicClothing"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "implementation of MagicClothing with garment and prompt in ComfyUI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "BlakeOne",
|
"author": "BlakeOne",
|
||||||
"title": "ComfyUI SchedulerMixer",
|
"title": "ComfyUI SchedulerMixer",
|
||||||
@ -6859,6 +6999,26 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Simple node for setting the sigma values directly. Note, for a full denoise the last sigma should be zero."
|
"description": "Simple node for setting the sigma values directly. Note, for a full denoise the last sigma should be zero."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "BlakeOne",
|
||||||
|
"title": "ComfyUI NodePresets",
|
||||||
|
"reference": "https://github.com/BlakeOne/ComfyUI-NodePresets",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/BlakeOne/ComfyUI-NodePresets"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "An extension for ComyUI that enables saving and loading node presets using the node's context menu.\nRight click a node and choose 'Presets' from its context menu to access the node's presets."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "BlakeOne",
|
||||||
|
"title": "ComfyUI NodeReset",
|
||||||
|
"reference": "https://github.com/BlakeOne/ComfyUI-NodeReset",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/BlakeOne/ComfyUI-NodeReset"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "An extension for ComyUI to allow resetting a node's inputs to their default values.\nNOTE:Right click any node and choose 'Reset' from the context menu."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "kale4eat",
|
"author": "kale4eat",
|
||||||
"title": "ComfyUI_demucus",
|
"title": "ComfyUI_demucus",
|
||||||
@ -6889,6 +7049,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Text file utility for ComfyUI"
|
"description": "Text file utility for ComfyUI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "kale4eat",
|
||||||
|
"title": "ComfyUI-speech-dataset-toolkit",
|
||||||
|
"reference": "https://github.com/kale4eat/ComfyUI-speech-dataset-toolkit",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/kale4eat/ComfyUI-speech-dataset-toolkit"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Basic audio tools using torchaudio for ComfyUI. It is assumed to assist in the speech dataset creation for ASR, TTS, etc."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "DrMWeigand",
|
"author": "DrMWeigand",
|
||||||
"title": "ComfyUI Color Detection Nodes",
|
"title": "ComfyUI Color Detection Nodes",
|
||||||
@ -6959,6 +7129,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Attach a debug node to an output to obtain more detailed information. Uncover the details of your models in ComfyUI with ease."
|
"description": "Attach a debug node to an output to obtain more detailed information. Uncover the details of your models in ComfyUI with ease."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "Sida Liu",
|
||||||
|
"title": "ComfyUI-Login",
|
||||||
|
"reference": "https://github.com/liusida/ComfyUI-Login",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/liusida/ComfyUI-Login"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "A simple password to protect ComfyUI."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "jtydhr88",
|
"author": "jtydhr88",
|
||||||
"title": "ComfyUI-Workflow-Encrypt",
|
"title": "ComfyUI-Workflow-Encrypt",
|
||||||
@ -6999,16 +7179,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "This repository simply caches the CLIP embeddings and subtly accelerates the inference process by bypassing unnecessary computations."
|
"description": "This repository simply caches the CLIP embeddings and subtly accelerates the inference process by bypassing unnecessary computations."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "abdozmantar",
|
|
||||||
"title": "InstaSwap Face Swap Node for ComfyUI",
|
|
||||||
"reference": "https://github.com/abdozmantar/ComfyUI-InstaSwap",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/abdozmantar/ComfyUI-InstaSwap"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "Fastest Face Swap Extension Node for ComfyUI, Single node and FastTrack: Lightning-Speed Facial Transformation for your projects."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "AIFSH",
|
"author": "AIFSH",
|
||||||
"title": "ComfyUI-UVR5",
|
"title": "ComfyUI-UVR5",
|
||||||
@ -7020,14 +7190,54 @@
|
|||||||
"description": "the custom code for [a/UVR5](https://github.com/Anjok07/ultimatevocalremovergui) to separate vocals and background music"
|
"description": "the custom code for [a/UVR5](https://github.com/Anjok07/ultimatevocalremovergui) to separate vocals and background music"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "CapsAdmin",
|
"author": "AIFSH",
|
||||||
"title": "ComfyUI-Euler-Smea-Dyn-Sampler",
|
"title": "ComfyUI-IP_LAP",
|
||||||
"reference": "https://github.com/CapsAdmin/ComfyUI-Euler-Smea-Dyn-Sampler",
|
"reference": "https://github.com/AIFSH/ComfyUI-IP_LAP",
|
||||||
"files": [
|
"files": [
|
||||||
"https://github.com/CapsAdmin/ComfyUI-Euler-Smea-Dyn-Sampler"
|
"https://github.com/AIFSH/ComfyUI-IP_LAP"
|
||||||
],
|
],
|
||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Just a comfyui version of [a/Euler Smea Dyn Sampler](https://github.com/Koishi-Star/Euler-Smea-Dyn-Sampler). It adds the sampler directly to existing samplers."
|
"description": "Nodes:IP_LAP Node, Video Loader, PreView Video, Combine Audio Video. the comfyui custom node of [a/IP_LAP](https://github.com/Weizhi-Zhong/IP_LAP) to make audio driven videos!"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "AIFSH",
|
||||||
|
"title": "ComfyUI-GPT_SoVITS",
|
||||||
|
"reference": "https://github.com/AIFSH/ComfyUI-GPT_SoVITS",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/AIFSH/ComfyUI-GPT_SoVITS"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "a comfyui custom node for [a/GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)! you can voice cloning and tts in comfyui now\n[w/NOTE:make sure ffmpeg is worked in your commandline]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "AIFSH",
|
||||||
|
"title": "ComfyUI-MuseTalk_FSH",
|
||||||
|
"reference": "https://github.com/AIFSH/ComfyUI-MuseTalk_FSH",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/AIFSH/ComfyUI-MuseTalk_FSH"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "the comfyui custom node of [a/MuseTalk](https://github.com/TMElyralab/MuseTalk) to make audio driven videos!"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "AIFSH",
|
||||||
|
"title": "ComfyUI-WhisperX",
|
||||||
|
"reference": "https://github.com/AIFSH/ComfyUI-WhisperX",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/AIFSH/ComfyUI-WhisperX"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "a comfyui cuatom node for audio subtitling based on [a/whisperX](https://github.com/m-bain/whisperX.git) and [a/translators](https://github.com/UlionTse/translators)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "Koishi-Star",
|
||||||
|
"title": "Euler-Smea-Dyn-Sampler",
|
||||||
|
"reference": "https://github.com/Koishi-Star/Euler-Smea-Dyn-Sampler",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Koishi-Star/Euler-Smea-Dyn-Sampler"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "СomfyUI version of [a/Euler Smea Dyn Sampler](https://github.com/Koishi-Star/Euler-Smea-Dyn-Sampler). It adds samplers directly to KSampler nodes."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"author": "sdfxai",
|
"author": "sdfxai",
|
||||||
@ -7039,7 +7249,376 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "SDFXBridgeForComfyUI is a custom node designed for seamless integration between ComfyUI and SDFX. This custom node allows users to make ComfyUI compatible with SDFX when running the ComfyUI instance on their local machines."
|
"description": "SDFXBridgeForComfyUI is a custom node designed for seamless integration between ComfyUI and SDFX. This custom node allows users to make ComfyUI compatible with SDFX when running the ComfyUI instance on their local machines."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "smthemex",
|
||||||
|
"title": "ComfyUI_ChatGLM_API",
|
||||||
|
"reference": "https://github.com/smthemex/ComfyUI_ChatGLM_API",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/smthemex/ComfyUI_ChatGLM_API"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "You can call Chatglm's API in comfyUI to translate and describe pictures, and the API similar to OpenAI."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "smthemex",
|
||||||
|
"title": "ComfyUI_ParlerTTS",
|
||||||
|
"reference": "https://github.com/smthemex/ComfyUI_ParlerTTS",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/smthemex/ComfyUI_ParlerTTS"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This is a simple ComfyUI custom TTS node based on [a/Parler_tts](https://huggingface.co/parler-tts)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "smthemex",
|
||||||
|
"title": "ComfyUI_Pic2Story",
|
||||||
|
"reference": "https://github.com/smthemex/ComfyUI_Pic2Story",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/smthemex/ComfyUI_Pic2Story"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI simple node based on BLIP method, with the function of 'Image to Txt'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "smthemex",
|
||||||
|
"title": "ComfyUI_Pic2Story",
|
||||||
|
"reference": "https://github.com/smthemex/ComfyUI_Pic2Story",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/smthemex/ComfyUI_Pic2Story"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI simple node based on BLIP method, with the function of 'Image to Txt'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "smthemex",
|
||||||
|
"title": "ComfyUI_Pipeline_Tool",
|
||||||
|
"reference": "https://github.com/smthemex/ComfyUI_Pipeline_Tool",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/smthemex/ComfyUI_Pipeline_Tool"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Pipeline_Tool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "choey",
|
||||||
|
"title": "Comfy-Topaz",
|
||||||
|
"reference": "https://github.com/choey/Comfy-Topaz",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/choey/Comfy-Topaz"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Comfy-Topaz is a custom node for ComfyUI, which integrates with Topaz Photo AI to enhance (upscale, sharpen, denoise, etc.) images, allowing this traditionally asynchronous step to become a part of ComfyUI workflows.\nNOTE:Licensed installation of Topaz Photo AI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "ALatentPlace",
|
||||||
|
"title": "ComfyUI_yanc",
|
||||||
|
"reference": "https://github.com/ALatentPlace/ComfyUI_yanc",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/ALatentPlace/ComfyUI_yanc"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Yet Another Node Collection. Adds some useful nodes, check out the GitHub page for more details."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "Wicloz",
|
||||||
|
"title": "ComfyUI-Simply-Nodes",
|
||||||
|
"reference": "https://github.com/Wicloz/ComfyUI-Simply-Nodes",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Wicloz/ComfyUI-Simply-Nodes"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Conditional LoRA Loader, Multiline Text, Text Flow Controller, Select SDXL Resolution, Random Style Prompt."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "wandbrandon",
|
||||||
|
"title": "comfyui-pixel",
|
||||||
|
"reference": "https://github.com/wandbrandon/comfyui-pixel",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/wandbrandon/comfyui-pixel"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "pixel art workshop nodes for comfyui."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "nullquant",
|
||||||
|
"title": "BrushNet",
|
||||||
|
"reference": "https://github.com/nullquant/ComfyUI-BrushNet",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/nullquant/ComfyUI-BrushNet"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Custom nodes for ComfyUI allow to inpaint using Brushnet: '[a/BrushNet: A Plug-and-Play Image Inpainting Model with Decomposed Dual-Branch Diffusion](https://arxiv.org/abs/2403.06976)'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "pamparamm",
|
||||||
|
"title": "Perturbed-Attention Guidance",
|
||||||
|
"reference": "https://github.com/pamparamm/sd-perturbed-attention",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/pamparamm/sd-perturbed-attention"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Perturbed-Attention Guidance node for ComfyUI."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "unwdef",
|
||||||
|
"title": "unwdef-nodes",
|
||||||
|
"reference": "https://github.com/unwdef/unwdef-nodes-comfyui",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/unwdef/unwdef-nodes-comfyui"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Custom nodes for ComfyUI by unwdef."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "fevre27",
|
||||||
|
"title": "Self-Guidance nodes",
|
||||||
|
"reference": "https://github.com/forever22777/comfyui-self-guidance",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/forever22777/comfyui-self-guidance"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Unofficial ComfyUI implementation of Self-Guidance."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "aburahamu",
|
||||||
|
"title": "ComfyUI-RequestsPoster",
|
||||||
|
"reference": "https://github.com/aburahamu/ComfyUI-RequestsPoster",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/aburahamu/ComfyUI-RequestsPoster"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This custom node is that simply posts HttpRequest from ComfyUI."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "Sorcerio",
|
||||||
|
"title": "MBM's Music Visualizer",
|
||||||
|
"reference": "https://github.com/Sorcerio/MBM-Music-Visualizer",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Sorcerio/MBM-Music-Visualizer"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "An image generation based music visualizer integrated into comfyanonymous/ComfyUI as custom nodes."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "quadmoon",
|
||||||
|
"title": "quadmoon's ComfyUI nodes",
|
||||||
|
"reference": "https://github.com/traugdor/ComfyUI-quadMoons-nodes",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/traugdor/ComfyUI-quadMoons-nodes"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "These are just some nodes I wanted and couldn't find where anyone else had made them yet."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "quadme7macoon",
|
||||||
|
"title": "ComfyUI-ShadertoyGL",
|
||||||
|
"reference": "https://github.com/e7mac/ComfyUI-ShadertoyGL",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/e7mac/ComfyUI-ShadertoyGL"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Shadertoy, Shader, ColorChannelOffset."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "turkyden",
|
||||||
|
"title": "ComfyUI-Sticker",
|
||||||
|
"reference": "https://github.com/turkyden/ComfyUI-Sticker",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/turkyden/ComfyUI-Sticker"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "image to sticker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "turkyden",
|
||||||
|
"title": "ComfyUI-Comic",
|
||||||
|
"reference": "https://github.com/turkyden/ComfyUI-Comic",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/turkyden/ComfyUI-Comic"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "a comfyui plugin for image to comic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "royceschultz",
|
||||||
|
"title": "ComfyUI-TranscriptionTools",
|
||||||
|
"reference": "https://github.com/royceschultz/ComfyUI-TranscriptionTools",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/royceschultz/ComfyUI-TranscriptionTools"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Transcribe audio and video files in ComfyUI."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "kunieone",
|
||||||
|
"title": "ComfyUI_alkaid",
|
||||||
|
"reference": "https://github.com/kunieone/ComfyUI_alkaid",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/kunieone/ComfyUI_alkaid"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:A_Face3DSwapper, A_FaceCrop, A_FacePaste, A_OpenPosePreprocessor, A_EmptyLatentImageLongside, A_GetImageSize, AlkaidLoader, AdapterFaceLoader, AdapterStyleLoader, ..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "jtydhr88",
|
||||||
|
"title": "ComfyUI-InstantMesh",
|
||||||
|
"reference": "https://github.com/jtydhr88/ComfyUI-InstantMesh",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/jtydhr88/ComfyUI-InstantMesh"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI InstantMesh is custom nodes that running TencentARC/InstantMesh into ComfyUI, this extension depends on ComfyUI-3D-Pack. Please refer to Readme carefully to install."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "txt2any",
|
||||||
|
"title": "ComfyUI-PromptOrganizer",
|
||||||
|
"reference": "https://github.com/txt2any/ComfyUI-PromptOrganizer",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/txt2any/ComfyUI-PromptOrganizer"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This is a custom node for ComfyUI that automatically saves your AI-generated images specifically to [a/www.txt2any.com](http://www.txt2any.com/)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "kealiu",
|
||||||
|
"title": "ComfyUI Load and Save file to S3",
|
||||||
|
"reference": "https://github.com/kealiu/ComfyUI-S3-Tools",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/kealiu/ComfyUI-S3-Tools"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Load From S3, Save To S3."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "TashaSkyUp",
|
||||||
|
"title": "ComfyUI_LiteLLM",
|
||||||
|
"reference": "https://github.com/Hopping-Mad-Games/ComfyUI_LiteLLM",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Hopping-Mad-Games/ComfyUI_LiteLLM"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes for interfacing with LiteLLM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "AonekoSS",
|
||||||
|
"title": "ComfyUI-SimpleCounter",
|
||||||
|
"reference": "https://github.com/AonekoSS/ComfyUI-SimpleCounter",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/AonekoSS/ComfyUI-SimpleCounter"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Simple Counter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "heshengtao",
|
||||||
|
"title": "comfyui_LLM_party",
|
||||||
|
"reference": "https://github.com/heshengtao/comfyui_LLM_party",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/heshengtao/comfyui_LLM_party"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "A set of block-based LLM agent node libraries designed for ComfyUI.This project aims to develop a complete set of nodes for LLM workflow construction based on comfyui. It allows users to quickly and conveniently build their own LLM workflows and easily integrate them into their existing SD workflows."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "VAST-AI-Research",
|
||||||
|
"title": "Tripo for ComfyUI",
|
||||||
|
"reference": "https://github.com/VAST-AI-Research/ComfyUI-Tripo",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/VAST-AI-Research/ComfyUI-Tripo"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Custom nodes for using [a/Tripo](https://www.tripo3d.ai/) in ComfyUI to create 3D from text and image prompts."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "JettHu",
|
||||||
|
"title": "ComfyUI_TGate",
|
||||||
|
"reference": "https://github.com/JettHu/ComfyUI_TGate",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/JettHu/ComfyUI_TGate"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI reference implementation for [a/T-GATE](https://github.com/HaozheLiu-ST/T-GATE)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "sugarkwork",
|
||||||
|
"title": "comfyui_tag_filter",
|
||||||
|
"reference": "https://github.com/sugarkwork/comfyui_tag_fillter",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/sugarkwork/comfyui_tag_fillter"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This is a custom node of ComfyUI that categorizes tags outputted by tools like WD14Tagger, filters them by each category, and returns the filtered results."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "Intersection98",
|
||||||
|
"title": "ComfyUI-MX-post-processing-nodes",
|
||||||
|
"reference": "https://github.com/Intersection98/ComfyUI_MX_post_processing-nodes",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Intersection98/ComfyUI_MX_post_processing-nodes"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "A collection of post processing nodes for ComfyUI, dds image post-processing adjustment capabilities to the ComfyUI."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "TencentQQGYLab",
|
||||||
|
"title": "ComfyUI-ELLA",
|
||||||
|
"reference": "https://github.com/TencentQQGYLab/ComfyUI-ELLA",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/TencentQQGYLab/ComfyUI-ELLA"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "ComfyUI implementation for [a/ELLA](https://github.com/TencentQQGYLab/ELLA)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "DarKDinDoN",
|
||||||
|
"title": "ComfyUI Checkpoint Automatic Config",
|
||||||
|
"reference": "https://github.com/DarKDinDoN/comfyui-checkpoint-automatic-config",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/DarKDinDoN/comfyui-checkpoint-automatic-config"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This node was designed to help with checkpoint configuration."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "aburahamu",
|
||||||
|
"title": "ComfyUI-RequestPoster",
|
||||||
|
"reference": "https://github.com/aburahamu/ComfyUI-RequestsPoster",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/aburahamu/ComfyUI-RequestsPoster"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This extension can send HTTP Requests. You can request image generation to StableDiffusion3 and post images to X (Twitter) and Discord."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "MinusZoneAI",
|
||||||
|
"title": "ComfyUI-Prompt-MZ",
|
||||||
|
"reference": "https://github.com/MinusZoneAI/ComfyUI-Prompt-MZ",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/MinusZoneAI/ComfyUI-Prompt-MZ"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Use llama.cpp to help generate some nodes for prompt word related work"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "blueraincoatli",
|
||||||
|
"title": "comfyUI_SillyNodes",
|
||||||
|
"reference": "https://github.com/blueraincoatli/comfyUI_SillyNodes",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/blueraincoatli/comfyUI_SillyNodes"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Using rgthree's fast_group_muter and bookmark nodes, introduce the pyautogui library to simulate clicks and hotkeys, and run groups in sequence. screen manipulation is involved"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "ty0x2333",
|
||||||
|
"title": "ComfyUI-Dev-Utils",
|
||||||
|
"reference": "https://github.com/ty0x2333/ComfyUI-Dev-Utils",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/ty0x2333/ComfyUI-Dev-Utils"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Execution Time Analysis, Reroute Enhancement, Node collection for developers."
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -7353,6 +7932,18 @@
|
|||||||
"install_type": "copy",
|
"install_type": "copy",
|
||||||
"description": "Extension to show random cat GIFs while queueing prompt."
|
"description": "Extension to show random cat GIFs while queueing prompt."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "xliry",
|
||||||
|
"title": "ComfyUI_SendDiscord",
|
||||||
|
"reference": "https://github.com/xliry/ComfyUI_SendDiscord",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/xliry/ComfyUI_SendDiscord/raw/main/SendDiscord.py"
|
||||||
|
],
|
||||||
|
"install_type": "copy",
|
||||||
|
"description": "Nodes:Send Video to Discord"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"author": "theally",
|
"author": "theally",
|
||||||
"title": "TheAlly's Custom Nodes",
|
"title": "TheAlly's Custom Nodes",
|
||||||
|
|||||||
140
docs/en/cm-cli.md
Normal file
140
docs/en/cm-cli.md
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
# `cm-cli`: ComfyUI-Manager CLI
|
||||||
|
|
||||||
|
`cm-cli` is a tool that allows you to use various functions of ComfyUI-Manager from the command line without launching ComfyUI.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
-= ComfyUI-Manager CLI (V2.22) =-
|
||||||
|
|
||||||
|
python cm-cli.py [OPTIONS]
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
[install|reinstall|uninstall|update|disable|enable|fix] node_name ... ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||||
|
[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||||
|
[simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||||
|
save-snapshot
|
||||||
|
restore-snapshot <snapshot>
|
||||||
|
cli-only-mode [enable|disable]
|
||||||
|
restore-dependencies
|
||||||
|
clear
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## How To Use?
|
||||||
|
* You can execute it via `python cm-cli.py`.
|
||||||
|
* For example, if you want to update all custom nodes:
|
||||||
|
* In the ComfyUI-Manager directory, you can execute the command `python cm-cli.py update all`.
|
||||||
|
* If running from the ComfyUI directory, you can specify the path to cm-cli.py like this: `python custom_nodes/ComfyUI-Manager/cm-cli.py update all`.
|
||||||
|
|
||||||
|
## Prerequisite
|
||||||
|
* It must be run in the same Python environment as the one running ComfyUI.
|
||||||
|
* If using a venv, you must run it with the venv activated.
|
||||||
|
* If using a portable version, and you are in the directory with the run_nvidia_gpu.bat file, you should execute the command as follows:
|
||||||
|
`.\python_embeded\python.exe ComfyUI\custom_nodes\ComfyUI-Manager\cm-cli.py update all`
|
||||||
|
* The path for ComfyUI can be set with the COMFYUI_PATH environment variable. If omitted, a warning message will appear, and the path will be set relative to the installed location of ComfyUI-Manager:
|
||||||
|
```
|
||||||
|
WARN: The `COMFYUI_PATH` environment variable is not set. Assuming `custom_nodes/ComfyUI-Manager/../../` as the ComfyUI path.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### 1. --channel, --mode
|
||||||
|
* For viewing information and managing custom nodes, you can set the information database through --channel and --mode.
|
||||||
|
* For instance, executing the command `python cm-cli.py update all --channel recent --mode remote` will operate based on the latest information from remote rather than local data embedded in the current ComfyUI-Manager repo and will only target the list in the recent channel.
|
||||||
|
* --channel, --mode are only available with the commands `simple-show, show, install, uninstall, update, disable, enable, fix`.
|
||||||
|
|
||||||
|
### 2. Viewing Management Information
|
||||||
|
|
||||||
|
`[simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||||
|
|
||||||
|
* `[show|simple-show]` - `show` provides detailed information, while `simple-show` displays information more simply.
|
||||||
|
|
||||||
|
Executing a command like `python cm-cli.py show installed` will display detailed information about the installed custom nodes.
|
||||||
|
|
||||||
|
```
|
||||||
|
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||||
|
|
||||||
|
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||||
|
[ ENABLED ] ComfyUI-Manager (author: Dr.Lt.Data)
|
||||||
|
[ ENABLED ] ComfyUI-Impact-Pack (author: Dr.Lt.Data)
|
||||||
|
[ ENABLED ] ComfyUI-Inspire-Pack (author: Dr.Lt.Data)
|
||||||
|
[ ENABLED ] ComfyUI_experiments (author: comfyanonymous)
|
||||||
|
[ ENABLED ] ComfyUI-SAI_API (author: Stability-AI)
|
||||||
|
[ ENABLED ] stability-ComfyUI-nodes (author: Stability-AI)
|
||||||
|
[ ENABLED ] comfyui_controlnet_aux (author: Fannovel16)
|
||||||
|
[ ENABLED ] ComfyUI-Frame-Interpolation (author: Fannovel16)
|
||||||
|
[ DISABLED ] ComfyUI-Loopchain (author: Fannovel16)
|
||||||
|
```
|
||||||
|
|
||||||
|
Using a command like `python cm-cli.py simple-show installed` will simply display information about the installed custom nodes.
|
||||||
|
|
||||||
|
```
|
||||||
|
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||||
|
|
||||||
|
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||||
|
ComfyUI-Manager
|
||||||
|
ComfyUI-Impact-Pack
|
||||||
|
ComfyUI-Inspire-Pack
|
||||||
|
ComfyUI_experiments
|
||||||
|
ComfyUI-SAI_API
|
||||||
|
stability-ComfyUI-nodes
|
||||||
|
comfyui_controlnet_aux
|
||||||
|
ComfyUI-Frame-Interpolation
|
||||||
|
ComfyUI-Loopchain
|
||||||
|
```
|
||||||
|
|
||||||
|
`[installed|enabled|not-installed|disabled|all|snapshot|snapshot-list]`
|
||||||
|
* `enabled`, `disabled`: Shows nodes that have been enabled or disabled among the installed custom nodes.
|
||||||
|
* `installed`: Shows all nodes that have been installed, regardless of whether they are enabled or disabled.
|
||||||
|
* `not-installed`: Shows a list of custom nodes that have not been installed.
|
||||||
|
* `all`: Shows a list of all custom nodes.
|
||||||
|
* `snapshot`: Displays snapshot information of the currently installed custom nodes. When viewed with `show`, it is displayed in JSON format, and with `simple-show`, it is displayed simply, along with the commit hash.
|
||||||
|
* `snapshot-list`: Shows a list of snapshot files stored in ComfyUI-Manager/snapshots.
|
||||||
|
|
||||||
|
### 3. Managing Custom Nodes
|
||||||
|
|
||||||
|
`[install|reinstall|uninstall|update|disable|enable|fix] node_name ... ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||||
|
|
||||||
|
* You can apply management functions by listing the names of custom nodes, such as `python cm-cli.py install ComfyUI-Impact-Pack ComfyUI-Inspire-Pack ComfyUI_experiments`.
|
||||||
|
* The names of the custom nodes are as shown by `show` and are the names of the git repositories.
|
||||||
|
(Plans are to update the use of nicknames in the future.)
|
||||||
|
|
||||||
|
`[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||||
|
|
||||||
|
* The `update, disable, enable, fix` functions can be specified for all.
|
||||||
|
|
||||||
|
* Detailed Operations
|
||||||
|
* `install`: Installs the specified custom nodes.
|
||||||
|
* `reinstall`: Removes and then reinstalls the specified custom nodes.
|
||||||
|
* `uninstall`: Uninstalls the specified custom nodes.
|
||||||
|
* `update`: Updates the specified custom nodes.
|
||||||
|
* `disable`: Disables the specified custom nodes.
|
||||||
|
* `enable`: Enables the specified custom nodes.
|
||||||
|
* `fix`: Attempts to fix dependencies for the specified custom nodes.
|
||||||
|
|
||||||
|
### 4. Snapshot Management
|
||||||
|
* `python cm-cli.py save-snapshot`: Saves the current snapshot.
|
||||||
|
* `python cm-cli.py restore-snapshot <snapshot>`: Restores to the specified snapshot.
|
||||||
|
* It is assumed that the snapshot files are located in ComfyUI-Manager/snapshots.
|
||||||
|
(An update is planned to allow files from other paths in the future.)
|
||||||
|
|
||||||
|
### 5. CLI Only Mode
|
||||||
|
|
||||||
|
You can set whether to use ComfyUI-Manager solely via CLI.
|
||||||
|
|
||||||
|
`cli-only-mode [enable|disable]`
|
||||||
|
|
||||||
|
* This mode can be used if you want to restrict the use of ComfyUI-Manager through the GUI for security or policy reasons.
|
||||||
|
* When CLI only mode is enabled, ComfyUI-Manager is loaded in a very restricted state, the internal web API is disabled, and the Manager button is not displayed in the main menu.
|
||||||
|
|
||||||
|
### 6. Dependency Restoration
|
||||||
|
|
||||||
|
`restore-dependencies`
|
||||||
|
|
||||||
|
* This command can be used if custom nodes are installed under the `ComfyUI/custom_nodes` path but their dependencies are not installed.
|
||||||
|
* It is useful when starting a new cloud instance, like colab, where dependencies need to be reinstalled and installation scripts re-executed.
|
||||||
|
* It can also be utilized if ComfyUI is reinstalled and only the custom_nodes path has been backed up and restored.
|
||||||
|
|
||||||
|
### 7. Clear
|
||||||
|
|
||||||
|
In the GUI, installations, updates, or snapshot restorations are scheduled to execute the next time ComfyUI is launched. The `clear` command clears this scheduled state, ensuring no pre-execution actions are applied.
|
||||||
145
docs/ko/cm-cli.md
Normal file
145
docs/ko/cm-cli.md
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# `cm-cli`: ComfyUI-Manager CLI
|
||||||
|
|
||||||
|
`cm-cli` 는 ComfyUI를 실행시키지 않고 command line에서 ComfyUI-Manager의 여러가지 기능을 사용할 수 있도록 도와주는 도구입니다.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||||
|
|
||||||
|
python cm-cli.py [OPTIONS]
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
[install|reinstall|uninstall|update|disable|enable|fix] node_name ... ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||||
|
[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||||
|
[simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||||
|
save-snapshot
|
||||||
|
restore-snapshot <snapshot>
|
||||||
|
cli-only-mode [enable|disable]
|
||||||
|
restore-dependencies
|
||||||
|
clear
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## How To Use?
|
||||||
|
* `python cm-cli.py` 를 통해서 실행 시킬 수 있습니다.
|
||||||
|
* 예를 들어 custom node를 모두 업데이트 하고 싶다면
|
||||||
|
* ComfyUI-Manager경로 에서 `python cm-cli.py update all` 를 command를 실행할 수 있습니다.
|
||||||
|
* ComfyUI 경로에서 실행한다면, `python custom_nodes/ComfyUI-Manager/cm-cli.py update all` 와 같이 cm-cli.py 의 경로를 지정할 수도 있습니다.
|
||||||
|
|
||||||
|
## Prerequisite
|
||||||
|
* ComfyUI 를 실행하는 python과 동일한 python 환경에서 실행해야 합니다.
|
||||||
|
* venv를 사용할 경우 해당 venv를 activate 한 상태에서 실행해야 합니다.
|
||||||
|
* portable 버전을 사용할 경우 run_nvidia_gpu.bat 파일이 있는 경로인 경우, 다음과 같은 방식으로 코맨드를 실행해야 합니다.
|
||||||
|
`.\python_embeded\python.exe ComfyUI\custom_nodes\ComfyUI-Manager\cm-cli.py update all`
|
||||||
|
* ComfyUI 의 경로는 COMFYUI_PATH 환경 변수로 설정할 수 있습니다. 만약 생략할 경우 다음과 같은 경고 메시지가 나타나며, ComfyUI-Manager가 설치된 경로를 기준으로 상대 경로로 설정됩니다.
|
||||||
|
```
|
||||||
|
WARN: The `COMFYUI_PATH` environment variable is not set. Assuming `custom_nodes/ComfyUI-Manager/../../` as the ComfyUI path.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### 1. --channel, --mode
|
||||||
|
* 정보 보기 기능과 커스텀 노드 관리 기능의 경우는 --channel과 --mode를 통해 정보 DB를 설정할 수 있습니다.
|
||||||
|
* 예들 들어 `python cm-cli.py update all --channel recent --mode remote`와 같은 command를 실행할 경우, 현재 ComfyUI-Manager repo에 내장된 로컬의 정보가 아닌 remote의 최신 정보를 기준으로 동작하며, recent channel에 있는 목록을 대상으로만 동작합니다.
|
||||||
|
* --channel, --mode 는 `simple-show, show, install, uninstall, update, disable, enable, fix` command에서만 사용 가능합니다.
|
||||||
|
|
||||||
|
### 2. 관리 정보 보기
|
||||||
|
|
||||||
|
`[simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||||
|
|
||||||
|
|
||||||
|
* `[show|simple-show]` - `show`는 상세하게 정보를 보여주며, `simple-show`는 간단하게 정보를 보여줍니다.
|
||||||
|
|
||||||
|
|
||||||
|
`python cm-cli.py show installed` 와 같은 코맨드를 실행하면 설치된 커스텀 노드의 정보를 상세하게 보여줍니다.
|
||||||
|
```
|
||||||
|
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||||
|
|
||||||
|
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||||
|
[ ENABLED ] ComfyUI-Manager (author: Dr.Lt.Data)
|
||||||
|
[ ENABLED ] ComfyUI-Impact-Pack (author: Dr.Lt.Data)
|
||||||
|
[ ENABLED ] ComfyUI-Inspire-Pack (author: Dr.Lt.Data)
|
||||||
|
[ ENABLED ] ComfyUI_experiments (author: comfyanonymous)
|
||||||
|
[ ENABLED ] ComfyUI-SAI_API (author: Stability-AI)
|
||||||
|
[ ENABLED ] stability-ComfyUI-nodes (author: Stability-AI)
|
||||||
|
[ ENABLED ] comfyui_controlnet_aux (author: Fannovel16)
|
||||||
|
[ ENABLED ] ComfyUI-Frame-Interpolation (author: Fannovel16)
|
||||||
|
[ DISABLED ] ComfyUI-Loopchain (author: Fannovel16)
|
||||||
|
```
|
||||||
|
|
||||||
|
`python cm-cli.py simple-show installed` 와 같은 코맨드를 이용해서 설치된 커스텀 노드의 정보를 간단하게 보여줍니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||||
|
|
||||||
|
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||||
|
ComfyUI-Manager
|
||||||
|
ComfyUI-Impact-Pack
|
||||||
|
ComfyUI-Inspire-Pack
|
||||||
|
ComfyUI_experiments
|
||||||
|
ComfyUI-SAI_API
|
||||||
|
stability-ComfyUI-nodes
|
||||||
|
comfyui_controlnet_aux
|
||||||
|
ComfyUI-Frame-Interpolation
|
||||||
|
ComfyUI-Loopchain
|
||||||
|
```
|
||||||
|
|
||||||
|
* `[installed|enabled|not-installed|disabled|all|snapshot|snapshot-list]`
|
||||||
|
* `enabled`, `disabled`: 설치된 커스텀 노드들 중 enable 되었거나, disable된 노드들을 보여줍니다.
|
||||||
|
* `installed`: enable, disable 여부와 상관없이 설치된 모든 노드를 보여줍니다
|
||||||
|
* `not-installed`: 설치되지 않은 커스텀 노드의 목록을 보여줍니다.
|
||||||
|
* `all`: 모든 커스텀 노드의 목록을 보여줍니다.
|
||||||
|
* `snapshot`: 현재 설치된 커스텀 노드의 snapshot 정보를 보여줍니다. `show`롤 통해서 볼 경우는 json 출력 형태로 보여주며, `simple-show`를 통해서 볼 경우는 간단하게, 커밋 해시와 함께 보여줍니다.
|
||||||
|
* `snapshot-list`: ComfyUI-Manager/snapshots 에 저장된 snapshot 파일의 목록을 보여줍니다.
|
||||||
|
|
||||||
|
### 3. 커스텀 노드 관리 하기
|
||||||
|
|
||||||
|
`[install|reinstall|uninstall|update|disable|enable|fix] node_name ... ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||||
|
|
||||||
|
* `python cm-cli.py install ComfyUI-Impact-Pack ComfyUI-Inspire-Pack ComfyUI_experiments` 와 같이 커스텀 노드의 이름을 나열해서 관리 기능을 적용할 수 있습니다.
|
||||||
|
* 커스텀 노드의 이름은 `show`를 했을 때 보여주는 이름이며, git repository의 이름입니다.
|
||||||
|
(추후 nickname 을 사용가능하돌고 업데이트 할 예정입니다.)
|
||||||
|
|
||||||
|
`[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||||
|
|
||||||
|
* `update, disable, enable, fix` 기능은 all 로 지정 가능합니다.
|
||||||
|
|
||||||
|
* 세부 동작
|
||||||
|
* `install`: 지정된 커스텀 노드들을 설치합니다
|
||||||
|
* `reinstall`: 지정된 커스텀 노드를 삭제하고 재설치 합니다.
|
||||||
|
* `uninstall`: 지정된 커스텀 노드들을 삭제합니다.
|
||||||
|
* `update`: 지정된 커스텀 노드들을 업데이트합니다.
|
||||||
|
* `disable`: 지정된 커스텀 노드들을 비활성화합니다.
|
||||||
|
* `enable`: 지정된 커스텀 노드들을 활성화합니다.
|
||||||
|
* `fix`: 지정된 커스텀 노드의 의존성을 고치기 위한 시도를 합니다.
|
||||||
|
|
||||||
|
|
||||||
|
### 4. 스냅샷 관리 기능
|
||||||
|
* `python cm-cli.py save-snapshot`: 현재의 snapshot을 저장합니다.
|
||||||
|
* `python cm-cli.py restore-snapshot <snapshot>`: 지정된 snapshot으로 복구합니다.
|
||||||
|
* snapshot 파일은 ComfyUI-Manager/snapshots 에 있다고 가정합니다.
|
||||||
|
(추후 다른 경로에 있는 파일을 허용 가능하도록 업데이트 예정입니다.)
|
||||||
|
|
||||||
|
|
||||||
|
### 5. CLI only mode
|
||||||
|
|
||||||
|
ComfyUI-Manager를 CLI로만 사용할 것인지를 설정할 수 있습니다.
|
||||||
|
|
||||||
|
`cli-only-mode [enable|disable]`
|
||||||
|
|
||||||
|
* security 혹은 policy 의 이유로 GUI 를 통한 ComfyUI-Manager 사용을 제한하고 싶은 경우 이 모드를 사용할 수 있습니다.
|
||||||
|
* CLI only mode를 적용할 경우 ComfyUI-Manager 가 매우 제한된 상태로 로드되어, 내부적으로 제공하는 web API가 비활성화 되며, 메인 메뉴에서도 Manager 버튼이 표시되지 않습니다.
|
||||||
|
|
||||||
|
|
||||||
|
### 6. 의존성 설치
|
||||||
|
|
||||||
|
`restore-dependencies`
|
||||||
|
|
||||||
|
* `ComfyUI/custom_nodes` 하위 경로에 커스텀 노드들이 설치되어 있긴 하지만, 의존성이 설치되지 않은 경우 사용할 수 있습니다.
|
||||||
|
* colab 과 같이 cloud instance를 새로 시작하는 경우 의존성 재설치 및 설치 스크립트가 재실행 되어야 하는 경우 사용합니다.
|
||||||
|
* ComfyUI을 재설치할 경우, custom_nodes 경로만 백업했다가 재설치 할 경우 활용 가능합니다.
|
||||||
|
|
||||||
|
|
||||||
|
### 7. clear
|
||||||
|
|
||||||
|
GUI에서 install, update를 하거나 snapshot 을 restore하는 경우 예약을 통해서 다음번 ComfyUI를 실행할 경우 실행되는 구조입니다. `clear` 는 이런 예약 상태를 clear해서, 아무런 사전 실행이 적용되지 않도록 합니다.
|
||||||
File diff suppressed because it is too large
Load Diff
@ -176,6 +176,14 @@ def checkout_custom_node_hash(git_custom_node_infos):
|
|||||||
if repo_name.endswith('.disabled'):
|
if repo_name.endswith('.disabled'):
|
||||||
repo_name = repo_name[:-9]
|
repo_name = repo_name[:-9]
|
||||||
|
|
||||||
|
if repo_name not in repo_name_to_url:
|
||||||
|
if not is_disabled:
|
||||||
|
# should be disabled
|
||||||
|
print(f"DISABLE: {repo_name}")
|
||||||
|
new_path = fullpath + ".disabled"
|
||||||
|
os.rename(fullpath, new_path)
|
||||||
|
need_checkout = False
|
||||||
|
else:
|
||||||
item = git_custom_node_infos[repo_name_to_url[repo_name]]
|
item = git_custom_node_infos[repo_name_to_url[repo_name]]
|
||||||
if item['disabled'] and is_disabled:
|
if item['disabled'] and is_disabled:
|
||||||
pass
|
pass
|
||||||
@ -184,7 +192,7 @@ def checkout_custom_node_hash(git_custom_node_infos):
|
|||||||
print(f"DISABLE: {repo_name}")
|
print(f"DISABLE: {repo_name}")
|
||||||
new_path = fullpath + ".disabled"
|
new_path = fullpath + ".disabled"
|
||||||
os.rename(fullpath, new_path)
|
os.rename(fullpath, new_path)
|
||||||
pass
|
|
||||||
elif not item['disabled'] and is_disabled:
|
elif not item['disabled'] and is_disabled:
|
||||||
# enable
|
# enable
|
||||||
print(f"ENABLE: {repo_name}")
|
print(f"ENABLE: {repo_name}")
|
||||||
@ -202,6 +210,7 @@ def checkout_custom_node_hash(git_custom_node_infos):
|
|||||||
if commit_hash != item['hash']:
|
if commit_hash != item['hash']:
|
||||||
print(f"CHECKOUT: {repo_name} [{item['hash']}]")
|
print(f"CHECKOUT: {repo_name} [{item['hash']}]")
|
||||||
repo.git.checkout(item['hash'])
|
repo.git.checkout(item['hash'])
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
print(f"Failed to restore snapshots for the custom node '{path}'")
|
print(f"Failed to restore snapshots for the custom node '{path}'")
|
||||||
|
|
||||||
|
|||||||
1368
github-stats.json
1368
github-stats.json
File diff suppressed because it is too large
Load Diff
951
glob/manager_core.py
Normal file
951
glob/manager_core.py
Normal file
@ -0,0 +1,951 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import configparser
|
||||||
|
import platform
|
||||||
|
from datetime import datetime
|
||||||
|
import git
|
||||||
|
from git.remote import RemoteProgress
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
from tqdm.auto import tqdm
|
||||||
|
import aiohttp
|
||||||
|
import threading
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
glob_path = os.path.join(os.path.dirname(__file__)) # ComfyUI-Manager/glob
|
||||||
|
sys.path.append(glob_path)
|
||||||
|
|
||||||
|
import cm_global
|
||||||
|
from manager_util import *
|
||||||
|
|
||||||
|
version = [2, 22, 1]
|
||||||
|
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
|
||||||
|
|
||||||
|
comfyui_manager_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
custom_nodes_path = os.path.abspath(os.path.join(comfyui_manager_path, '..'))
|
||||||
|
comfy_path = os.path.abspath(os.path.join(custom_nodes_path, '..'))
|
||||||
|
channel_list_path = os.path.join(comfyui_manager_path, 'channels.list')
|
||||||
|
config_path = os.path.join(comfyui_manager_path, "config.ini")
|
||||||
|
startup_script_path = os.path.join(comfyui_manager_path, "startup-scripts")
|
||||||
|
git_script_path = os.path.join(comfyui_manager_path, "git_helper.py")
|
||||||
|
cache_dir = os.path.join(comfyui_manager_path, '.cache')
|
||||||
|
cached_config = None
|
||||||
|
js_path = None
|
||||||
|
|
||||||
|
comfy_ui_required_revision = 1930
|
||||||
|
comfy_ui_required_commit_datetime = datetime(2024, 1, 24, 0, 0, 0)
|
||||||
|
|
||||||
|
comfy_ui_revision = "Unknown"
|
||||||
|
comfy_ui_commit_datetime = datetime(1900, 1, 1, 0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
cache_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
|
channel_dict = None
|
||||||
|
channel_list = None
|
||||||
|
pip_map = None
|
||||||
|
|
||||||
|
|
||||||
|
def remap_pip_package(pkg):
|
||||||
|
if pkg in cm_global.pip_overrides:
|
||||||
|
res = cm_global.pip_overrides[pkg]
|
||||||
|
print(f"[ComfyUI-Manager] '{pkg}' is remapped to '{res}'")
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
return pkg
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
||||||
|
name = name.strip()
|
||||||
|
|
||||||
|
pattern = r'([^<>!=]+)([<>!=]=?)(.*)'
|
||||||
|
match = re.search(pattern, name)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
name = match.group(1)
|
||||||
|
|
||||||
|
if name in cm_global.pip_downgrade_blacklist:
|
||||||
|
pips = get_installed_packages()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def is_installed(name):
|
||||||
|
name = name.strip()
|
||||||
|
|
||||||
|
if name.startswith('#'):
|
||||||
|
return True
|
||||||
|
|
||||||
|
pattern = r'([^<>!=]+)([<>!=]=?)(.*)'
|
||||||
|
match = re.search(pattern, name)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
name = match.group(1)
|
||||||
|
|
||||||
|
if name in cm_global.pip_downgrade_blacklist:
|
||||||
|
pips = get_installed_packages()
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
def get_channel_dict():
|
||||||
|
global channel_dict
|
||||||
|
|
||||||
|
if channel_dict is None:
|
||||||
|
channel_dict = {}
|
||||||
|
|
||||||
|
if not os.path.exists(channel_list_path):
|
||||||
|
shutil.copy(channel_list_path+'.template', channel_list_path)
|
||||||
|
|
||||||
|
with open(os.path.join(comfyui_manager_path, 'channels.list'), 'r') as file:
|
||||||
|
channels = file.read()
|
||||||
|
for x in channels.split('\n'):
|
||||||
|
channel_info = x.split("::")
|
||||||
|
if len(channel_info) == 2:
|
||||||
|
channel_dict[channel_info[0]] = channel_info[1]
|
||||||
|
|
||||||
|
return channel_dict
|
||||||
|
|
||||||
|
|
||||||
|
def get_channel_list():
|
||||||
|
global channel_list
|
||||||
|
|
||||||
|
if channel_list is None:
|
||||||
|
channel_list = []
|
||||||
|
for k, v in get_channel_dict().items():
|
||||||
|
channel_list.append(f"{k}::{v}")
|
||||||
|
|
||||||
|
return channel_list
|
||||||
|
|
||||||
|
|
||||||
|
class ManagerFuncs:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_current_preview_method(self):
|
||||||
|
return "none"
|
||||||
|
|
||||||
|
def run_script(self, cmd, cwd='.'):
|
||||||
|
if len(cmd) > 0 and cmd[0].startswith("#"):
|
||||||
|
print(f"[ComfyUI-Manager] Unexpected behavior: `{cmd}`")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
out = subprocess.check_call(cmd, cwd=cwd)
|
||||||
|
print(out)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
manager_funcs = ManagerFuncs()
|
||||||
|
|
||||||
|
|
||||||
|
def write_config():
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config['default'] = {
|
||||||
|
'preview_method': manager_funcs.get_current_preview_method(),
|
||||||
|
'badge_mode': get_config()['badge_mode'],
|
||||||
|
'git_exe': get_config()['git_exe'],
|
||||||
|
'channel_url': get_config()['channel_url'],
|
||||||
|
'share_option': get_config()['share_option'],
|
||||||
|
'bypass_ssl': get_config()['bypass_ssl'],
|
||||||
|
"file_logging": get_config()['file_logging'],
|
||||||
|
'default_ui': get_config()['default_ui'],
|
||||||
|
'component_policy': get_config()['component_policy'],
|
||||||
|
'double_click_policy': get_config()['double_click_policy'],
|
||||||
|
'windows_selector_event_loop_policy': get_config()['windows_selector_event_loop_policy'],
|
||||||
|
'model_download_by_agent': get_config()['model_download_by_agent'],
|
||||||
|
'downgrade_blacklist': get_config()['downgrade_blacklist']
|
||||||
|
}
|
||||||
|
with open(config_path, 'w') as configfile:
|
||||||
|
config.write(configfile)
|
||||||
|
|
||||||
|
|
||||||
|
def read_config():
|
||||||
|
try:
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(config_path)
|
||||||
|
default_conf = config['default']
|
||||||
|
|
||||||
|
return {
|
||||||
|
'preview_method': default_conf['preview_method'] if 'preview_method' in default_conf else manager_funcs.get_current_preview_method(),
|
||||||
|
'badge_mode': default_conf['badge_mode'] if 'badge_mode' in default_conf else 'none',
|
||||||
|
'git_exe': default_conf['git_exe'] if 'git_exe' in default_conf else '',
|
||||||
|
'channel_url': default_conf['channel_url'] if 'channel_url' in default_conf else 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main',
|
||||||
|
'share_option': default_conf['share_option'] if 'share_option' in default_conf else 'all',
|
||||||
|
'bypass_ssl': default_conf['bypass_ssl'] if 'bypass_ssl' in default_conf else False,
|
||||||
|
'file_logging': default_conf['file_logging'] if 'file_logging' in default_conf else True,
|
||||||
|
'default_ui': default_conf['default_ui'] if 'default_ui' in default_conf else 'none',
|
||||||
|
'component_policy': default_conf['component_policy'] if 'component_policy' in default_conf else 'workflow',
|
||||||
|
'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,
|
||||||
|
'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:
|
||||||
|
return {
|
||||||
|
'preview_method': manager_funcs.get_current_preview_method(),
|
||||||
|
'badge_mode': 'none',
|
||||||
|
'git_exe': '',
|
||||||
|
'channel_url': 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main',
|
||||||
|
'share_option': 'all',
|
||||||
|
'bypass_ssl': False,
|
||||||
|
'file_logging': True,
|
||||||
|
'default_ui': 'none',
|
||||||
|
'component_policy': 'workflow',
|
||||||
|
'double_click_policy': 'copy-all',
|
||||||
|
'windows_selector_event_loop_policy': False,
|
||||||
|
'model_download_by_agent': False,
|
||||||
|
'downgrade_blacklist': ''
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_config():
|
||||||
|
global cached_config
|
||||||
|
|
||||||
|
if cached_config is None:
|
||||||
|
cached_config = read_config()
|
||||||
|
|
||||||
|
return cached_config
|
||||||
|
|
||||||
|
|
||||||
|
def switch_to_default_branch(repo):
|
||||||
|
show_result = repo.git.remote("show", "origin")
|
||||||
|
matches = re.search(r"\s*HEAD branch:\s*(.*)", show_result)
|
||||||
|
if matches:
|
||||||
|
default_branch = matches.group(1)
|
||||||
|
repo.git.checkout(default_branch)
|
||||||
|
|
||||||
|
|
||||||
|
def try_install_script(url, repo_path, install_cmd, instant_execution=False):
|
||||||
|
if not instant_execution and ((len(install_cmd) > 0 and install_cmd[0].startswith('#')) or (platform.system() == "Windows" and comfy_ui_commit_datetime.date() >= comfy_ui_required_commit_datetime.date())):
|
||||||
|
if not os.path.exists(startup_script_path):
|
||||||
|
os.makedirs(startup_script_path)
|
||||||
|
|
||||||
|
script_path = os.path.join(startup_script_path, "install-scripts.txt")
|
||||||
|
with open(script_path, "a") as file:
|
||||||
|
obj = [repo_path] + install_cmd
|
||||||
|
file.write(f"{obj}\n")
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if len(install_cmd) == 5 and install_cmd[2:4] == ['pip', 'install']:
|
||||||
|
if is_blacklisted(install_cmd[4]):
|
||||||
|
print(f"[ComfyUI-Manager] skip black listed pip installation: '{install_cmd[4]}'")
|
||||||
|
return True
|
||||||
|
|
||||||
|
print(f"\n## ComfyUI-Manager: EXECUTE => {install_cmd}")
|
||||||
|
code = manager_funcs.run_script(install_cmd, cwd=repo_path)
|
||||||
|
|
||||||
|
if platform.system() != "Windows":
|
||||||
|
try:
|
||||||
|
if comfy_ui_commit_datetime.date() < comfy_ui_required_commit_datetime.date():
|
||||||
|
print("\n\n###################################################################")
|
||||||
|
print(f"[WARN] ComfyUI-Manager: Your ComfyUI version ({comfy_ui_revision})[{comfy_ui_commit_datetime.date()}] is too old. Please update to the latest version.")
|
||||||
|
print(f"[WARN] The extension installation feature may not work properly in the current installed ComfyUI version on Windows environment.")
|
||||||
|
print("###################################################################\n\n")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if code != 0:
|
||||||
|
if url is None:
|
||||||
|
url = os.path.dirname(repo_path)
|
||||||
|
print(f"install script failed: {url}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# use subprocess to avoid file system lock by git (Windows)
|
||||||
|
def __win_check_git_update(path, do_fetch=False, do_update=False):
|
||||||
|
if do_fetch:
|
||||||
|
command = [sys.executable, git_script_path, "--fetch", path]
|
||||||
|
elif do_update:
|
||||||
|
command = [sys.executable, git_script_path, "--pull", path]
|
||||||
|
else:
|
||||||
|
command = [sys.executable, git_script_path, "--check", path]
|
||||||
|
|
||||||
|
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
output, _ = process.communicate()
|
||||||
|
output = output.decode('utf-8').strip()
|
||||||
|
|
||||||
|
if 'detected dubious' in output:
|
||||||
|
# fix and try again
|
||||||
|
safedir_path = path.replace('\\', '/')
|
||||||
|
try:
|
||||||
|
print(f"[ComfyUI-Manager] Try fixing 'dubious repository' error on '{safedir_path}' repo")
|
||||||
|
process = subprocess.Popen(['git', 'config', '--global', '--add', 'safe.directory', safedir_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
output, _ = process.communicate()
|
||||||
|
|
||||||
|
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
output, _ = process.communicate()
|
||||||
|
output = output.decode('utf-8').strip()
|
||||||
|
except Exception:
|
||||||
|
print(f'[ComfyUI-Manager] failed to fixing')
|
||||||
|
|
||||||
|
if 'detected dubious' in output:
|
||||||
|
print(f'\n[ComfyUI-Manager] Failed to fixing repository setup. Please execute this command on cmd: \n'
|
||||||
|
f'-----------------------------------------------------------------------------------------\n'
|
||||||
|
f'git config --global --add safe.directory "{safedir_path}"\n'
|
||||||
|
f'-----------------------------------------------------------------------------------------\n')
|
||||||
|
|
||||||
|
if do_update:
|
||||||
|
if "CUSTOM NODE PULL: Success" in output:
|
||||||
|
process.wait()
|
||||||
|
print(f"\rUpdated: {path}")
|
||||||
|
return True, True # updated
|
||||||
|
elif "CUSTOM NODE PULL: None" in output:
|
||||||
|
process.wait()
|
||||||
|
return False, True # there is no update
|
||||||
|
else:
|
||||||
|
print(f"\rUpdate error: {path}")
|
||||||
|
process.wait()
|
||||||
|
return False, False # update failed
|
||||||
|
else:
|
||||||
|
if "CUSTOM NODE CHECK: True" in output:
|
||||||
|
process.wait()
|
||||||
|
return True, True
|
||||||
|
elif "CUSTOM NODE CHECK: False" in output:
|
||||||
|
process.wait()
|
||||||
|
return False, True
|
||||||
|
else:
|
||||||
|
print(f"\rFetch error: {path}")
|
||||||
|
print(f"\n{output}\n")
|
||||||
|
process.wait()
|
||||||
|
return False, True
|
||||||
|
|
||||||
|
|
||||||
|
def __win_check_git_pull(path):
|
||||||
|
command = [sys.executable, git_script_path, "--pull", path]
|
||||||
|
process = subprocess.Popen(command)
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
|
||||||
|
def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=False):
|
||||||
|
install_script_path = os.path.join(repo_path, "install.py")
|
||||||
|
requirements_path = os.path.join(repo_path, "requirements.txt")
|
||||||
|
|
||||||
|
if lazy_mode:
|
||||||
|
install_cmd = ["#LAZY-INSTALL-SCRIPT", sys.executable]
|
||||||
|
try_install_script(url, repo_path, install_cmd)
|
||||||
|
else:
|
||||||
|
if os.path.exists(requirements_path):
|
||||||
|
print("Install: pip packages")
|
||||||
|
with open(requirements_path, "r") as requirements_file:
|
||||||
|
for line in requirements_file:
|
||||||
|
package_name = remap_pip_package(line.strip())
|
||||||
|
if package_name and not package_name.startswith('#'):
|
||||||
|
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||||
|
if package_name.strip() != "":
|
||||||
|
try_install_script(url, repo_path, install_cmd, instant_execution=instant_execution)
|
||||||
|
|
||||||
|
if os.path.exists(install_script_path):
|
||||||
|
print(f"Install: install script")
|
||||||
|
install_cmd = [sys.executable, "install.py"]
|
||||||
|
try_install_script(url, repo_path, install_cmd, instant_execution=instant_execution)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def git_repo_has_updates(path, do_fetch=False, do_update=False):
|
||||||
|
if do_fetch:
|
||||||
|
print(f"\x1b[2K\rFetching: {path}", end='')
|
||||||
|
elif do_update:
|
||||||
|
print(f"\x1b[2K\rUpdating: {path}", end='')
|
||||||
|
|
||||||
|
# Check if the path is a git repository
|
||||||
|
if not os.path.exists(os.path.join(path, '.git')):
|
||||||
|
raise ValueError('Not a git repository')
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
updated, success = __win_check_git_update(path, do_fetch, do_update)
|
||||||
|
if updated and success:
|
||||||
|
execute_install_script(None, path, lazy_mode=True)
|
||||||
|
return updated, success
|
||||||
|
else:
|
||||||
|
# Fetch the latest commits from the remote repository
|
||||||
|
repo = git.Repo(path)
|
||||||
|
|
||||||
|
current_branch = repo.active_branch
|
||||||
|
branch_name = current_branch.name
|
||||||
|
|
||||||
|
remote_name = 'origin'
|
||||||
|
remote = repo.remote(name=remote_name)
|
||||||
|
|
||||||
|
# Get the current commit hash
|
||||||
|
commit_hash = repo.head.commit.hexsha
|
||||||
|
|
||||||
|
if do_fetch or do_update:
|
||||||
|
remote.fetch()
|
||||||
|
|
||||||
|
if do_update:
|
||||||
|
if repo.head.is_detached:
|
||||||
|
switch_to_default_branch(repo)
|
||||||
|
|
||||||
|
remote_commit_hash = repo.refs[f'{remote_name}/{branch_name}'].object.hexsha
|
||||||
|
|
||||||
|
if commit_hash == remote_commit_hash:
|
||||||
|
repo.close()
|
||||||
|
return False, True
|
||||||
|
|
||||||
|
try:
|
||||||
|
remote.pull()
|
||||||
|
repo.git.submodule('update', '--init', '--recursive')
|
||||||
|
new_commit_hash = repo.head.commit.hexsha
|
||||||
|
|
||||||
|
if commit_hash != new_commit_hash:
|
||||||
|
execute_install_script(None, path)
|
||||||
|
print(f"\x1b[2K\rUpdated: {path}")
|
||||||
|
return True, True
|
||||||
|
else:
|
||||||
|
return False, False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\nUpdating failed: {path}\n{e}", file=sys.stderr)
|
||||||
|
return False, False
|
||||||
|
|
||||||
|
if repo.head.is_detached:
|
||||||
|
repo.close()
|
||||||
|
return True, True
|
||||||
|
|
||||||
|
# Get commit hash of the remote branch
|
||||||
|
current_branch = repo.active_branch
|
||||||
|
branch_name = current_branch.name
|
||||||
|
|
||||||
|
remote_commit_hash = repo.refs[f'{remote_name}/{branch_name}'].object.hexsha
|
||||||
|
|
||||||
|
# Compare the commit hashes to determine if the local repository is behind the remote repository
|
||||||
|
if commit_hash != remote_commit_hash:
|
||||||
|
# Get the commit dates
|
||||||
|
commit_date = repo.head.commit.committed_datetime
|
||||||
|
remote_commit_date = repo.refs[f'{remote_name}/{branch_name}'].object.committed_datetime
|
||||||
|
|
||||||
|
# Compare the commit dates to determine if the local repository is behind the remote repository
|
||||||
|
if commit_date < remote_commit_date:
|
||||||
|
repo.close()
|
||||||
|
return True, True
|
||||||
|
|
||||||
|
repo.close()
|
||||||
|
|
||||||
|
return False, True
|
||||||
|
|
||||||
|
|
||||||
|
class GitProgress(RemoteProgress):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.pbar = tqdm()
|
||||||
|
|
||||||
|
def update(self, op_code, cur_count, max_count=None, message=''):
|
||||||
|
self.pbar.total = max_count
|
||||||
|
self.pbar.n = cur_count
|
||||||
|
self.pbar.pos = 0
|
||||||
|
self.pbar.refresh()
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_url(url):
|
||||||
|
try:
|
||||||
|
result = urlparse(url)
|
||||||
|
return all([result.scheme, result.netloc])
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def gitclone_install(files, instant_execution=False, msg_prefix=''):
|
||||||
|
print(f"{msg_prefix}Install: {files}")
|
||||||
|
for url in files:
|
||||||
|
if not is_valid_url(url):
|
||||||
|
print(f"Invalid git url: '{url}'")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if url.endswith("/"):
|
||||||
|
url = url[:-1]
|
||||||
|
try:
|
||||||
|
print(f"Download: git clone '{url}'")
|
||||||
|
repo_name = os.path.splitext(os.path.basename(url))[0]
|
||||||
|
repo_path = os.path.join(custom_nodes_path, repo_name)
|
||||||
|
|
||||||
|
# Clone the repository from the remote URL
|
||||||
|
if not instant_execution and platform.system() == 'Windows':
|
||||||
|
res = manager_funcs.run_script([sys.executable, git_script_path, "--clone", custom_nodes_path, url])
|
||||||
|
if res != 0:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
repo = git.Repo.clone_from(url, repo_path, recursive=True, progress=GitProgress())
|
||||||
|
repo.git.clear_cache()
|
||||||
|
repo.close()
|
||||||
|
|
||||||
|
if not execute_install_script(url, repo_path, instant_execution=instant_execution):
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Install(git-clone) error: {url} / {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print("Installation was successful.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def git_pull(path):
|
||||||
|
# Check if the path is a git repository
|
||||||
|
if not os.path.exists(os.path.join(path, '.git')):
|
||||||
|
raise ValueError('Not a git repository')
|
||||||
|
|
||||||
|
# Pull the latest changes from the remote repository
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
return __win_check_git_pull(path)
|
||||||
|
else:
|
||||||
|
repo = git.Repo(path)
|
||||||
|
|
||||||
|
if repo.is_dirty():
|
||||||
|
repo.git.stash()
|
||||||
|
|
||||||
|
if repo.head.is_detached:
|
||||||
|
switch_to_default_branch(repo)
|
||||||
|
|
||||||
|
current_branch = repo.active_branch
|
||||||
|
remote_name = current_branch.tracking_branch().remote_name
|
||||||
|
remote = repo.remote(name=remote_name)
|
||||||
|
|
||||||
|
remote.pull()
|
||||||
|
repo.git.submodule('update', '--init', '--recursive')
|
||||||
|
|
||||||
|
repo.close()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def get_data(uri, silent=False):
|
||||||
|
if not silent:
|
||||||
|
print(f"FETCH DATA from: {uri}")
|
||||||
|
|
||||||
|
if uri.startswith("http"):
|
||||||
|
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||||
|
async with session.get(uri) as resp:
|
||||||
|
json_text = await resp.text()
|
||||||
|
else:
|
||||||
|
with cache_lock:
|
||||||
|
with open(uri, "r", encoding="utf-8") as f:
|
||||||
|
json_text = f.read()
|
||||||
|
|
||||||
|
json_obj = json.loads(json_text)
|
||||||
|
return json_obj
|
||||||
|
|
||||||
|
|
||||||
|
def simple_hash(input_string):
|
||||||
|
hash_value = 0
|
||||||
|
for char in input_string:
|
||||||
|
hash_value = (hash_value * 31 + ord(char)) % (2**32)
|
||||||
|
|
||||||
|
return hash_value
|
||||||
|
|
||||||
|
|
||||||
|
def is_file_created_within_one_day(file_path):
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
return False
|
||||||
|
|
||||||
|
file_creation_time = os.path.getctime(file_path)
|
||||||
|
current_time = datetime.now().timestamp()
|
||||||
|
time_difference = current_time - file_creation_time
|
||||||
|
|
||||||
|
return time_difference <= 86400
|
||||||
|
|
||||||
|
|
||||||
|
async def get_data_by_mode(mode, filename, channel_url=None):
|
||||||
|
try:
|
||||||
|
if mode == "local":
|
||||||
|
uri = os.path.join(comfyui_manager_path, filename)
|
||||||
|
json_obj = await get_data(uri)
|
||||||
|
else:
|
||||||
|
if channel_url is None:
|
||||||
|
uri = get_config()['channel_url'] + '/' + filename
|
||||||
|
else:
|
||||||
|
uri = channel_url + '/' + filename
|
||||||
|
|
||||||
|
cache_uri = str(simple_hash(uri))+'_'+filename
|
||||||
|
cache_uri = os.path.join(cache_dir, cache_uri)
|
||||||
|
|
||||||
|
if mode == "cache":
|
||||||
|
if is_file_created_within_one_day(cache_uri):
|
||||||
|
json_obj = await get_data(cache_uri)
|
||||||
|
else:
|
||||||
|
json_obj = await get_data(uri)
|
||||||
|
with cache_lock:
|
||||||
|
with open(cache_uri, "w", encoding='utf-8') as file:
|
||||||
|
json.dump(json_obj, file, indent=4, sort_keys=True)
|
||||||
|
else:
|
||||||
|
json_obj = await get_data(uri)
|
||||||
|
with cache_lock:
|
||||||
|
with open(cache_uri, "w", encoding='utf-8') as file:
|
||||||
|
json.dump(json_obj, file, indent=4, sort_keys=True)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ComfyUI-Manager] Due to a network error, switching to local mode.\n=> {filename}\n=> {e}")
|
||||||
|
uri = os.path.join(comfyui_manager_path, filename)
|
||||||
|
json_obj = await get_data(uri)
|
||||||
|
|
||||||
|
return json_obj
|
||||||
|
|
||||||
|
|
||||||
|
def gitclone_fix(files, instant_execution=False):
|
||||||
|
print(f"Try fixing: {files}")
|
||||||
|
for url in files:
|
||||||
|
if not is_valid_url(url):
|
||||||
|
print(f"Invalid git url: '{url}'")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if url.endswith("/"):
|
||||||
|
url = url[:-1]
|
||||||
|
try:
|
||||||
|
repo_name = os.path.splitext(os.path.basename(url))[0]
|
||||||
|
repo_path = os.path.join(custom_nodes_path, repo_name)
|
||||||
|
|
||||||
|
if os.path.exists(repo_path+'.disabled'):
|
||||||
|
repo_path = repo_path+'.disabled'
|
||||||
|
|
||||||
|
if not execute_install_script(url, repo_path, instant_execution=instant_execution):
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Install(git-clone) error: {url} / {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"Attempt to fixing '{files}' is done.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def pip_install(packages):
|
||||||
|
install_cmd = ['#FORCE', sys.executable, "-m", "pip", "install", '-U'] + packages
|
||||||
|
try_install_script('pip install via manager', '..', install_cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def rmtree(path):
|
||||||
|
retry_count = 3
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
retry_count -= 1
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
manager_funcs.run_script(['attrib', '-R', path + '\\*', '/S'])
|
||||||
|
shutil.rmtree(path)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
print(f"ex: {ex}")
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
if retry_count < 0:
|
||||||
|
raise ex
|
||||||
|
|
||||||
|
print(f"Uninstall retry({retry_count})")
|
||||||
|
|
||||||
|
|
||||||
|
def gitclone_uninstall(files):
|
||||||
|
import os
|
||||||
|
|
||||||
|
print(f"Uninstall: {files}")
|
||||||
|
for url in files:
|
||||||
|
if url.endswith("/"):
|
||||||
|
url = url[:-1]
|
||||||
|
try:
|
||||||
|
dir_name = os.path.splitext(os.path.basename(url))[0].replace(".git", "")
|
||||||
|
dir_path = os.path.join(custom_nodes_path, dir_name)
|
||||||
|
|
||||||
|
# safety check
|
||||||
|
if dir_path == '/' or dir_path[1:] == ":/" or dir_path == '':
|
||||||
|
print(f"Uninstall(git-clone) error: invalid path '{dir_path}' for '{url}'")
|
||||||
|
return False
|
||||||
|
|
||||||
|
install_script_path = os.path.join(dir_path, "uninstall.py")
|
||||||
|
disable_script_path = os.path.join(dir_path, "disable.py")
|
||||||
|
if os.path.exists(install_script_path):
|
||||||
|
uninstall_cmd = [sys.executable, "uninstall.py"]
|
||||||
|
code = manager_funcs.run_script(uninstall_cmd, cwd=dir_path)
|
||||||
|
|
||||||
|
if code != 0:
|
||||||
|
print(f"An error occurred during the execution of the uninstall.py script. Only the '{dir_path}' will be deleted.")
|
||||||
|
elif os.path.exists(disable_script_path):
|
||||||
|
disable_script = [sys.executable, "disable.py"]
|
||||||
|
code = manager_funcs.run_script(disable_script, cwd=dir_path)
|
||||||
|
if code != 0:
|
||||||
|
print(f"An error occurred during the execution of the disable.py script. Only the '{dir_path}' will be deleted.")
|
||||||
|
|
||||||
|
if os.path.exists(dir_path):
|
||||||
|
rmtree(dir_path)
|
||||||
|
elif os.path.exists(dir_path + ".disabled"):
|
||||||
|
rmtree(dir_path + ".disabled")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Uninstall(git-clone) error: {url} / {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print("Uninstallation was successful.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def gitclone_set_active(files, is_disable):
|
||||||
|
import os
|
||||||
|
|
||||||
|
if is_disable:
|
||||||
|
action_name = "Disable"
|
||||||
|
else:
|
||||||
|
action_name = "Enable"
|
||||||
|
|
||||||
|
print(f"{action_name}: {files}")
|
||||||
|
for url in files:
|
||||||
|
if url.endswith("/"):
|
||||||
|
url = url[:-1]
|
||||||
|
try:
|
||||||
|
dir_name = os.path.splitext(os.path.basename(url))[0].replace(".git", "")
|
||||||
|
dir_path = os.path.join(custom_nodes_path, dir_name)
|
||||||
|
|
||||||
|
# safety check
|
||||||
|
if dir_path == '/' or dir_path[1:] == ":/" or dir_path == '':
|
||||||
|
print(f"{action_name}(git-clone) error: invalid path '{dir_path}' for '{url}'")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if is_disable:
|
||||||
|
current_path = dir_path
|
||||||
|
new_path = dir_path + ".disabled"
|
||||||
|
else:
|
||||||
|
current_path = dir_path + ".disabled"
|
||||||
|
new_path = dir_path
|
||||||
|
|
||||||
|
os.rename(current_path, new_path)
|
||||||
|
|
||||||
|
if is_disable:
|
||||||
|
if os.path.exists(os.path.join(new_path, "disable.py")):
|
||||||
|
disable_script = [sys.executable, "disable.py"]
|
||||||
|
try_install_script(url, new_path, disable_script)
|
||||||
|
else:
|
||||||
|
if os.path.exists(os.path.join(new_path, "enable.py")):
|
||||||
|
enable_script = [sys.executable, "enable.py"]
|
||||||
|
try_install_script(url, new_path, enable_script)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{action_name}(git-clone) error: {url} / {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"{action_name} was successful.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def gitclone_update(files, instant_execution=False, skip_script=False, msg_prefix=""):
|
||||||
|
import os
|
||||||
|
|
||||||
|
print(f"{msg_prefix}Update: {files}")
|
||||||
|
for url in files:
|
||||||
|
if url.endswith("/"):
|
||||||
|
url = url[:-1]
|
||||||
|
try:
|
||||||
|
repo_name = os.path.splitext(os.path.basename(url))[0].replace(".git", "")
|
||||||
|
repo_path = os.path.join(custom_nodes_path, repo_name)
|
||||||
|
|
||||||
|
if os.path.exists(repo_path+'.disabled'):
|
||||||
|
repo_path = repo_path+'.disabled'
|
||||||
|
|
||||||
|
git_pull(repo_path)
|
||||||
|
|
||||||
|
if not skip_script:
|
||||||
|
if instant_execution:
|
||||||
|
if not execute_install_script(url, repo_path, lazy_mode=False, instant_execution=True):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if not execute_install_script(url, repo_path, lazy_mode=True):
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Update(git-clone) error: {url} / {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not skip_script:
|
||||||
|
print("Update was successful.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def lookup_customnode_by_url(data, target):
|
||||||
|
for x in data['custom_nodes']:
|
||||||
|
if target in x['files']:
|
||||||
|
dir_name = os.path.splitext(os.path.basename(target))[0].replace(".git", "")
|
||||||
|
dir_path = os.path.join(custom_nodes_path, dir_name)
|
||||||
|
if os.path.exists(dir_path):
|
||||||
|
x['installed'] = 'True'
|
||||||
|
elif os.path.exists(dir_path + ".disabled"):
|
||||||
|
x['installed'] = 'Disabled'
|
||||||
|
return x
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def check_a_custom_node_installed(item, do_fetch=False, do_update_check=True, do_update=False):
|
||||||
|
item['installed'] = 'None'
|
||||||
|
|
||||||
|
if item['install_type'] == 'git-clone' and len(item['files']) == 1:
|
||||||
|
url = item['files'][0]
|
||||||
|
|
||||||
|
if url.endswith("/"):
|
||||||
|
url = url[:-1]
|
||||||
|
|
||||||
|
dir_name = os.path.splitext(os.path.basename(url))[0].replace(".git", "")
|
||||||
|
dir_path = os.path.join(custom_nodes_path, dir_name)
|
||||||
|
if os.path.exists(dir_path):
|
||||||
|
try:
|
||||||
|
item['installed'] = 'True' # default
|
||||||
|
|
||||||
|
if cm_global.try_call(api="cm.is_import_failed_extension", name=dir_name):
|
||||||
|
item['installed'] = 'Fail'
|
||||||
|
|
||||||
|
if do_update_check:
|
||||||
|
update_state, success = git_repo_has_updates(dir_path, do_fetch, do_update)
|
||||||
|
if (do_update_check or do_update) and update_state:
|
||||||
|
item['installed'] = 'Update'
|
||||||
|
elif do_update and not success:
|
||||||
|
item['installed'] = 'Fail'
|
||||||
|
except:
|
||||||
|
if cm_global.try_call(api="cm.is_import_failed_extension", name=dir_name):
|
||||||
|
item['installed'] = 'Fail'
|
||||||
|
else:
|
||||||
|
item['installed'] = 'True'
|
||||||
|
|
||||||
|
elif os.path.exists(dir_path + ".disabled"):
|
||||||
|
item['installed'] = 'Disabled'
|
||||||
|
|
||||||
|
else:
|
||||||
|
item['installed'] = 'False'
|
||||||
|
|
||||||
|
elif item['install_type'] == 'copy' and len(item['files']) == 1:
|
||||||
|
dir_name = os.path.basename(item['files'][0])
|
||||||
|
|
||||||
|
if item['files'][0].endswith('.py'):
|
||||||
|
base_path = custom_nodes_path
|
||||||
|
elif 'js_path' in item:
|
||||||
|
base_path = os.path.join(js_path, item['js_path'])
|
||||||
|
else:
|
||||||
|
base_path = js_path
|
||||||
|
|
||||||
|
file_path = os.path.join(base_path, dir_name)
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
if cm_global.try_call(api="cm.is_import_failed_extension", name=dir_name):
|
||||||
|
item['installed'] = 'Fail'
|
||||||
|
else:
|
||||||
|
item['installed'] = 'True'
|
||||||
|
elif os.path.exists(file_path + ".disabled"):
|
||||||
|
item['installed'] = 'Disabled'
|
||||||
|
else:
|
||||||
|
item['installed'] = 'False'
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_snapshot():
|
||||||
|
# Get ComfyUI hash
|
||||||
|
repo_path = comfy_path
|
||||||
|
|
||||||
|
print(f"comfy_path: {comfy_path}")
|
||||||
|
if not os.path.exists(os.path.join(repo_path, '.git')):
|
||||||
|
print(f"ComfyUI update fail: The installed ComfyUI does not have a Git repository.")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
repo = git.Repo(repo_path)
|
||||||
|
comfyui_commit_hash = repo.head.commit.hexsha
|
||||||
|
|
||||||
|
git_custom_nodes = {}
|
||||||
|
file_custom_nodes = []
|
||||||
|
|
||||||
|
# Get custom nodes hash
|
||||||
|
for path in os.listdir(custom_nodes_path):
|
||||||
|
fullpath = os.path.join(custom_nodes_path, path)
|
||||||
|
|
||||||
|
if os.path.isdir(fullpath):
|
||||||
|
is_disabled = path.endswith(".disabled")
|
||||||
|
|
||||||
|
try:
|
||||||
|
git_dir = os.path.join(fullpath, '.git')
|
||||||
|
|
||||||
|
if not os.path.exists(git_dir):
|
||||||
|
continue
|
||||||
|
|
||||||
|
repo = git.Repo(fullpath)
|
||||||
|
commit_hash = repo.head.commit.hexsha
|
||||||
|
url = repo.remotes.origin.url
|
||||||
|
git_custom_nodes[url] = {
|
||||||
|
'hash': commit_hash,
|
||||||
|
'disabled': is_disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
except:
|
||||||
|
print(f"Failed to extract snapshots for the custom node '{path}'.")
|
||||||
|
|
||||||
|
elif path.endswith('.py'):
|
||||||
|
is_disabled = path.endswith(".py.disabled")
|
||||||
|
filename = os.path.basename(path)
|
||||||
|
item = {
|
||||||
|
'filename': filename,
|
||||||
|
'disabled': is_disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
file_custom_nodes.append(item)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'comfyui': comfyui_commit_hash,
|
||||||
|
'git_custom_nodes': git_custom_nodes,
|
||||||
|
'file_custom_nodes': file_custom_nodes,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def save_snapshot_with_postfix(postfix):
|
||||||
|
now = datetime.now()
|
||||||
|
|
||||||
|
date_time_format = now.strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
file_name = f"{date_time_format}_{postfix}"
|
||||||
|
|
||||||
|
path = os.path.join(comfyui_manager_path, 'snapshots', f"{file_name}.json")
|
||||||
|
with open(path, "w") as json_file:
|
||||||
|
json.dump(get_current_snapshot(), json_file, indent=4)
|
||||||
|
|
||||||
|
return file_name+'.json'
|
||||||
|
|
||||||
1627
glob/manager_server.py
Normal file
1627
glob/manager_server.py
Normal file
File diff suppressed because it is too large
Load Diff
12
js/common.js
12
js/common.js
@ -89,7 +89,10 @@ export async function install_pip(packages) {
|
|||||||
if(packages.includes('&'))
|
if(packages.includes('&'))
|
||||||
app.ui.dialog.show(`Invalid PIP package enumeration: '${packages}'`);
|
app.ui.dialog.show(`Invalid PIP package enumeration: '${packages}'`);
|
||||||
|
|
||||||
const res = await api.fetchApi(`/customnode/install/pip?packages=${packages}`);
|
const res = await api.fetchApi("/customnode/install/pip", {
|
||||||
|
method: "POST",
|
||||||
|
body: packages,
|
||||||
|
});
|
||||||
|
|
||||||
if(res.status == 200) {
|
if(res.status == 200) {
|
||||||
app.ui.dialog.show(`PIP package installation is processed.<br>To apply the pip packages, please click the <button id='cm-reboot-button3'><font size='3px'>RESTART</font></button> button in ComfyUI.`);
|
app.ui.dialog.show(`PIP package installation is processed.<br>To apply the pip packages, please click the <button id='cm-reboot-button3'><font size='3px'>RESTART</font></button> button in ComfyUI.`);
|
||||||
@ -121,7 +124,10 @@ export async function install_via_git_url(url, manager_dialog) {
|
|||||||
app.ui.dialog.show(`Wait...<BR><BR>Installing '${url}'`);
|
app.ui.dialog.show(`Wait...<BR><BR>Installing '${url}'`);
|
||||||
app.ui.dialog.element.style.zIndex = 10010;
|
app.ui.dialog.element.style.zIndex = 10010;
|
||||||
|
|
||||||
const res = await api.fetchApi(`/customnode/install/git_url?url=${url}`);
|
const res = await api.fetchApi("/customnode/install/git_url", {
|
||||||
|
method: "POST",
|
||||||
|
body: url,
|
||||||
|
});
|
||||||
|
|
||||||
if(res.status == 200) {
|
if(res.status == 200) {
|
||||||
app.ui.dialog.show(`'${url}' is installed<BR>To apply the installed custom node, please <button id='cm-reboot-button4'><font size='3px'>RESTART</font></button> ComfyUI.`);
|
app.ui.dialog.show(`'${url}' is installed<BR>To apply the installed custom node, please <button id='cm-reboot-button4'><font size='3px'>RESTART</font></button> ComfyUI.`);
|
||||||
@ -148,7 +154,7 @@ export async function free_models() {
|
|||||||
let res = await api.fetchApi(`/free`, {
|
let res = await api.fetchApi(`/free`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: '{}'
|
body: '{"unload_models": true}'
|
||||||
});
|
});
|
||||||
|
|
||||||
if(res.status == 200) {
|
if(res.status == 200) {
|
||||||
|
|||||||
@ -269,6 +269,7 @@ export class SnapshotManager extends ComfyDialog {
|
|||||||
save_button.onclick = () => { save_current_snapshot(); }
|
save_button.onclick = () => { save_current_snapshot(); }
|
||||||
save_button.style.display = "inline-block";
|
save_button.style.display = "inline-block";
|
||||||
save_button.style.horizontalAlign = "right";
|
save_button.style.horizontalAlign = "right";
|
||||||
|
save_button.style.width = "170px";
|
||||||
|
|
||||||
this.message_box = $el('div', {id:'custom-download-message'}, [$el('br'), '']);
|
this.message_box = $el('div', {id:'custom-download-message'}, [$el('br'), '']);
|
||||||
this.message_box.style.height = '60px';
|
this.message_box.style.height = '60px';
|
||||||
|
|||||||
@ -2400,6 +2400,26 @@
|
|||||||
"filename": "SUPIR-v0Q.ckpt",
|
"filename": "SUPIR-v0Q.ckpt",
|
||||||
"url": "https://huggingface.co/camenduru/SUPIR/resolve/main/SUPIR-v0Q.ckpt"
|
"url": "https://huggingface.co/camenduru/SUPIR/resolve/main/SUPIR-v0Q.ckpt"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Kijai/SUPIR-v0F_fp16.safetensors (pruned)",
|
||||||
|
"type": "checkpoints",
|
||||||
|
"base": "SUPIR",
|
||||||
|
"save_path": "checkpoints/SUPIR",
|
||||||
|
"description": "SUPIR checkpoint model",
|
||||||
|
"reference": "https://huggingface.co/Kijai/SUPIR_pruned/tree/main",
|
||||||
|
"filename": "SUPIR-v0F_fp16.safetensors",
|
||||||
|
"url": "https://huggingface.co/Kijai/SUPIR_pruned/resolve/main/SUPIR-v0F_fp16.safetensors"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kijai/SUPIR-v0Q_fp16.safetensors (pruned)",
|
||||||
|
"type": "checkpoints",
|
||||||
|
"base": "SUPIR",
|
||||||
|
"save_path": "checkpoints/SUPIR",
|
||||||
|
"description": "SUPIR checkpoint model",
|
||||||
|
"reference": "https://huggingface.co/Kijai/SUPIR_pruned/tree/main",
|
||||||
|
"filename": "SUPIR-v0Q_fp16.safetensors",
|
||||||
|
"url": "https://huggingface.co/Kijai/SUPIR_pruned/resolve/main/SUPIR-v0Q_fp16.safetensors"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "RAM",
|
"name": "RAM",
|
||||||
"type": "RAM",
|
"type": "RAM",
|
||||||
|
|||||||
@ -10,6 +10,77 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"author": "kijai",
|
||||||
|
"title": "ComfyUI nodes to use DeepSeek-VL",
|
||||||
|
"reference": "https://github.com/kijai/ComfyUI-DeepSeek-VL",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/kijai/ComfyUI-DeepSeek-VL"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "[a/https://huggingface.co/deepseek-ai](https://huggingface.co/deepseek-ai)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "GentlemanHu",
|
||||||
|
"title": "ComfyUI-Notifier",
|
||||||
|
"reference": "https://github.com/GentlemanHu/ComfyUI-Notifier",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/GentlemanHu/ComfyUI-Notifier"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:GentlemanHu_Notifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "nat-chan",
|
||||||
|
"title": "comfyui-in-memory-transceiver",
|
||||||
|
"reference": "https://github.com/nat-chan/comfyui-in-memory-transceiver",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/nat-chan/comfyui-in-memory-transceiver"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Why? When processing a large number of requests, the SaveImage and LoadImage nodes may be IO-limited, and using shared memory improves performance by passing images only through memory access, not through IO."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "DrMWeigand",
|
||||||
|
"title": "ComfyUI_LineBreakInserter",
|
||||||
|
"reference": "https://github.com/DrMWeigand/ComfyUI_LineBreakInserter",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/DrMWeigand/ComfyUI_LineBreakInserter"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Line Break Inserter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "WilliamStanford",
|
||||||
|
"title": "visuallabs_comfyui_nodes",
|
||||||
|
"reference": "https://github.com/WilliamStanford/visuallabs_comfyui_nodes",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/WilliamStanford/visuallabs_comfyui_nodes"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:PointStringFromFloatArray"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "bruce007lee",
|
||||||
|
"title": "comfyui-cleaner",
|
||||||
|
"reference": "https://github.com/bruce007lee/comfyui-cleaner",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/bruce007lee/comfyui-cleaner"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:cleaner"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "ExponentialML",
|
||||||
|
"title": "ComfyUI_LiveDirector (WIP)",
|
||||||
|
"reference": "https://github.com/ExponentialML/ComfyUI_LiveDirector",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/ExponentialML/ComfyUI_LiveDirector"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Experimental method to use reference video to drive motion in generations without training in ComfyUI."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "logtd",
|
"author": "logtd",
|
||||||
"title": "ComfyUI-MotionThiefExperiment",
|
"title": "ComfyUI-MotionThiefExperiment",
|
||||||
@ -30,16 +101,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Nodes:sound voice, text concat, latent to list, movie generate, movie batch, hy save image, generate story"
|
"description": "Nodes:sound voice, text concat, latent to list, movie generate, movie batch, hy save image, generate story"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "liusida",
|
|
||||||
"title": "ComfyUI-Login",
|
|
||||||
"reference": "https://github.com/liusida/ComfyUI-Login",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/liusida/ComfyUI-Login"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "This custom node serves as a proof-of-concept to explore the implementation of basic login functionality for ComfyUI.\nNOTE:In the future, if proven useful, this feature might be directly integrated into either ComfyUI or ComfyUI-Manager."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "gameltb",
|
"author": "gameltb",
|
||||||
"title": "io_comfyui",
|
"title": "io_comfyui",
|
||||||
|
|||||||
@ -1,5 +1,25 @@
|
|||||||
{
|
{
|
||||||
"custom_nodes": [
|
"custom_nodes": [
|
||||||
|
{
|
||||||
|
"author": "ZHO-ZHO-ZHO",
|
||||||
|
"title": "Dr.Lt.Data/ComfyUI-YoloWorld-EfficientSAM",
|
||||||
|
"reference": "https://github.com/ltdrdata/ComfyUI-YoloWorld-EfficientSAM",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/ltdrdata/ComfyUI-YoloWorld-EfficientSAM"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This fork includes [a/PR32](https://github.com/ZHO-ZHO-ZHO/ComfyUI-YoloWorld-EfficientSAM/pull/32)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "ertu110",
|
||||||
|
"title": "sdxl_prompt_style",
|
||||||
|
"reference": "https://github.com/ertu110/sdxl_prompt_style",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/ertu110/sdxl_prompt_style"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This project is a complete benchmark [a/https://github.com/twri/sdxl_prompt_styler](https://github.com/twri/sdxl_prompt_styler) A large amount of code inside comes from https://github.com/twri/sdxl_prompt_styler Project and [a/https://www.nodecafe.org/package/pythongosssss_ComfyUI-Custom-Scripts](https://www.nodecafe.org/package/pythongosssss_ComfyUI-Custom-Scripts) project\nThe functionality of this project is related to https://github.com/twri/sdxl_prompt_styler Highly overlapping, the only purpose of creating this project is because there are too many styles when selecting, resulting in a long and inconvenient dropdown box. Therefore, To address this issue, this project has added a secondary menu to the style."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "gustproof",
|
"author": "gustproof",
|
||||||
"title": "ComfyUI_IPAdapter_plus_Style_Components",
|
"title": "ComfyUI_IPAdapter_plus_Style_Components",
|
||||||
@ -10,16 +30,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Style Components is an IP-Adapter model conditioned on anime styles. The style embeddings can either be extracted from images or created manually. This repo currently only supports the SDXL model trained on AutismmixPony."
|
"description": "Style Components is an IP-Adapter model conditioned on anime styles. The style embeddings can either be extracted from images or created manually. This repo currently only supports the SDXL model trained on AutismmixPony."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "BlenderNeko",
|
|
||||||
"title": "Dr.Lt.Data/Advanced CLIP Text Encode (PR21)",
|
|
||||||
"reference": "https://github.com/ltdrdata/ComfyUI_ADV_CLIP_emb",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/ltdrdata/ComfyUI_ADV_CLIP_emb"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "[a/PR21](https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb/pull/21) is applied.\nmissing 'clip_layer' method fix."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "gameltb",
|
"author": "gameltb",
|
||||||
"title": "comfyui-stablsr",
|
"title": "comfyui-stablsr",
|
||||||
|
|||||||
@ -9,6 +9,47 @@
|
|||||||
"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": "Big Idea Technology",
|
||||||
|
"title": "Image Text Overlay Node for ComfyUI [DEPRECATED]",
|
||||||
|
"reference": "https://github.com/Big-Idea-Technology/ComfyUI_Image_Text_Overlay",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/Big-Idea-Technology/ComfyUI_Image_Text_Overlay"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Please note that the ImageTextOverlay project is no longer supported and has been moved to a new repository. For ongoing developments, contributions, and issues, please refer to the new repository at: [a/https://github.com/Big-Idea-Technology/ComfyUI-Book-Tools](https://github.com/Big-Idea-Technology/ComfyUI-Book-Tools)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "meimeilook",
|
||||||
|
"title": "ComfyUI_IPAdapter_plus.old [backward compatbility]",
|
||||||
|
"reference": "https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "This repo is created to provide backward compatibility for workflows configured with the old IPAdapter."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "mlinmg",
|
||||||
|
"title": "LaMa Preprocessor [DEPRECATED]",
|
||||||
|
"reference": "https://github.com/mlinmg/ComfyUI-LaMA-Preprocessor",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/mlinmg/ComfyUI-LaMA-Preprocessor"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "A LaMa prerocessor for ComfyUI. This preprocessor finally enable users to generate coherent inpaint and outpaint prompt-free. The best results are given on landscapes, not so much in drawings/animation."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "CapsAdmin",
|
||||||
|
"title": "ComfyUI-Euler-Smea-Dyn-Sampler [DEPRECATED]",
|
||||||
|
"reference": "https://github.com/CapsAdmin/ComfyUI-Euler-Smea-Dyn-Sampler",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/CapsAdmin/ComfyUI-Euler-Smea-Dyn-Sampler"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Just a comfyui version of [a/Euler Smea Dyn Sampler](https://github.com/Koishi-Star/Euler-Smea-Dyn-Sampler). It adds the sampler directly to existing samplers."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "BlakeOne",
|
"author": "BlakeOne",
|
||||||
"title": "ComfyUI FastImageListToImageBatch [REMOVED]",
|
"title": "ComfyUI FastImageListToImageBatch [REMOVED]",
|
||||||
@ -59,16 +100,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Proof of concent on how to use IPAdapter to control tiled upscaling. NOTE: You need to have 'ComfyUI_IPAdapter_plus' installed."
|
"description": "Proof of concent on how to use IPAdapter to control tiled upscaling. NOTE: You need to have 'ComfyUI_IPAdapter_plus' installed."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "meimeilook",
|
|
||||||
"title": "ComfyUI_IPAdapter_plus",
|
|
||||||
"reference": "https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "This repo is created to provide backward compatibility for workflows configured with the old IPAdapter."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "XINZHANG-ops",
|
"author": "XINZHANG-ops",
|
||||||
"title": "comfyui-xin-nodes [REMOVED]",
|
"title": "comfyui-xin-nodes [REMOVED]",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,25 @@
|
|||||||
{
|
{
|
||||||
"models": [
|
"models": [
|
||||||
|
{
|
||||||
|
"name": "Kijai/SUPIR-v0F_fp16.safetensors (pruned)",
|
||||||
|
"type": "checkpoints",
|
||||||
|
"base": "SUPIR",
|
||||||
|
"save_path": "checkpoints/SUPIR",
|
||||||
|
"description": "SUPIR checkpoint model",
|
||||||
|
"reference": "https://huggingface.co/Kijai/SUPIR_pruned/tree/main",
|
||||||
|
"filename": "SUPIR-v0F_fp16.safetensors",
|
||||||
|
"url": "https://huggingface.co/Kijai/SUPIR_pruned/resolve/main/SUPIR-v0F_fp16.safetensors"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kijai/SUPIR-v0Q_fp16.safetensors (pruned)",
|
||||||
|
"type": "checkpoints",
|
||||||
|
"base": "SUPIR",
|
||||||
|
"save_path": "checkpoints/SUPIR",
|
||||||
|
"description": "SUPIR checkpoint model",
|
||||||
|
"reference": "https://huggingface.co/Kijai/SUPIR_pruned/tree/main",
|
||||||
|
"filename": "SUPIR-v0Q_fp16.safetensors",
|
||||||
|
"url": "https://huggingface.co/Kijai/SUPIR_pruned/resolve/main/SUPIR-v0Q_fp16.safetensors"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "SUPIR-v0F.ckpt",
|
"name": "SUPIR-v0F.ckpt",
|
||||||
"type": "checkpoints",
|
"type": "checkpoints",
|
||||||
@ -641,86 +661,6 @@
|
|||||||
"reference": "https://huggingface.co/Lightricks/LongAnimateDiff",
|
"reference": "https://huggingface.co/Lightricks/LongAnimateDiff",
|
||||||
"filename": "lt_long_mm_16_64_frames.ckpt",
|
"filename": "lt_long_mm_16_64_frames.ckpt",
|
||||||
"url": "https://huggingface.co/Lightricks/LongAnimateDiff/resolve/main/lt_long_mm_16_64_frames.ckpt"
|
"url": "https://huggingface.co/Lightricks/LongAnimateDiff/resolve/main/lt_long_mm_16_64_frames.ckpt"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter_sd15.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SD1.5",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter_sd15.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15.safetensors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter_sd15_light.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SD1.5",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter_sd15_light.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15_light.safetensors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter_sd15_vit-G.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SD1.5",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter_sd15_vit-G.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15_vit-G.safetensors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter-plus_sd15.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SD1.5",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter-plus_sd15.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-plus_sd15.safetensors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter-plus-face_sd15.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SD1.5",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter-plus-face_sd15.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-plus-face_sd15.safetensors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter-full-face_sd15.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SD1.5",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter-full-face_sd15.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-full-face_sd15.safetensors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter_sdxl.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SDXL",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter_sdxl.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter_sdxl.safetensors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ip-adapter_sdxl_vit-h.safetensors",
|
|
||||||
"type": "IP-Adapter",
|
|
||||||
"base": "SDXL",
|
|
||||||
"save_path": "ipadapter",
|
|
||||||
"description": "This model requires the use of the SD1.5 encoder despite being for SDXL checkpoints",
|
|
||||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
|
||||||
"filename": "ip-adapter_sdxl_vit-h.safetensors",
|
|
||||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter_sdxl_vit-h.safetensors"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,16 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "There is a small node pack attached to this guide. This includes the init file and 3 nodes associated with the tutorials."
|
"description": "There is a small node pack attached to this guide. This includes the init file and 3 nodes associated with the tutorials."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"author": "bamboodia",
|
||||||
|
"title": "BAM Nodes",
|
||||||
|
"reference": "https://github.com/bamboodia/BAM_Nodes",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/bamboodia/BAM_Nodes"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "A collection of comfyui nodes that I have made for nothing more than educational purposes."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"author": "BadCafeCode",
|
"author": "BadCafeCode",
|
||||||
"title": "execution-inversion-demo-comfyui",
|
"title": "execution-inversion-demo-comfyui",
|
||||||
@ -159,6 +169,16 @@
|
|||||||
],
|
],
|
||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "Nodes:Woman_in_a_dress"
|
"description": "Nodes:Woman_in_a_dress"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "shinich39",
|
||||||
|
"title": "comfyui-concat-text-39",
|
||||||
|
"reference": "https://github.com/shinich39/comfyui-concat-text-39",
|
||||||
|
"files": [
|
||||||
|
"https://github.com/shinich39/comfyui-concat-text-39"
|
||||||
|
],
|
||||||
|
"install_type": "git-clone",
|
||||||
|
"description": "Nodes:Concatenate multiple text nodes."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -50,11 +50,21 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"if OPTIONS['UPDATE_COMFY_UI']:\n",
|
"if OPTIONS['UPDATE_COMFY_UI']:\n",
|
||||||
" !echo -= Updating ComfyUI =-\n",
|
" !echo -= Updating ComfyUI =-\n",
|
||||||
|
"\n",
|
||||||
|
" # Correction of the issue of permissions being deleted on Google Drive.\n",
|
||||||
|
" ![ -f \".ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat\" ] && chmod 755 .ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat\n",
|
||||||
|
" ![ -f \".ci/nightly/windows_base_files/run_nvidia_gpu.bat\" ] && chmod 755 .ci/nightly/windows_base_files/run_nvidia_gpu.bat\n",
|
||||||
|
" ![ -f \".ci/update_windows/update_comfyui_and_python_dependencies.bat\" ] && chmod 755 .ci/update_windows/update_comfyui_and_python_dependencies.bat\n",
|
||||||
|
" ![ -f \".ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat\" ] && chmod 755 .ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat\n",
|
||||||
|
" ![ -f \".ci/update_windows/update.py\" ] && chmod 755 .ci/update_windows/update.py\n",
|
||||||
|
" ![ -f \".ci/update_windows/update_comfyui.bat\" ] && chmod 755 .ci/update_windows/update_comfyui.bat\n",
|
||||||
|
" ![ -f \".ci/update_windows/README_VERY_IMPORTANT.txt\" ] && chmod 755 .ci/update_windows/README_VERY_IMPORTANT.txt\n",
|
||||||
|
" ![ -f \".ci/update_windows/run_cpu.bat\" ] && chmod 755 .ci/update_windows/run_cpu.bat\n",
|
||||||
|
" ![ -f \".ci/update_windows/run_nvidia_gpu.bat\" ] && chmod 755 .ci/update_windows/run_nvidia_gpu.bat\n",
|
||||||
|
"\n",
|
||||||
" !git pull\n",
|
" !git pull\n",
|
||||||
"\n",
|
"\n",
|
||||||
"!echo -= Install dependencies =-\n",
|
"!echo -= Install dependencies =-\n",
|
||||||
"#Remove cu121 as it causes issues in Colab.\n",
|
|
||||||
"#!pip install xformers!=0.0.18 -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cu121 --extra-index-url https://download.pytorch.org/whl/cu118 --extra-index-url https://download.pytorch.org/whl/cu117\n",
|
|
||||||
"!pip3 install accelerate\n",
|
"!pip3 install accelerate\n",
|
||||||
"!pip3 install einops transformers>=4.25.1 safetensors>=0.3.0 aiohttp pyyaml Pillow scipy tqdm psutil\n",
|
"!pip3 install einops transformers>=4.25.1 safetensors>=0.3.0 aiohttp pyyaml Pillow scipy tqdm psutil\n",
|
||||||
"!pip3 install xformers!=0.0.18 torch==2.1.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121\n",
|
"!pip3 install xformers!=0.0.18 torch==2.1.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121\n",
|
||||||
@ -62,6 +72,14 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"if OPTIONS['USE_COMFYUI_MANAGER']:\n",
|
"if OPTIONS['USE_COMFYUI_MANAGER']:\n",
|
||||||
" %cd custom_nodes\n",
|
" %cd custom_nodes\n",
|
||||||
|
"\n",
|
||||||
|
" # Correction of the issue of permissions being deleted on Google Drive.\n",
|
||||||
|
" ![ -f \"ComfyUI-Manager/check.sh\" ] && chmod 755 ComfyUI-Manager/check.sh\n",
|
||||||
|
" ![ -f \"ComfyUI-Manager/scan.sh\" ] && chmod 755 ComfyUI-Manager/scan.sh\n",
|
||||||
|
" ![ -f \"ComfyUI-Manager/node_db/dev/scan.sh\" ] && chmod 755 ComfyUI-Manager/node_db/dev/scan.sh\n",
|
||||||
|
" ![ -f \"ComfyUI-Manager/scripts/install-comfyui-venv-linux.sh\" ] && chmod 755 ComfyUI-Manager/scripts/install-comfyui-venv-linux.sh\n",
|
||||||
|
" ![ -f \"ComfyUI-Manager/scripts/install-comfyui-venv-win.bat\" ] && chmod 755 ComfyUI-Manager/scripts/install-comfyui-venv-win.bat\n",
|
||||||
|
"\n",
|
||||||
" ![ ! -d ComfyUI-Manager ] && echo -= Initial setup ComfyUI-Manager =- && git clone https://github.com/ltdrdata/ComfyUI-Manager\n",
|
" ![ ! -d ComfyUI-Manager ] && echo -= Initial setup ComfyUI-Manager =- && git clone https://github.com/ltdrdata/ComfyUI-Manager\n",
|
||||||
" %cd ComfyUI-Manager\n",
|
" %cd ComfyUI-Manager\n",
|
||||||
" !git pull\n",
|
" !git pull\n",
|
||||||
@ -69,9 +87,9 @@
|
|||||||
"%cd $WORKSPACE\n",
|
"%cd $WORKSPACE\n",
|
||||||
"\n",
|
"\n",
|
||||||
"if OPTIONS['INSTALL_CUSTOM_NODES_DEPENDENCIES']:\n",
|
"if OPTIONS['INSTALL_CUSTOM_NODES_DEPENDENCIES']:\n",
|
||||||
" !pwd\n",
|
|
||||||
" !echo -= Install custom nodes dependencies =-\n",
|
" !echo -= Install custom nodes dependencies =-\n",
|
||||||
" ![ -f \"custom_nodes/ComfyUI-Manager/scripts/colab-dependencies.py\" ] && python \"custom_nodes/ComfyUI-Manager/scripts/colab-dependencies.py\"\n"
|
" !pip install GitPython\n",
|
||||||
|
" !python custom_nodes/ComfyUI-Manager/cm-cli.py restore-dependencies\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
21
pip_overrides.json.template
Normal file
21
pip_overrides.json.template
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"imageio-ffmpeg": "imageio",
|
||||||
|
"imageio[ffmpeg]": "imageio",
|
||||||
|
"imageio_ffmpeg": "imageio",
|
||||||
|
"diffusers~=0.21.4": "diffusers",
|
||||||
|
"huggingface_hub": "huggingface-hub",
|
||||||
|
"numpy<1.24>=1.18": "numpy",
|
||||||
|
"numpy>=1.18.5, <1.25.0": "numpy",
|
||||||
|
"opencv-contrib-python": "opencv-contrib-python-headless",
|
||||||
|
"opencv-python": "opencv-contrib-python-headless",
|
||||||
|
"opencv-python-headless": "opencv-contrib-python-headless",
|
||||||
|
"opencv-python-headless[ffmpeg]<=4.7.0.72": "opencv-contrib-python-headless",
|
||||||
|
"opencv-python>=4.7.0.72": "opencv-contrib-python-headless",
|
||||||
|
"pandas<=1.5.1": "pandas",
|
||||||
|
"scikit-image==0.20.0": "scikit-image",
|
||||||
|
"scipy>=1.11.4": "scipy",
|
||||||
|
"segment_anything": "segment-anything",
|
||||||
|
"timm==0.6.5": "timm",
|
||||||
|
"timm>=0.4.12": "timm",
|
||||||
|
"transformers==4.26.1": "transformers"
|
||||||
|
}
|
||||||
@ -7,13 +7,13 @@ import threading
|
|||||||
import re
|
import re
|
||||||
import locale
|
import locale
|
||||||
import platform
|
import platform
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
from manager_util import *
|
from manager_util import *
|
||||||
|
|
||||||
import cm_global
|
import cm_global
|
||||||
|
|
||||||
|
|
||||||
@ -69,6 +69,23 @@ custom_nodes_path = os.path.abspath(os.path.join(comfyui_manager_path, ".."))
|
|||||||
startup_script_path = os.path.join(comfyui_manager_path, "startup-scripts")
|
startup_script_path = os.path.join(comfyui_manager_path, "startup-scripts")
|
||||||
restore_snapshot_path = os.path.join(startup_script_path, "restore-snapshot.json")
|
restore_snapshot_path = os.path.join(startup_script_path, "restore-snapshot.json")
|
||||||
git_script_path = os.path.join(comfyui_manager_path, "git_helper.py")
|
git_script_path = os.path.join(comfyui_manager_path, "git_helper.py")
|
||||||
|
pip_overrides_path = os.path.join(comfyui_manager_path, "pip_overrides.json")
|
||||||
|
|
||||||
|
|
||||||
|
cm_global.pip_overrides = {}
|
||||||
|
if os.path.exists(pip_overrides_path):
|
||||||
|
with open(pip_overrides_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
|
||||||
|
cm_global.pip_overrides = json.load(json_file)
|
||||||
|
|
||||||
|
|
||||||
|
def remap_pip_package(pkg):
|
||||||
|
if pkg in cm_global.pip_overrides:
|
||||||
|
res = cm_global.pip_overrides[pkg]
|
||||||
|
print(f"[ComfyUI-Manager] '{pkg}' is remapped to '{res}'")
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
return pkg
|
||||||
|
|
||||||
|
|
||||||
std_log_lock = threading.Lock()
|
std_log_lock = threading.Lock()
|
||||||
|
|
||||||
@ -283,6 +300,30 @@ except Exception as e:
|
|||||||
print(f"[ComfyUI-Manager] Logging failed: {e}")
|
print(f"[ComfyUI-Manager] Logging failed: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
import git
|
||||||
|
except:
|
||||||
|
my_path = os.path.dirname(__file__)
|
||||||
|
requirements_path = os.path.join(my_path, "requirements.txt")
|
||||||
|
|
||||||
|
print(f"## ComfyUI-Manager: installing dependencies. (GitPython)")
|
||||||
|
|
||||||
|
result = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'install', '-r', requirements_path])
|
||||||
|
|
||||||
|
try:
|
||||||
|
import git
|
||||||
|
except:
|
||||||
|
print(f"## [ERROR] ComfyUI-Manager: Attempting to reinstall dependencies using an alternative method.")
|
||||||
|
result = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'install', '--user', '-r', requirements_path])
|
||||||
|
|
||||||
|
try:
|
||||||
|
import git
|
||||||
|
except:
|
||||||
|
print(f"## [ERROR] ComfyUI-Manager: Failed to install the GitPython package in the correct Python environment. Please install it manually in the appropriate environment. (You can seek help at https://app.element.io/#/room/%23comfyui_space%3Amatrix.org)")
|
||||||
|
|
||||||
|
print(f"## ComfyUI-Manager: installing dependencies done.")
|
||||||
|
|
||||||
|
|
||||||
print("** ComfyUI startup time:", datetime.datetime.now())
|
print("** ComfyUI startup time:", datetime.datetime.now())
|
||||||
print("** Platform:", platform.system())
|
print("** Platform:", platform.system())
|
||||||
print("** Python version:", sys.version)
|
print("** Python version:", sys.version)
|
||||||
@ -391,8 +432,6 @@ def is_installed(name):
|
|||||||
|
|
||||||
if os.path.exists(restore_snapshot_path):
|
if os.path.exists(restore_snapshot_path):
|
||||||
try:
|
try:
|
||||||
import json
|
|
||||||
|
|
||||||
cloned_repos = []
|
cloned_repos = []
|
||||||
|
|
||||||
def msg_capture(stream, prefix):
|
def msg_capture(stream, prefix):
|
||||||
@ -420,8 +459,7 @@ if os.path.exists(restore_snapshot_path):
|
|||||||
cmd_str = [sys.executable, git_script_path, '--apply-snapshot', restore_snapshot_path]
|
cmd_str = [sys.executable, git_script_path, '--apply-snapshot', restore_snapshot_path]
|
||||||
exit_code = process_wrap(cmd_str, custom_nodes_path, handler=msg_capture)
|
exit_code = process_wrap(cmd_str, custom_nodes_path, handler=msg_capture)
|
||||||
|
|
||||||
with open(restore_snapshot_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
|
repository_name = ''
|
||||||
info = json.load(json_file)
|
|
||||||
for url in cloned_repos:
|
for url in cloned_repos:
|
||||||
try:
|
try:
|
||||||
repository_name = url.split("/")[-1].strip()
|
repository_name = url.split("/")[-1].strip()
|
||||||
@ -436,7 +474,7 @@ if os.path.exists(restore_snapshot_path):
|
|||||||
if os.path.exists(requirements_path):
|
if os.path.exists(requirements_path):
|
||||||
with open(requirements_path, 'r', encoding="UTF-8", errors="ignore") as file:
|
with open(requirements_path, 'r', encoding="UTF-8", errors="ignore") as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
package_name = line.strip()
|
package_name = remap_pip_package(line.strip())
|
||||||
if package_name and not is_installed(package_name):
|
if package_name and not is_installed(package_name):
|
||||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||||
this_exit_code += process_wrap(install_cmd, repo_path)
|
this_exit_code += process_wrap(install_cmd, repo_path)
|
||||||
@ -476,7 +514,7 @@ def execute_lazy_install_script(repo_path, executable):
|
|||||||
print(f"Install: pip packages for '{repo_path}'")
|
print(f"Install: pip packages for '{repo_path}'")
|
||||||
with open(requirements_path, "r") as requirements_file:
|
with open(requirements_path, "r") as requirements_file:
|
||||||
for line in requirements_file:
|
for line in requirements_file:
|
||||||
package_name = line.strip()
|
package_name = remap_pip_package(line.strip())
|
||||||
if package_name and not is_installed(package_name):
|
if package_name and not is_installed(package_name):
|
||||||
install_cmd = [executable, "-m", "pip", "install", package_name]
|
install_cmd = [executable, "-m", "pip", "install", package_name]
|
||||||
process_wrap(install_cmd, repo_path)
|
process_wrap(install_cmd, repo_path)
|
||||||
|
|||||||
13
scanner.py
13
scanner.py
@ -14,7 +14,6 @@ import sys
|
|||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from github import Github
|
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:
|
||||||
@ -25,7 +24,15 @@ else:
|
|||||||
if not os.path.exists(temp_dir):
|
if not os.path.exists(temp_dir):
|
||||||
os.makedirs(temp_dir)
|
os.makedirs(temp_dir)
|
||||||
|
|
||||||
skip_update = '--skip-update' in sys.argv
|
|
||||||
|
skip_update = '--skip-update' in sys.argv or '--skip-all' in sys.argv
|
||||||
|
skip_stat_update = '--skip-stat-update' in sys.argv or '--skip-all' in sys.argv
|
||||||
|
|
||||||
|
if not skip_stat_update:
|
||||||
|
g = Github(os.environ.get('GITHUB_TOKEN'))
|
||||||
|
else:
|
||||||
|
g = None
|
||||||
|
|
||||||
|
|
||||||
print(f"TEMP DIR: {temp_dir}")
|
print(f"TEMP DIR: {temp_dir}")
|
||||||
|
|
||||||
@ -301,7 +308,9 @@ def update_custom_nodes():
|
|||||||
# pass
|
# pass
|
||||||
|
|
||||||
with concurrent.futures.ThreadPoolExecutor(11) as executor:
|
with concurrent.futures.ThreadPoolExecutor(11) as executor:
|
||||||
|
if not skip_stat_update:
|
||||||
executor.submit(process_git_stats, git_url_titles_preemptions) # One single thread for `process_git_stats()`. Runs concurrently with `process_git_url_title()`.
|
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)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user