Edit and save notes with model file in model info view.

- If notes are all whitespace, the .txt file is deleted.
This commit is contained in:
Christian Bastian
2024-02-20 00:56:58 -05:00
parent b3f00dd60f
commit a72fe681b5
4 changed files with 87 additions and 28 deletions

View File

@@ -33,6 +33,7 @@ I made this fork because the original repo was inactive and missing many things
- View model metadata, including training tags and bucket resolutions. - View model metadata, including training tags and bucket resolutions.
- Delete or move a model. - Delete or move a model.
- Read, edit and save notes in a `.txt` file beside the model.
### ComfyUI Node Graph ### ComfyUI Node Graph

View File

@@ -457,11 +457,11 @@ async def get_model_info(request):
file_name, _ = os.path.splitext(file) file_name, _ = os.path.splitext(file)
txt_file = file_name + ".txt" txt_file = file_name + ".txt"
description = "" notes = ""
if os.path.isfile(txt_file): if os.path.isfile(txt_file):
with open(txt_file, 'r', encoding="utf-8") as f: with open(txt_file, 'r', encoding="utf-8") as f:
description = f.read() notes = f.read()
info["Description"] = description info["Notes"] = notes
if metadata is not None: if metadata is not None:
img_buckets = metadata.get("ss_bucket_info", "{}") img_buckets = metadata.get("ss_bucket_info", "{}")
@@ -635,6 +635,33 @@ async def delete_model(request):
return web.json_response(result) return web.json_response(result)
@server.PromptServer.instance.routes.post("/model-manager/notes/save")
async def set_notes(request):
body = await request.json()
text = body.get("notes", None)
if type(text) is not str:
return web.json_response({ "success": False })
model_path = body.get("path", None)
if type(model_path) is not str:
return web.json_response({ "success": False })
model_path, _ = search_path_to_system_path(model_path)
file_path_without_extension, _ = os.path.splitext(model_path)
filename = os.path.normpath(file_path_without_extension + ".txt")
if text.isspace() or text == "":
if os.path.exists(filename):
os.remove(filename)
else:
try:
with open(filename, "w") as f:
f.write(text)
except:
web.json_response({ "success": False })
return web.json_response({ "success": True })
WEB_DIRECTORY = "web" WEB_DIRECTORY = "web"
NODE_CLASS_MAPPINGS = {} NODE_CLASS_MAPPINGS = {}
__all__ = ["NODE_CLASS_MAPPINGS"] __all__ = ["NODE_CLASS_MAPPINGS"]

View File

