feat: introduce dependencies upload
This commit is contained in:
		
							parent
							
								
									df46e3a0e5
								
							
						
					
					
						commit
						4348ab45dc
					
				
							
								
								
									
										134
									
								
								custom_routes.py
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								custom_routes.py
									
									
									
									
									
								
							@ -22,6 +22,8 @@ from logging.handlers import RotatingFileHandler
 | 
				
			|||||||
from enum import Enum
 | 
					from enum import Enum
 | 
				
			||||||
from urllib.parse import quote
 | 
					from urllib.parse import quote
 | 
				
			||||||
import threading
 | 
					import threading
 | 
				
			||||||
 | 
					import hashlib
 | 
				
			||||||
 | 
					import aiohttp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
api = None
 | 
					api = None
 | 
				
			||||||
api_task = None
 | 
					api_task = None
 | 
				
			||||||
@ -143,6 +145,138 @@ async def comfy_deploy_run(request):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
sockets = dict()
 | 
					sockets = dict()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_comfyui_path_from_file_path(file_path):
 | 
				
			||||||
 | 
					    file_path_parts = file_path.split("\\")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if file_path_parts[0] == "input":
 | 
				
			||||||
 | 
					        print("matching input")
 | 
				
			||||||
 | 
					        file_path = os.path.join(folder_paths.get_directory_by_type("input"), *file_path_parts[1:])
 | 
				
			||||||
 | 
					    elif file_path_parts[0] == "models":
 | 
				
			||||||
 | 
					        print("matching models")
 | 
				
			||||||
 | 
					        file_path = folder_paths.get_full_path(file_path_parts[1], os.path.join(*file_path_parts[2:]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print(file_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return file_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Form ComfyUI Manager
 | 
				
			||||||
 | 
					def compute_sha256_checksum(filepath):
 | 
				
			||||||
 | 
					    filepath = get_comfyui_path_from_file_path(filepath)
 | 
				
			||||||
 | 
					    """Compute the SHA256 checksum of a file, in chunks"""
 | 
				
			||||||
 | 
					    sha256 = hashlib.sha256()
 | 
				
			||||||
 | 
					    with open(filepath, 'rb') as f:
 | 
				
			||||||
 | 
					        for chunk in iter(lambda: f.read(4096), b''):
 | 
				
			||||||
 | 
					            sha256.update(chunk)
 | 
				
			||||||
 | 
					    return sha256.hexdigest()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This is start uploading the files to Comfy Deploy
 | 
				
			||||||
 | 
					@server.PromptServer.instance.routes.post('/comfyui-deploy/upload-file')
 | 
				
			||||||
 | 
					async def upload_file(request):
 | 
				
			||||||
 | 
					    data = await request.json()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    file_path = data.get("file_path")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print("Original file path", file_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    file_path = get_comfyui_path_from_file_path(file_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # return web.json_response({
 | 
				
			||||||
 | 
					    #     "error": f"File not uploaded"
 | 
				
			||||||
 | 
					    # }, status=500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    token = data.get("token")
 | 
				
			||||||
 | 
					    get_url = data.get("url")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        base = folder_paths.base_path
 | 
				
			||||||
 | 
					        file_path = os.path.join(base, file_path)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if os.path.exists(file_path):
 | 
				
			||||||
 | 
					            file_size = os.path.getsize(file_path)
 | 
				
			||||||
 | 
					            file_extension = os.path.splitext(file_path)[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if file_extension in ['.jpg', '.jpeg']:
 | 
				
			||||||
 | 
					                file_type = 'image/jpeg'
 | 
				
			||||||
 | 
					            elif file_extension == '.png':
 | 
				
			||||||
 | 
					                file_type = 'image/png'
 | 
				
			||||||
 | 
					            elif file_extension == '.webp':
 | 
				
			||||||
 | 
					                file_type = 'image/webp'
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                file_type = 'application/octet-stream'  # Default to binary file type if unknown
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return web.json_response({
 | 
				
			||||||
 | 
					                "error": f"File not found: {file_path}"
 | 
				
			||||||
 | 
					            }, status=404)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        return web.json_response({
 | 
				
			||||||
 | 
					            "error": str(e)
 | 
				
			||||||
 | 
					        }, status=500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if get_url:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            async with aiohttp.ClientSession() as session:
 | 
				
			||||||
 | 
					                headers = {'Authorization': f'Bearer {token}'}
 | 
				
			||||||
 | 
					                params = {'file_size': file_size, 'type': file_type}
 | 
				
			||||||
 | 
					                async with session.get(get_url, params=params, headers=headers) as response:
 | 
				
			||||||
 | 
					                    if response.status == 200:
 | 
				
			||||||
 | 
					                        content = await response.json()
 | 
				
			||||||
 | 
					                        upload_url = content["upload_url"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        with open(file_path, 'rb') as f:
 | 
				
			||||||
 | 
					                            headers = {
 | 
				
			||||||
 | 
					                                "Content-Type": file_type,
 | 
				
			||||||
 | 
					                                "x-amz-acl": "public-read",
 | 
				
			||||||
 | 
					                                "Content-Length": str(file_size)
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            async with session.put(upload_url, data=f, headers=headers) as upload_response:
 | 
				
			||||||
 | 
					                                if upload_response.status == 200:
 | 
				
			||||||
 | 
					                                    return web.json_response({
 | 
				
			||||||
 | 
					                                        "message": "File uploaded successfully",
 | 
				
			||||||
 | 
					                                        "download_url": content["download_url"]
 | 
				
			||||||
 | 
					                                    })
 | 
				
			||||||
 | 
					                                else:
 | 
				
			||||||
 | 
					                                    return web.json_response({
 | 
				
			||||||
 | 
					                                        "error": f"Failed to upload file to {upload_url}. Status code: {upload_response.status}"
 | 
				
			||||||
 | 
					                                    }, status=upload_response.status)
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        return web.json_response({
 | 
				
			||||||
 | 
					                            "error": f"Failed to fetch data from {get_url}. Status code: {response.status}"
 | 
				
			||||||
 | 
					                        }, status=response.status)
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            return web.json_response({
 | 
				
			||||||
 | 
					                "error": f"An error occurred while fetching data from {get_url}: {str(e)}"
 | 
				
			||||||
 | 
					            }, status=500)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    return web.json_response({
 | 
				
			||||||
 | 
					        "error": f"File not uploaded"
 | 
				
			||||||
 | 
					    }, status=500)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@server.PromptServer.instance.routes.get('/comfyui-deploy/get-file-hash')
 | 
				
			||||||
 | 
					async def get_file_hash(request):
 | 
				
			||||||
 | 
					    file_path = request.rel_url.query.get('file_path', '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if file_path is None:
 | 
				
			||||||
 | 
					        return web.json_response({
 | 
				
			||||||
 | 
					            "error": "file_path is required"
 | 
				
			||||||
 | 
					        }, status=400)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        base = folder_paths.base_path
 | 
				
			||||||
 | 
					        file_path = os.path.join(base, file_path)
 | 
				
			||||||
 | 
					        # print("file_path", file_path)
 | 
				
			||||||
 | 
					        file_hash = compute_sha256_checksum(
 | 
				
			||||||
 | 
					            file_path
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return web.json_response({
 | 
				
			||||||
 | 
					            "file_hash": file_hash
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        return web.json_response({
 | 
				
			||||||
 | 
					            "error": str(e)
 | 
				
			||||||
 | 
					        }, status=500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@server.PromptServer.instance.routes.get('/comfyui-deploy/ws')
 | 
					@server.PromptServer.instance.routes.get('/comfyui-deploy/ws')
 | 
				
			||||||
async def websocket_handler(request):
 | 
					async def websocket_handler(request):
 | 
				
			||||||
    ws = web.WebSocketResponse()
 | 
					    ws = web.WebSocketResponse()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
import { app } from "./app.js";
 | 
					import { app } from "./app.js";
 | 
				
			||||||
import { api } from "./api.js";
 | 
					import { api } from "./api.js";
 | 
				
			||||||
import { ComfyWidgets, LGraphNode } from "./widgets.js";
 | 
					import { ComfyWidgets, LGraphNode } from "./widgets.js";
 | 
				
			||||||
 | 
					import { generateDependencyGraph } from "https://esm.sh/comfyui-json@0.1.7";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @typedef {import('../../../web/types/comfy.js').ComfyExtension} ComfyExtension*/
 | 
					/** @typedef {import('../../../web/types/comfy.js').ComfyExtension} ComfyExtension*/
 | 
				
			||||||
/** @type {ComfyExtension} */
 | 
					/** @type {ComfyExtension} */
 | 
				
			||||||
@ -178,6 +179,71 @@ function showError(title, message) {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createDynamicUIHtml(data) {
 | 
				
			||||||
 | 
					  let html =
 | 
				
			||||||
 | 
					    '<div style="max-width: 1024px; margin: 14px auto; display: flex; flex-direction: column; gap: 24px;">';
 | 
				
			||||||
 | 
					  const bgcolor = "var(--comfy-input-bg)";
 | 
				
			||||||
 | 
					  const textColor = "var(--input-text)";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Custom Nodes
 | 
				
			||||||
 | 
					  html += `<div style="background-color: ${bgcolor}; padding: 24px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">`;
 | 
				
			||||||
 | 
					  html +=
 | 
				
			||||||
 | 
					    '<h2 style="margin-top: 0px; font-size: 24px; font-weight: bold; margin-bottom: 16px;">Custom Nodes</h2>';
 | 
				
			||||||
 | 
					  Object.values(data.custom_nodes).forEach((node) => {
 | 
				
			||||||
 | 
					    html += `
 | 
				
			||||||
 | 
					          <div style="border-bottom: 1px solid #e2e8f0; padding-top: 16px;">
 | 
				
			||||||
 | 
					              <a href="${
 | 
				
			||||||
 | 
					                node.url
 | 
				
			||||||
 | 
					              }" target="_blank" style="font-size: 18px; font-weight: semibold; color: white; text-decoration: none;">${
 | 
				
			||||||
 | 
					                node.name
 | 
				
			||||||
 | 
					              }</a>
 | 
				
			||||||
 | 
					              <p style="font-size: 14px; color: #4b5563;">${node.hash}</p>
 | 
				
			||||||
 | 
					              ${
 | 
				
			||||||
 | 
					                node.warning
 | 
				
			||||||
 | 
					                  ? `<p style="font-size: 14px; color: #d69e2e;">${node.warning}</p>`
 | 
				
			||||||
 | 
					                  : ""
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					      `;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  html += "</div>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Models
 | 
				
			||||||
 | 
					  html += `<div style="background-color: ${bgcolor}; padding: 24px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">`;
 | 
				
			||||||
 | 
					  html +=
 | 
				
			||||||
 | 
					    '<h2 style="margin-top: 0px; font-size: 24px; font-weight: bold; margin-bottom: 16px;">Models</h2>';
 | 
				
			||||||
 | 
					  const modelSections = ["checkpoints", "ipadapter", "clip_vision"];
 | 
				
			||||||
 | 
					  modelSections.forEach((section) => {
 | 
				
			||||||
 | 
					    html += `
 | 
				
			||||||
 | 
					          <div style="border-bottom: 1px solid #e2e8f0; padding-top: 8px; padding-bottom: 8px;">
 | 
				
			||||||
 | 
					              <h3 style="font-size: 18px; font-weight: semibold; margin-bottom: 8px;">${
 | 
				
			||||||
 | 
					                section.charAt(0).toUpperCase() + section.slice(1)
 | 
				
			||||||
 | 
					              }</h3>
 | 
				
			||||||
 | 
					      `;
 | 
				
			||||||
 | 
					    data.models[section].forEach((item) => {
 | 
				
			||||||
 | 
					      html += `<p style="font-size: 14px; color: ${textColor};">${item.name}</p>`;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    html += "</div>";
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  html += "</div>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Files
 | 
				
			||||||
 | 
					  html += `<div style="background-color: ${bgcolor}; padding: 24px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">`;
 | 
				
			||||||
 | 
					  html +=
 | 
				
			||||||
 | 
					    '<h2 style="margin-top: 0px; font-size: 24px; font-weight: bold; margin-bottom: 16px;">Files</h2>';
 | 
				
			||||||
 | 
					  html += `
 | 
				
			||||||
 | 
					      <div style="border-bottom: 1px solid #e2e8f0; padding-top: 8px; padding-bottom: 8px;">
 | 
				
			||||||
 | 
					          <h3 style="font-size: 18px; font-weight: semibold; margin-bottom: 8px;">Images</h3>
 | 
				
			||||||
 | 
					  `;
 | 
				
			||||||
 | 
					  data.files.images.forEach((image) => {
 | 
				
			||||||
 | 
					    html += `<p style="font-size: 14px; color: ${textColor};">${image.name}</p>`;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  html += "</div></div>";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  html += "</div>";
 | 
				
			||||||
 | 
					  return html;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function addButton() {
 | 
					function addButton() {
 | 
				
			||||||
  const menu = document.querySelector(".comfy-menu");
 | 
					  const menu = document.querySelector(".comfy-menu");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -189,8 +255,29 @@ function addButton() {
 | 
				
			|||||||
    /** @type {LGraph} */
 | 
					    /** @type {LGraph} */
 | 
				
			||||||
    const graph = app.graph;
 | 
					    const graph = app.graph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let { endpoint, apiKey, displayName } = getData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!endpoint || !apiKey || apiKey === "" || endpoint === "") {
 | 
				
			||||||
 | 
					      configDialog.show();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ok = await confirmDialog.confirm(
 | 
				
			||||||
 | 
					      "Confirm deployment -> " + displayName,
 | 
				
			||||||
 | 
					      `A new version will be deployed, are you conform? <br><br><input id="include-deps" type="checkbox" checked>Include dependence</input>`,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    if (!ok) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const includeDeps = document.getElementById("include-deps").checked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (endpoint.endsWith("/")) {
 | 
				
			||||||
 | 
					      endpoint = endpoint.slice(0, -1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    loadingDialog.showLoading("Generating snapshot", "Please wait...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const snapshot = await fetch("/snapshot/get_current").then((x) => x.json());
 | 
					    const snapshot = await fetch("/snapshot/get_current").then((x) => x.json());
 | 
				
			||||||
    // console.log(snapshot);
 | 
					    // console.log(snapshot);
 | 
				
			||||||
 | 
					    loadingDialog.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!snapshot) {
 | 
					    if (!snapshot) {
 | 
				
			||||||
      showError(
 | 
					      showError(
 | 
				
			||||||
@ -224,32 +311,94 @@ function addButton() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const deployMetaNode = deployMeta[0];
 | 
					    const deployMetaNode = deployMeta[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // console.log(deployMetaNode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const workflow_name = deployMetaNode.widgets[0].value;
 | 
					    const workflow_name = deployMetaNode.widgets[0].value;
 | 
				
			||||||
    const workflow_id = deployMetaNode.widgets[1].value;
 | 
					    const workflow_id = deployMetaNode.widgets[1].value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    console.log(workflow_name, workflow_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const prompt = await app.graphToPrompt();
 | 
					    const prompt = await app.graphToPrompt();
 | 
				
			||||||
    console.log(graph);
 | 
					    let deps = undefined;
 | 
				
			||||||
    console.log(prompt);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // const endpoint = localStorage.getItem("endpoint") ?? "";
 | 
					    if (includeDeps) {
 | 
				
			||||||
    // const apiKey = localStorage.getItem("apiKey");
 | 
					      loadingDialog.showLoading("Fetching existing version", "Please wait...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { endpoint, apiKey, displayName } = getData();
 | 
					      const existing_workflow = await fetch(
 | 
				
			||||||
 | 
					        endpoint + "/api/workflow/" + workflow_id,
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          method: "GET",
 | 
				
			||||||
 | 
					          headers: {
 | 
				
			||||||
 | 
					            "Content-Type": "application/json",
 | 
				
			||||||
 | 
					            Authorization: "Bearer " + apiKey,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					        .then((x) => x.json())
 | 
				
			||||||
 | 
					        .catch(() => {
 | 
				
			||||||
 | 
					          return {};
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!endpoint || !apiKey || apiKey === "" || endpoint === "") {
 | 
					      loadingDialog.close();
 | 
				
			||||||
      configDialog.show();
 | 
					
 | 
				
			||||||
      return;
 | 
					      loadingDialog.showLoading(
 | 
				
			||||||
 | 
					        "Generating dependency graph",
 | 
				
			||||||
 | 
					        "Please wait...",
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      deps = await generateDependencyGraph(
 | 
				
			||||||
 | 
					        prompt.output,
 | 
				
			||||||
 | 
					        snapshot,
 | 
				
			||||||
 | 
					        async (file) => {
 | 
				
			||||||
 | 
					          console.log(file);
 | 
				
			||||||
 | 
					          loadingDialog.showLoading("Generating hash", file);
 | 
				
			||||||
 | 
					          const hash = await fetch(
 | 
				
			||||||
 | 
					            `/comfyui-deploy/get-file-hash?file_path=${encodeURIComponent(
 | 
				
			||||||
 | 
					              file,
 | 
				
			||||||
 | 
					            )}`,
 | 
				
			||||||
 | 
					          ).then((x) => x.json());
 | 
				
			||||||
 | 
					          loadingDialog.showLoading("Generating hash", file);
 | 
				
			||||||
 | 
					          console.log(hash);
 | 
				
			||||||
 | 
					          return hash.file_hash;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        async (file, hash, prevhash) => {
 | 
				
			||||||
 | 
					          console.log("Uploading ", file);
 | 
				
			||||||
 | 
					          loadingDialog.showLoading("Uploading file", file);
 | 
				
			||||||
 | 
					          try {
 | 
				
			||||||
 | 
					            const { download_url } = await fetch(
 | 
				
			||||||
 | 
					              `/comfyui-deploy/upload-file`,
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                method: "POST",
 | 
				
			||||||
 | 
					                body: JSON.stringify({
 | 
				
			||||||
 | 
					                  file_path: file,
 | 
				
			||||||
 | 
					                  token: apiKey,
 | 
				
			||||||
 | 
					                  url: endpoint + "/api/upload-url",
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					              .then((x) => x.json())
 | 
				
			||||||
 | 
					              .catch(() => {
 | 
				
			||||||
 | 
					                loadingDialog.close();
 | 
				
			||||||
 | 
					                confirmDialog.confirm("Error", "Unable to upload file " + file);
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            loadingDialog.showLoading("Uploaded file", file);
 | 
				
			||||||
 | 
					            console.log(download_url);
 | 
				
			||||||
 | 
					            return download_url;
 | 
				
			||||||
 | 
					          } catch (error) {
 | 
				
			||||||
 | 
					            return undefined;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        existing_workflow.dependencies,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      loadingDialog.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const depsOk = await confirmDialog.confirm(
 | 
				
			||||||
 | 
					        "Check dependencies",
 | 
				
			||||||
 | 
					        // JSON.stringify(deps, null, 2),
 | 
				
			||||||
 | 
					        createDynamicUIHtml(deps),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      if (!depsOk) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      console.log(deps);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const ok = await confirmDialog.confirm(
 | 
					    loadingDialog.showLoading("Deploying...");
 | 
				
			||||||
      "Confirm deployment -> " + displayName,
 | 
					 | 
				
			||||||
      "A new version will be deployed, are you conform?",
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    if (!ok) return;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    title.innerText = "Deploying...";
 | 
					    title.innerText = "Deploying...";
 | 
				
			||||||
    title.style.color = "orange";
 | 
					    title.style.color = "orange";
 | 
				
			||||||
@ -261,6 +410,8 @@ function addButton() {
 | 
				
			|||||||
      endpoint = endpoint.slice(0, -1);
 | 
					      endpoint = endpoint.slice(0, -1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // console.log(prompt.workflow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const apiRoute = endpoint + "/api/workflow";
 | 
					    const apiRoute = endpoint + "/api/workflow";
 | 
				
			||||||
    // const userId = apiKey
 | 
					    // const userId = apiKey
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@ -270,6 +421,7 @@ function addButton() {
 | 
				
			|||||||
        workflow: prompt.workflow,
 | 
					        workflow: prompt.workflow,
 | 
				
			||||||
        workflow_api: prompt.output,
 | 
					        workflow_api: prompt.output,
 | 
				
			||||||
        snapshot: snapshot,
 | 
					        snapshot: snapshot,
 | 
				
			||||||
 | 
					        dependencies: deps,
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      console.log(body);
 | 
					      console.log(body);
 | 
				
			||||||
      let data = await fetch(apiRoute, {
 | 
					      let data = await fetch(apiRoute, {
 | 
				
			||||||
@ -289,6 +441,8 @@ function addButton() {
 | 
				
			|||||||
        data = await data.json();
 | 
					        data = await data.json();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      loadingDialog.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      title.textContent = "Done";
 | 
					      title.textContent = "Done";
 | 
				
			||||||
      title.style.color = "green";
 | 
					      title.style.color = "green";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -305,6 +459,7 @@ function addButton() {
 | 
				
			|||||||
        title.style.color = "white";
 | 
					        title.style.color = "white";
 | 
				
			||||||
      }, 1000);
 | 
					      }, 1000);
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      loadingDialog.close();
 | 
				
			||||||
      app.ui.dialog.show(e);
 | 
					      app.ui.dialog.show(e);
 | 
				
			||||||
      console.error(e);
 | 
					      console.error(e);
 | 
				
			||||||
      title.textContent = "Error";
 | 
					      title.textContent = "Error";
 | 
				
			||||||
@ -381,7 +536,7 @@ export class InfoDialog extends ComfyDialog {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  showMessage(title, message) {
 | 
					  showMessage(title, message) {
 | 
				
			||||||
    this.show(`
 | 
					    this.show(`
 | 
				
			||||||
      <div style="width: 400px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
 | 
					      <div style="width: 100%; max-width: 600px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
 | 
				
			||||||
        <h3 style="margin: 0px;">${title}</h3>
 | 
					        <h3 style="margin: 0px;">${title}</h3>
 | 
				
			||||||
        <label>
 | 
					        <label>
 | 
				
			||||||
          ${message}
 | 
					          ${message}
 | 
				
			||||||
@ -437,7 +592,10 @@ export class LoadingDialog extends ComfyDialog {
 | 
				
			|||||||
  showLoading(title, message) {
 | 
					  showLoading(title, message) {
 | 
				
			||||||
    this.show(`
 | 
					    this.show(`
 | 
				
			||||||
      <div style="width: 400px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
 | 
					      <div style="width: 400px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
 | 
				
			||||||
        <h3 style="margin: 0px; display: flex; align-items: center; justify-content: center; gap: 4px;">${title} ${this.loadingIcon}</h3>
 | 
					        <h3 style="margin: 0px; display: flex; align-items: center; justify-content: center; gap: 12px;">${title} ${
 | 
				
			||||||
 | 
					          this.loadingIcon
 | 
				
			||||||
 | 
					        }</h3>
 | 
				
			||||||
 | 
					          ${message ? `<label>${message}</label>` : ""}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      `);
 | 
					      `);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -556,7 +714,7 @@ export class ConfirmDialog extends InfoDialog {
 | 
				
			|||||||
    return new Promise((resolve, reject) => {
 | 
					    return new Promise((resolve, reject) => {
 | 
				
			||||||
      this.callback = resolve;
 | 
					      this.callback = resolve;
 | 
				
			||||||
      this.show(`
 | 
					      this.show(`
 | 
				
			||||||
      <div style="width: 400px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
 | 
					      <div style="width: 100%; max-width: 600px; display: flex; gap: 18px; flex-direction: column; overflow: unset">
 | 
				
			||||||
        <h3 style="margin: 0px;">${title}</h3>
 | 
					        <h3 style="margin: 0px;">${title}</h3>
 | 
				
			||||||
        <label>
 | 
					        <label>
 | 
				
			||||||
          ${message}
 | 
					          ${message}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user