Files
nathannlu-ComfyUI-Cloud/js/utils.js
T

223 lines
6.3 KiB
JavaScript

import _ from 'https://cdn.jsdelivr.net/npm/@esm-bundle/lodash@4.17.21/+esm'
import { app } from './comfy/comfy.js';
import { inputDialog } from './comfy/ui.js';
import { getData } from './store.js';
/**
* HELPERS
*
* File for helper functions, local network api's
*/
export function formatTimestamp(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
const second = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}
export function formatDuration(seconds) {
if (seconds < 60) {
return seconds.toFixed(2) + " seconds";
} else if (seconds < 3600) {
return (seconds / 60).toFixed(2) + " minutes";
} else {
return (seconds / 3600).toFixed(2) + " hours";
}
}
export const compareDates = (a, b) => {
return b.date - a.date; // Sort in descending order (most recent to least recent)
};
export function generateUUID() {
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
return uuid;
}
export const createMetaNode = async () => {
const text = await inputDialog.input(
"Create your deployment",
"Workflow name",
);
if (!text) throw new Error("Node not created");
app.graph.beforeChange();
var node = LiteGraph.createNode("ComfyCloud");
node.configure({
widgets_values: [text],
properties: {
workflow_name: text,
}
});
node.pos = [0, 0];
app.graph.add(node);
app.graph.afterChange();
}
export const getUser = async () => {
const { user } = await fetch(
'/comfy-cloud/user',
).then((x) => x.json())
return user;
}
export const getApiToken = () => {
const { apiKey } = getData();
return apiKey;
}
export const getWorkflowName = () => {
let deployMeta = app.graph.findNodesByType("ComfyCloud");
const deployMetaNode = deployMeta[0];
// @todo
// handle no deployMetaNode
if(deployMetaNode) {
const { workflow_name } = deployMetaNode.properties;
//const name = deployMetaNode.widgets[0].value;
return workflow_name;
} else {
return null
}
}
export const getWorkflowId = () => {
let deployMeta = app.graph.findNodesByType("ComfyCloud");
const deployMetaNode = deployMeta[0];
// @todo
// handle no deployMetaNode
if(deployMetaNode) {
const { workflow_id } = deployMetaNode.properties;
//const workflow_id = deployMetaNode.widgets[1].value;
return workflow_id;
} else {
return null
}
}
export const getVersion = () => {
let deployMeta = app.graph.findNodesByType("ComfyCloud");
const deployMetaNode = deployMeta[0];
// @todo
// handle no deployMetaNode
const { version } = deployMetaNode.properties;
//const version = deployMetaNode.widgets[2].value;
return version;
}
export const setWorkflowId = (id) => {
let deployMeta = app.graph.findNodesByType("ComfyCloud");
const deployMetaNode = deployMeta[0];
// @todo
// handle no deployMetaNode
//deployMetaNode.widgets[1].value = version;
deployMetaNode.properties.workflow_id = id;
}
export const setVersion = (version) => {
let deployMeta = app.graph.findNodesByType("ComfyCloud");
const deployMetaNode = deployMeta[0];
// @todo
// handle no deployMetaNode
//deployMetaNode.widgets[2].value = version;
deployMetaNode.properties.version = version;
}
export const isCustomNode = (class_type) => {
const defaultCustomNodes = ["KSampler","KSamplerAdvanced","CheckpointLoader","CheckpointLoaderSimple","VAELoader","LoraLoader","CLIPLoader","ControlNetLoader","DiffControlNetLoader","StyleModelLoader","CLIPVisionLoader","UpscaleModelLoader","CLIPVisionEncode","StyleModelApply","CLIPTextEncode","CLIPSetLastLayer","ConditioningCombine","ConditioningAverage ","ConditioningConcat","ConditioningSetArea","ConditioningSetAreaPercentage","ConditioningSetMask","ControlNetApply","ControlNetApplyAdvanced","VAEEncodeForInpaint","SetLatentNoiseMask","VAEDecode","VAEEncode","LatentRotate","LatentFlip","LatentCrop","EmptyLatentImage","LatentUpscale","LatentUpscaleBy","LatentComposite","LatentBlend","LatentFromBatch","RepeatLatentBatch","SaveImage","PreviewImage","LoadImage","LoadImageMask","ImageScale","ImageScaleBy","ImageUpscaleWithModel","ImageInvert","ImagePadForOutpaint","ImageBatch","VAEDecodeTiled","VAEEncodeTiled"]
if (defaultCustomNodes.indexOf(class_type) !== -1) {
return true
} else {
return false;
}
}
export const getCustomNodesList = async () => {
const custom_nodes_list = await fetch("/comfy-cloud/custom-nodes-list", {
method: "get",
}).then((x) => x.json())
return custom_nodes_list.custom_nodes
}
// Exec
// returns new changes
export const compareWorkflows = (local, cloud) => {
const changes = _.differenceWith(_.toPairs(local), _.toPairs(cloud), _.isEqual)
//const changes = _.difference(_.toPairs(cloud), _.toPairs(local), _.isEqual)
const diff = changes.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {});
//console.log(local, cloud, diff)
return diff
}
export async function validatePrompt(workflow_api) {
app.lastNodeErrors = null;
const body = {
workflow_api,
}
const data = await fetch("/comfy-cloud/validate-prompt", {
method: "POST",
body: JSON.stringify(body),
}).then((x) => x.json())
app.lastNodeErrors = data.node_errors;
if (data.node_errors.length > 0) {
app.canvas.draw(true, true);
}
if(data.is_valid){
return true;
} else {
return false;
}
}
export function extractAfterInput(inputString) {
// Check if the string contains 'input'
if (inputString.includes('input')) {
// Find the index of 'input/'
const index = inputString.indexOf('input/');
// Check if 'input/' is found
if (index !== -1) {
// Return the substring after 'input/'
return inputString.substring(index + 'input/'.length);
} else {
throw new Error("Path is not in input folder")
}
}
// Return null if 'input' is not found or 'input/' is not found
return null;
}
export const isWorkflowUpToDate = diffDeps => _.isEmpty(diffDeps);