From 9ff6f9d7a3b98035b6a538284686ab4b2654197f Mon Sep 17 00:00:00 2001 From: Hayden <48267247+hayden-fr@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:28:50 +0800 Subject: [PATCH] Revert "File download scans and urls" --- README.md | 2 - __init__.py | 633 ++---------- ...odel-preview-thumbnail-buttons-example.png | Bin 78388 -> 73525 bytes requirements.txt | 1 - web/model-manager.css | 23 +- web/model-manager.js | 928 ++++++------------ 6 files changed, 383 insertions(+), 1204 deletions(-) delete mode 100644 requirements.txt diff --git a/README.md b/README.md index 2e3f391..41626f7 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ Designed to support desktop, mobile and multi-screen devices. - Press the "copy" button to copy a model to ComfyUI's clipboard or copy the embedding to the system clipboard. (Copying the embedding to the system clipboard requires a secure http connection.) - Press the "add" button to add the model to the ComfyUI graph or append the embedding to one or more selected nodes. - Press the "load workflow" button to try and load a workflow embedded in a model's preview image. -- Press the "open model url" button to try and search the web and open a model's webpage. ### Download Tab @@ -56,7 +55,6 @@ Designed to support desktop, mobile and multi-screen devices. - Read, edit and save notes. (Saved as a `.txt` file beside the model). - `Ctrl+s` or `⌘+S` to save a note when the textarea is in focus. - Autosave can be enabled in settings. (Note: Once the model info view is closed, the undo history is lost.) - - Automatically search the web for model info and save as notes with a single button. - Change or remove a model's preview image. - View training tags and use the random tag generator to generate prompt ideas. (Inspired by the one in A1111.) diff --git a/__init__.py b/__init__.py index 9d38800..f63cc65 100644 --- a/__init__.py +++ b/__init__.py @@ -8,8 +8,6 @@ import copy import importlib import re import base64 -import hashlib -import markdownify from aiohttp import web import server @@ -25,7 +23,7 @@ import folder_paths comfyui_model_uri = folder_paths.models_dir -extension_uri = os.path.dirname(os.path.abspath(__file__)) +extension_uri = os.path.dirname(__file__) config_loader_path = os.path.join(extension_uri, 'config_loader.py') config_loader_spec = importlib.util.spec_from_file_location('config_loader', config_loader_path) @@ -60,8 +58,7 @@ preview_extensions = ( # TODO: JavaScript does not know about this (x2 states) image_extensions + # order matters stable_diffusion_webui_civitai_helper_image_extensions ) -model_notes_extension = ".txt" -model_info_extension = ".json" +model_info_extension = ".txt" #video_extensions = (".avi", ".mp4", ".webm") # TODO: Requires ffmpeg or cv2. Cache preview frame? def split_valid_ext(s, *arg_exts): @@ -74,7 +71,6 @@ def split_valid_ext(s, *arg_exts): _folder_names_and_paths = None # dict[str, tuple[list[str], list[str]]] def folder_paths_folder_names_and_paths(refresh = False): - # TODO: "diffusers" extension whitelist is ["folder"] global _folder_names_and_paths if refresh or _folder_names_and_paths is None: _folder_names_and_paths = {} @@ -193,7 +189,6 @@ def ui_rules(): Rule("model-show-add-button", True, bool), Rule("model-show-copy-button", True, bool), Rule("model-show-load-workflow-button", True, bool), - Rule("model-show-open-model-url-button", False, bool), Rule("model-info-button-on-left", False, bool), Rule("model-buttons-only-on-hover", False, bool), @@ -237,7 +232,6 @@ def get_def_headers(url=""): if url.startswith("https://civitai.com/"): api_key = server_settings["civitai_api_key"] if (api_key != ""): - def_headers["Content-Type"] = f"application/json" def_headers["Authorization"] = f"Bearer {api_key}" url += "&" if "?" in url else "?" # not the most robust solution url += f"token={api_key}" # TODO: Authorization didn't work in the header @@ -249,246 +243,6 @@ def get_def_headers(url=""): return def_headers -def save_web_url(path, url): - with open(path, "w", encoding="utf-8") as f: - f.write(f"[InternetShortcut]\nURL={url}\n") - - -def try_load_web_url(path): - with open(path, "r", encoding="utf-8") as f: - if f.readline() != "[InternetShortcut]\n": return "" - url = f.readline() - if not url.startswith("URL="): return "" - if not url.endswith("\n"): return "" - return url[4:len(url)-1] - - -def hash_file(path, buffer_size=1024*1024): - sha256 = hashlib.sha256() - with open(path, 'rb') as f: - while True: - data = f.read(buffer_size) - if not data: break - sha256.update(data) - return sha256.hexdigest() - - -class Civitai: - IMAGE_URL_SUBDIRECTORY_PREFIX = "https://civitai.com/images/" - IMAGE_URL_DOMAIN_PREFIX = "'https://image.civitai.com/" - - @staticmethod - def image_subdirectory_url_to_image_url(image_url): - url_suffix = image_url[len(Civitai.IMAGE_URL_SUBDIRECTORY_PREFIX):] - image_id = re.search(r"^\d+", url_suffix).group(0) - image_id = str(int(image_id)) - image_info_url = f"https://civitai.com/api/v1/images?imageId={image_id}" - def_headers = get_def_headers(image_info_url) - response = requests.get( - url=image_info_url, - stream=False, - verify=False, - headers=def_headers, - proxies=None, - allow_redirects=False, - ) - if response.ok: - #content_type = response.headers.get("Content-Type") - info = response.json() - items = info["items"] - if len(items) == 0: - raise RuntimeError("Civitai /api/v1/images returned 0 items!") - return items[0]["url"] - else: - raise RuntimeError("Bad response from api/v1/images!") - - @staticmethod - def image_domain_url_full_size(url, width = None): - result = re.search("/width=(\d+)", url) - if width is None: - i0 = result.span()[0] - i1 = result.span()[1] - return url[0:i0] + url[i1:] - else: - w = int(result.group(1)) - return url.replace(str(w), str(width)) - - @staticmethod - def search_by_hash(sha256_hash): - url_api_hash = r"https://civitai.com/api/v1/model-versions/by-hash/" + sha256_hash - hash_response = requests.get(url_api_hash) - if hash_response.status_code != 200: - return {} - return hash_response.json() # model version info - - @staticmethod - def search_by_model_id(model_id): - url_api_model = r"https://civitai.com/api/v1/models/" + str(model_id) - model_response = requests.get(url_api_model) - if model_response.status_code != 200: - return {} - return model_response.json() # model group info - - @staticmethod - def get_model_url(model_version_info): - if len(model_version_info) == 0: return "" - model_id = model_version_info.get("modelId") - if model_id is None: - # there can be incomplete model info, so don't throw just in case - return "" - url = f"https://civitai.com/models/{model_id}" - version_id = model_version_info.get("id") - if version_id is not None: - url += f"?modelVersionId={version_id}" - return url - - @staticmethod - def get_preview_urls(model_version_info, full_size=False): - images = model_version_info.get("images", None) - if images is None: - return [] - preview_urls = [] - for image_info in images: - url = image_info["url"] - if full_size: - url = Civitai.image_domain_url_full_size(url, image_info.get("width", None)) - preview_urls.append(url) - return preview_urls - - @staticmethod - def search_notes(model_version_info): - if len(model_version_info) == 0: - return "" - model_name = None - if "modelId" in model_version_info and "id" in model_version_info: - model_id = model_version_info.get("modelId") - model_version_id = model_version_info.get("id") - - model_version_description = "" - model_trigger_words = [] - model_info = Civitai.search_by_model_id(model_id) - if len(model_info) == 0: # can happen if model download is disabled - print("Model Manager WARNING: Unable to find Civitai 'modelId' " + str(model_id) + ". Try deleting .json file and trying again later!") - return "" - model_name = model_info.get("name") - model_description = model_info.get("description") - for model_version in model_info["modelVersions"]: - if model_version["id"] == model_version_id: - model_version_description = model_version.get("description") - model_trigger_words = model_version.get("trainedWords") - break - elif "description" in model_version_info and "activation text" in model_version_info and "notes" in model_version_info: - # {'description': str, 'sd version': str, 'activation text': str, 'preferred weight': int, 'notes': str} - model_description = model_version_info.get("description") - activation_text = model_version_info.get("activation text") - if activation_text != "": - model_trigger_words = [activation_text] - else: - model_trigger_words = [] - model_version_description = model_version_info.get("notes") - else: - return "" - model_description = model_description if model_description is not None else "" - model_trigger_words = model_trigger_words if model_trigger_words is not None else [] - model_version_description = model_version_description if model_version_description is not None else "" - model_name = model_name if model_name is not None else "Model Description" - - notes = "" - if len(model_trigger_words) > 0: - notes += "# Trigger Words\n\n" - model_trigger_words = [re.sub(",$", "", s.strip()) for s in model_trigger_words] - join_separator = ', ' - for s in model_trigger_words: - if ',' in s: - join_separator = '\n' - break - if join_separator == '\n': - model_trigger_words = ["* " + s for s in model_trigger_words] - notes += join_separator.join(model_trigger_words) - if model_version_description != "": - if len(notes) > 0: notes += "\n\n" - notes += "# About this version\n\n" - notes += markdownify.markdownify(model_version_description) - if model_description != "": - if len(notes) > 0: notes += "\n\n" - notes += "# " + model_name + "\n\n" - notes += markdownify.markdownify(model_description) - return notes.strip() - - -class ModelInfo: - @staticmethod - def search_by_hash(sha256_hash): - model_info = Civitai.search_by_hash(sha256_hash) - if len(model_info) > 0: return model_info - # TODO: search other websites - return {} - - @staticmethod - def try_load_cached(model_path): - model_info_path = os.path.splitext(model_path)[0] + model_info_extension - if os.path.isfile(model_info_path): - with open(model_info_path, "r", encoding="utf-8") as f: - model_info = json.load(f) - return model_info - return {} - - @staticmethod - def get_hash(model_info): - model_info = Civitai.get_hash(model_info) - if len(model_info) > 0: return model_info - # TODO: search other websites - return {} - - @staticmethod - def search_info(model_path, cache=True, use_cached=True): - model_info = ModelInfo.try_load_cached(model_path) - if use_cached and len(model_info) > 0: - return model_info - - sha256_hash = hash_file(model_path) - model_info = ModelInfo.search_by_hash(sha256_hash) - if cache and len(model_info) > 0: - model_info_path = os.path.splitext(model_path)[0] + model_info_extension - with open(model_info_path, "w", encoding="utf-8") as f: - json.dump(model_info, f, indent=4) - print("Saved file: " + model_info_path) - - return model_info - - @staticmethod - def get_url(model_info): - if len(model_info) == 0: - return "" - model_url = Civitai.get_model_url(model_info) - if model_url != "": - return model_url - # TODO: huggingface has / formats - # TODO: support other websites - return "" - - @staticmethod - def search_notes(model_path): - assert(os.path.isfile(model_path)) - model_info = ModelInfo.search_info(model_path, cache=True, use_cached=True) # assume cached is correct; re-download elsewhere - if len(model_info) == 0: - return "" - notes = Civitai.search_notes(model_info) - if len(notes) > 0 and not notes.isspace(): - return notes - # TODO: search other websites - return "" - - @staticmethod - def get_web_preview_urls(model_info, full_size=False): - if len(model_info) == 0: - return [] - preview_urls = Civitai.get_preview_urls(model_info, full_size) - if len(preview_urls) > 0: - return preview_urls - # TODO: support other websites - return [] - @server.PromptServer.instance.routes.get("/model-manager/timestamp") async def get_timestamp(request): return web.json_response({ "timestamp": datetime.now().timestamp() }) @@ -573,12 +327,9 @@ def get_auto_thumbnail_format(original_format): return "JPEG" # default fallback -@server.PromptServer.instance.routes.get("/model-manager/preview/get/{uri}") +@server.PromptServer.instance.routes.get("/model-manager/preview/get") async def get_model_preview(request): - uri = request.match_info["uri"] - if uri is None: # BUG: this should never happen - print(f"Invalid uri! Request url: {request.url}") - uri = "no-preview" + uri = request.query.get("uri") quality = 75 response_image_format = request.query.get("image-format", None) if isinstance(response_image_format, str): @@ -700,16 +451,42 @@ async def get_image_extensions(request): return web.json_response(image_extensions) -def download_model_preview(path, image, overwrite): - if not os.path.isfile(path): +def download_model_preview(formdata): + path = formdata.get("path", None) + if type(path) is not str: raise ValueError("Invalid path!") - path_without_extension = os.path.splitext(path)[0] + path, model_type = search_path_to_system_path(path) + model_type_extensions = folder_paths_get_supported_pt_extensions(model_type) + path_without_extension, _ = split_valid_ext(path, model_type_extensions) + overwrite = formdata.get("overwrite", "true").lower() + overwrite = True if overwrite == "true" else False + + image = formdata.get("image", None) if type(image) is str: - if image.startswith(Civitai.IMAGE_URL_SUBDIRECTORY_PREFIX): - image = Civitai.image_subdirectory_url_to_image_url(image) - if image.startswith(Civitai.IMAGE_URL_DOMAIN_PREFIX): - image = Civitai.image_domain_url_full_size(image) + civitai_image_url = "https://civitai.com/images/" + if image.startswith(civitai_image_url): + image_id = re.search(r"^\d+", image[len(civitai_image_url):]).group(0) + image_id = str(int(image_id)) + image_info_url = f"https://civitai.com/api/v1/images?imageId={image_id}" + def_headers = get_def_headers(image_info_url) + response = requests.get( + url=image_info_url, + stream=False, + verify=False, + headers=def_headers, + proxies=None, + allow_redirects=False, + ) + if response.ok: + content_type = response.headers.get("Content-Type") + info = response.json() + items = info["items"] + if len(items) == 0: + raise RuntimeError("Civitai /api/v1/images returned 0 items!") + image = items[0]["url"] + else: + raise RuntimeError("Bad response from api/v1/images!") _, image_extension = split_valid_ext(image, image_extensions) if image_extension == "": raise ValueError("Invalid image type!") @@ -737,23 +514,17 @@ def download_model_preview(path, image, overwrite): # detect (and try to fix) wrong file extension image_format = None - try: - with Image.open(image_path) as image: - image_format = image.format - image_dir_and_name, image_ext = os.path.splitext(image_path) - if not image_format_is_equal(image_format, image_ext): - corrected_image_path = image_dir_and_name + "." + image_format.lower() - if os.path.exists(corrected_image_path) and not overwrite: - print("WARNING: '" + image_path + "' has wrong extension!") - else: - os.rename(image_path, corrected_image_path) - print("Saved file: " + corrected_image_path) - image_path = corrected_image_path - except Image.UnidentifiedImageError as e: #TODO: handle case where "image" is actually video - print("WARNING: '" + image_path + "' image format was unknown!") - os.remove(image_path) - print("Deleted file: " + image_path) - image_path = "" + with Image.open(image_path) as image: + image_format = image.format + image_dir_and_name, image_ext = os.path.splitext(image_path) + if not image_format_is_equal(image_format, image_ext): + corrected_image_path = image_dir_and_name + "." + image_format.lower() + if os.path.exists(corrected_image_path) and not overwrite: + print("WARNING: '" + image_path + "' has wrong extension!") + else: + os.rename(image_path, corrected_image_path) + print("Saved file: " + corrected_image_path) + image_path = corrected_image_path return image_path # return in-case need corrected path @@ -761,15 +532,7 @@ def download_model_preview(path, image, overwrite): async def set_model_preview(request): formdata = await request.post() try: - search_path = formdata.get("path", None) - model_path, model_type = search_path_to_system_path(search_path) - - image = formdata.get("image", None) - - overwrite = formdata.get("overwrite", "true").lower() - overwrite = True if overwrite == "true" else False - - download_model_preview(model_path, image, overwrite) + download_model_preview(formdata) return web.json_response({ "success": True }) except ValueError as e: print(e, file=sys.stderr, flush=True) @@ -947,8 +710,8 @@ async def get_model_list(request): if image is not None: raw_post = os.path.join(model_type, str(base_path_index), rel_path, image) item["preview"] = { - "path": raw_post, - "dateModified": str(image_modified), + "path": urllib.parse.quote_plus(raw_post), + "dateModified": urllib.parse.quote_plus(str(image_modified)), } model_items.append(item) @@ -1016,116 +779,6 @@ async def get_directory_list(request): return web.json_response(dir_list) -def try_download_and_save_model_info(model_file_path): - success = (0, 0, 0) #info, notes, url - head, _ = os.path.splitext(model_file_path) - model_info_path = head + model_info_extension - model_notes_path = head + model_notes_extension - model_url_path = head + ".url" - if os.path.exists(model_info_path) and os.path.exists(model_notes_path) and os.path.exists(model_url_path): - return success - print("Scanning " + model_file_path) - - model_info = {} - model_info = ModelInfo.search_info(model_file_path, cache=True, use_cached=True) - if len(model_info) == 0: - return success - success[0] = 1 - - if not os.path.exists(model_notes_path): - notes = ModelInfo.search_notes(model_file_path) - if not notes.isspace() and notes != "": - try: - with open(model_notes_path, "w", encoding="utf-8") as f: - f.write(notes) - print("Saved file: " + model_notes_path) - success[1] = 1 - except Exception as e: - print(f"Failed to save {model_notes_path}!") - print(e, file=sys.stderr, flush=True) - - if not os.path.exists(model_url_path): - web_url = ModelInfo.get_url(model_info) - if web_url is not None and web_url != "": - try: - save_web_url(model_url_path, web_url) - print("Saved file: " + model_url_path) - success[2] = 1 - except Exception as e: - print(f"Failed to save {model_url_path}!") - print(e, file=sys.stderr, flush=True) - return success - - -@server.PromptServer.instance.routes.post("/model-manager/models/scan") -async def try_scan_download(request): - refresh = request.query.get("refresh", None) is not None - response = { - "success": False, - "infoCount": 0, - "notesCount": 0, - "urlCount": 0, - } - model_paths = folder_paths_folder_names_and_paths(refresh) - for _, (model_dirs, model_extension_whitelist) in model_paths.items(): - for root_dir in model_dirs: - for root, dirs, files in os.walk(root_dir): - for file in files: - file_name, file_extension = os.path.splitext(file) - if file_extension not in model_extension_whitelist: - continue - model_file_path = root + os.path.sep + file - savedInfo, savedNotes, savedUrl = try_download_and_save_model_info(model_file_path) - response["infoCount"] += savedInfo - response["notesCount"] += savedNotes - response["urlCount"] += savedUrl - - response["success"] = True - return web.json_response(response) - -@server.PromptServer.instance.routes.post("/model-manager/preview/scan") -async def try_scan_download_previews(request): - refresh = request.query.get("refresh", None) is not None - response = { - "success": False, - "count": 0, - } - model_paths = folder_paths_folder_names_and_paths(refresh) - for _, (model_dirs, model_extension_whitelist) in model_paths.items(): - for root_dir in model_dirs: - for root, dirs, files in os.walk(root_dir): - for file in files: - file_name, file_extension = os.path.splitext(file) - if file_extension not in model_extension_whitelist: - continue - model_file_path = root + os.path.sep + file - model_file_head = os.path.splitext(model_file_path)[0] - - preview_exists = False - for preview_extension in preview_extensions: - preview_path = model_file_head + preview_extension - if os.path.isfile(preview_path): - preview_exists = True - break - if preview_exists: - continue - - model_info = ModelInfo.try_load_cached(model_file_path) # NOTE: model info must already be downloaded - web_previews = ModelInfo.get_web_preview_urls(model_info, True) - if len(web_previews) == 0: - continue - saved_image_path = download_model_preview( - model_file_path, - image=web_previews[0], - overwrite=False, - ) - if os.path.isfile(saved_image_path): - response["count"] += 1 - - response["success"] = True - return web.json_response(response) - - def download_file(url, filename, overwrite): if not overwrite and os.path.isfile(filename): raise ValueError("File already exists!") @@ -1232,13 +885,13 @@ def bytes_to_size(total_bytes): return "{:.2f}".format(total_bytes / (1 << (i * 10))) + " " + units[i] -@server.PromptServer.instance.routes.get("/model-manager/model/info/{path}") -async def get_model_metadata(request): +@server.PromptServer.instance.routes.get("/model-manager/model/info") +async def get_model_info(request): result = { "success": False } - model_path = request.match_info["path"] + model_path = request.query.get("path", None) if model_path is None: - result["alert"] = "Invalid model path!" + result["alert"] = "Missing model path!" return web.json_response(result) model_path = urllib.parse.unquote(model_path) @@ -1247,16 +900,16 @@ async def get_model_metadata(request): result["alert"] = "Invalid model path!" return web.json_response(result) - data = {} + info = {} comfyui_directory, name = os.path.split(model_path) - data["File Name"] = name - data["File Directory"] = comfyui_directory - data["File Size"] = bytes_to_size(os.path.getsize(abs_path)) + info["File Name"] = name + info["File Directory"] = comfyui_directory + info["File Size"] = bytes_to_size(os.path.getsize(abs_path)) stats = pathlib.Path(abs_path).stat() date_format = "%Y-%m-%d %H:%M:%S" date_modified = datetime.fromtimestamp(stats.st_mtime).strftime(date_format) - #data["Date Modified"] = date_modified - #data["Date Created"] = datetime.fromtimestamp(stats.st_ctime).strftime(date_format) + #info["Date Modified"] = date_modified + #info["Date Created"] = datetime.fromtimestamp(stats.st_ctime).strftime(date_format) model_extensions = folder_paths_get_supported_pt_extensions(model_type) abs_name , _ = split_valid_ext(abs_path, model_extensions) @@ -1266,36 +919,36 @@ async def get_model_metadata(request): if os.path.isfile(maybe_preview): preview_path, _ = split_valid_ext(model_path, model_extensions) preview_modified = pathlib.Path(maybe_preview).stat().st_mtime_ns - data["Preview"] = { - "path": preview_path + extension, - "dateModified": str(preview_modified), + info["Preview"] = { + "path": urllib.parse.quote_plus(preview_path + extension), + "dateModified": urllib.parse.quote_plus(str(preview_modified)), } break header = get_safetensor_header(abs_path) metadata = header.get("__metadata__", None) - if metadata is not None and data.get("Preview", None) is None: + if metadata is not None and info.get("Preview", None) is None: thumbnail = metadata.get("modelspec.thumbnail") if thumbnail is not None: i0 = thumbnail.find("/") + 1 i1 = thumbnail.find(";", i0) thumbnail_extension = "." + thumbnail[i0:i1] if thumbnail_extension in image_extensions: - data["Preview"] = { + info["Preview"] = { "path": request.query["path"] + thumbnail_extension, "dateModified": date_modified, } if metadata is not None: - data["Base Training Model"] = metadata.get("ss_sd_model_name", "") - data["Base Model Version"] = metadata.get("ss_base_model_version", "") - data["Network Dimension"] = metadata.get("ss_network_dim", "") - data["Network Alpha"] = metadata.get("ss_network_alpha", "") + info["Base Training Model"] = metadata.get("ss_sd_model_name", "") + info["Base Model Version"] = metadata.get("ss_base_model_version", "") + info["Network Dimension"] = metadata.get("ss_network_dim", "") + info["Network Alpha"] = metadata.get("ss_network_alpha", "") if metadata is not None: training_comment = metadata.get("ss_training_comment", "") - data["Description"] = ( + info["Description"] = ( metadata.get("modelspec.description", "") + "\n\n" + metadata.get("modelspec.usage_hint", "") + @@ -1303,17 +956,12 @@ async def get_model_metadata(request): training_comment if training_comment != "None" else "" ).strip() - notes_file = abs_name + model_notes_extension + info_text_file = abs_name + model_info_extension notes = "" - if os.path.isfile(notes_file): - with open(notes_file, 'r', encoding="utf-8") as f: + if os.path.isfile(info_text_file): + with open(info_text_file, 'r', encoding="utf-8") as f: notes = f.read() - web_url_file = abs_name + ".url" - web_url = "" - if os.path.isfile(web_url_file): - web_url = try_load_web_url(web_url_file) - if metadata is not None: img_buckets = metadata.get("ss_bucket_info", None) datasets = metadata.get("ss_datasets", None) @@ -1335,7 +983,7 @@ async def get_model_metadata(request): resolutions[str(x) + "x" + str(y)] = count resolutions = list(resolutions.items()) resolutions.sort(key=lambda x: x[1], reverse=True) - data["Bucket Resolutions"] = resolutions + info["Bucket Resolutions"] = resolutions tags = None if metadata is not None: @@ -1349,82 +997,21 @@ async def get_model_metadata(request): tags = list(tags.items()) tags.sort(key=lambda x: x[1], reverse=True) - model_info = ModelInfo.try_load_cached(abs_path) - web_previews = ModelInfo.get_web_preview_urls(model_info, True) - result["success"] = True - result["info"] = data + result["info"] = info if metadata is not None: result["metadata"] = metadata if tags is not None: result["tags"] = tags result["notes"] = notes - result["url"] = web_url - result["webPreviews"] = web_previews return web.json_response(result) -@server.PromptServer.instance.routes.get("/model-manager/model/web-url") -async def get_model_web_url(request): - result = { "success": False } - - model_path = request.query.get("path", None) - if model_path is None: - result["alert"] = "Invalid model path!" - return web.json_response(result) - model_path = urllib.parse.unquote(model_path) - - abs_path, model_type = search_path_to_system_path(model_path) - if abs_path is None: - result["alert"] = "Invalid model path!" - return web.json_response(result) - - url_path = os.path.splitext(abs_path)[0] + ".url" - if os.path.isfile(url_path): - web_url = try_load_web_url(url_path) - if web_url != "": - result["success"] = True - return web.json_response({ "url": web_url }) - - model_info = ModelInfo.search_info(abs_path) - if len(model_info) == 0: - result["alert"] = "Unable to find model info!" - return web.json_response(result) - web_url = ModelInfo.get_url(model_info) - if web_url != "" and web_url is not None: - save_web_url(url_path, web_url) - result["success"] = True - - return web.json_response({ "url": web_url }) - - @server.PromptServer.instance.routes.get("/model-manager/system-separator") async def get_system_separator(request): return web.json_response(os.path.sep) -@server.PromptServer.instance.routes.post("/model-manager/model/download/info") -async def download_model_info(request): - result = { "success": False } - - model_path = request.query.get("path", None) - if model_path is None: - result["alert"] = "Missing model path!" - return web.json_response(result) - model_path = urllib.parse.unquote(model_path) - - abs_path, model_type = search_path_to_system_path(model_path) - if abs_path is None: - result["alert"] = "Invalid model path!" - return web.json_response(result) - - model_info = ModelInfo.search_info(abs_path, cache=True, use_cached=False) - if len(model_info) > 0: - result["success"] = True - - return web.json_response(result) - - @server.PromptServer.instance.routes.post("/model-manager/model/download") async def download_model(request): formdata = await request.post() @@ -1439,7 +1026,6 @@ async def download_model(request): result["alert"] = "Invalid save path!" return web.json_response(result) - # download model download_uri = formdata.get("download") if download_uri is None: result["alert"] = "Invalid download url!" @@ -1463,24 +1049,14 @@ async def download_model(request): result["alert"] = "Failed to download model!\n\n" + str(e) return web.json_response(result) - # download model info - model_info = ModelInfo.search_info(file_name, cache=True) # save json - - # save url - url_file_path = os.path.splitext(file_name)[0] + ".url" - url = ModelInfo.get_url(model_info) - if url != "" and url is not None: - save_web_url(url_file_path, url) - - # save image as model preview image = formdata.get("image") if image is not None and image != "": try: - download_model_preview( - file_name, - image, - formdata.get("overwrite"), - ) + download_model_preview({ + "path": model_path + os.sep + name, + "image": image, + "overwrite": formdata.get("overwrite"), + }) except Exception as e: print(e, file=sys.stderr, flush=True) result["alert"] = "Failed to download preview!\n\n" + str(e) @@ -1546,7 +1122,7 @@ async def move_model(request): return web.json_response(result) # TODO: this could overwrite existing files in destination; do a check beforehand? - for extension in preview_extensions + (model_notes_extension,) + (model_info_extension,): + for extension in preview_extensions + (model_info_extension,): old_file = old_file_without_extension + extension if os.path.isfile(old_file): new_file = new_file_without_extension + extension @@ -1600,7 +1176,6 @@ async def delete_model(request): print("Deleted file: " + model_path) delete_same_name_files(path_and_name, preview_extensions) - delete_same_name_files(path_and_name, (model_notes_extension,)) delete_same_name_files(path_and_name, (model_info_extension,)) return web.json_response(result) @@ -1625,7 +1200,7 @@ async def set_notes(request): model_path, model_type = search_path_to_system_path(model_path) model_extensions = folder_paths_get_supported_pt_extensions(model_type) file_path_without_extension, _ = split_valid_ext(model_path, model_extensions) - filename = os.path.normpath(file_path_without_extension + model_notes_extension) + filename = os.path.normpath(file_path_without_extension + model_info_extension) if dt_epoch is not None and os.path.exists(filename) and os.path.getmtime(filename) > dt_epoch: # discard late save @@ -1646,52 +1221,12 @@ async def set_notes(request): except ValueError as e: print(e, file=sys.stderr, flush=True) result["alert"] = "Failed to save notes!\n\n" + str(e) - return web.json_response(result) + web.json_response(result) result["success"] = True return web.json_response(result) -@server.PromptServer.instance.routes.post("/model-manager/notes/download") -async def try_download_notes(request): - result = { "success": False } - - model_path = request.query.get("path", None) - if model_path is None: - result["alert"] = "Missing model path!" - return web.json_response(result) - model_path = urllib.parse.unquote(model_path) - - abs_path, model_type = search_path_to_system_path(model_path) - if abs_path is None: - result["alert"] = "Invalid model path!" - return web.json_response(result) - - overwrite = request.query.get("overwrite", None) - overwrite = not (overwrite == "False" or overwrite == "false" or overwrite == None) - notes_path = os.path.splitext(abs_path)[0] + ".txt" - if not overwrite and os.path.isfile(notes_path): - result["alert"] = "Notes already exist!" - return web.json_response(result) - - notes = ModelInfo.search_notes(abs_path) - if notes.isspace() or notes == "": - result["alert"] = "No notes found!" - return web.json_response(result) - - try: - with open(notes_path, "w", encoding="utf-8") as f: - f.write(notes) - result["success"] = True - except ValueError as e: - print(e, file=sys.stderr, flush=True) - result["alert"] = "Failed to save notes!\n\n" + str(e) - return web.json_response(result) - - result["notes"] = notes - return web.json_response(result) - - WEB_DIRECTORY = "web" NODE_CLASS_MAPPINGS = {} __all__ = ["NODE_CLASS_MAPPINGS"] diff --git a/demo/tab-model-preview-thumbnail-buttons-example.png b/demo/tab-model-preview-thumbnail-buttons-example.png index 0eef0db5916f0b65987e543b0fda26c1b5fb81d9..8f96ba6e6adff439521ac091795ae5641a6ed0cf 100644 GIT binary patch literal 73525 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 fkMBJ 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 z

AtIE2)4fE#CYl()I;{OX#~ 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�R7#^rL) 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�{q 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

