From 76c0ce817bffb1e8ee5abbc2f68a82ef31d32e47 Mon Sep 17 00:00:00 2001 From: Christian Bastian <80225746+cdb-boop@users.noreply.github.com> Date: Thu, 12 Sep 2024 04:32:51 -0400 Subject: [PATCH] Save model webpage links beside model. --- __init__.py | 34 +++++++++++++++++++++++++++++++++- web/model-manager.js | 43 ++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/__init__.py b/__init__.py index 417ec92..06d4e2f 100644 --- a/__init__.py +++ b/__init__.py @@ -244,6 +244,20 @@ 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: @@ -1114,6 +1128,11 @@ async def get_model_metadata(request): with open(notes_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) @@ -1156,6 +1175,7 @@ async def get_model_metadata(request): if tags is not None: result["tags"] = tags result["notes"] = notes + result["url"] = web_url return web.json_response(result) @@ -1174,14 +1194,22 @@ async def get_model_web_url(request): 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 != "": + save_web_url(url_path, web_url) result["success"] = True + return web.json_response({ "url": web_url }) @@ -1231,6 +1259,10 @@ async def download_model(request): # download model info _ = ModelInfo.search_info(file_name, cache=True) # save json + # save url + url_file_path = os.path.splitext(file_name)[0] + ".url" + save_web_url(url_file_path, download_uri) + # save image as model preview image = formdata.get("image") if image is not None and image != "": diff --git a/web/model-manager.js b/web/model-manager.js index a498cc6..2c06bbd 100644 --- a/web/model-manager.js +++ b/web/model-manager.js @@ -147,21 +147,29 @@ async function loadWorkflow(url) { /** * @param {string} modelSearchPath - * @returns {Promise} + * @returns {Promise} */ -async function tryOpenModelUrl(modelSearchPath) { +async function tryGetModelWebUrl(modelSearchPath) { const encodedPath = encodeURIComponent(modelSearchPath); - const requestUrl = `/model-manager/model/web-url?path=${encodedPath}`; - const webUrlResponse = await comfyRequest(requestUrl); - let modelUrl; + 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 { - modelUrl = new URL(webUrlResponse["url"]); + new URL(url); } catch (exception) { return false; } try { - window.open(modelUrl, '_blank').focus(); + window.open(url, '_blank').focus(); } catch (exception) { // browser or ad-blocker blocking opening new window @@ -169,13 +177,13 @@ async function tryOpenModelUrl(modelSearchPath) { [ $el("p", { style: { color: "var(--input-text)" }, - }, [modelSearchPath]), + }, [name]), $el("a", { - href: modelUrl, + href: url, target: "_blank", }, [ $el("span", [ - modelUrl, + url, $el("i.mdi.mdi-open-in-new"), ]) ]), @@ -1970,7 +1978,8 @@ class ModelGrid { action: async (e) => { const [button, icon, span] = comfyButtonDisambiguate(e.target); button.disabled = true; - const success = await tryOpenModelUrl(searchPath); + const webUrl = await tryGetModelWebUrl(searchPath); + const success = tryOpenUrl(webUrl, searchPath); comfyButtonAlert(e.target, success, "mdi-check-bold", "mdi-close-thick"); button.disabled = false; }, @@ -2443,7 +2452,7 @@ class ModelInfo { */ async update(searchPath, updateModels, searchSeparator) { const path = encodeURIComponent(searchPath); - const [info, metadata, tags, noteText] = await comfyRequest(`/model-manager/model/info/${path}`) + const [info, metadata, tags, noteText, url] = await comfyRequest(`/model-manager/model/info/${path}`) .then((result) => { const success = result["success"]; const message = result["alert"]; @@ -2458,6 +2467,7 @@ class ModelInfo { result["metadata"], result["tags"], result["notes"], + result["url"], ]; }) .catch((err) => { @@ -2585,7 +2595,14 @@ class ModelInfo { action: async (e) => { const [button, icon, span] = comfyButtonDisambiguate(e.target); button.disabled = true; - const success = await tryOpenModelUrl(searchPath); + 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; },