fix: mismatches caused by manager-core integration

This commit is contained in:
Dr.Lt.Data 2024-12-19 09:29:30 +09:00
parent e4bb21f25c
commit a44d1fbd37
4 changed files with 136 additions and 110 deletions

View File

@ -31,6 +31,8 @@ sys.path.append(glob_path)
import cm_global import cm_global
import cnr_utils import cnr_utils
import manager_util import manager_util
import manager_downloader
version_code = [3, 0] version_code = [3, 0]
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
@ -872,7 +874,7 @@ class UnifiedManager:
archive_name = f"CNR_temp_{str(uuid.uuid4())}.zip" # should be unpredictable name - security precaution archive_name = f"CNR_temp_{str(uuid.uuid4())}.zip" # should be unpredictable name - security precaution
download_path = os.path.join(get_default_custom_nodes_path(), archive_name) download_path = os.path.join(get_default_custom_nodes_path(), archive_name)
manager_util.download_url(node_info.download_url, get_default_custom_nodes_path(), archive_name) manager_downloader.download_url(node_info.download_url, get_default_custom_nodes_path(), archive_name)
# 2. extract files into <node_id>@<cur_ver> # 2. extract files into <node_id>@<cur_ver>
install_path = self.active_nodes[node_id][1] install_path = self.active_nodes[node_id][1]
@ -1142,7 +1144,7 @@ class UnifiedManager:
if os.path.exists(install_path): if os.path.exists(install_path):
return result.fail(f'Install path already exists: {install_path}') return result.fail(f'Install path already exists: {install_path}')
manager_util.download_url(node_info.download_url, get_default_custom_nodes_path(), archive_name) manager_downloader.download_url(node_info.download_url, get_default_custom_nodes_path(), archive_name)
os.makedirs(install_path, exist_ok=True) os.makedirs(install_path, exist_ok=True)
extracted = manager_util.extract_package_as_zip(download_path, install_path) extracted = manager_util.extract_package_as_zip(download_path, install_path)
os.remove(download_path) os.remove(download_path)
@ -2232,6 +2234,19 @@ def lookup_customnode_by_url(data, target):
return None return None
def lookup_installed_custom_nodes_legacy(repo_name):
base_paths = get_custom_nodes_paths()
for base_path in base_paths:
repo_path = os.path.join(base_path, repo_name)
if os.path.exists(repo_path):
return True, repo_path
elif os.path.exists(repo_path + '.disabled'):
return False, repo_path
return None
def simple_check_custom_node(url): def simple_check_custom_node(url):
dir_name = os.path.splitext(os.path.basename(url))[0].replace(".git", "") dir_name = os.path.splitext(os.path.basename(url))[0].replace(".git", "")
dir_path = os.path.join(get_default_custom_nodes_path(), dir_name) dir_path = os.path.join(get_default_custom_nodes_path(), dir_name)

View File

@ -1,5 +1,7 @@
import os import os
from urllib.parse import urlparse from urllib.parse import urlparse
import urllib
import sys
aria2 = os.getenv('COMFYUI_MANAGER_ARIA2_SERVER') aria2 = os.getenv('COMFYUI_MANAGER_ARIA2_SERVER')
HF_ENDPOINT = os.getenv('HF_ENDPOINT') HF_ENDPOINT = os.getenv('HF_ENDPOINT')
@ -14,12 +16,32 @@ if aria2 is not None:
aria2 = aria2p.API(aria2p.Client(host=host, port=port, secret=secret)) aria2 = aria2p.API(aria2p.Client(host=host, port=port, secret=secret))
def basic_download_url(url, dest_folder, filename):
import requests
# Ensure the destination folder exists
if not os.path.exists(dest_folder):
os.makedirs(dest_folder)
# Full path to save the file
dest_path = os.path.join(dest_folder, filename)
# Download the file
response = requests.get(url, stream=True)
if response.status_code == 200:
with open(dest_path, 'wb') as file:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
file.write(chunk)
else:
raise Exception(f"Failed to download file from {url}")
def download_url(model_url: str, model_dir: str, filename: str): def download_url(model_url: str, model_dir: str, filename: str):
if aria2: if aria2:
return aria2_download_url(model_url, model_dir, filename) return aria2_download_url(model_url, model_dir, filename)
else: else:
from torchvision.datasets.utils import download_url as torchvision_download_url from torchvision.datasets.utils import download_url as torchvision_download_url
return torchvision_download_url(model_url, model_dir, filename) return torchvision_download_url(model_url, model_dir, filename)
@ -68,3 +90,26 @@ def aria2_download_url(model_url: str, model_dir: str, filename: str):
progress_bar.update(download.completed_length - progress_bar.n) progress_bar.update(download.completed_length - progress_bar.n)
time.sleep(1) time.sleep(1)
download.update() download.update()
def download_url_with_agent(url, save_path):
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
req = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(req)
data = response.read()
if not os.path.exists(os.path.dirname(save_path)):
os.makedirs(os.path.dirname(save_path))
with open(save_path, 'wb') as f:
f.write(data)
except Exception as e:
print(f"Download error: {url} / {e}", file=sys.stderr)
return False
print("Installation was successful.")
return True

