diff --git a/comfyui_manager/common/context.py b/comfyui_manager/common/context.py index eae152ad..88fa9089 100644 --- a/comfyui_manager/common/context.py +++ b/comfyui_manager/common/context.py @@ -31,7 +31,6 @@ manager_startup_script_path:str = None manager_snapshot_path = None manager_pip_overrides_path = None manager_pip_blacklist_path = None -manager_components_path = None manager_batch_history_path = None def update_user_directory(manager_dir): @@ -42,7 +41,6 @@ def update_user_directory(manager_dir): global manager_snapshot_path global manager_pip_overrides_path global manager_pip_blacklist_path - global manager_components_path global manager_batch_history_path manager_files_path = manager_dir @@ -61,7 +59,6 @@ def update_user_directory(manager_dir): manager_channel_list_path = os.path.join(manager_files_path, 'channels.list') manager_pip_overrides_path = os.path.join(manager_files_path, "pip_overrides.json") manager_pip_blacklist_path = os.path.join(manager_files_path, "pip_blacklist.list") - manager_components_path = os.path.join(manager_files_path, "components") manager_util.cache_dir = os.path.join(manager_files_path, "cache") manager_batch_history_path = os.path.join(manager_files_path, "batch_history") diff --git a/comfyui_manager/glob/manager_core.py b/comfyui_manager/glob/manager_core.py index 162a86a1..fa9eb808 100644 --- a/comfyui_manager/glob/manager_core.py +++ b/comfyui_manager/glob/manager_core.py @@ -1574,9 +1574,6 @@ class ManagerFuncs: def __init__(self): pass - def get_current_preview_method(self): - return "none" - def run_script(self, cmd, cwd='.'): if len(cmd) > 0 and cmd[0].startswith("#"): print(f"[ComfyUI-Manager] Unexpected behavior: `{cmd}`") @@ -1594,14 +1591,12 @@ def write_config(): config = configparser.ConfigParser(strict=False) config['default'] = { - 'preview_method': manager_funcs.get_current_preview_method(), 'git_exe': get_config()['git_exe'], 'use_uv': get_config()['use_uv'], 'channel_url': get_config()['channel_url'], 'share_option': get_config()['share_option'], 'bypass_ssl': get_config()['bypass_ssl'], "file_logging": get_config()['file_logging'], - 'component_policy': get_config()['component_policy'], 'update_policy': get_config()['update_policy'], 'windows_selector_event_loop_policy': get_config()['windows_selector_event_loop_policy'], 'model_download_by_agent': get_config()['model_download_by_agent'], @@ -1634,7 +1629,6 @@ def read_config(): return { 'http_channel_enabled': get_bool('http_channel_enabled', False), - 'preview_method': default_conf.get('preview_method', manager_funcs.get_current_preview_method()).lower(), 'git_exe': default_conf.get('git_exe', ''), 'use_uv': get_bool('use_uv', True), 'channel_url': default_conf.get('channel_url', DEFAULT_CHANNEL), @@ -1642,7 +1636,6 @@ def read_config(): 'share_option': default_conf.get('share_option', 'all').lower(), 'bypass_ssl': get_bool('bypass_ssl', False), 'file_logging': get_bool('file_logging', True), - 'component_policy': default_conf.get('component_policy', 'workflow').lower(), 'update_policy': default_conf.get('update_policy', 'stable-comfyui').lower(), 'windows_selector_event_loop_policy': get_bool('windows_selector_event_loop_policy', False), 'model_download_by_agent': get_bool('model_download_by_agent', False), @@ -1661,7 +1654,6 @@ def read_config(): return { 'http_channel_enabled': False, - 'preview_method': manager_funcs.get_current_preview_method(), 'git_exe': '', 'use_uv': manager_util.use_uv, 'channel_url': DEFAULT_CHANNEL, @@ -1669,7 +1661,6 @@ def read_config(): 'share_option': 'all', 'bypass_ssl': manager_util.bypass_ssl, 'file_logging': True, - 'component_policy': 'workflow', 'update_policy': 'stable-comfyui', 'windows_selector_event_loop_policy': False, 'model_download_by_agent': False, diff --git a/comfyui_manager/glob/manager_server.py b/comfyui_manager/glob/manager_server.py index c81b482e..8ff83ec7 100644 --- a/comfyui_manager/glob/manager_server.py +++ b/comfyui_manager/glob/manager_server.py @@ -27,7 +27,6 @@ from typing import Any, Optional from comfyui_manager.common.timestamp_utils import get_timestamp_for_filename, get_now import folder_paths -import latent_preview import nodes from aiohttp import web from comfy.cli_args import args @@ -131,16 +130,6 @@ def error_response( class ManagerFuncsInComfyUI(core.ManagerFuncs): - def get_current_preview_method(self): - if args.preview_method == latent_preview.LatentPreviewMethod.Auto: - return "auto" - elif args.preview_method == latent_preview.LatentPreviewMethod.Latent2RGB: - return "latent2rgb" - elif args.preview_method == latent_preview.LatentPreviewMethod.TAESD: - return "taesd" - else: - return "none" - def run_script(self, cmd, cwd="."): if len(cmd) > 0 and cmd[0].startswith("#"): logging.error(f"[ComfyUI-Manager] Unexpected behavior: `{cmd}`") @@ -704,8 +693,6 @@ class TaskQueue: cli_args["listen"] = args.listen if hasattr(args, "port"): cli_args["port"] = args.port - if hasattr(args, "preview_method"): - cli_args["preview_method"] = str(args.preview_method) if hasattr(args, "enable_manager_legacy_ui"): cli_args["enable_manager_legacy_ui"] = args.enable_manager_legacy_ui if hasattr(args, "front_end_version"): @@ -819,14 +806,6 @@ class TaskQueue: task_queue = TaskQueue() -# Preview method initialization -if args.preview_method == latent_preview.LatentPreviewMethod.NoPreviews: - environment_utils.set_preview_method(core.get_config()["preview_method"]) -else: - logging.warning( - "[ComfyUI-Manager] Since --preview-method is set, ComfyUI-Manager's preview method feature will be ignored." - ) - async def task_worker(): logging.debug("[ComfyUI-Manager] Task worker started") diff --git a/comfyui_manager/glob/utils/environment_utils.py b/comfyui_manager/glob/utils/environment_utils.py index abcf175b..2cacab0b 100644 --- a/comfyui_manager/glob/utils/environment_utils.py +++ b/comfyui_manager/glob/utils/environment_utils.py @@ -5,8 +5,6 @@ import traceback from comfyui_manager.common import context import folder_paths -from comfy.cli_args import args -import latent_preview from comfyui_manager.glob import manager_core as core from comfyui_manager.common import cm_global @@ -93,19 +91,6 @@ def print_comfyui_version(): ) -def set_preview_method(method): - if method == "auto": - args.preview_method = latent_preview.LatentPreviewMethod.Auto - elif method == "latent2rgb": - args.preview_method = latent_preview.LatentPreviewMethod.Latent2RGB - elif method == "taesd": - args.preview_method = latent_preview.LatentPreviewMethod.TAESD - else: - args.preview_method = latent_preview.LatentPreviewMethod.NoPreviews - - core.get_config()["preview_method"] = method - - def set_update_policy(mode): core.get_config()["update_policy"] = mode @@ -135,7 +120,6 @@ def initialize_environment(): # manager_util.comfyui_manager_path, "extension-node-map.json" # ) - set_preview_method(core.get_config()["preview_method"]) print_comfyui_version() setup_environment() diff --git a/comfyui_manager/js/comfyui-manager.js b/comfyui_manager/js/comfyui-manager.js index 2c0b6cc8..cc655944 100644 --- a/comfyui_manager/js/comfyui-manager.js +++ b/comfyui_manager/js/comfyui-manager.js @@ -16,7 +16,6 @@ import { rebootAPI, setManagerInstance, show_message, customAlert, customPrompt, infoToast, showTerminal, setNeedRestart, generateUUID } from "./common.js"; -import { ComponentBuilderDialog, load_components, set_component_policy } from "./components-manager.js"; import { CustomNodesManager } from "./custom-nodes-manager.js"; import { ModelManager } from "./model-manager.js"; import { SnapshotManager } from "./snapshot.js"; @@ -957,25 +956,6 @@ class ManagerMenuDialog extends ComfyDialog { const dbRetrievalSetttingItem = createSettingsCombo("DB", this.datasrc_combo); - // preview method - let preview_combo = document.createElement("select"); - preview_combo.setAttribute("title", "Configure how latent variables will be decoded during preview in the sampling process."); - preview_combo.className = "cm-menu-combo p-select p-component p-inputwrapper p-inputwrapper-filled"; - preview_combo.appendChild($el('option', { value: 'auto', text: 'Auto' }, [])); - preview_combo.appendChild($el('option', { value: 'taesd', text: 'TAESD (slow)' }, [])); - preview_combo.appendChild($el('option', { value: 'latent2rgb', text: 'Latent2RGB (fast)' }, [])); - preview_combo.appendChild($el('option', { value: 'none', text: 'None (very fast)' }, [])); - - api.fetchApi('/v2/manager/preview_method') - .then(response => response.text()) - .then(data => { preview_combo.value = data; }); - - preview_combo.addEventListener('change', function (event) { - api.fetchApi(`/v2/manager/preview_method?value=${event.target.value}`); - }); - - const previewSetttingItem = createSettingsCombo("Preview method", preview_combo); - // channel let channel_combo = document.createElement("select"); channel_combo.setAttribute("title", "Configure the channel for retrieving data from the Custom Node list (including missing nodes) or the Model list."); @@ -1044,26 +1024,6 @@ class ManagerMenuDialog extends ComfyDialog { const shareSetttingItem = createSettingsCombo("Share", share_combo); - let component_policy_combo = document.createElement("select"); - component_policy_combo.setAttribute("title", "When loading the workflow, configure which version of the component to use."); - component_policy_combo.className = "cm-menu-combo p-select p-component p-inputwrapper p-inputwrapper-filled"; - component_policy_combo.appendChild($el('option', { value: 'workflow', text: 'Use workflow version' }, [])); - component_policy_combo.appendChild($el('option', { value: 'higher', text: 'Use higher version' }, [])); - component_policy_combo.appendChild($el('option', { value: 'mine', text: 'Use my version' }, [])); - api.fetchApi('/v2/manager/policy/component') - .then(response => response.text()) - .then(data => { - component_policy_combo.value = data; - set_component_policy(data); - }); - - component_policy_combo.addEventListener('change', function (event) { - api.fetchApi(`/v2/manager/policy/component?value=${event.target.value}`); - set_component_policy(event.target.value); - }); - - const componentSetttingItem = createSettingsCombo("Component", component_policy_combo); - update_policy_combo = document.createElement("select"); update_policy_combo.setAttribute("title", "Sets the policy to be applied when performing an update."); @@ -1088,9 +1048,7 @@ class ManagerMenuDialog extends ComfyDialog { return [ dbRetrievalSetttingItem, channelSetttingItem, - previewSetttingItem, shareSetttingItem, - componentSetttingItem, updateSetttingItem, //[TODO] replace mt-2 with wrapper div with flex column gap $el("filedset.cm-experimental.mt-auto", {}, [ @@ -1430,14 +1388,6 @@ app.registerExtension({ }); }, async setup() { - let orig_clear = app.graph.clear; - app.graph.clear = function () { - orig_clear.call(app.graph); - load_components(); - }; - - load_components(); - const menu = document.querySelector(".comfy-menu"); const separator = document.createElement("hr"); @@ -1566,19 +1516,6 @@ app.registerExtension({ node.prototype.getExtraMenuOptions = function (_, options) { origGetExtraMenuOptions?.apply?.(this, arguments); - if (node.category.startsWith('group nodes>')) { - options.push({ - content: "Save As Component", - callback: (obj) => { - if (!ComponentBuilderDialog.instance) { - ComponentBuilderDialog.instance = new ComponentBuilderDialog(); - } - ComponentBuilderDialog.instance.target_node = node; - ComponentBuilderDialog.instance.show(); - } - }, null); - } - if (isOutputNode(node)) { const { potential_outputs } = getPotentialOutputsAndOutputNodes([this]); const hasOutput = potential_outputs.length > 0; diff --git a/comfyui_manager/js/components-manager.js b/comfyui_manager/js/components-manager.js deleted file mode 100644 index 551c11f5..00000000 --- a/comfyui_manager/js/components-manager.js +++ /dev/null @@ -1,812 +0,0 @@ -import { app } from "../../scripts/app.js"; -import { api } from "../../scripts/api.js" -import { sleep, show_message, customConfirm, customAlert } from "./common.js"; -import { GroupNodeConfig, GroupNodeHandler } from "../../extensions/core/groupNode.js"; -import { ComfyDialog, $el } from "../../scripts/ui.js"; - -const SEPARATOR = ">" - -let pack_map = {}; -let rpack_map = {}; - -export function getPureName(node) { - // group nodes/ - let category = null; - if(node.category) { - category = node.category.substring(12); - } - else { - category = node.constructor.category?.substring(12); - } - if(category) { - let purename = node.comfyClass.substring(category.length+1); - return purename; - } - else if(node.comfyClass.startsWith('workflow/') || node.comfyClass.startsWith(`workflow${SEPARATOR}`)) { - return node.comfyClass.substring(9); - } - else { - return node.comfyClass; - } -} - -function isValidVersionString(version) { - const versionPattern = /^(\d+)\.(\d+)(\.(\d+))?$/; - - const match = version.match(versionPattern); - - return match !== null && - parseInt(match[1], 10) >= 0 && - parseInt(match[2], 10) >= 0 && - (!match[3] || parseInt(match[4], 10) >= 0); -} - -function register_pack_map(name, data) { - if(data.packname) { - pack_map[data.packname] = name; - rpack_map[name] = data; - } - else { - rpack_map[name] = data; - } -} - -function storeGroupNode(name, data, register=true) { - let extra = app.graph.extra; - if (!extra) app.graph.extra = extra = {}; - let groupNodes = extra.groupNodes; - if (!groupNodes) extra.groupNodes = groupNodes = {}; - groupNodes[name] = data; - - if(register) { - register_pack_map(name, data); - } -} - -export async function load_components() { - let data = await api.fetchApi('/v2/manager/component/loads', {method: "POST"}); - let components = await data.json(); - - let start_time = Date.now(); - let failed = []; - let failed2 = []; - - for(let name in components) { - if(app.graph.extra?.groupNodes?.[name]) { - if(data) { - let data = components[name]; - - let category = data.packname; - if(data.category) { - category += SEPARATOR + data.category; - } - if(category == '') { - category = 'components'; - } - - const config = new GroupNodeConfig(name, data); - await config.registerType(category); - - register_pack_map(name, data); - continue; - } - } - - let nodeData = components[name]; - - storeGroupNode(name, nodeData); - - const config = new GroupNodeConfig(name, nodeData); - - while(true) { - try { - let category = nodeData.packname; - if(nodeData.category) { - category += SEPARATOR + nodeData.category; - } - if(category == '') { - category = 'components'; - } - - await config.registerType(category); - register_pack_map(name, nodeData); - break; - } - catch { - let elapsed_time = Date.now() - start_time; - if (elapsed_time > 5000) { - failed.push(name); - break; - } else { - await sleep(100); - } - } - } - } - - // fallback1 - for(let i in failed) { - let name = failed[i]; - - if(app.graph.extra?.groupNodes?.[name]) { - continue; - } - - let nodeData = components[name]; - - storeGroupNode(name, nodeData); - - const config = new GroupNodeConfig(name, nodeData); - while(true) { - try { - let category = nodeData.packname; - if(nodeData.workflow.category) { - category += SEPARATOR + nodeData.category; - } - if(category == '') { - category = 'components'; - } - - await config.registerType(category); - register_pack_map(name, nodeData); - break; - } - catch { - let elapsed_time = Date.now() - start_time; - if (elapsed_time > 10000) { - failed2.push(name); - break; - } else { - await sleep(100); - } - } - } - } - - // fallback2 - for(let name in failed2) { - let name = failed2[i]; - - let nodeData = components[name]; - - storeGroupNode(name, nodeData); - - const config = new GroupNodeConfig(name, nodeData); - while(true) { - try { - let category = nodeData.workflow.packname; - if(nodeData.workflow.category) { - category += SEPARATOR + nodeData.category; - } - if(category == '') { - category = 'components'; - } - - await config.registerType(category); - register_pack_map(name, nodeData); - break; - } - catch { - let elapsed_time = Date.now() - start_time; - if (elapsed_time > 30000) { - failed.push(name); - break; - } else { - await sleep(100); - } - } - } - } -} - -async function save_as_component(node, version, author, prefix, nodename, packname, category) { - let component_name = `${prefix}::${nodename}`; - - let subgraph = app.graph.extra?.groupNodes?.[component_name]; - if(!subgraph) { - subgraph = app.graph.extra?.groupNodes?.[getPureName(node)]; - } - - subgraph.version = version; - subgraph.author = author; - subgraph.datetime = Date.now(); - subgraph.packname = packname; - subgraph.category = category; - - let body = - { - name: component_name, - workflow: subgraph - }; - - pack_map[packname] = component_name; - rpack_map[component_name] = subgraph; - - const res = await api.fetchApi('/v2/manager/component/save', { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(body), - }); - - if(res.status == 200) { - storeGroupNode(component_name, subgraph); - const config = new GroupNodeConfig(component_name, subgraph); - - let category = body.workflow.packname; - if(body.workflow.category) { - category += SEPARATOR + body.workflow.category; - } - if(category == '') { - category = 'components'; - } - - await config.registerType(category); - - let path = await res.text(); - show_message(`Component '${component_name}' is saved into:\n${path}`); - } - else - show_message(`Failed to save component.`); -} - -async function import_component(component_name, component, mode) { - if(mode) { - let body = - { - name: component_name, - workflow: component - }; - - const res = await api.fetchApi('/v2/manager/component/save', { - method: "POST", - headers: { "Content-Type": "application/json", }, - body: JSON.stringify(body) - }); - } - - let category = component.packname; - if(component.category) { - category += SEPARATOR + component.category; - } - if(category == '') { - category = 'components'; - } - - storeGroupNode(component_name, component); - const config = new GroupNodeConfig(component_name, component); - await config.registerType(category); -} - -function restore_to_loaded_component(component_name) { - if(rpack_map[component_name]) { - let component = rpack_map[component_name]; - storeGroupNode(component_name, component, false); - const config = new GroupNodeConfig(component_name, component); - config.registerType(component.category); - } -} - -// Using a timestamp prevents duplicate pastes and ensures the prevention of re-deletion of litegrapheditor_clipboard. -let last_paste_timestamp = null; - -function versionCompare(v1, v2) { - let ver1; - let ver2; - if(v1 && v1 != '') { - ver1 = v1.split('.'); - ver1[0] = parseInt(ver1[0]); - ver1[1] = parseInt(ver1[1]); - if(ver1.length == 2) - ver1.push(0); - else - ver1[2] = parseInt(ver2[2]); - } - else { - ver1 = [0,0,0]; - } - - if(v2 && v2 != '') { - ver2 = v2.split('.'); - ver2[0] = parseInt(ver2[0]); - ver2[1] = parseInt(ver2[1]); - if(ver2.length == 2) - ver2.push(0); - else - ver2[2] = parseInt(ver2[2]); - } - else { - ver2 = [0,0,0]; - } - - if(ver1[0] > ver2[0]) - return -1; - else if(ver1[0] < ver2[0]) - return 1; - - if(ver1[1] > ver2[1]) - return -1; - else if(ver1[1] < ver2[1]) - return 1; - - if(ver1[2] > ver2[2]) - return -1; - else if(ver1[2] < ver2[2]) - return 1; - - return 0; -} - -function checkVersion(name, component) { - let msg = ''; - if(rpack_map[name]) { - let old_version = rpack_map[name].version; - if(!old_version || old_version == '') { - msg = ` '${name}' Upgrade (V0.0 -> V${component.version})`; - } - else { - let c = versionCompare(old_version, component.version); - if(c < 0) { - msg = ` '${name}' Downgrade (V${old_version} -> V${component.version})`; - } - else if(c > 0) { - msg = ` '${name}' Upgrade (V${old_version} -> V${component.version})`; - } - else { - msg = ` '${name}' Same version (V${component.version})`; - } - } - } - else { - msg = `'${name}' NEW (V${component.version})`; - } - - return msg; -} - -async function handle_import_components(components) { - let msg = 'Components:\n'; - let cnt = 0; - for(let name in components) { - let component = components[name]; - let v = checkVersion(name, component); - - if(cnt < 10) { - msg += v + '\n'; - } - else if (cnt == 10) { - msg += '...\n'; - } - else { - // do nothing - } - - cnt++; - } - - let last_name = null; - msg += '\nWill you load components?\n'; - const confirmed = await customConfirm(msg); - if(confirmed) { - const mode = await customConfirm('\nWill you save components?\n(cancel=load without save)'); - - for(let name in components) { - let component = components[name]; - import_component(name, component, mode); - last_name = name; - } - - if(mode) { - show_message('Components are saved.'); - } - else { - show_message('Components are loaded.'); - } - } - - if(cnt == 1 && last_name) { - const node = LiteGraph.createNode(`workflow${SEPARATOR}${last_name}`); - node.pos = [app.canvas.graph_mouse[0], app.canvas.graph_mouse[1]]; - app.canvas.graph.add(node, false); - } -} - -async function handlePaste(e) { - let data = (e.clipboardData || window.clipboardData); - const items = data.items; - for(const item of items) { - if(item.kind == 'string' && item.type == 'text/plain') { - data = data.getData("text/plain"); - try { - let json_data = JSON.parse(data); - if(json_data.kind == 'ComfyUI Components' && last_paste_timestamp != json_data.timestamp) { - last_paste_timestamp = json_data.timestamp; - await handle_import_components(json_data.components); - - // disable paste node - localStorage.removeItem("litegrapheditor_clipboard", null); - } - else { - console.log('This components are already pasted: ignored'); - } - } - catch { - // nothing to do - } - } - } -} - -document.addEventListener("paste", handlePaste); - - -export class ComponentBuilderDialog extends ComfyDialog { - constructor() { - super(); - } - - clear() { - while (this.element.children.length) { - this.element.removeChild(this.element.children[0]); - } - } - - show() { - this.invalidateControl(); - - this.element.style.display = "block"; - this.element.style.zIndex = 1099; - this.element.style.width = "500px"; - this.element.style.height = "480px"; - } - - invalidateControl() { - this.clear(); - - let self = this; - - const close_button = $el("button", { id: "cm-close-button", type: "button", textContent: "Close", onclick: () => self.close() }); - this.save_button = $el("button", - { id: "cm-save-button", type: "button", textContent: "Save", onclick: () => - { - save_as_component(self.target_node, self.version_string.value.trim(), self.author.value.trim(), self.node_prefix.value.trim(), - self.getNodeName(), self.getPackName(), self.category.value.trim()); - } - }); - - let default_nodename = getPureName(this.target_node).trim(); - - let groupNode = app.graph.extra.groupNodes[default_nodename]; - let default_packname = groupNode.packname; - if(!default_packname) { - default_packname = ''; - } - - let default_category = groupNode.category; - if(!default_category) { - default_category = ''; - } - - this.default_ver = groupNode.version; - if(!this.default_ver) { - this.default_ver = '0.0'; - } - - let default_author = groupNode.author; - if(!default_author) { - default_author = ''; - } - - let delimiterIndex = default_nodename.indexOf('::'); - let default_prefix = ""; - if(delimiterIndex != -1) { - default_prefix = default_nodename.substring(0, delimiterIndex); - default_nodename = default_nodename.substring(delimiterIndex + 2); - } - - if(!default_prefix) { - this.save_button.disabled = true; - } - - this.pack_list = this.createPackListCombo(); - - let version_string = this.createLabeledInput('input version (e.g. 1.0)', '*Version : ', this.default_ver); - this.version_string = version_string[1]; - this.version_string.disabled = true; - - let author = this.createLabeledInput('input author (e.g. Dr.Lt.Data)', 'Author : ', default_author); - this.author = author[1]; - - let node_prefix = this.createLabeledInput('input node prefix (e.g. mypack)', '*Prefix : ', default_prefix); - this.node_prefix = node_prefix[1]; - - let manual_nodename = this.createLabeledInput('input node name (e.g. MAKE_BASIC_PIPE)', 'Nodename : ', default_nodename); - this.manual_nodename = manual_nodename[1]; - - let manual_packname = this.createLabeledInput('input pack name (e.g. mypack)', 'Packname : ', default_packname); - this.manual_packname = manual_packname[1]; - - let category = this.createLabeledInput('input category (e.g. util/pipe)', 'Category : ', default_category); - this.category = category[1]; - - this.node_label = this.createNodeLabel(); - - let author_mode = this.createAuthorModeCheck(); - this.author_mode = author_mode[0]; - - const content = - $el("div.comfy-modal-content", - [ - $el("tr.cm-title", {}, [ - $el("font", {size:6, color:"white"}, [`ComfyUI-Manager: Component Builder`])] - ), - $el("br", {}, []), - $el("div.cm-menu-container", - [ - author_mode[0], - author_mode[1], - category[0], - author[0], - node_prefix[0], - manual_nodename[0], - manual_packname[0], - version_string[0], - this.pack_list, - $el("br", {}, []), - this.node_label - ]), - - $el("br", {}, []), - this.save_button, - close_button, - ] - ); - - content.style.width = '100%'; - content.style.height = '100%'; - - this.element = $el("div.comfy-modal", { id:'cm-manager-dialog', parent: document.body }, [ content ]); - } - - validateInput() { - let msg = ""; - - if(!isValidVersionString(this.version_string.value)) { - msg += 'Invalid version string: '+event.value+"\n"; - } - - if(this.node_prefix.value.trim() == '') { - msg += 'Node prefix cannot be empty\n'; - } - - if(this.manual_nodename.value.trim() == '') { - msg += 'Node name cannot be empty\n'; - } - - if(msg != '') { -// alert(msg); - } - - this.save_button.disabled = msg != ""; - } - - getPackName() { - if(this.pack_list.selectedIndex == 0) { - return this.manual_packname.value.trim(); - } - - return this.pack_list.value.trim(); - } - - getNodeName() { - if(this.manual_nodename.value.trim() != '') { - return this.manual_nodename.value.trim(); - } - - return getPureName(this.target_node); - } - - createAuthorModeCheck() { - let check = $el("input",{type:'checkbox', id:"author-mode"},[]) - const check_label = $el("label",{for:"author-mode"},["Enable author mode"]); - check_label.style.color = "var(--fg-color)"; - check_label.style.cursor = "pointer"; - check.checked = false; - - let self = this; - check.onchange = () => { - self.version_string.disabled = !check.checked; - - if(!check.checked) { - self.version_string.value = self.default_ver; - } - else { - customAlert('If you are not the author, it is not recommended to change the version, as it may cause component update issues.'); - } - }; - - return [check, check_label]; - } - - createNodeLabel() { - let label = $el('p'); - label.className = 'cb-node-label'; - if(this.target_node.comfyClass.includes('::')) - label.textContent = getPureName(this.target_node); - else - label.textContent = " _::" + getPureName(this.target_node); - return label; - } - - createLabeledInput(placeholder, label, value) { - let textbox = $el('input.cb-widget-input', {type:'text', placeholder:placeholder, value:value}, []); - - let self = this; - textbox.onchange = () => { - this.validateInput.call(self); - this.node_label.textContent = this.node_prefix.value + "::" + this.manual_nodename.value; - } - let row = $el('span.cb-widget', {}, [ $el('span.cb-widget-input-label', label), textbox]); - - return [row, textbox]; - } - - createPackListCombo() { - let combo = document.createElement("select"); - combo.className = "cb-widget"; - let default_packname_option = { value: '##manual', text: 'Packname: Manual' }; - - combo.appendChild($el('option', default_packname_option, [])); - for(let name in pack_map) { - combo.appendChild($el('option', { value: name, text: 'Packname: '+ name }, [])); - } - - let self = this; - combo.onchange = function () { - if(combo.selectedIndex == 0) { - self.manual_packname.disabled = false; - } - else { - self.manual_packname.disabled = true; - } - }; - - return combo; - } -} - -let orig_handleFile = app.handleFile; - -async function handleFile(file) { - if (file.name?.endsWith(".json") || file.name?.endsWith(".pack")) { - const reader = new FileReader(); - reader.onload = async () => { - let is_component = false; - const jsonContent = JSON.parse(reader.result); - for(let name in jsonContent) { - let cand = jsonContent[name]; - is_component = cand.datetime && cand.version; - break; - } - - if(is_component) { - await handle_import_components(jsonContent); - } - else { - orig_handleFile.call(app, file); - } - }; - reader.readAsText(file); - - return; - } - - orig_handleFile.call(app, file); -} - -app.handleFile = handleFile; - -let current_component_policy = 'workflow'; -try { - api.fetchApi('/v2/manager/policy/component') - .then(response => response.text()) - .then(data => { current_component_policy = data; }); -} -catch {} - -function getChangedVersion(groupNodes) { - if(!Object.keys(pack_map).length || !groupNodes) - return null; - - let res = {}; - for(let component_name in groupNodes) { - let data = groupNodes[component_name]; - - if(rpack_map[component_name]) { - let v = versionCompare(data.version, rpack_map[component_name].version); - res[component_name] = v; - } - } - - return res; -} - -const loadGraphData = app.loadGraphData; -app.loadGraphData = async function () { - if(arguments.length == 0) - return await loadGraphData.apply(this, arguments); - - let graphData = arguments[0]; - let groupNodes = graphData.extra?.groupNodes; - let res = getChangedVersion(groupNodes); - - if(res) { - let target_components = null; - switch(current_component_policy) { - case 'higher': - target_components = Object.keys(res).filter(key => res[key] == 1); - break; - - case 'mine': - target_components = Object.keys(res); - break; - - default: - // do nothing - } - - if(target_components) { - for(let i in target_components) { - let component_name = target_components[i]; - let component = rpack_map[component_name]; - if(component && graphData.extra?.groupNodes) { - graphData.extra.groupNodes[component_name] = component; - } - } - } - } - else { - console.log('Empty components: policy ignored'); - } - - arguments[0] = graphData; - return await loadGraphData.apply(this, arguments); -}; - -export function set_component_policy(v) { - current_component_policy = v; -} - -let graphToPrompt = app.graphToPrompt; -app.graphToPrompt = async function () { - let p = await graphToPrompt.call(app); - try { - let groupNodes = p.workflow.extra?.groupNodes; - if(groupNodes) { - p.workflow.extra = { ... p.workflow.extra}; - - // get used group nodes - let used_group_nodes = new Set(); - for(let node of p.workflow.nodes) { - if(node.type.startsWith(`workflow/`) || node.type.startsWith(`workflow${SEPARATOR}`)) { - used_group_nodes.add(node.type.substring(9)); - } - } - - // remove unused group nodes - let new_groupNodes = {}; - for (let key in p.workflow.extra.groupNodes) { - if (used_group_nodes.has(key)) { - new_groupNodes[key] = p.workflow.extra.groupNodes[key]; - } - } - p.workflow.extra.groupNodes = new_groupNodes; - } - } - catch(e) { - console.log(`Failed to filtering group nodes: ${e}`); - } - - return p; -} diff --git a/comfyui_manager/legacy/manager_core.py b/comfyui_manager/legacy/manager_core.py index 7c93e03d..1a289955 100644 --- a/comfyui_manager/legacy/manager_core.py +++ b/comfyui_manager/legacy/manager_core.py @@ -1577,9 +1577,6 @@ class ManagerFuncs: def __init__(self): pass - def get_current_preview_method(self): - return "none" - def run_script(self, cmd, cwd='.'): if len(cmd) > 0 and cmd[0].startswith("#"): print(f"[ComfyUI-Manager] Unexpected behavior: `{cmd}`") @@ -1597,14 +1594,12 @@ def write_config(): config = configparser.ConfigParser(strict=False) config['default'] = { - 'preview_method': manager_funcs.get_current_preview_method(), 'git_exe': get_config()['git_exe'], 'use_uv': get_config()['use_uv'], 'channel_url': get_config()['channel_url'], 'share_option': get_config()['share_option'], 'bypass_ssl': get_config()['bypass_ssl'], "file_logging": get_config()['file_logging'], - 'component_policy': get_config()['component_policy'], 'update_policy': get_config()['update_policy'], 'windows_selector_event_loop_policy': get_config()['windows_selector_event_loop_policy'], 'model_download_by_agent': get_config()['model_download_by_agent'], @@ -1637,7 +1632,6 @@ def read_config(): return { 'http_channel_enabled': get_bool('http_channel_enabled', False), - 'preview_method': default_conf.get('preview_method', manager_funcs.get_current_preview_method()).lower(), 'git_exe': default_conf.get('git_exe', ''), 'use_uv': get_bool('use_uv', True), 'channel_url': default_conf.get('channel_url', DEFAULT_CHANNEL), @@ -1645,7 +1639,6 @@ def read_config(): 'share_option': default_conf.get('share_option', 'all').lower(), 'bypass_ssl': get_bool('bypass_ssl', False), 'file_logging': get_bool('file_logging', True), - 'component_policy': default_conf.get('component_policy', 'workflow').lower(), 'update_policy': default_conf.get('update_policy', 'stable-comfyui').lower(), 'windows_selector_event_loop_policy': get_bool('windows_selector_event_loop_policy', False), 'model_download_by_agent': get_bool('model_download_by_agent', False), @@ -1662,7 +1655,6 @@ def read_config(): return { 'http_channel_enabled': False, - 'preview_method': manager_funcs.get_current_preview_method(), 'git_exe': '', 'use_uv': True, 'channel_url': DEFAULT_CHANNEL, @@ -1670,7 +1662,6 @@ def read_config(): 'share_option': 'all', 'bypass_ssl': manager_util.bypass_ssl, 'file_logging': True, - 'component_policy': 'workflow', 'update_policy': 'stable-comfyui', 'windows_selector_event_loop_policy': False, 'model_download_by_agent': False, diff --git a/comfyui_manager/legacy/manager_server.py b/comfyui_manager/legacy/manager_server.py index 3d431427..e463d4ef 100644 --- a/comfyui_manager/legacy/manager_server.py +++ b/comfyui_manager/legacy/manager_server.py @@ -61,7 +61,6 @@ def handle_stream(stream, prefix): from comfy.cli_args import args -import latent_preview def is_loopback(address): import ipaddress @@ -146,16 +145,6 @@ async def get_risky_level(files, pip_packages): class ManagerFuncsInComfyUI(core.ManagerFuncs): - def get_current_preview_method(self): - if args.preview_method == latent_preview.LatentPreviewMethod.Auto: - return "auto" - elif args.preview_method == latent_preview.LatentPreviewMethod.Latent2RGB: - return "latent2rgb" - elif args.preview_method == latent_preview.LatentPreviewMethod.TAESD: - return "taesd" - else: - return "none" - def run_script(self, cmd, cwd='.'): if len(cmd) > 0 and cmd[0].startswith("#"): logging.error(f"[ComfyUI-Manager] Unexpected behavior: `{cmd}`") @@ -188,25 +177,6 @@ local_db_custom_node_list = os.path.join(manager_util.comfyui_manager_path, "cus local_db_extension_node_mappings = os.path.join(manager_util.comfyui_manager_path, "extension-node-map.json") -def set_preview_method(method): - if method == 'auto': - args.preview_method = latent_preview.LatentPreviewMethod.Auto - elif method == 'latent2rgb': - args.preview_method = latent_preview.LatentPreviewMethod.Latent2RGB - elif method == 'taesd': - args.preview_method = latent_preview.LatentPreviewMethod.TAESD - else: - args.preview_method = latent_preview.LatentPreviewMethod.NoPreviews - - core.get_config()['preview_method'] = method - - -set_preview_method(core.get_config()['preview_method']) - - -def set_component_policy(mode): - core.get_config()['component_policy'] = mode - def set_update_policy(mode): core.get_config()['update_policy'] = mode @@ -1725,17 +1695,6 @@ async def _install_model(json_data): return web.Response(status=200) -@routes.get("/v2/manager/preview_method") -async def preview_method(request): - if "value" in request.rel_url.query: - set_preview_method(request.rel_url.query['value']) - core.write_config() - else: - return web.Response(text=core.manager_funcs.get_current_preview_method(), status=200) - - return web.Response(status=200) - - @routes.get("/v2/manager/db_mode") async def db_mode(request): if "value" in request.rel_url.query: @@ -1747,18 +1706,6 @@ async def db_mode(request): return web.Response(status=200) - -@routes.get("/v2/manager/policy/component") -async def component_policy(request): - if "value" in request.rel_url.query: - set_component_policy(request.rel_url.query['value']) - core.write_config() - else: - return web.Response(text=core.get_config()['component_policy'], status=200) - - return web.Response(status=200) - - @routes.get("/v2/manager/policy/update") async def update_policy(request): if "value" in request.rel_url.query: @@ -1897,61 +1844,6 @@ def restart(self): return os.execv(sys.executable, cmds) -@routes.post("/v2/manager/component/save") -async def save_component(request): - try: - data = await request.json() - name = data['name'] - workflow = data['workflow'] - - if not os.path.exists(context.manager_components_path): - os.mkdir(context.manager_components_path) - - if 'packname' in workflow and workflow['packname'] != '': - sanitized_name = manager_util.sanitize_filename(workflow['packname']) + '.pack' - else: - sanitized_name = manager_util.sanitize_filename(name) + '.json' - - filepath = os.path.join(context.manager_components_path, sanitized_name) - components = {} - if os.path.exists(filepath): - with open(filepath) as f: - components = json.load(f) - - components[name] = workflow - - with open(filepath, 'w') as f: - json.dump(components, f, indent=4, sort_keys=True) - return web.Response(text=filepath, status=200) - except Exception: - return web.Response(status=400) - - -@routes.post("/v2/manager/component/loads") -async def load_components(request): - if os.path.exists(context.manager_components_path): - try: - json_files = [f for f in os.listdir(context.manager_components_path) if f.endswith('.json')] - pack_files = [f for f in os.listdir(context.manager_components_path) if f.endswith('.pack')] - - components = {} - for json_file in json_files + pack_files: - file_path = os.path.join(context.manager_components_path, json_file) - with open(file_path, 'r') as file: - try: - # When there is a conflict between the .pack and the .json, the pack takes precedence and overrides. - components.update(json.load(file)) - except json.JSONDecodeError as e: - logging.error(f"[ComfyUI-Manager] Error decoding component file in file {json_file}: {e}") - - return web.json_response(components) - except Exception as e: - logging.error(f"[ComfyUI-Manager] failed to load components\n{e}") - return web.Response(status=400) - else: - return web.json_response({}) - - @routes.get("/v2/manager/version") async def get_version(request): return web.Response(text=core.version_str, status=200) diff --git a/pyproject.toml b/pyproject.toml index 78eef4e3..6a20017c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "comfyui-manager" license = { text = "GPL-3.0-only" } -version = "4.0.3b6" +version = "4.0.3b7" requires-python = ">= 3.9" description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI." readme = "README.md"