@@ -442,11 +442,12 @@
width: 100%; width: 100%;
} }
.model-manager .model-manager-settings textarea { .model-manager textarea {
width: 100%; width: 100%;
font-size: 1.2em; font-size: 1.2em;
border: solid 2px var(--border-color); border: solid 2px var(--border-color);
border-radius: 8px; border-radius: 8px;
resize: vertical;
} }
.model-preview-select-radio-container img { .model-preview-select-radio-container img {

View File

@@ -1386,22 +1386,25 @@ class ModelManager extends ComfyDialog {
if (confirmation === affirmation) { if (confirmation === affirmation) {
const container = this.#el.modelInfoContainer; const container = this.#el.modelInfoContainer;
const path = encodeURIComponent(container.dataset.path); const path = encodeURIComponent(container.dataset.path);
await request( deleted = await request(
`/model-manager/model/delete?path=${path}`, `/model-manager/model/delete?path=${path}`,
{ {
method: "POST", method: "POST",
} }
) )
.then((result) => { .then((result) => {
if (result["success"]) const deleted = result["success"];
if (deleted)
{ {
container.innerHTML = ""; container.innerHTML = "";
this.#el.modelInfoView.style.display = "none"; this.#el.modelInfoView.style.display = "none";
this.#modelTab_updateModels(); this.#modelTab_updateModels();
deleted = true;
} }
return deleted;
}) })
.catch(err => {}); .catch(err => {
return false;
});
} }
if (!deleted) { if (!deleted) {
buttonAlert(e.target, false); buttonAlert(e.target, false);
@@ -1421,8 +1424,7 @@ class ModelManager extends ComfyDialog {
textContent: "Move", textContent: "Move",
onclick: async(e) => { onclick: async(e) => {
const container = this.#el.modelInfoContainer; const container = this.#el.modelInfoContainer;
let moved = false; const moved = await request(
await request(
`/model-manager/model/move`, `/model-manager/model/move`,
{ {
method: "POST", method: "POST",
@@ -1433,15 +1435,18 @@ class ModelManager extends ComfyDialog {
} }
) )
.then((result) => { .then((result) => {
if (result["success"]) const moved = result["success"];
if (moved)
{ {
container.innerHTML = ""; container.innerHTML = "";
this.#el.modelInfoView.style.display = "none"; this.#el.modelInfoView.style.display = "none";
this.#modelTab_updateModels(); this.#modelTab_updateModels();
moved = true;
} }
return moved;
}) })
.catch(err => {}); .catch(err => {
return false;
});
if (!moved) { if (!moved) {
buttonAlert(e.target, false); buttonAlert(e.target, false);
} }
@@ -1644,7 +1649,7 @@ class ModelManager extends ComfyDialog {
innerHtml.push($el("h1", [filename])); innerHtml.push($el("h1", [filename]));
} }
for (const [key, value] of Object.entries(info)) { for (const [key, value] of Object.entries(info)) {
if (value === undefined || value === null || value === "") { if (value === undefined || value === null) {
continue; continue;
} }
@@ -1669,7 +1674,38 @@ class ModelManager extends ComfyDialog {
} }
} }
else { else {
innerHtml.push($el("p", [key + ": " + value])); if (key === "Notes") {
innerHtml.push($el("h2", [key + ":"]));
const noteArea = $el("textarea.comfy-multiline-input", {
value: value,
rows: 5,
});
innerHtml.push(noteArea);
innerHtml.push($el("button", {
textContent: "Save Notes",
onclick: (e) => {
const saved = request(
"/model-manager/notes/save",
{
method: "POST",
body: JSON.stringify({
"path": this.#el.modelInfoContainer.dataset.path,
"notes": noteArea.value,
}),
}
).then((result) => {
return result["success"];
})
.catch((err) => {
return false;
});
buttonAlert(e.target, saved);
},
}));
}
else {
innerHtml.push($el("p", [key + ": " + value]));
}
} }
} }
infoHtml.append.apply(infoHtml, innerHtml); infoHtml.append.apply(infoHtml, innerHtml);
@@ -2106,27 +2142,21 @@ class ModelManager extends ComfyDialog {
})(); })();
record["overwrite"] = this.#el.modelInfoOverwrite.checked; record["overwrite"] = this.#el.modelInfoOverwrite.checked;
e.target.disabled = true; e.target.disabled = true;
let success = true; const [success, resultText] = await request(
let resultText = "✔";
await request(
"/model-manager/model/download", "/model-manager/model/download",
{ {
method: "POST", method: "POST",
body: JSON.stringify(record), body: JSON.stringify(record),
} }
).then(data => { ).then(data => {
if (data["success"] !== true) { const success = data["success"];
// TODO: notify user in app return [success, success ? "✔" : "📥︎"];
console.error('Failed to download model:', data);
success = false;
resultText = "📥︎";
}
}).catch(err => { }).catch(err => {
// TODO: notify user in app return [false, "📥︎"];
console.error('Failed to download model:', err);
success = false;
resultText = "📥︎";
}); });
if (success) {
this.#modelTab_updateModels();
}
buttonAlert(e.target, success, "✔", "✖", resultText); buttonAlert(e.target, success, "✔", "✖", resultText);
e.target.disabled = success; e.target.disabled = success;
}, },