Save model webpage links beside model.

This commit is contained in:
Christian Bastian
2024-09-12 04:32:51 -04:00
parent 408f5887cd
commit 76c0ce817b
2 changed files with 63 additions and 14 deletions

View File

@@ -244,6 +244,20 @@ def get_def_headers(url=""):
return def_headers 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): def hash_file(path, buffer_size=1024*1024):
sha256 = hashlib.sha256() sha256 = hashlib.sha256()
with open(path, 'rb') as f: 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: with open(notes_file, 'r', encoding="utf-8") as f:
notes = f.read() 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: if metadata is not None:
img_buckets = metadata.get("ss_bucket_info", None) img_buckets = metadata.get("ss_bucket_info", None)
datasets = metadata.get("ss_datasets", None) datasets = metadata.get("ss_datasets", None)
@@ -1156,6 +1175,7 @@ async def get_model_metadata(request):
if tags is not None: if tags is not None:
result["tags"] = tags result["tags"] = tags
result["notes"] = notes result["notes"] = notes
result["url"] = web_url
return web.json_response(result) return web.json_response(result)
@@ -1174,14 +1194,22 @@ async def get_model_web_url(request):
result["alert"] = "Invalid model path!" result["alert"] = "Invalid model path!"
return web.json_response(result) 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) model_info = ModelInfo.search_info(abs_path)
if len(model_info) == 0: if len(model_info) == 0:
result["alert"] = "Unable to find model info!" result["alert"] = "Unable to find model info!"
return web.json_response(result) return web.json_response(result)
web_url = ModelInfo.get_url(model_info) web_url = ModelInfo.get_url(model_info)
if web_url != "": if web_url != "":
save_web_url(url_path, web_url)
result["success"] = True result["success"] = True
return web.json_response({ "url": web_url }) return web.json_response({ "url": web_url })
@@ -1231,6 +1259,10 @@ async def download_model(request):
# download model info # download model info
_ = ModelInfo.search_info(file_name, cache=True) # save json _ = 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 # save image as model preview
image = formdata.get("image") image = formdata.get("image")
if image is not None and image != "": if image is not None and image != "":

View File

@@ -147,21 +147,29 @@ async function loadWorkflow(url) {
/** /**
* @param {string} modelSearchPath * @param {string} modelSearchPath
* @returns {Promise<boolean>} * @returns {Promise<string|undefined>}
*/ */
async function tryOpenModelUrl(modelSearchPath) { async function tryGetModelWebUrl(modelSearchPath) {
const encodedPath = encodeURIComponent(modelSearchPath); const encodedPath = encodeURIComponent(modelSearchPath);
const requestUrl = `/model-manager/model/web-url?path=${encodedPath}`; const response = await comfyRequest(`/model-manager/model/web-url?path=${encodedPath}`);
const webUrlResponse = await comfyRequest(requestUrl); const url = response.url;
let modelUrl; return url !== undefined && url !== "" ? url : undefined;
}
/**
* @param {string} url
* @param {string} name
* @returns {boolean}
*/
function tryOpenUrl(url, name="Url") {
try { try {
modelUrl = new URL(webUrlResponse["url"]); new URL(url);
} }
catch (exception) { catch (exception) {
return false; return false;
} }
try { try {
window.open(modelUrl, '_blank').focus(); window.open(url, '_blank').focus();
} }
catch (exception) { catch (exception) {
// browser or ad-blocker blocking opening new window // browser or ad-blocker blocking opening new window
@@ -169,13 +177,13 @@ async function tryOpenModelUrl(modelSearchPath) {
[ [
$el("p", { $el("p", {
style: { color: "var(--input-text)" }, style: { color: "var(--input-text)" },
}, [modelSearchPath]), }, [name]),
$el("a", { $el("a", {
href: modelUrl, href: url,
target: "_blank", target: "_blank",
}, [ }, [
$el("span", [ $el("span", [
modelUrl, url,
$el("i.mdi.mdi-open-in-new"), $el("i.mdi.mdi-open-in-new"),
]) ])
]), ]),
@@ -1970,7 +1978,8 @@ class ModelGrid {
action: async (e) => { action: async (e) => {
const [button, icon, span] = comfyButtonDisambiguate(e.target); const [button, icon, span] = comfyButtonDisambiguate(e.target);
button.disabled = true; 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"); comfyButtonAlert(e.target, success, "mdi-check-bold", "mdi-close-thick");
button.disabled = false; button.disabled = false;
}, },
@@ -2443,7 +2452,7 @@ class ModelInfo {
*/ */
async update(searchPath, updateModels, searchSeparator) { async update(searchPath, updateModels, searchSeparator) {
const path = encodeURIComponent(searchPath); 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) => { .then((result) => {
const success = result["success"]; const success = result["success"];
const message = result["alert"]; const message = result["alert"];
@@ -2458,6 +2467,7 @@ class ModelInfo {
result["metadata"], result["metadata"],
result["tags"], result["tags"],
result["notes"], result["notes"],
result["url"],
]; ];
}) })
.catch((err) => { .catch((err) => {
@@ -2585,7 +2595,14 @@ class ModelInfo {
action: async (e) => { action: async (e) => {
const [button, icon, span] = comfyButtonDisambiguate(e.target); const [button, icon, span] = comfyButtonDisambiguate(e.target);
button.disabled = true; 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"); comfyButtonAlert(e.target, success, "mdi-check-bold", "mdi-close-thick");
button.disabled = false; button.disabled = false;
}, },