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:
@@ -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
|
||||||
|
|
||||||
|
|||||||
33
__init__.py
33
__init__.py
@@ -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"]
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user