diff --git a/README.md b/README.md
index f6ef260..2e8c29c 100644
--- a/README.md
+++ b/README.md
@@ -198,7 +198,7 @@ NODE_CLASS_MAPPINGS.update({
- [x] Specification scanner
- [x] workflow download -> workflow gallery
- [x] Search extension by node name -> [ltdrdata.github.io](https://ltdrdata.github.io)
-- [ ] installation from git url
+- [x] installation from git url
# Disclaimer
diff --git a/__init__.py b/__init__.py
index 40943d8..6539acb 100644
--- a/__init__.py
+++ b/__init__.py
@@ -11,8 +11,9 @@ import subprocess # don't remove this
from tqdm.auto import tqdm
import concurrent
import ssl
+from urllib.parse import urlparse
-version = "V0.41"
+version = "V0.42"
print(f"### Loading: ComfyUI-Manager ({version})")
@@ -990,10 +991,20 @@ class GitProgress(RemoteProgress):
self.pbar.pos = 0
self.pbar.refresh()
+def is_valid_url(url):
+ try:
+ result = urlparse(url)
+ return all([result.scheme, result.netloc])
+ except ValueError:
+ return False
def gitclone_install(files):
print(f"install: {files}")
for url in files:
+ if not is_valid_url(url):
+ print(f"Invalid git url: '{url}'")
+ return False
+
if url.endswith("/"):
url = url[:-1]
try:
@@ -1003,7 +1014,9 @@ def gitclone_install(files):
# Clone the repository from the remote URL
if platform.system() == 'Windows':
- run_script([sys.executable, git_script_path, "--clone", custom_nodes_path, url])
+ res = run_script([sys.executable, git_script_path, "--clone", custom_nodes_path, url])
+ if res != 0:
+ return False
else:
repo = git.Repo.clone_from(url, repo_path, recursive=True, progress=GitProgress())
repo.git.clear_cache()
@@ -1196,6 +1209,20 @@ async def install_custom_node(request):
return web.Response(status=400)
+@server.PromptServer.instance.routes.get("/customnode/install/git_url")
+async def install_custom_node_git_url(request):
+ res = False
+ if "url" in request.rel_url.query:
+ url = request.rel_url.query['url']
+ res = gitclone_install([url])
+
+ if res:
+ print(f"After restarting ComfyUI, please refresh the browser.")
+ return web.Response(status=200)
+
+ return web.Response(status=400)
+
+
@server.PromptServer.instance.routes.post("/customnode/uninstall")
async def uninstall_custom_node(request):
json_data = await request.json()
diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js
index 4a227d2..d4ddf46 100644
--- a/js/comfyui-manager.js
+++ b/js/comfyui-manager.js
@@ -5,7 +5,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 } from "./common.js";
+import { manager_instance, setManagerInstance, install_via_git_url } from "./common.js";
var style = document.createElement('style');
style.innerHTML = `
@@ -372,6 +372,17 @@ class ManagerMenuDialog extends ComfyDialog {
SnapshotManager.instance.show();
}
}),
+ $el("button", {
+ type: "button",
+ textContent: "Install via Git URL",
+ onclick: () => {
+ var url = prompt("Please enter the URL of the Git repository to install", "");
+
+ if (url !== null) {
+ install_via_git_url(url);
+ }
+ }
+ }),
];
}
diff --git a/js/common.js b/js/common.js
index b556269..175522d 100644
--- a/js/common.js
+++ b/js/common.js
@@ -59,4 +59,35 @@ export var manager_instance = null;
export function setManagerInstance(obj) {
manager_instance = obj;
+}
+
+function isValidURL(url) {
+ const pattern = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/;
+ return pattern.test(url);
+}
+
+export async function install_via_git_url(url) {
+ if(!url) {
+ return;
+ }
+
+ if(!isValidURL(url)) {
+ app.ui.dialog.show(`Invalid Git url '${url}'`);
+ app.ui.dialog.element.style.zIndex = 10010;
+ return;
+ }
+
+ app.ui.dialog.show(`Wait...
Installing '${url}'`);
+ app.ui.dialog.element.style.zIndex = 10010;
+
+ const res = await api.fetchApi(`/customnode/install/git_url?url=${url}`);
+
+ if(res.status == 200) {
+ app.ui.dialog.show(`'${url}' is installed
To apply the installed/disabled/enabled custom node, please restart ComfyUI.`);
+ app.ui.dialog.element.style.zIndex = 10010;
+ }
+ else {
+ app.ui.dialog.show(`Failed to install '${url}'
See terminal log.`);
+ app.ui.dialog.element.style.zIndex = 10010;
+ }
}
\ No newline at end of file