Bb__(()L_a)uhPO5wTr`3M^Wn1wZB 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 z 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 YHDssj!Yp#9{Q+F(&sv#RoN -1; * @param {string} url */ async function loadWorkflow(url) { - const fileName = SearchPath.filename(decodeURIComponent(url)); - const response = await fetch(url); - const data = await response.blob(); - const file = new File([data], fileName, { type: data.type }); - app.handleFile(file); -} - -/** - * @param {string} modelSearchPath - * @returns {Promise} - */ -async function tryGetModelWebUrl(modelSearchPath) { - const encodedPath = encodeURIComponent(modelSearchPath); - const response = await comfyRequest(`/model-manager/model/web-url?path=${encodedPath}`); - const url = response.url; - return url !== undefined && url !== '' ? url : undefined; -} - -/** - * @param {string} url - * @param {string} name - * @returns {boolean} - */ -function tryOpenUrl(url, name="Url") { - try { - new URL(url); - } - catch (exception) { - return false; - } - try { - window.open(url, '_blank').focus(); - } - catch (exception) { - // browser or ad-blocker blocking opening new window - modelManagerDialog.show($el("span", - [ - $el("p", { - style: { color: "var(--input-text)" }, - }, [name]), - $el("a", { - href: url, - target: "_blank", - }, [ - $el("span", [ - url, - $el("i.mdi.mdi-open-in-new"), - ]) - ]), - ] - )); - } - return true; + const uri = new URL(url).searchParams.get('uri'); + const fileNameIndex = + Math.max(uri.lastIndexOf('/'), uri.lastIndexOf('\\')) + 1; + const fileName = uri.substring(fileNameIndex); + const response = await fetch(url); + const data = await response.blob(); + const file = new File([data], fileName, { type: data.type }); + app.handleFile(file); } const modelNodeType = { @@ -260,57 +215,40 @@ class SearchPath { const i2 = path.indexOf(searchSeparator, i1 + 1); return path.slice(i2 + 1).replaceAll(searchSeparator, systemSeparator); } - - /** - * @param {string} s search path or url - * @returns {string} - */ - static filename(s) { - let name = SearchPath.split(s)[1]; - const queryIndex = name.indexOf('?'); - if (queryIndex > -1) { - return name.substring(0, queryIndex); - } - return name; - } } /** - * @param {string | undefined} [imageUriSearchPath=undefined] + * @param {string | undefined} [searchPath=undefined] * @param {string | undefined} [dateImageModified=undefined] * @param {string | undefined} [width=undefined] * @param {string | undefined} [height=undefined] * @param {string | undefined} [imageFormat=undefined] * @returns {string} */ - function imageUri( - imageUriSearchPath = undefined, - dateImageModified = undefined, - width = undefined, - height = undefined, - imageFormat = undefined, - ) { - const params = []; +function imageUri( + imageSearchPath = undefined, + dateImageModified = undefined, + width = undefined, + height = undefined, + imageFormat = undefined, +) { + const path = imageSearchPath ?? 'no-preview'; + const date = dateImageModified; + let uri = `/model-manager/preview/get?uri=${path}`; if (width !== undefined && width !== null) { - params.push(`width=${width}`); + uri += `&width=${width}`; } if (height !== undefined && height !== null) { - params.push(`height=${height}`); + uri += `&height=${height}`; } - if (dateImageModified !== undefined && dateImageModified !== null) { - params.push(`v=${dateImageModified}`); + if (date !== undefined && date !== null) { + uri += `&v=${date}`; } if (imageFormat !== undefined && imageFormat !== null) { - params.push(`image-format=${imageFormat}`); - } - - const path = imageUriSearchPath ?? 'no-preview'; - const uri = `/model-manager/preview/get/${path}`; - if (params.length > 0) { - return uri + '?' + params.join('&'); + uri += `&image-format=${imageFormat}`; } return uri; - } +} const PREVIEW_NONE_URI = imageUri(); /** @@ -656,7 +594,6 @@ class ImageSelect { /** @type {HTMLImageElement} */ defaultPreviewNoImage: null, /** @type {HTMLDivElement} */ defaultPreviews: null, /** @type {HTMLDivElement} */ defaultUrl: null, - /** @type {HTMLDivElement} */ previewButtons: null, /** @type {HTMLImageElement} */ customUrlPreview: null, /** @type {HTMLInputElement} */ customUrl: null, @@ -721,15 +658,11 @@ class ImageSelect { case this.#PREVIEW_NONE: return PREVIEW_NONE_URI; } - console.warn(`Invalid preview select type: ${value}`); - return PREVIEW_NONE_URI; + return ''; } - /** - * @param {String[]} defaultPreviewUrls - * @returns {void} - */ - resetModelInfoPreview(defaultPreviewUrls = []) { + /** @returns {void} */ + resetModelInfoPreview() { let noimage = this.elements.defaultUrl.dataset.noimage; [ this.elements.defaultPreviewNoImage, @@ -748,18 +681,6 @@ class ImageSelect { el.src = PREVIEW_NONE_URI; } }); - const defaultPreviews = this.elements.defaultPreviews; - defaultPreviews.innerHTML = ''; - if (defaultPreviewUrls.length > 0) { - ImageSelect.generateDefaultPreviews(defaultPreviewUrls).forEach(previewElement => { - defaultPreviews.appendChild(previewElement); - }); - } - else { - const defaultImage = ImageSelect.generateDefaultPreviews([PREVIEW_NONE_URI]); - defaultPreviews.appendChild(defaultImage[0]); - } - this.elements.previewButtons.style.display = defaultPreviewUrls.length > 1 ? 'block' : 'none'; this.checkDefault(); this.elements.uploadFile.value = ''; this.elements.customUrl.value = ''; @@ -820,28 +741,6 @@ class ImageSelect { children[currentIndex].style.display = 'block'; } - /** - * @param {string[]|undefined} defaultPreviewUrls - * @returns {HTMLImageElement[]} - */ - static generateDefaultPreviews(defaultPreviewUrls) { - const imgs = defaultPreviewUrls.map((url) => { - return $el('img', { - loading: - 'lazy' /* `loading` BEFORE `src`; Known bug in Firefox 124.0.2 and Safari for iOS 17.4.1 (https://stackoverflow.com/a/76252772) */, - src: url, - style: { display: 'none' }, - onerror: (e) => { - e.target.src = PREVIEW_NONE_URI; - }, - }); - }); - if (imgs.length > 0) { - imgs[0].style.display = 'block'; - } - return imgs; - } - /** * @param {string} radioGroupName - Should be unique for every radio group. * @param {string[]|undefined} defaultPreviews @@ -879,7 +778,23 @@ class ImageSelect { height: '100%', }, }, - ImageSelect.generateDefaultPreviews(defaultPreviews), + (() => { + const imgs = defaultPreviews.map((url) => { + return $el('img', { + loading: + 'lazy' /* `loading` BEFORE `src`; Known bug in Firefox 124.0.2 and Safari for iOS 17.4.1 (https://stackoverflow.com/a/76252772) */, + src: url, + style: { display: 'none' }, + onerror: (e) => { + e.target.src = el_defaultUri.dataset.noimage ?? PREVIEW_NONE_URI; + }, + }); + }); + if (imgs.length > 0) { + imgs[0].style.display = 'block'; + } + return imgs; + })(), ); const el_uploadPreview = $el('img', { @@ -989,7 +904,6 @@ class ImageSelect { const el_previewButtons = $el( 'div.model-preview-overlay', { - $: (el) => (this.elements.previewButtons = el), style: { display: el_defaultPreviews.children.length > 1 ? 'block' : 'none', }, @@ -1914,7 +1828,6 @@ class ModelGrid { const widgetIndex = ModelGrid.modelWidgetIndex(nodeType); const target = selectedNode?.widgets[widgetIndex]?.element; if (target && target.type === 'textarea') { - // TODO: If the node has >1 text areas, the textarea element must be selected target.value = ModelGrid.insertEmbeddingIntoText( target.value, embeddingFile, @@ -1924,7 +1837,7 @@ class ModelGrid { } } if (!success) { - window.alert('No selected nodes have a text area!'); + console.warn('Try selecting a node before adding the embedding.'); } event.stopPropagation(); } @@ -2109,16 +2022,13 @@ class ModelGrid { // TODO: separate text and model logic; getting too messy // TODO: fallback on button failure to copy text? const canShowButtons = modelNodeType[modelType] !== undefined; - const shouldShowTryOpenModelUrl = - canShowButtons && - settingsElements['model-show-open-model-url-button'].checked; - const showLoadWorkflowButton = - canShowButtons && - settingsElements['model-show-load-workflow-button'].checked; const showAddButton = canShowButtons && settingsElements['model-show-add-button'].checked; const showCopyButton = canShowButtons && settingsElements['model-show-copy-button'].checked; + const showLoadWorkflowButton = + canShowButtons && + settingsElements['model-show-load-workflow-button'].checked; const strictDragToAdd = settingsElements['model-add-drag-strict-on-field'].checked; const addOffset = parseInt(settingsElements['model-add-offset'].value); @@ -2186,8 +2096,8 @@ class ModelGrid { loading: 'lazy' /* `loading` BEFORE `src`; Known bug in Firefox 124.0.2 and Safari for iOS 17.4.1 (https://stackoverflow.com/a/76252772) */, src: imageUri( - previewInfo?.path ? encodeURIComponent(previewInfo.path) : undefined, - previewInfo?.dateModified ? encodeURIComponent(previewInfo.dateModified) : undefined, + previewInfo?.path, + previewInfo?.dateModified, previewThumbnailWidth, previewThumbnailHeight, previewThumbnailFormat, @@ -2201,47 +2111,23 @@ class ModelGrid { systemSeparator, ); let actionButtons = []; - if (shouldShowTryOpenModelUrl) { + if (showCopyButton) { actionButtons.push( - new ComfyButton({ - icon: 'open-in-new', - tooltip: 'Attempt to open model url page in a new tab.', - classList: 'comfyui-button icon-button model-button', - action: async (e) => { - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; - const webUrl = await tryGetModelWebUrl(searchPath); - const success = tryOpenUrl(webUrl, searchPath); - comfyButtonAlert(e.target, success, 'mdi-check-bold', 'mdi-close-thick'); - button.disabled = false; - }, - }).element + new ComfyButton({ + icon: 'content-copy', + tooltip: 'Copy model to clipboard', + classList: 'comfyui-button icon-button model-button', + action: (e) => + ModelGrid.#copyModelToClipboard( + e, + modelType, + path, + removeEmbeddingExtension, + ), + }).element, ); - } - if (showLoadWorkflowButton) { - actionButtons.push( - new ComfyButton({ - icon: 'arrow-bottom-left-bold-box-outline', - tooltip: 'Load preview workflow', - classList: 'comfyui-button icon-button model-button', - action: async (e) => { - const urlString = previewThumbnail.src; - const url = new URL(urlString); - const urlSearchParams = url.searchParams; - const uri = urlSearchParams.get('uri'); - const v = urlSearchParams.get('v'); - const urlFull = - urlString.substring(0, urlString.indexOf('?')) + - '?uri=' + - uri + - '&v=' + - v; - await loadWorkflow(urlFull); - }, - }).element, - ); - } - if (showAddButton) { + } + if (showAddButton && !(modelType === 'embeddings' && !navigator.clipboard)) { actionButtons.push( new ComfyButton({ icon: 'plus-box-outline', @@ -2258,36 +2144,37 @@ class ModelGrid { }).element, ); } - if ( - showCopyButton && - !(modelType === 'embeddings' && !navigator.clipboard) - ) { - actionButtons.push( - new ComfyButton({ - icon: 'content-copy', - tooltip: 'Copy model to clipboard', - classList: 'comfyui-button icon-button model-button', - action: (e) => - ModelGrid.#copyModelToClipboard( - e, - modelType, - path, - removeEmbeddingExtension, - ), - }).element, - ); + if (showLoadWorkflowButton) { + actionButtons.push( + new ComfyButton({ + icon: 'arrow-bottom-left-bold-box-outline', + tooltip: 'Load preview workflow', + classList: 'comfyui-button icon-button model-button', + action: async (e) => { + const urlString = previewThumbnail.src; + const url = new URL(urlString); + const urlSearchParams = url.searchParams; + const uri = urlSearchParams.get('uri'); + const v = urlSearchParams.get('v'); + const urlFull = + urlString.substring(0, urlString.indexOf('?')) + + '?uri=' + + uri + + '&v=' + + v; + await loadWorkflow(urlFull); + }, + }).element, + ); } const infoButtons = [ new ComfyButton({ icon: 'information-outline', tooltip: 'View model information', classList: 'comfyui-button icon-button model-button', - action: async(e) => { - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; + action: async () => { await showModelInfo(searchPath); - button.disabled = false; - }, + }, }).element, ]; return $el('div.item', {}, [ @@ -2377,21 +2264,14 @@ class ModelGrid { previousModelType.value = modelType; } - let modelTypeOptions = []; - for (const key of Object.keys(models)) { - const el = $el('option', [key]); - modelTypeOptions.push(el); - } - modelTypeOptions.sort((a, b) => - a.innerText.localeCompare( - b.innerText, - undefined, - {sensitivity : 'base'}, - ) - ); - modelSelect.innerHTML = ""; - modelTypeOptions.forEach(option => modelSelect.add(option)); - modelSelect.value = modelType; + let modelTypeOptions = []; + for (const [key, value] of Object.entries(models)) { + const el = $el('option', [key]); + modelTypeOptions.push(el); + } + modelSelect.innerHTML = ''; + modelTypeOptions.forEach((option) => modelSelect.add(option)); + modelSelect.value = modelType; const searchAppend = settings['model-search-always-append'].value; const searchText = modelFilter.value + ' ' + searchAppend; @@ -2433,18 +2313,13 @@ class ModelInfo { /** @type {[HTMLElement][]} */ #settingsElements = null; - /** @type {() -> Promise} */ - #tryHideModelInfo = () => {}; - /** * @param {ModelData} modelData * @param {(withoutComfyRefresh?: boolean) => Promise} updateModels * @param {any} settingsElements - * @param {() => Promise} tryHideModelInfo */ - constructor(modelData, updateModels, settingsElements, tryHideModelInfo) { + constructor(modelData, updateModels, settingsElements) { this.#settingsElements = settingsElements; - this.#tryHideModelInfo = tryHideModelInfo; const moveDestinationInput = $el('input.search-text-area', { name: 'move directory', autocomplete: 'off', @@ -2530,6 +2405,11 @@ class ModelInfo { }, }).element; this.elements.setPreviewButton = setPreviewButton; + previewSelect.elements.radioButtons.addEventListener('change', (e) => { + setPreviewButton.style.display = previewSelect.defaultIsChecked() + ? 'none' + : 'block'; + }); this.element = $el( 'div', @@ -2662,9 +2542,9 @@ class ModelInfo { tabContent: this.element, }, { - name: 'Notes', - icon: 'pencil-outline', - tabContent: $el('div', ['Notes']), + name: 'Metadata', + icon: 'file-document-outline', + tabContent: $el('div', ['Metadata']), }, { name: 'Tags', @@ -2672,9 +2552,9 @@ class ModelInfo { tabContent: $el('div', ['Tags']), }, { - name: 'Metadata', - icon: 'file-document-outline', - tabContent: $el('div', ['Metadata']), + name: 'Notes', + icon: 'pencil-outline', + tabContent: $el('div', ['Notes']), }, ]); } @@ -2745,8 +2625,8 @@ class ModelInfo { */ async update(searchPath, updateModels, searchSeparator) { const path = encodeURIComponent(searchPath); - const [info, metadata, tags, noteText, url, webPreviews] = await comfyRequest( - `/model-manager/model/info/${path}`, + const [info, metadata, tags, noteText] = await comfyRequest( + `/model-manager/model/info?path=${path}`, ) .then((result) => { const success = result['success']; @@ -2762,8 +2642,6 @@ class ModelInfo { result['metadata'], result['tags'], result['notes'], - result['url'], - result['webPreviews'], ]; }) .catch((err) => { @@ -2870,131 +2748,38 @@ class ModelInfo { const previewSelect = this.previewSelect; const defaultUrl = previewSelect.elements.defaultUrl; if (info['Preview']) { - const imagePath = encodeURIComponent(info['Preview']['path']); - const imageDateModified = encodeURIComponent(info['Preview']['dateModified']); + const imagePath = info['Preview']['path']; + const imageDateModified = info['Preview']['dateModified']; defaultUrl.dataset.noimage = imageUri(imagePath, imageDateModified); } else { defaultUrl.dataset.noimage = PREVIEW_NONE_URI; } - previewSelect.resetModelInfoPreview(webPreviews); - const setPreviewDiv = $el('div.row.tab-header', { - style: { - display: "none" - } - }, [ - $el('div.row.tab-header-flex-block', [ - previewSelect.elements.radioGroup, - ]), - $el('div.row.tab-header-flex-block', [ - this.elements.setPreviewButton, - ]), - ]); - previewSelect.elements.previews.style.display = "none"; - - let previewUri; - if (info['Preview']) { - const imagePath = encodeURIComponent(info['Preview']['path']); - const imageDateModified = encodeURIComponent(info['Preview']['dateModified']); - previewUri = imageUri(imagePath, imageDateModified); - } else { - previewUri = PREVIEW_NONE_URI; - } - const previewImage = $el('img.model-preview-full', { - loading: - 'lazy' /* `loading` BEFORE `src`; Known bug in Firefox 124.0.2 and Safari for iOS 17.4.1 (https://stackoverflow.com/a/76252772) */, - src: previewUri, - }); + previewSelect.resetModelInfoPreview(); + const setPreviewButton = this.elements.setPreviewButton; + setPreviewButton.style.display = previewSelect.defaultIsChecked() + ? 'none' + : 'block'; innerHtml.push( $el('div', [ - $el('div.row.tab-header', { style: { "flex-direction": "row" } }, [ - new ComfyButton({ - icon: 'arrow-bottom-left-bold-box-outline', - tooltip: 'Attempt to load preview image workflow', - classList: 'comfyui-button icon-button', - action: async () => { - await loadWorkflow(previewImage.src); - }, - }).element, - new ComfyButton({ - icon: 'open-in-new', - tooltip: 'Attempt to open model url page in a new tab.', - classList: 'comfyui-button icon-button', - action: async (e) => { - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; - let webUrl; - if (url !== undefined && url !== "") { - webUrl = url; - } - else { - webUrl = await tryGetModelWebUrl(searchPath); - } - const success = tryOpenUrl(webUrl, searchPath); - comfyButtonAlert(e.target, success, "mdi-check-bold", "mdi-close-thick"); - button.disabled = false; - }, - }).element, - new ComfyButton({ - icon: 'earth-arrow-down', - tooltip: 'Hash model and try to download model info.', - classList: 'comfyui-button icon-button', - action: async(e) => { - const confirm = window.confirm('Overwrite model info?'); - if (!confirm) { - comfyButtonAlert(e.target, false, 'mdi-check-bold', 'mdi-close-thick'); - return; - } - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; - const success = await comfyRequest( - `/model-manager/model/download/info?path=${path}`, - { - method: 'POST', - body: {}, - } - ).then((data) => { - const success = data['success']; - const message = data['alert']; - if (message !== undefined) { - window.alert(message); - } - return success; - }).catch((err) => { - return false; - }); - if (success) { - this.#tryHideModelInfo(); - } - comfyButtonAlert(e.target, success, 'mdi-check-bold', 'mdi-close-thick'); - button.disabled = false; - }, - }).element, - new ComfyButton({ - icon: 'image-edit-outline', - tooltip: 'Open preview edit dialog.', - classList: 'comfyui-button icon-button', - action: () => { - // TODO: toggle button border highlight - if (previewImage.style.display === "none") { - setPreviewDiv.style.display = "none"; - previewSelect.elements.previews.style.display = "none"; - previewImage.style.display = ""; - } - else { - previewImage.style.display = "none"; - previewSelect.elements.previews.style.display = ""; - setPreviewDiv.style.display = ""; - if (previewSelect.elements.defaultPreviews.children[0].src.includes(PREVIEW_NONE_URI)) { - window.alert("No model previews found!\nTry downloading model info first!"); - } - } - }, - }).element, - ]), - previewImage, previewSelect.elements.previews, - setPreviewDiv, + $el('div.row.tab-header', [ + $el('div', [ + new ComfyButton({ + content: 'Load Workflow', + tooltip: 'Attempt to load preview image workflow', + action: async () => { + const urlString = + previewSelect.elements.defaultPreviews.children[0].src; + await loadWorkflow(urlString); + }, + }).element, + ]), + $el('div.row.tab-header-flex-block', [ + previewSelect.elements.radioGroup, + ]), + $el('div.row.tab-header-flex-block', [setPreviewButton]), + ]), $el('h2', ['File Info:']), $el( 'div', @@ -3037,163 +2822,40 @@ class ModelInfo { infoHtml.append.apply(infoHtml, innerHtml); // TODO: set default value of dropdown and value to model type? - // - // NOTES - // - - const saveIcon = 'content-save'; - const savingIcon = 'cloud-upload-outline'; - - const saveNotesButton = new ComfyButton({ - icon: saveIcon, - tooltip: 'Save note', - classList: 'comfyui-button icon-button', - action: async (e) => { - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; - const saved = await this.trySave(false); - comfyButtonAlert(e.target, saved); - button.disabled = false; - }, - }).element; - - const downloadNotesButton = new ComfyButton({ - icon: 'earth-arrow-down', - tooltip: 'Attempt to download model info from the internet.', - classList: 'comfyui-button icon-button', - action: async (e) => { - if (this.#savedNotesValue !== '') { - const overwriteNoteConfirmation = window.confirm('Overwrite note?'); - if (!overwriteNoteConfirmation) { - comfyButtonAlert(e.target, false, 'mdi-check-bold', 'mdi-close-thick'); - return; - } - } - - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; - const [success, downloadedNotesValue] = await comfyRequest( - `/model-manager/notes/download?path=${path}&overwrite=True`, - { - method: 'POST', - body: {}, - } - ).then((data) => { - const success = data['success']; - const message = data['alert']; - if (message !== undefined) { - window.alert(message); - } - return [success, data['notes']]; - }).catch((err) => { - return [false, '']; - }); - if (success) { - this.#savedNotesValue = downloadedNotesValue; - this.elements.notes.value = downloadedNotesValue; - this.elements.markdown.innerHTML = marked.parse(downloadedNotesValue); - } - comfyButtonAlert(e.target, success, 'mdi-check-bold', 'mdi-close-thick'); - button.disabled = false; - }, - }).element; - - const saveDebounce = debounce(async () => { - const saveIconClass = 'mdi-' + saveIcon; - const savingIconClass = 'mdi-' + savingIcon; - const iconElement = saveNotesButton.getElementsByTagName('i')[0]; - iconElement.classList.remove(saveIconClass); - iconElement.classList.add(savingIconClass); - const saved = await this.trySave(false); - iconElement.classList.remove(savingIconClass); - iconElement.classList.add(saveIconClass); - }, 1000); - /** @type {HTMLDivElement} */ - const notesElement = this.elements.tabContents[1]; // TODO: remove magic value - notesElement.innerHTML = ''; - const markdown = $el('div', {}, ''); - markdown.innerHTML = marked.parse(noteText); - - notesElement.append.apply( - notesElement, - (() => { - const notes = $el('textarea.comfy-multiline-input', { - name: 'model notes', - value: noteText, - oninput: (e) => { - if (this.#settingsElements['model-info-autosave-notes'].checked) { - saveDebounce(); + const metadataElement = this.elements.tabContents[1]; // TODO: remove magic value + const isMetadata = + typeof metadata === 'object' && + metadata !== null && + Object.keys(metadata).length > 0; + metadataElement.innerHTML = ''; + metadataElement.append.apply(metadataElement, [ + $el('h1', ['Metadata']), + $el( + 'div', + (() => { + const tableRows = []; + if (isMetadata) { + for (const [key, value] of Object.entries(metadata)) { + if (value === undefined || value === null) { + continue; + } + if (value !== '') { + tableRows.push( + $el('tr', [ + $el('th.model-metadata-key', [key]), + $el('th.model-metadata-value', [value]), + ]), + ); + } } - }, - }); - - if (navigator.userAgent.includes('Mac')) { - new KeyComboListener(['MetaLeft', 'KeyS'], saveDebounce, notes); - new KeyComboListener(['MetaRight', 'KeyS'], saveDebounce, notes); - } else { - new KeyComboListener(['ControlLeft', 'KeyS'], saveDebounce, notes); - new KeyComboListener(['ControlRight', 'KeyS'], saveDebounce, notes); - } - - this.elements.notes = notes; - this.elements.markdown = markdown; - this.#savedNotesValue = noteText; - - const notesEditor = $el( - 'div', - { - style: { - display: noteText == '' ? 'flex' : 'none', - height: '100%', - 'min-height': '60px', - }, - }, - notes, - ); - const notesViewer = $el( - 'div', - { - style: { - display: noteText == '' ? 'none' : 'flex', - height: '100%', - 'min-height': '60px', - overflow: 'scroll', - 'overflow-wrap': 'anywhere', - }, - }, - markdown, - ); - - const editNotesButton = new ComfyButton({ - icon: 'pencil', - tooltip: 'Change file name', - classList: 'comfyui-button icon-button', - action: async () => { - notesEditor.style.display = - notesEditor.style.display == 'flex' ? 'none' : 'flex'; - notesViewer.style.display = - notesViewer.style.display == 'none' ? 'flex' : 'none'; - }, - }).element; - - return [ - $el( - 'div.row', - { - style: { 'align-items': 'center' }, - }, - [$el('h1', ['Notes']), downloadNotesButton, saveNotesButton, editNotesButton], - ), - notesEditor, - notesViewer, - ]; - })(), - ); - - // - // TAGS - // + } + return $el('table.model-metadata', tableRows); + })(), + ), + ]); + const metadataButton = this.elements.tabButtons[1]; // TODO: remove magic value + metadataButton.style.display = isMetadata ? '' : 'none'; /** @type {HTMLDivElement} */ const tagsElement = this.elements.tabContents[2]; // TODO: remove magic value @@ -3307,44 +2969,114 @@ class ModelInfo { const tagButton = this.elements.tabButtons[2]; // TODO: remove magic value tagButton.style.display = isTags ? '' : 'none'; - // - // METADATA - // + const saveIcon = 'content-save'; + const savingIcon = 'cloud-upload-outline'; + + const saveNotesButton = new ComfyButton({ + icon: saveIcon, + tooltip: 'Save note', + classList: 'comfyui-button icon-button', + action: async (e) => { + const [button, icon, span] = comfyButtonDisambiguate(e.target); + button.disabled = true; + const saved = await this.trySave(false); + comfyButtonAlert(e.target, saved); + button.disabled = false; + }, + }).element; + + const saveDebounce = debounce(async () => { + const saveIconClass = 'mdi-' + saveIcon; + const savingIconClass = 'mdi-' + savingIcon; + const iconElement = saveNotesButton.getElementsByTagName('i')[0]; + iconElement.classList.remove(saveIconClass); + iconElement.classList.add(savingIconClass); + const saved = await this.trySave(false); + iconElement.classList.remove(savingIconClass); + iconElement.classList.add(saveIconClass); + }, 1000); /** @type {HTMLDivElement} */ - const metadataElement = this.elements.tabContents[3]; // TODO: remove magic value - const isMetadata = - typeof metadata === 'object' && - metadata !== null && - Object.keys(metadata).length > 0; - metadataElement.innerHTML = ''; - metadataElement.append.apply(metadataElement, [ - $el('h1', ['Metadata']), - $el( - 'div', - (() => { - const tableRows = []; - if (isMetadata) { - for (const [key, value] of Object.entries(metadata)) { - if (value === undefined || value === null) { - continue; - } - if (value !== '') { - tableRows.push( - $el('tr', [ - $el('th.model-metadata-key', [key]), - $el('th.model-metadata-value', [value]), - ]), - ); - } + const notesElement = this.elements.tabContents[3]; // TODO: remove magic value + notesElement.innerHTML = ''; + const markdown = $el('div', {}, ''); + markdown.innerHTML = marked.parse(noteText); + + notesElement.append.apply( + notesElement, + (() => { + const notes = $el('textarea.comfy-multiline-input', { + name: 'model notes', + value: noteText, + oninput: (e) => { + if (this.#settingsElements['model-info-autosave-notes'].checked) { + saveDebounce(); } - } - return $el('table.model-metadata', tableRows); - })(), - ), - ]); - const metadataButton = this.elements.tabButtons[3]; // TODO: remove magic value - metadataButton.style.display = isMetadata ? '' : 'none'; + }, + }); + + if (navigator.userAgent.includes('Mac')) { + new KeyComboListener(['MetaLeft', 'KeyS'], saveDebounce, notes); + new KeyComboListener(['MetaRight', 'KeyS'], saveDebounce, notes); + } else { + new KeyComboListener(['ControlLeft', 'KeyS'], saveDebounce, notes); + new KeyComboListener(['ControlRight', 'KeyS'], saveDebounce, notes); + } + + this.elements.notes = notes; + this.elements.markdown = markdown; + this.#savedNotesValue = noteText; + + const notes_editor = $el( + 'div', + { + style: { + display: noteText == '' ? 'flex' : 'none', + height: '100%', + 'min-height': '60px', + }, + }, + notes, + ); + const notes_viewer = $el( + 'div', + { + style: { + display: noteText == '' ? 'none' : 'flex', + height: '100%', + 'min-height': '60px', + overflow: 'scroll', + 'overflow-wrap': 'anywhere', + }, + }, + markdown, + ); + + const editNotesButton = new ComfyButton({ + icon: 'pencil', + tooltip: 'Change file name', + classList: 'comfyui-button icon-button', + action: async () => { + notes_editor.style.display = + notes_editor.style.display == 'flex' ? 'none' : 'flex'; + notes_viewer.style.display = + notes_viewer.style.display == 'none' ? 'flex' : 'none'; + }, + }).element; + + return [ + $el( + 'div.row', + { + style: { 'align-items': 'center' }, + }, + [$el('h1', ['Notes']), saveNotesButton, editNotesButton], + ), + notes_editor, + notes_viewer, + ]; + })(), + ); } static UniformTagSampling( @@ -3994,7 +3726,11 @@ class DownloadView { onkeydown: async (e) => { if (e.key === 'Enter') { e.stopPropagation(); - searchButton.click(); + if (this.elements.url.value === '') { + reset(); + } else { + await update(); + } e.target.blur(); } }, @@ -4639,7 +4375,6 @@ class SettingsView { /** @type {HTMLInputElement} */ 'model-show-add-button': null, /** @type {HTMLInputElement} */ 'model-show-copy-button': null, /** @type {HTMLInputElement} */ 'model-show-load-workflow-button': null, - /** @type {HTMLInputElement} */ 'model-show-open-model-url-button': null, /** @type {HTMLInputElement} */ 'model-info-button-on-left': null, /** @type {HTMLInputElement} */ 'model-buttons-only-on-hover': null, @@ -4667,7 +4402,7 @@ class SettingsView { }; /** @return {(withoutComfyRefresh?: boolean) => Promise} */ - #updateModels = async () => {}; + #updateModels = () => {}; /** @return {() => void} */ #updateSidebarSettings = () => {}; @@ -4809,7 +4544,7 @@ class SettingsView { this.elements.saveButton = saveButton; const correctPreviewsButton = new ComfyButton({ - content: 'Fix Preview Extensions', + content: 'Fix Extensions', tooltip: 'Correct image file extensions in all model directories', action: async (e) => { const [button, icon, span] = comfyButtonDisambiguate(e.target); @@ -4834,70 +4569,6 @@ class SettingsView { }, }).element; - const scanDownloadModelInfosButton = new ComfyButton({ - content: 'Download Model Info', - tooltip: 'Scans all model files and tries to download and save model info, notes and urls.', - action: async (e) => { - const confirmation = window.confirm( - 'WARNING: This may take a while and generate MANY server requests!\nUSE AT YOUR OWN RISK!', - ); - if (!confirmation) { - return; - } - - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; - const data = await comfyRequest('/model-manager/models/scan', { - method: 'POST', - body: JSON.stringify({}), - }).catch((err) => { - return { success: false }; - }); - const success = data['success']; - const successMessage = success ? "Scan Finished!" : "Scan Failed!"; - const infoCount = data['infoCount']; - const notesCount = data['notesCount']; - const urlCount = data['urlCount']; - window.alert(`${successMessage}\nScanned: ${infoCount}\nSaved Notes: ${notesCount}\nSaved Url: ${urlCount}`); - comfyButtonAlert(e.target, success); - if (infoCount > 0 || notesCount > 0 || urlCount > 0) { - await this.reload(true); - } - button.disabled = false; - }, - }).element; - - const scanDownloadPreviewsButton = new ComfyButton({ - content: 'Download Missing Previews', - tooltip: 'Downloads missing model previews from model info.\nRun model info scan first!', - action: async (e) => { - const confirmation = window.confirm( - 'WARNING: This may take a while and generate MANY server requests!\nUSE AT YOUR OWN RISK!', - ); - if (!confirmation) { - return; - } - - const [button, icon, span] = comfyButtonDisambiguate(e.target); - button.disabled = true; - const data = await comfyRequest('/model-manager/preview/scan', { - method: 'POST', - body: JSON.stringify({}), - }).catch((err) => { - return { success: false }; - }); - const success = data['success']; - const successMessage = success ? "Scan Finished!" : "Scan Failed!"; - const count = data['count']; - window.alert(`${successMessage}\nPreviews Downloaded: ${count}`); - comfyButtonAlert(e.target, success); - if (count > 0) { - await this.reload(true); - } - button.disabled = false; - }, - }).element; - $el( 'div.model-manager-settings', { @@ -4947,6 +4618,11 @@ class SettingsView { 'vae_approx', ], }), + $select({ + $: (el) => (settings['sidebar-default-state'] = el), + textContent: 'Default model manager position (on start up)', + options: ['Left', 'Right', 'Top', 'Bottom', 'None'], + }), $checkbox({ $: (el) => (settings['model-real-time-search'] = el), textContent: 'Real-time search', @@ -5010,9 +4686,6 @@ class SettingsView { $checkbox({ $: (el) => (settings['model-show-load-workflow-button'] = el), textContent: 'Show "Load Workflow" button', - }),$checkbox({ - $: (el) => (settings['model-show-open-model-url-button'] = el), - textContent: 'Show "Open Model Url" button', }), $checkbox({ $: (el) => (settings['model-info-button-on-left'] = el), @@ -5051,11 +4724,6 @@ class SettingsView { textContent: 'Save notes by default.', }), $el('h2', ['Window']), - $select({ - $: (el) => (settings['sidebar-default-state'] = el), - textContent: 'Default model manager position (on start up)', - options: ['None', 'Left', 'Bottom', 'Top', 'Right'], - }), sidebarControl, $el('label', [ 'Sidebar width (on start up)', @@ -5089,18 +4757,16 @@ class SettingsView { $: (el) => (settings['text-input-always-hide-clear-button'] = el), textContent: 'Always hide "Clear Search" buttons.', }), - $el('h2', ['Scan Files']), + $el('h2', ['Model Preview Images']), $el('div', [correctPreviewsButton]), - $el('div', [scanDownloadModelInfosButton]), - $el('div', [scanDownloadPreviewsButton]), $el('h2', ['Random Tag Generator']), $select({ $: (el) => (settings['tag-generator-sampler-method'] = el), - textContent: 'Sampling method', + textContent: 'Default sampling method', options: ['Frequency', 'Uniform'], }), $el('label', [ - 'Generation count', + 'Default count', $el('input', { $: (el) => (settings['tag-generator-count'] = el), type: 'number', @@ -5110,7 +4776,7 @@ class SettingsView { }), ]), $el('label', [ - 'Minimum frequency threshold', + 'Default minimum threshold', $el('input', { $: (el) => (settings['tag-generator-threshold'] = el), type: 'number', @@ -5361,7 +5027,6 @@ class ModelManager extends ComfyDialog { this.#modelData, this.#refreshModels, this.#settingsView.elements.settings, - () => this.#tryHideModelInfo(), ); this.#browseView = new BrowseView( @@ -5922,21 +5587,14 @@ class ModelManager extends ComfyDialog { /** @type {ModelManager | undefined} */ let instance; -/** @type {ComfyDialog | undefined} */ -let modelManagerDialog; - /** * @returns {ModelManager} */ function getInstance() { - if (!instance) { - instance = new ModelManager(); - - modelManagerDialog = new ComfyDialog(); - modelManagerDialog.element.classList.add("model-manager-dialog"); - instance.element.appendChild(modelManagerDialog.element); - } - return instance; + if (!instance) { + instance = new ModelManager(); + } + return instance; } const toggleModelManager = () => {