View File

@ -17,6 +17,7 @@ from server import PromptServer
import manager_core as core import manager_core as core
import manager_util import manager_util
import cm_global import cm_global
import logging
print(f"### Loading: ComfyUI-Manager ({core.version_str})") print(f"### Loading: ComfyUI-Manager ({core.version_str})")
@ -125,7 +126,7 @@ core.manager_funcs = ManagerFuncsInComfyUI()
sys.path.append('../..') sys.path.append('../..')
from manager_downloader import download_url from manager_downloader import download_url, download_url_with_agent
core.comfy_path = os.path.dirname(folder_paths.__file__) core.comfy_path = os.path.dirname(folder_paths.__file__)
core.js_path = os.path.join(core.comfy_path, "web", "extensions") core.js_path = os.path.join(core.comfy_path, "web", "extensions")
@ -187,14 +188,11 @@ def print_comfyui_version():
is_detached = repo.head.is_detached is_detached = repo.head.is_detached
current_branch = repo.active_branch.name current_branch = repo.active_branch.name
if current_branch == "master": comfyui_tag = core.get_comfyui_tag()
comfyui_tag = repo.git.describe('--tags', repo.heads.main.commit.hexsha)
if not comfyui_tag.startswith("v"):
comfyui_tag = None
try: try:
if core.comfy_ui_commit_datetime.date() < core.comfy_ui_required_commit_datetime.date(): if core.comfy_ui_commit_datetime.date() < core.comfy_ui_required_commit_datetime.date():
print(f"\n\n## [WARN] ComfyUI-Manager: Your ComfyUI version ({core.get_comfyui_tag()})[{core.comfy_ui_commit_datetime.date()}] is too old. Please update to the latest version. ##\n\n") print(f"\n\n## [WARN] ComfyUI-Manager: Your ComfyUI version ({core.comfy_ui_revision})[{core.comfy_ui_commit_datetime.date()}] is too old. Please update to the latest version. ##\n\n")
except: except:
pass pass
@ -213,11 +211,13 @@ def print_comfyui_version():
# <-- # <--
if current_branch == "master": if current_branch == "master":
version_tag = core.get_comfyui_tag() if comfyui_tag:
if version_tag is None: print(f"### ComfyUI Version: {comfyui_tag} | Released on '{core.comfy_ui_commit_datetime.date()}'")
else:
print(f"### ComfyUI Revision: {core.comfy_ui_revision} [{comfy_ui_hash[:8]}] | Released on '{core.comfy_ui_commit_datetime.date()}'") print(f"### ComfyUI Revision: {core.comfy_ui_revision} [{comfy_ui_hash[:8]}] | Released on '{core.comfy_ui_commit_datetime.date()}'")
else: else:
print(f"### ComfyUI Version: {core.get_comfyui_tag()} | Released on '{core.comfy_ui_commit_datetime.date()}'") if comfyui_tag:
print(f"### ComfyUI Version: {comfyui_tag} on '{current_branch}' | Released on '{core.comfy_ui_commit_datetime.date()}'")
else: else:
print(f"### ComfyUI Revision: {core.comfy_ui_revision} on '{current_branch}' [{comfy_ui_hash[:8]}] | Released on '{core.comfy_ui_commit_datetime.date()}'") print(f"### ComfyUI Revision: {core.comfy_ui_revision} on '{current_branch}' [{comfy_ui_hash[:8]}] | Released on '{core.comfy_ui_commit_datetime.date()}'")
except: except:
@ -231,6 +231,7 @@ print_comfyui_version()
core.check_invalid_nodes() core.check_invalid_nodes()
def setup_environment(): def setup_environment():
git_exe = core.get_config()['git_exe'] git_exe = core.get_config()['git_exe']
@ -249,7 +250,7 @@ import zipfile
import urllib.request import urllib.request
def get_model_dir(data): def get_model_dir(data, show_log=False):
if 'download_model_base' in folder_paths.folder_names_and_paths: if 'download_model_base' in folder_paths.folder_names_and_paths:
models_base = folder_paths.folder_names_and_paths['download_model_base'][0][0] models_base = folder_paths.folder_names_and_paths['download_model_base'][0][0]
else: else:
@ -258,7 +259,9 @@ def get_model_dir(data):
def resolve_custom_node(save_path): def resolve_custom_node(save_path):
save_path = save_path[13:] # remove 'custom_nodes/' save_path = save_path[13:] # remove 'custom_nodes/'
repo_name = save_path.replace('\\','/').split('/')[0] # get custom node repo name repo_name = save_path.replace('\\','/').split('/')[0] # get custom node repo name
repo_path = core.lookup_installed_custom_nodes(repo_name)
# NOTE: The creation of files within the custom node path should be removed in the future.
repo_path = core.lookup_installed_custom_nodes_legacy(repo_name)
if repo_path is not None and repo_path[0]: if repo_path is not None and repo_path[0]:
# Returns the retargeted path based on the actually installed repository # Returns the retargeted path based on the actually installed repository
return os.path.join(os.path.dirname(repo_path[1]), save_path) return os.path.join(os.path.dirname(repo_path[1]), save_path)
@ -267,13 +270,15 @@ def get_model_dir(data):
if data['save_path'] != 'default': if data['save_path'] != 'default':
if '..' in data['save_path'] or data['save_path'].startswith('/'): if '..' in data['save_path'] or data['save_path'].startswith('/'):
print(f"[WARN] '{data['save_path']}' is not allowed path. So it will be saved into 'models/etc'.") if show_log:
logging.info(f"[WARN] '{data['save_path']}' is not allowed path. So it will be saved into 'models/etc'.")
base_model = os.path.join(models_base, "etc") base_model = os.path.join(models_base, "etc")
else: else:
if data['save_path'].startswith("custom_nodes"): if data['save_path'].startswith("custom_nodes"):
base_model = resolve_custom_node(data['save_path']) base_model = resolve_custom_node(data['save_path'])
if base_model is None: if base_model is None:
print(f"[ComfyUI-Manager] The target custom node for model download is not installed: {data['save_path']}") if show_log:
logging.info(f"[ComfyUI-Manager] The target custom node for model download is not installed: {data['save_path']}")
return None return None
else: else:
base_model = os.path.join(models_base, data['save_path']) base_model = os.path.join(models_base, data['save_path'])
@ -287,7 +292,8 @@ def get_model_dir(data):
if folder_paths.folder_names_and_paths.get("text_encoders"): if folder_paths.folder_names_and_paths.get("text_encoders"):
base_model = folder_paths.folder_names_and_paths["text_encoders"][0][0] base_model = folder_paths.folder_names_and_paths["text_encoders"][0][0]
else: else:
print("[ComfyUI-Manager] Your ComfyUI is outdated version.") if show_log:
logging.info("[ComfyUI-Manager] Your ComfyUI is outdated version.")
base_model = folder_paths.folder_names_and_paths["clip"][0][0] # outdated version base_model = folder_paths.folder_names_and_paths["clip"][0][0] # outdated version
elif model_type == "VAE": elif model_type == "VAE":
base_model = folder_paths.folder_names_and_paths["vae"][0][0] base_model = folder_paths.folder_names_and_paths["vae"][0][0]
@ -311,7 +317,8 @@ def get_model_dir(data):
if folder_paths.folder_names_and_paths.get("diffusion_models"): if folder_paths.folder_names_and_paths.get("diffusion_models"):
base_model = folder_paths.folder_names_and_paths["diffusion_models"][0][1] base_model = folder_paths.folder_names_and_paths["diffusion_models"][0][1]
else: else:
print("[ComfyUI-Manager] Your ComfyUI is outdated version.") if show_log:
logging.info("[ComfyUI-Manager] Your ComfyUI is outdated version.")
base_model = folder_paths.folder_names_and_paths["unet"][0][0] # outdated version base_model = folder_paths.folder_names_and_paths["unet"][0][0] # outdated version
else: else:
base_model = os.path.join(models_base, "etc") base_model = os.path.join(models_base, "etc")
@ -319,8 +326,8 @@ def get_model_dir(data):
return base_model return base_model
def get_model_path(data): def get_model_path(data, show_log=False):
base_model = get_model_dir(data) base_model = get_model_dir(data, show_log)
if base_model is None: if base_model is None:
return None return None
else: else:
@ -488,13 +495,13 @@ async def update_all(request):
traceback.print_exc() traceback.print_exc()
return web.Response(status=400) return web.Response(status=400)
finally: finally:
core.clear_pip_cache() manager_util.clear_pip_cache()
def convert_markdown_to_html(input_text): def convert_markdown_to_html(input_text):
pattern_a = re.compile(r'\[a/([^]]+)\]\(([^)]+)\)') pattern_a = re.compile(r'\[a/([^]]+)]\(([^)]+)\)')
pattern_w = re.compile(r'\[w/([^]]+)\]') pattern_w = re.compile(r'\[w/([^]]+)]')
pattern_i = re.compile(r'\[i/([^]]+)\]') pattern_i = re.compile(r'\[i/([^]]+)]')
pattern_bold = re.compile(r'\*\*([^*]+)\*\*') pattern_bold = re.compile(r'\*\*([^*]+)\*\*')
pattern_white = re.compile(r'%%([^*]+)%%') pattern_white = re.compile(r'%%([^*]+)%%')
@ -594,7 +601,7 @@ async def fetch_customnode_alternatives(request):
def check_model_installed(json_obj): def check_model_installed(json_obj):
def process_model(item): def process_model(item):
model_path = get_model_path(item) model_path = get_model_path(item, False)
item['installed'] = 'None' item['installed'] = 'None'
if model_path is not None: if model_path is not None:
@ -627,7 +634,7 @@ async def fetch_externalmodel_list(request):
@PromptServer.instance.routes.get("/snapshot/getlist") @PromptServer.instance.routes.get("/snapshot/getlist")
async def get_snapshot_list(request): async def get_snapshot_list(request):
snapshots_directory = os.path.join(core.comfyui_manager_path, 'snapshots') snapshots_directory = os.path.join(manager_util.comfyui_manager_path, 'snapshots')
items = [f[:-5] for f in os.listdir(snapshots_directory) if f.endswith('.json')] items = [f[:-5] for f in os.listdir(snapshots_directory) if f.endswith('.json')]
items.sort(reverse=True) items.sort(reverse=True)
return web.json_response({'items': items}, content_type='application/json') return web.json_response({'items': items}, content_type='application/json')
@ -642,7 +649,7 @@ async def remove_snapshot(request):
try: try:
target = request.rel_url.query["target"] target = request.rel_url.query["target"]
path = os.path.join(core.comfyui_manager_path, 'snapshots', f"{target}.json") path = os.path.join(manager_util.comfyui_manager_path, 'snapshots', f"{target}.json")
if os.path.exists(path): if os.path.exists(path):
os.remove(path) os.remove(path)
@ -660,7 +667,7 @@ async def restore_snapshot(request):
try: try:
target = request.rel_url.query["target"] target = request.rel_url.query["target"]
path = os.path.join(core.comfyui_manager_path, 'snapshots', f"{target}.json") path = os.path.join(manager_util.comfyui_manager_path, 'snapshots', f"{target}.json")
if os.path.exists(path): if os.path.exists(path):
if not os.path.exists(core.startup_script_path): if not os.path.exists(core.startup_script_path):
os.makedirs(core.startup_script_path) os.makedirs(core.startup_script_path)
@ -711,7 +718,7 @@ def unzip_install(files):
f.write(data) f.write(data)
with zipfile.ZipFile(temp_filename, 'r') as zip_ref: with zipfile.ZipFile(temp_filename, 'r') as zip_ref:
zip_ref.extractall(core.custom_nodes_path) zip_ref.extractall(core.get_default_custom_nodes_path())
os.remove(temp_filename) os.remove(temp_filename)
except Exception as e: except Exception as e:
@ -722,29 +729,6 @@ def unzip_install(files):
return True return True
def download_url_with_agent(url, save_path):
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
req = urllib.request.Request(url, headers=headers)
response = urllib.request.urlopen(req)
data = response.read()
if not os.path.exists(os.path.dirname(save_path)):
os.makedirs(os.path.dirname(save_path))
with open(save_path, 'wb') as f:
f.write(data)
except Exception as e:
print(f"Download error: {url} / {e}", file=sys.stderr)
return False
print("Installation was successful.")
return True
def copy_install(files, js_path_name=None): def copy_install(files, js_path_name=None):
for url in files: for url in files:
if url.endswith("/"): if url.endswith("/"):
@ -752,7 +736,7 @@ def copy_install(files, js_path_name=None):
try: try:
filename = os.path.basename(url) filename = os.path.basename(url)
if url.endswith(".py"): if url.endswith(".py"):
download_url(url, core.custom_nodes_path, filename) download_url(url, core.get_default_custom_nodes_path(), filename)
else: else:
path = os.path.join(core.js_path, js_path_name) if js_path_name is not None else core.js_path path = os.path.join(core.js_path, js_path_name) if js_path_name is not None else core.js_path
if not os.path.exists(path): if not os.path.exists(path):
@ -772,7 +756,7 @@ def copy_uninstall(files, js_path_name='.'):
if url.endswith("/"): if url.endswith("/"):
url = url[:-1] url = url[:-1]
dir_name = os.path.basename(url) dir_name = os.path.basename(url)
base_path = core.custom_nodes_path if url.endswith('.py') else os.path.join(core.js_path, js_path_name) base_path = core.get_default_custom_nodes_path() if url.endswith('.py') else os.path.join(core.js_path, js_path_name)
file_path = os.path.join(base_path, dir_name) file_path = os.path.join(base_path, dir_name)
try: try:
@ -798,7 +782,7 @@ def copy_set_active(files, is_disable, js_path_name='.'):
if url.endswith("/"): if url.endswith("/"):
url = url[:-1] url = url[:-1]
dir_name = os.path.basename(url) dir_name = os.path.basename(url)
base_path = core.custom_nodes_path if url.endswith('.py') else os.path.join(core.js_path, js_path_name) base_path = core.get_default_custom_nodes_path() if url.endswith('.py') else os.path.join(core.js_path, js_path_name)
file_path = os.path.join(base_path, dir_name) file_path = os.path.join(base_path, dir_name)
try: try:
@ -857,7 +841,7 @@ async def reinstall_custom_node(request):
async def install_custom_node(request): async def install_custom_node(request):
if not is_allowed_security_level('middle'): if not is_allowed_security_level('middle'):
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW) print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
return web.Response(status=403) return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
json_data = await request.json() json_data = await request.json()
@ -884,28 +868,28 @@ async def install_custom_node(request):
if not is_allowed_security_level(risky_level): if not is_allowed_security_level(risky_level):
print(SECURITY_MESSAGE_GENERAL) print(SECURITY_MESSAGE_GENERAL)
return web.Response(status=404) return web.Response(status=404, text="A security error has occurred. Please check the terminal logs")
node_spec = core.unified_manager.resolve_node_spec(node_spec_str) node_spec = core.unified_manager.resolve_node_spec(node_spec_str)
if node_spec is None: if node_spec is None:
return return web.Response(status=400, text=f"Cannot resolve install target: '{node_spec_str}'")
node_name, version_spec, is_specified = node_spec node_name, version_spec, is_specified = node_spec
res = await core.unified_manager.install_by_id(node_name, version_spec, json_data['channel'], json_data['mode'], return_postinstall=skip_post_install) res = await core.unified_manager.install_by_id(node_name, version_spec, json_data['channel'], json_data['mode'], return_postinstall=skip_post_install)
# discard post install if skip_post_install mode # discard post install if skip_post_install mode
if res not in ['skip', 'enable', 'install-git', 'install-cnr', 'switch-cnr']: if res.action not in ['skip', 'enable', 'install-git', 'install-cnr', 'switch-cnr']:
return web.Response(status=400) return web.Response(status=400, text=f"Installation failed: {res}")
return web.Response(status=200) return web.Response(status=200, text="Installation success.")
@routes.post("/customnode/fix") @routes.post("/customnode/fix")
async def fix_custom_node(request): async def fix_custom_node(request):
if not is_allowed_security_level('middle'): if not is_allowed_security_level('middle'):
print(SECURITY_MESSAGE_GENERAL) print(SECURITY_MESSAGE_GENERAL)
return web.Response(status=403) return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
json_data = await request.json() json_data = await request.json()
@ -924,7 +908,7 @@ async def fix_custom_node(request):
return web.json_response({}, content_type='application/json') return web.json_response({}, content_type='application/json')
print(f"ERROR: An error occurred while fixing '{node_name}@{node_ver}'.") print(f"ERROR: An error occurred while fixing '{node_name}@{node_ver}'.")
return web.Response(status=400) return web.Response(status=400, text=f"An error occurred while fixing '{node_name}@{node_ver}'.")
@routes.post("/customnode/install/git_url") @routes.post("/customnode/install/git_url")
@ -963,7 +947,7 @@ async def install_custom_node_pip(request):
async def uninstall_custom_node(request): async def uninstall_custom_node(request):
if not is_allowed_security_level('middle'): if not is_allowed_security_level('middle'):
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW) print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
return web.Response(status=403) return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
json_data = await request.json() json_data = await request.json()
@ -983,14 +967,14 @@ async def uninstall_custom_node(request):
return web.json_response({}, content_type='application/json') return web.json_response({}, content_type='application/json')
print(f"ERROR: An error occurred while uninstalling '{node_name}'.") print(f"ERROR: An error occurred while uninstalling '{node_name}'.")
return web.Response(status=400) return web.Response(status=400, text=f"An error occurred while uninstalling '{node_name}'.")
@routes.post("/customnode/update") @routes.post("/customnode/update")
async def update_custom_node(request): async def update_custom_node(request):
if not is_allowed_security_level('middle'): if not is_allowed_security_level('middle'):
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW) print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
return web.Response(status=403) return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
json_data = await request.json() json_data = await request.json()
@ -1003,14 +987,14 @@ async def update_custom_node(request):
res = core.unified_manager.unified_update(node_name, json_data['version']) res = core.unified_manager.unified_update(node_name, json_data['version'])
core.clear_pip_cache() manager_util.clear_pip_cache()
if res.result: if res.result:
print("After restarting ComfyUI, please refresh the browser.") print("After restarting ComfyUI, please refresh the browser.")
return web.json_response({}, content_type='application/json') return web.json_response({}, content_type='application/json')
print(f"ERROR: An error occurred while updating '{node_name}'.") print(f"ERROR: An error occurred while updating '{node_name}'.")
return web.Response(status=400) return web.Response(status=400, text=f"An error occurred while updating '{node_name}'.")
@routes.get("/comfyui_manager/update_comfyui") @routes.get("/comfyui_manager/update_comfyui")
@ -1075,7 +1059,7 @@ async def disable_node(request):
if res: if res:
return web.json_response({}, content_type='application/json') return web.json_response({}, content_type='application/json')
return web.Response(status=400) return web.Response(status=400, text="Failed to disable")
@routes.get("/manager/migrate_unmanaged_nodes") @routes.get("/manager/migrate_unmanaged_nodes")
@ -1123,7 +1107,7 @@ async def install_model(request):
model_url = json_data['url'] model_url = json_data['url']
if not core.get_config()['model_download_by_agent'] and ( if not core.get_config()['model_download_by_agent'] and (
model_url.startswith('https://github.com') or model_url.startswith('https://huggingface.co') or model_url.startswith('https://heibox.uni-heidelberg.de')): model_url.startswith('https://github.com') or model_url.startswith('https://huggingface.co') or model_url.startswith('https://heibox.uni-heidelberg.de')):
model_dir = get_model_dir(json_data) model_dir = get_model_dir(json_data, True)
download_url(model_url, model_dir, filename=json_data['filename']) download_url(model_url, model_dir, filename=json_data['filename'])
if model_path.endswith('.zip'): if model_path.endswith('.zip'):
res = core.unzip(model_path) res = core.unzip(model_path)
@ -1147,7 +1131,7 @@ async def install_model(request):
return web.Response(status=400) return web.Response(status=400)
@PromptServer.instance.routes.get("/manager/preview_method") @routes.get("/manager/preview_method")
async def preview_method(request): async def preview_method(request):
if "value" in request.rel_url.query: if "value" in request.rel_url.query:
set_preview_method(request.rel_url.query['value']) set_preview_method(request.rel_url.query['value'])
@ -1306,14 +1290,9 @@ def restart(self):
sys_argv.remove('--windows-standalone-build') sys_argv.remove('--windows-standalone-build')
if sys.platform.startswith('win32'): if sys.platform.startswith('win32'):
return os.execv(sys.executable, ['"' + sys.executable + '"', '"' + sys.argv[0] + '"'] + sys.argv[1:]) return os.execv(sys.executable, ['"' + sys.executable + '"', '"' + sys_argv[0] + '"'] + sys_argv[1:])
else: else:
return os.execv(sys.executable, [sys.executable] + sys.argv) return os.execv(sys.executable, [sys.executable] + sys_argv)
def sanitize_filename(input_string):
result_string = re.sub(r'[^a-zA-Z0-9_]', '_', input_string)
return result_string
@routes.post("/manager/component/save") @routes.post("/manager/component/save")
@ -1327,9 +1306,9 @@ async def save_component(request):
os.mkdir(components_path) os.mkdir(components_path)
if 'packname' in workflow and workflow['packname'] != '': if 'packname' in workflow and workflow['packname'] != '':
sanitized_name = sanitize_filename(workflow['packname']) + '.pack' sanitized_name = manager_util.sanitize_filename(workflow['packname']) + '.pack'
else: else:
sanitized_name = sanitize_filename(name) + '.json' sanitized_name = manager_util.sanitize_filename(name) + '.json'
filepath = os.path.join(components_path, sanitized_name) filepath = os.path.join(components_path, sanitized_name)
components = {} components = {}
@ -1368,10 +1347,6 @@ async def load_components(request):
return web.Response(status=400) return web.Response(status=400)
def sanitize(data):
return data.replace("<", "&lt;").replace(">", "&gt;")
async def _confirm_try_install(sender, custom_node_url, msg): async def _confirm_try_install(sender, custom_node_url, msg):
json_obj = await core.get_data_by_mode('default', 'custom-node-list.json') json_obj = await core.get_data_by_mode('default', 'custom-node-list.json')

