diff --git a/__init__.py b/__init__.py
index e753eb41..775100bb 100644
--- a/__init__.py
+++ b/__init__.py
@@ -16,7 +16,7 @@ from urllib.parse import urlparse
import http.client
import re
-version = "V1.4.1"
+version = "V1.5"
print(f"### Loading: ComfyUI-Manager ({version})")
@@ -1477,6 +1477,10 @@ async def get_notice(request):
conn.close()
+@server.PromptServer.instance.routes.get("/manager/reboot")
+def restart(self):
+ return os.execv(sys.executable, ['python'] + sys.argv)
+
@server.PromptServer.instance.routes.get("/manager/share_option")
async def share_option(request):
@@ -1517,6 +1521,7 @@ def get_matrix_auth():
except:
return None
+
def get_comfyworkflows_auth():
if not os.path.exists(os.path.join(comfyui_manager_path, "comfyworkflows_sharekey")):
return None
@@ -1529,6 +1534,7 @@ def get_comfyworkflows_auth():
except:
return None
+
@server.PromptServer.instance.routes.get("/manager/get_openart_auth")
async def api_get_openart_auth(request):
# print("Getting stored Matrix credentials...")
@@ -1537,6 +1543,7 @@ async def api_get_openart_auth(request):
return web.Response(status=404)
return web.json_response({"openart_key": openart_key})
+
@server.PromptServer.instance.routes.post("/manager/set_openart_auth")
async def api_set_openart_auth(request):
json_data = await request.json()
@@ -1545,6 +1552,7 @@ async def api_set_openart_auth(request):
f.write(openart_key)
return web.Response(status=200)
+
@server.PromptServer.instance.routes.get("/manager/get_matrix_auth")
async def api_get_matrix_auth(request):
# print("Getting stored Matrix credentials...")
@@ -1553,6 +1561,7 @@ async def api_get_matrix_auth(request):
return web.Response(status=404)
return web.json_response(matrix_auth)
+
@server.PromptServer.instance.routes.get("/manager/get_comfyworkflows_auth")
async def api_get_comfyworkflows_auth(request):
# Check if the user has provided Matrix credentials in a file called 'matrix_accesstoken'
@@ -1563,6 +1572,7 @@ async def api_get_comfyworkflows_auth(request):
return web.Response(status=404)
return web.json_response({"comfyworkflows_sharekey" : comfyworkflows_auth})
+
def set_matrix_auth(json_data):
homeserver = json_data['homeserver']
username = json_data['username']
@@ -1570,6 +1580,7 @@ def set_matrix_auth(json_data):
with open(os.path.join(comfyui_manager_path, "matrix_auth"), "w") as f:
f.write("\n".join([homeserver, username, password]))
+
def set_comfyworkflows_auth(comfyworkflows_sharekey):
with open(os.path.join(comfyui_manager_path, "comfyworkflows_sharekey"), "w") as f:
f.write(comfyworkflows_sharekey)
diff --git a/js/a1111-alter-downloader.js b/js/a1111-alter-downloader.js
index 47bc28a8..36285f7f 100644
--- a/js/a1111-alter-downloader.js
+++ b/js/a1111-alter-downloader.js
@@ -1,7 +1,7 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
import { ComfyDialog, $el } from "../../scripts/ui.js";
-import { install_checked_custom_node, manager_instance } from "./common.js";
+import { install_checked_custom_node, manager_instance, rebootAPI } from "./common.js";
async function getAlterList() {
var mode = "url";
@@ -31,8 +31,9 @@ export class AlternativesInstaller extends ComfyDialog {
this.data = null;
}
- constructor() {
+ constructor(app, manager_dialog) {
super();
+ this.manager_dialog = manager_dialog;
this.search_keyword = '';
this.element = $el("div.comfy-modal", { parent: document.body }, []);
}
@@ -112,8 +113,18 @@ export class AlternativesInstaller extends ComfyDialog {
this.createBottomControls();
}
- updateMessage(msg) {
+ updateMessage(msg, btn_id) {
this.message_box.innerHTML = msg;
+ if(btn_id) {
+ const rebootButton = document.getElementById(btn_id);
+ const self = this;
+ rebootButton.onclick = function() {
+ if(rebootAPI()) {
+ self.close();
+ self.manager_dialog.close();
+ }
+ };
+ }
}
invalidate_checks(is_checked, install_state) {
diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js
index c31d0ecf..f5ee2c0b 100644
--- a/js/comfyui-manager.js
+++ b/js/comfyui-manager.js
@@ -7,7 +7,7 @@ import { CustomNodesInstaller } from "./custom-nodes-downloader.js";
import { AlternativesInstaller } from "./a1111-alter-downloader.js";
import { SnapshotManager } from "./snapshot.js";
import { ModelInstaller } from "./model-downloader.js";
-import { manager_instance, setManagerInstance, install_via_git_url } from "./common.js";
+import { manager_instance, setManagerInstance, install_via_git_url, rebootAPI } from "./common.js";
var docStyle = document.createElement('style');
docStyle.innerHTML = `
@@ -219,7 +219,7 @@ async function fetchUpdates(update_check_checkbox) {
}
}
-async function updateAll(update_check_checkbox) {
+async function updateAll(update_check_checkbox, manager_dialog) {
let prev_text = update_all_button.innerText;
update_all_button.innerText = "Updating all...(ComfyUI)";
update_all_button.disabled = true;
@@ -240,7 +240,15 @@ async function updateAll(update_check_checkbox) {
return false;
}
if(response1.status == 201 || response2.status == 201) {
- app.ui.dialog.show('ComfyUI and all extensions have been updated to the latest version.');
+ app.ui.dialog.show("ComfyUI and all extensions have been updated to the latest version.
To apply the updated custom node, please ComfyUI.");
+
+ const rebootButton = document.getElementById('cm-reboot-button');
+ rebootButton.onclick = function() {
+ if(rebootAPI()) {
+ manager_dialog.close();
+ }
+ };
+
app.ui.dialog.element.style.zIndex = 10010;
}
else {
@@ -293,6 +301,8 @@ class ManagerMenuDialog extends ComfyDialog {
local_mode_checkbox = null;
createControlsMid() {
+ let self = this;
+
update_comfyui_button =
$el("button", {
type: "button",
@@ -314,7 +324,7 @@ class ManagerMenuDialog extends ComfyDialog {
type: "button",
textContent: "Update All",
onclick:
- () => updateAll(this.update_check_checkbox)
+ () => updateAll(this.update_check_checkbox, self)
});
const res =
@@ -325,7 +335,7 @@ class ManagerMenuDialog extends ComfyDialog {
onclick:
() => {
if(!CustomNodesInstaller.instance)
- CustomNodesInstaller.instance = new CustomNodesInstaller(app);
+ CustomNodesInstaller.instance = new CustomNodesInstaller(app, self);
CustomNodesInstaller.instance.show(false);
}
}),
@@ -336,7 +346,7 @@ class ManagerMenuDialog extends ComfyDialog {
onclick:
() => {
if(!CustomNodesInstaller.instance)
- CustomNodesInstaller.instance = new CustomNodesInstaller(app);
+ CustomNodesInstaller.instance = new CustomNodesInstaller(app, self);
CustomNodesInstaller.instance.show(true);
}
}),
@@ -347,7 +357,7 @@ class ManagerMenuDialog extends ComfyDialog {
onclick:
() => {
if(!ModelInstaller.instance)
- ModelInstaller.instance = new ModelInstaller(app);
+ ModelInstaller.instance = new ModelInstaller(app, self);
ModelInstaller.instance.show();
}
}),
@@ -364,7 +374,7 @@ class ManagerMenuDialog extends ComfyDialog {
onclick:
() => {
if(!AlternativesInstaller.instance)
- AlternativesInstaller.instance = new AlternativesInstaller(app);
+ AlternativesInstaller.instance = new AlternativesInstaller(app, self);
AlternativesInstaller.instance.show();
}
}),
@@ -376,6 +386,8 @@ class ManagerMenuDialog extends ComfyDialog {
}
createControlsLeft() {
+ let self = this;
+
this.local_mode_checkbox = $el("input",{type:'checkbox', id:"use_local_db"},[])
const checkbox_text = $el("label",{},[" Use local DB"])
checkbox_text.style.color = "var(--fg-color)";
@@ -491,7 +503,7 @@ class ManagerMenuDialog extends ComfyDialog {
onclick:
() => {
if(!SnapshotManager.instance)
- SnapshotManager.instance = new SnapshotManager(app);
+ SnapshotManager.instance = new SnapshotManager(app, self);
SnapshotManager.instance.show();
}
}),
diff --git a/js/common.js b/js/common.js
index 175522dc..86290e81 100644
--- a/js/common.js
+++ b/js/common.js
@@ -1,6 +1,20 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
+export function rebootAPI() {
+ if (confirm("Are you sure you'd like to reboot the server?")) {
+ try {
+ api.fetchApi("/manager/reboot");
+ }
+ catch(exception) {
+
+ }
+ return true;
+ }
+
+ return false;
+}
+
export async function install_checked_custom_node(grid_rows, target_i, caller, mode) {
if(caller) {
let failed = '';
@@ -51,7 +65,7 @@ export async function install_checked_custom_node(grid_rows, target_i, caller, m
}
await caller.invalidateControl();
- caller.updateMessage('
To apply the installed/disabled/enabled custom node, please restart ComfyUI.');
+ caller.updateMessage("
To apply the installed/updated/disabled/enabled custom node, please ComfyUI.", 'cm-reboot-button');
}
};
diff --git a/js/custom-nodes-downloader.js b/js/custom-nodes-downloader.js
index a2f3f5a3..91e3aedc 100644
--- a/js/custom-nodes-downloader.js
+++ b/js/custom-nodes-downloader.js
@@ -1,7 +1,7 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
import { ComfyDialog, $el } from "../../scripts/ui.js";
-import { install_checked_custom_node, manager_instance } from "./common.js";
+import { install_checked_custom_node, manager_instance, rebootAPI } from "./common.js";
async function getCustomNodes() {
var mode = "url";
@@ -105,8 +105,9 @@ export class CustomNodesInstaller extends ComfyDialog {
this.data = null;
}
- constructor() {
+ constructor(app, manager_dialog) {
super();
+ this.manager_dialog = manager_dialog;
this.search_keyword = '';
this.element = $el("div.comfy-modal", { parent: document.body }, []);
}
@@ -244,8 +245,18 @@ export class CustomNodesInstaller extends ComfyDialog {
this.createBottomControls();
}
- updateMessage(msg) {
+ updateMessage(msg, btn_id) {
this.message_box.innerHTML = msg;
+ if(btn_id) {
+ const rebootButton = document.getElementById(btn_id);
+ const self = this;
+ rebootButton.onclick = function() {
+ if(rebootAPI()) {
+ self.close();
+ self.manager_dialog.close();
+ }
+ };
+ }
}
invalidate_checks(is_checked, install_state) {
diff --git a/js/model-downloader.js b/js/model-downloader.js
index c83950ff..c27d9872 100644
--- a/js/model-downloader.js
+++ b/js/model-downloader.js
@@ -1,7 +1,7 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
import { ComfyDialog, $el } from "../../scripts/ui.js";
-import { install_checked_custom_node, manager_instance } from "./common.js";
+import { install_checked_custom_node, manager_instance, rebootAPI } from "./common.js";
async function install_model(target) {
if(ModelInstaller.instance) {
@@ -55,8 +55,9 @@ export class ModelInstaller extends ComfyDialog {
this.data = null;
}
- constructor() {
+ constructor(app, manager_dialog) {
super();
+ this.manager_dialog = manager_dialog;
this.search_keyword = '';
this.element = $el("div.comfy-modal", { parent: document.body }, []);
}
@@ -126,8 +127,18 @@ export class ModelInstaller extends ComfyDialog {
this.apply_searchbox(this.data);
}
- updateMessage(msg) {
+ updateMessage(msg, btn_id) {
this.message_box.innerHTML = msg;
+ if(btn_id) {
+ const rebootButton = document.getElementById(btn_id);
+ const self = this;
+ rebootButton.onclick = function() {
+ if(rebootAPI()) {
+ self.close();
+ self.manager_dialog.close();
+ }
+ };
+ }
}
async createGrid(models_json) {
diff --git a/js/snapshot.js b/js/snapshot.js
index ff009543..f9e06dcb 100644
--- a/js/snapshot.js
+++ b/js/snapshot.js
@@ -1,7 +1,7 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"
import { ComfyDialog, $el } from "../../scripts/ui.js";
-import { manager_instance } from "./common.js";
+import { manager_instance, rebootAPI } from "./common.js";
async function restore_snapshot(target) {
@@ -23,7 +23,7 @@ async function restore_snapshot(target) {
}
finally {
await SnapshotManager.instance.invalidateControl();
- SnapshotManager.instance.updateMessage("
To apply the snapshot, please restart ComfyUI.");
+ SnapshotManager.instance.updateMessage("
To apply the snapshot, please ComfyUI.", 'cm-reboot-button');
}
}
}
@@ -87,8 +87,9 @@ export class SnapshotManager extends ComfyDialog {
this.data = null;
}
- constructor() {
+ constructor(app, manager_dialog) {
super();
+ this.manager_dialog = manager_dialog;
this.search_keyword = '';
this.element = $el("div.comfy-modal", { parent: document.body }, []);
}
@@ -132,8 +133,18 @@ export class SnapshotManager extends ComfyDialog {
await this.createBottomControls();
}
- updateMessage(msg) {
+ updateMessage(msg, btn_id) {
this.message_box.innerHTML = msg;
+ if(btn_id) {
+ const rebootButton = document.getElementById(btn_id);
+ const self = this;
+ rebootButton.onclick = function() {
+ if(rebootAPI()) {
+ self.close();
+ self.manager_dialog.close();
+ }
+ };
+ }
}
async createGrid(models_json) {