View File

@ -5,7 +5,7 @@ import os
from datetime import datetime from datetime import datetime
import subprocess import subprocess
import sys import sys
import re
cache_lock = threading.Lock() cache_lock = threading.Lock()
@ -140,27 +140,6 @@ def sanitize_tag(x):
return x.replace('<', '&lt;').replace('>', '&gt;') return x.replace('<', '&lt;').replace('>', '&gt;')
def download_url(url, dest_folder, filename):
import requests
# Ensure the destination folder exists
if not os.path.exists(dest_folder):
os.makedirs(dest_folder)
# Full path to save the file
dest_path = os.path.join(dest_folder, filename)
# Download the file
response = requests.get(url, stream=True)
if response.status_code == 200:
with open(dest_path, 'wb') as file:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
file.write(chunk)
else:
raise Exception(f"Failed to download file from {url}")
def extract_package_as_zip(file_path, extract_path): def extract_package_as_zip(file_path, extract_path):
import zipfile import zipfile
try: try:
@ -172,8 +151,11 @@ def extract_package_as_zip(file_path, extract_path):
except zipfile.BadZipFile: except zipfile.BadZipFile:
print(f"File '{file_path}' is not a zip or is corrupted.") print(f"File '{file_path}' is not a zip or is corrupted.")
return None return None
pip_map = None pip_map = None
def get_installed_packages(renew=False): def get_installed_packages(renew=False):
global pip_map global pip_map
@ -318,3 +300,12 @@ class PIPFixer:
except Exception as e: except Exception as e:
print("[manager-core] Failed to restore numpy") print("[manager-core] Failed to restore numpy")
print(e) print(e)
def sanitize(data):
return data.replace("<", "&lt;").replace(">", "&gt;")
def sanitize_filename(input_string):
result_string = re.sub(r'[^a-zA-Z0-9_]', '_', input_string)
return result_string