From 629f025f04e36b8fd32eef38ce73311b3fb263f1 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 13:52:54 +0900 Subject: [PATCH 01/35] update DB --- custom-node-list.json | 11 ++- extension-node-map.json | 101 +++++++++++++------------ node_db/dev/extension-node-map.json | 8 ++ node_db/new/custom-node-list.json | 10 +++ node_db/new/extension-node-map.json | 101 +++++++++++++------------ node_db/tutorial/custom-node-list.json | 30 ++++++++ 6 files changed, 160 insertions(+), 101 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index 27d5ea14..0c381bbe 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4224,7 +4224,16 @@ "install_type": "git-clone", "description": "Instead of LoraLoader or HypernetworkLoader, it receives a prompt and loads and applies LoRA or HN based on the specifications within the prompt. The main purpose of this custom node is to allow changes without reconnecting the LoraLoader node when the prompt is randomly altered, etc." }, - + { + "author": "foxtrot-roger", + "title": "RF Nodes", + "reference": "https://github.com/foxtrot-roger/comfyui-rf-nodes", + "files": [ + "https://github.com/foxtrot-roger/comfyui-rf-nodes" + ], + "install_type": "git-clone", + "description": "A bunch of nodes that can be useful to manipulate primitive types (numbers, text, ...) Also some helpers to generate text and timestamps." + }, { "author": "Ser-Hilary", diff --git a/extension-node-map.json b/extension-node-map.json index b7b9e103..245ac1cd 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -116,6 +116,8 @@ [ "ApplyMaskToImage-badger", "CropImageByMask-badger", + "ExpandImageWithColor-badger", + "FindThickLinesFromCanny-badger", "FloatToInt-badger", "FloatToString-badger", "ImageNormalization-badger", @@ -125,6 +127,7 @@ "SegmentToMaskByPoint-badger", "StringToFizz-badger", "TextListToString-badger", + "TrimTransparentEdges-badger", "VideoCut-badger", "deleteDir-badger", "findCenterOfMask-badger", @@ -1785,16 +1788,8 @@ ], "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes": [ [ - "CR 3D Camera Drone", - "CR 3D Camera Static", - "CR 3D Polygon", - "CR 3D Solids", "CR 8 Channel In", "CR 8 Channel Out", - "CR ASCII Pattern", - "CR Add Annotation", - "CR Alternate Latents", - "CR Apply Annotations", "CR Apply ControlNet", "CR Apply LoRA Stack", "CR Apply Model Merge", @@ -1810,7 +1805,6 @@ "CR Binary To Bit List", "CR Bit Schedule", "CR Central Schedule", - "CR Check Job Complete", "CR Checker Pattern", "CR Clamp Value", "CR Clip Input Switch", @@ -1820,28 +1814,20 @@ "CR Color Tint", "CR Combine Schedules", "CR Comic Panel Templates", - "CR Comic Panel Templates (Advanced)", - "CR Comic Panel Templates Advanced", "CR Composite Text", "CR Conditioning Input Switch", "CR Conditioning Mixer", - "CR Continuous Rotation", - "CR Continuous Track", - "CR Continuous Zoom", "CR ControlNet Input Switch", "CR Current Frame", "CR Cycle Images", "CR Cycle Images Simple", "CR Cycle LoRAs", "CR Cycle Models", - "CR Cycle Styles", "CR Cycle Text", "CR Cycle Text Simple", "CR Data Bus In", "CR Data Bus Out", "CR Debatch Frames", - "CR Display Font", - "CR Draw OBJ", "CR Draw Perspective Text", "CR Draw Pie", "CR Draw Shape", @@ -1870,7 +1856,6 @@ "CR Image Pipe In", "CR Image Pipe Out", "CR Image Size", - "CR Image Transition", "CR Image XY Panel", "CR Img2Img Process Switch", "CR Increment Float", @@ -1884,19 +1869,11 @@ "CR Integer Range List", "CR Integer To String", "CR Interpolate Latents", - "CR Interpolate Prompt Weights", - "CR Interpolate Rotation", - "CR Interpolate Track", - "CR Interpolate Zoom", "CR Intertwine Lists", - "CR Job Current Frame", - "CR Job List", - "CR Job Scheduler", "CR KSampler", "CR Keyframe List", "CR Latent Batch Size", "CR Latent Input Switch", - "CR List Schedule", "CR LoRA List", "CR LoRA Stack", "CR Load Animation Frames", @@ -1911,8 +1888,6 @@ "CR Load Scheduled LoRAs", "CR Load Scheduled Models", "CR Load Text List", - "CR Load Workflow", - "CR Load XY Annotation From File", "CR Loop List", "CR Mask Text", "CR Math Operation", @@ -1924,7 +1899,6 @@ "CR Module Pipe Loader", "CR Multi Upscale Stack", "CR Multi-ControlNet Stack", - "CR Multi-Panel Meme Template", "CR Multiline Text", "CR Output Flow Frames", "CR Output Schedule To File", @@ -1933,14 +1907,11 @@ "CR Page Layout", "CR Pipe Switch", "CR Polygons", - "CR Popular Meme Templates", "CR Prompt List", "CR Prompt List Keyframes", "CR Prompt Scheduler", "CR Prompt Text", - "CR Prompt Weight Scheduler", "CR Radial Gradient", - "CR Radial Gradient Map", "CR Random Hex Color", "CR Random LoRA Stack", "CR Random Multiline Colors", @@ -1950,6 +1921,7 @@ "CR Random RGB Gradient", "CR Random Shape Pattern", "CR Random Weight LoRA", + "CR Repeater", "CR SD1.5 Aspect Ratio", "CR SDXL Aspect Ratio", "CR SDXL Base Prompt Encoder", @@ -1957,11 +1929,9 @@ "CR SDXL Prompt Mixer", "CR SDXL Style Text", "CR Save Text To File", - "CR Schedule Camera Movements", - "CR Schedule ControlNets", "CR Schedule Input Switch", - "CR Schedule Styles", "CR Schedule To ScheduleList", + "CR Seamless Checker", "CR Seed", "CR Seed to Int", "CR Select Font", @@ -1969,12 +1939,10 @@ "CR Set Value On Binary", "CR Set Value On Boolean", "CR Set Value on String", - "CR Simple Annotations", "CR Simple Banner", "CR Simple Binary Pattern", "CR Simple Binary Pattern Simple", "CR Simple Image Compare", - "CR Simple Image Watermark", "CR Simple List", "CR Simple Meme Template", "CR Simple Prompt List", @@ -1986,25 +1954,21 @@ "CR Simple Text Watermark", "CR Simple Titles", "CR Simple Value Scheduler", - "CR Spawn Workflow Instance", "CR Split String", "CR Starburst Colors", "CR Starburst Lines", "CR String To Combo", "CR String To Number", - "CR Strobe Images", "CR Style Bars", - "CR Style List", "CR Switch Model and CLIP", - "CR System TrueType Font", "CR Text", + "CR Text Blacklist", "CR Text Concatenate", "CR Text Cycler", "CR Text Input Switch", "CR Text Input Switch (4 way)", "CR Text Length", "CR Text List", - "CR Text List Cross Join", "CR Text List Simple", "CR Text List To String", "CR Text Operation", @@ -2019,19 +1983,16 @@ "CR Value Scheduler", "CR Vignette Filter", "CR XY From Folder", - "CR XY Grid", "CR XY Index", "CR XY Interpolate", "CR XY List", "CR XY Product", "CR XY Save Grid Image", - "CR XYZ Index", - "CR XYZ Interpolate", - "CR XYZ List" + "CR XYZ Index" ], { "author": "Suzie1", - "description": "169 custom nodes for artists, designers and animators.", + "description": "170 custom nodes for artists, designers and animators.", "nickname": "Comfyroll Studio", "title": "Comfyroll Studio", "title_aux": "ComfyUI_Comfyroll_CustomNodes" @@ -2464,6 +2425,7 @@ "Integer place counter", "KSampler (WAS)", "KSampler Cycle", + "Latent Batch", "Latent Input Switch", "Latent Noise Injection", "Latent Size to Number", @@ -2806,7 +2768,7 @@ "https://github.com/alexopus/ComfyUI-Image-Saver": [ [ "Cfg Literal (Image Saver)", - "Checkpoint Selector (Image Saver)", + "Checkpoint Loader with Name (Image Saver)", "Float Literal (Image Saver)", "Image Saver", "Int Literal (Image Saver)", @@ -3449,7 +3411,8 @@ "https://github.com/chflame163/ComfyUI_WordCloud": [ [ "ComfyWordCloud", - "LoadTextFile" + "LoadTextFile", + "RGB_Picker" ], { "title_aux": "ComfyUI_WordCloud" @@ -3831,6 +3794,7 @@ "ExtractKeyframes+", "GetImageSize+", "ImageCASharpening+", + "ImageCompositeFromMaskBatch+", "ImageCrop+", "ImageDesaturate+", "ImageEnhanceDifference+", @@ -4263,6 +4227,38 @@ "title_aux": "As_ComfyUI_CustomNodes" } ], + "https://github.com/foxtrot-roger/comfyui-rf-nodes": [ + [ + "LogBool", + "LogFloat", + "LogInt", + "LogNumber", + "LogString", + "LogVec2", + "LogVec3", + "RF_BoolToString", + "RF_FloatToString", + "RF_IntToString", + "RF_JsonStyleLoader", + "RF_MergeLines", + "RF_NumberToString", + "RF_RangeFloat", + "RF_RangeInt", + "RF_RangeNumber", + "RF_SplitLines", + "RF_TextConcatenate", + "RF_TextInput", + "RF_TextReplace", + "RF_Timestamp", + "RF_ToString", + "RF_Vec2ToString", + "RF_Vec3ToString", + "TextLine" + ], + { + "title_aux": "RF Nodes" + } + ], "https://github.com/gemell1/ComfyUI_GMIC": [ [ "GmicCliWrapper" @@ -4782,6 +4778,7 @@ "https://github.com/komojini/komojini-comfyui-nodes": [ [ "ImageMerger", + "UltimateVideoLoader", "YouTubeVideoLoader" ], { @@ -6165,6 +6162,7 @@ "GroundingDinoModelLoader (segment anything)", "GroundingDinoSAMSegment (segment anything)", "InvertMask (segment anything)", + "IsMaskEmpty", "SAMModelLoader (segment anything)" ], { @@ -6252,6 +6250,7 @@ ], "https://github.com/taabata/LCM_Inpaint-Outpaint_Comfy": [ [ + "ComfyNodesToSaveCanvas", "FloatNumber", "FreeU_LCM", "ImageOutputToComfyNodes", @@ -6298,7 +6297,8 @@ "https://github.com/talesofai/comfyui-browser": [ [ "LoadImageByUrl //Browser", - "SelectInputs //Browser" + "SelectInputs //Browser", + "XyzPlot //Browser" ], { "title_aux": "ComfyUI Browser" @@ -6395,6 +6395,7 @@ "Iterative Mixing KSampler Advanced", "IterativeMixingSampler", "IterativeMixingScheduler", + "IterativeMixingSchedulerAdvanced", "Latent Batch Comparison Plot", "Latent Batch Statistics Plot", "MixingMaskGenerator" diff --git a/node_db/dev/extension-node-map.json b/node_db/dev/extension-node-map.json index 0c7ef5a3..6a420de5 100644 --- a/node_db/dev/extension-node-map.json +++ b/node_db/dev/extension-node-map.json @@ -61,6 +61,14 @@ "title_aux": "comfy-consistency-vae" } ], + "https://github.com/LarryJane491/ComfyUI-ModelUnloader": [ + [ + "Model Unloader" + ], + { + "title_aux": "ComfyUI-ModelUnloader" + } + ], "https://github.com/MrAdamBlack/CheckProgress": [ [ "CHECK_PROGRESS" diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index bea99c4d..28e44464 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,16 @@ }, + { + "author": "foxtrot-roger", + "title": "RF Nodes", + "reference": "https://github.com/foxtrot-roger/comfyui-rf-nodes", + "files": [ + "https://github.com/foxtrot-roger/comfyui-rf-nodes" + ], + "install_type": "git-clone", + "description": "A bunch of nodes that can be useful to manipulate primitive types (numbers, text, ...) Also some helpers to generate text and timestamps." + }, { "author": "LarryJane491", "title": "Lora-Training-in-Comfy", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index b7b9e103..245ac1cd 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -116,6 +116,8 @@ [ "ApplyMaskToImage-badger", "CropImageByMask-badger", + "ExpandImageWithColor-badger", + "FindThickLinesFromCanny-badger", "FloatToInt-badger", "FloatToString-badger", "ImageNormalization-badger", @@ -125,6 +127,7 @@ "SegmentToMaskByPoint-badger", "StringToFizz-badger", "TextListToString-badger", + "TrimTransparentEdges-badger", "VideoCut-badger", "deleteDir-badger", "findCenterOfMask-badger", @@ -1785,16 +1788,8 @@ ], "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes": [ [ - "CR 3D Camera Drone", - "CR 3D Camera Static", - "CR 3D Polygon", - "CR 3D Solids", "CR 8 Channel In", "CR 8 Channel Out", - "CR ASCII Pattern", - "CR Add Annotation", - "CR Alternate Latents", - "CR Apply Annotations", "CR Apply ControlNet", "CR Apply LoRA Stack", "CR Apply Model Merge", @@ -1810,7 +1805,6 @@ "CR Binary To Bit List", "CR Bit Schedule", "CR Central Schedule", - "CR Check Job Complete", "CR Checker Pattern", "CR Clamp Value", "CR Clip Input Switch", @@ -1820,28 +1814,20 @@ "CR Color Tint", "CR Combine Schedules", "CR Comic Panel Templates", - "CR Comic Panel Templates (Advanced)", - "CR Comic Panel Templates Advanced", "CR Composite Text", "CR Conditioning Input Switch", "CR Conditioning Mixer", - "CR Continuous Rotation", - "CR Continuous Track", - "CR Continuous Zoom", "CR ControlNet Input Switch", "CR Current Frame", "CR Cycle Images", "CR Cycle Images Simple", "CR Cycle LoRAs", "CR Cycle Models", - "CR Cycle Styles", "CR Cycle Text", "CR Cycle Text Simple", "CR Data Bus In", "CR Data Bus Out", "CR Debatch Frames", - "CR Display Font", - "CR Draw OBJ", "CR Draw Perspective Text", "CR Draw Pie", "CR Draw Shape", @@ -1870,7 +1856,6 @@ "CR Image Pipe In", "CR Image Pipe Out", "CR Image Size", - "CR Image Transition", "CR Image XY Panel", "CR Img2Img Process Switch", "CR Increment Float", @@ -1884,19 +1869,11 @@ "CR Integer Range List", "CR Integer To String", "CR Interpolate Latents", - "CR Interpolate Prompt Weights", - "CR Interpolate Rotation", - "CR Interpolate Track", - "CR Interpolate Zoom", "CR Intertwine Lists", - "CR Job Current Frame", - "CR Job List", - "CR Job Scheduler", "CR KSampler", "CR Keyframe List", "CR Latent Batch Size", "CR Latent Input Switch", - "CR List Schedule", "CR LoRA List", "CR LoRA Stack", "CR Load Animation Frames", @@ -1911,8 +1888,6 @@ "CR Load Scheduled LoRAs", "CR Load Scheduled Models", "CR Load Text List", - "CR Load Workflow", - "CR Load XY Annotation From File", "CR Loop List", "CR Mask Text", "CR Math Operation", @@ -1924,7 +1899,6 @@ "CR Module Pipe Loader", "CR Multi Upscale Stack", "CR Multi-ControlNet Stack", - "CR Multi-Panel Meme Template", "CR Multiline Text", "CR Output Flow Frames", "CR Output Schedule To File", @@ -1933,14 +1907,11 @@ "CR Page Layout", "CR Pipe Switch", "CR Polygons", - "CR Popular Meme Templates", "CR Prompt List", "CR Prompt List Keyframes", "CR Prompt Scheduler", "CR Prompt Text", - "CR Prompt Weight Scheduler", "CR Radial Gradient", - "CR Radial Gradient Map", "CR Random Hex Color", "CR Random LoRA Stack", "CR Random Multiline Colors", @@ -1950,6 +1921,7 @@ "CR Random RGB Gradient", "CR Random Shape Pattern", "CR Random Weight LoRA", + "CR Repeater", "CR SD1.5 Aspect Ratio", "CR SDXL Aspect Ratio", "CR SDXL Base Prompt Encoder", @@ -1957,11 +1929,9 @@ "CR SDXL Prompt Mixer", "CR SDXL Style Text", "CR Save Text To File", - "CR Schedule Camera Movements", - "CR Schedule ControlNets", "CR Schedule Input Switch", - "CR Schedule Styles", "CR Schedule To ScheduleList", + "CR Seamless Checker", "CR Seed", "CR Seed to Int", "CR Select Font", @@ -1969,12 +1939,10 @@ "CR Set Value On Binary", "CR Set Value On Boolean", "CR Set Value on String", - "CR Simple Annotations", "CR Simple Banner", "CR Simple Binary Pattern", "CR Simple Binary Pattern Simple", "CR Simple Image Compare", - "CR Simple Image Watermark", "CR Simple List", "CR Simple Meme Template", "CR Simple Prompt List", @@ -1986,25 +1954,21 @@ "CR Simple Text Watermark", "CR Simple Titles", "CR Simple Value Scheduler", - "CR Spawn Workflow Instance", "CR Split String", "CR Starburst Colors", "CR Starburst Lines", "CR String To Combo", "CR String To Number", - "CR Strobe Images", "CR Style Bars", - "CR Style List", "CR Switch Model and CLIP", - "CR System TrueType Font", "CR Text", + "CR Text Blacklist", "CR Text Concatenate", "CR Text Cycler", "CR Text Input Switch", "CR Text Input Switch (4 way)", "CR Text Length", "CR Text List", - "CR Text List Cross Join", "CR Text List Simple", "CR Text List To String", "CR Text Operation", @@ -2019,19 +1983,16 @@ "CR Value Scheduler", "CR Vignette Filter", "CR XY From Folder", - "CR XY Grid", "CR XY Index", "CR XY Interpolate", "CR XY List", "CR XY Product", "CR XY Save Grid Image", - "CR XYZ Index", - "CR XYZ Interpolate", - "CR XYZ List" + "CR XYZ Index" ], { "author": "Suzie1", - "description": "169 custom nodes for artists, designers and animators.", + "description": "170 custom nodes for artists, designers and animators.", "nickname": "Comfyroll Studio", "title": "Comfyroll Studio", "title_aux": "ComfyUI_Comfyroll_CustomNodes" @@ -2464,6 +2425,7 @@ "Integer place counter", "KSampler (WAS)", "KSampler Cycle", + "Latent Batch", "Latent Input Switch", "Latent Noise Injection", "Latent Size to Number", @@ -2806,7 +2768,7 @@ "https://github.com/alexopus/ComfyUI-Image-Saver": [ [ "Cfg Literal (Image Saver)", - "Checkpoint Selector (Image Saver)", + "Checkpoint Loader with Name (Image Saver)", "Float Literal (Image Saver)", "Image Saver", "Int Literal (Image Saver)", @@ -3449,7 +3411,8 @@ "https://github.com/chflame163/ComfyUI_WordCloud": [ [ "ComfyWordCloud", - "LoadTextFile" + "LoadTextFile", + "RGB_Picker" ], { "title_aux": "ComfyUI_WordCloud" @@ -3831,6 +3794,7 @@ "ExtractKeyframes+", "GetImageSize+", "ImageCASharpening+", + "ImageCompositeFromMaskBatch+", "ImageCrop+", "ImageDesaturate+", "ImageEnhanceDifference+", @@ -4263,6 +4227,38 @@ "title_aux": "As_ComfyUI_CustomNodes" } ], + "https://github.com/foxtrot-roger/comfyui-rf-nodes": [ + [ + "LogBool", + "LogFloat", + "LogInt", + "LogNumber", + "LogString", + "LogVec2", + "LogVec3", + "RF_BoolToString", + "RF_FloatToString", + "RF_IntToString", + "RF_JsonStyleLoader", + "RF_MergeLines", + "RF_NumberToString", + "RF_RangeFloat", + "RF_RangeInt", + "RF_RangeNumber", + "RF_SplitLines", + "RF_TextConcatenate", + "RF_TextInput", + "RF_TextReplace", + "RF_Timestamp", + "RF_ToString", + "RF_Vec2ToString", + "RF_Vec3ToString", + "TextLine" + ], + { + "title_aux": "RF Nodes" + } + ], "https://github.com/gemell1/ComfyUI_GMIC": [ [ "GmicCliWrapper" @@ -4782,6 +4778,7 @@ "https://github.com/komojini/komojini-comfyui-nodes": [ [ "ImageMerger", + "UltimateVideoLoader", "YouTubeVideoLoader" ], { @@ -6165,6 +6162,7 @@ "GroundingDinoModelLoader (segment anything)", "GroundingDinoSAMSegment (segment anything)", "InvertMask (segment anything)", + "IsMaskEmpty", "SAMModelLoader (segment anything)" ], { @@ -6252,6 +6250,7 @@ ], "https://github.com/taabata/LCM_Inpaint-Outpaint_Comfy": [ [ + "ComfyNodesToSaveCanvas", "FloatNumber", "FreeU_LCM", "ImageOutputToComfyNodes", @@ -6298,7 +6297,8 @@ "https://github.com/talesofai/comfyui-browser": [ [ "LoadImageByUrl //Browser", - "SelectInputs //Browser" + "SelectInputs //Browser", + "XyzPlot //Browser" ], { "title_aux": "ComfyUI Browser" @@ -6395,6 +6395,7 @@ "Iterative Mixing KSampler Advanced", "IterativeMixingSampler", "IterativeMixingScheduler", + "IterativeMixingSchedulerAdvanced", "Latent Batch Comparison Plot", "Latent Batch Statistics Plot", "MixingMaskGenerator" diff --git a/node_db/tutorial/custom-node-list.json b/node_db/tutorial/custom-node-list.json index d7ede227..dd6b3650 100644 --- a/node_db/tutorial/custom-node-list.json +++ b/node_db/tutorial/custom-node-list.json @@ -39,6 +39,36 @@ ], "install_type": "git-clone", "description": "This project is an `empty` custom node that is already in its own folder. It serves as a base to build any custom node. Whenever you want to create a custom node, you can download that, put it in custom_nodes, then you just have to change the names and fill it with code!" + }, + { + "author": "foxtrot-roger", + "title": "comfyui-custom-nodes", + "reference": "https://github.com/foxtrot-roger/comfyui-custom-nodes", + "files": [ + "https://github.com/foxtrot-roger/comfyui-custom-nodes" + ], + "install_type": "git-clone", + "description": "Tutorial nodes" + }, + { + "author": "GraftingRayman", + "title": "ComfyUI-Trajectory", + "reference": "https://github.com/GraftingRayman/ComfyUI-Trajectory", + "files": [ + "https://github.com/GraftingRayman/ComfyUI-Trajectory" + ], + "install_type": "git-clone", + "description": "Nodes:GR Trajectory" + }, + { + "author": "wailovet", + "title": "ComfyUI-WW", + "reference": "https://github.com/wailovet/ComfyUI-WW", + "files": [ + "https://github.com/wailovet/ComfyUI-WW" + ], + "install_type": "git-clone", + "description": "Nodes:WW_ImageResize" } ] } \ No newline at end of file From 2f3e7943dfb4dfc3dfa5e8fe0bc0f631363910e7 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 14:00:57 +0900 Subject: [PATCH 02/35] improve: better style for 'a tag' in lists --- __init__.py | 2 +- js/comfyui-manager.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index d0e6c210..69499083 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [1, 26] +version = [1, 26, 1] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index 9a8abfc6..4ebc2104 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -71,6 +71,39 @@ docStyle.innerHTML = ` position: relative; } +#custom-nodes-grid a { + color: #5555FF; + font-weight: bold; + text-decoration: none; +} + +#custom-nodes-grid a:hover { + color: #7777FF; + text-decoration: underline; +} + +#external-models-grid a { + color: #5555FF; + font-weight: bold; + text-decoration: none; +} + +#external-models-grid a:hover { + color: #7777FF; + text-decoration: underline; +} + +#alternatives-grid a { + color: #5555FF; + font-weight: bold; + text-decoration: none; +} + +#alternatives-grid a:hover { + color: #7777FF; + text-decoration: underline; +} + .cm-notice-board { width: 310px; padding: 0px !important; From ff5db97c4a14f2c5c3ed70a9e2f29bcd4a3debe2 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 15:12:18 +0900 Subject: [PATCH 03/35] update DB --- extension-node-map.json | 3 +++ node_db/new/custom-node-list.json | 40 ----------------------------- node_db/new/extension-node-map.json | 3 +++ 3 files changed, 6 insertions(+), 40 deletions(-) diff --git a/extension-node-map.json b/extension-node-map.json index 245ac1cd..570803e6 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -5089,7 +5089,9 @@ "InpaintPreprocessor_Provider_for_SEGS //Inspire", "KSampler //Inspire", "KSamplerAdvanced //Inspire", + "KSamplerAdvancedPipe //Inspire", "KSamplerAdvancedProgress //Inspire", + "KSamplerPipe //Inspire", "KSamplerProgress //Inspire", "LatentBatchSplitter //Inspire", "LeRes_DepthMap_Preprocessor_Provider_for_SEGS //Inspire", @@ -5798,6 +5800,7 @@ "CombineMasks_", "CombineSegMasks", "DynamicDelayProcessor", + "EmbeddingPrompt", "EnhanceImage", "FaceToMask", "FeatheredMask", diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 28e44464..9f63f16a 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -693,46 +693,6 @@ ], "install_type": "git-clone", "description": "This is an Extension for ComfyUI, which allows you to control the logic flow with just one click!" - }, - { - "author": "Trung0246", - "title": "ComfyUI-0246", - "reference": "https://github.com/Trung0246/ComfyUI-0246", - "files": [ - "https://github.com/Trung0246/ComfyUI-0246" - ], - "install_type": "git-clone", - "description": "Random nodes for ComfyUI I made to solve my struggle with ComfyUI (ex: pipe, process). Have varying quality." - }, - { - "author": "violet-chen", - "title": "comfyui-psd2png", - "reference": "https://github.com/violet-chen/comfyui-psd2png", - "files": [ - "https://github.com/violet-chen/comfyui-psd2png" - ], - "install_type": "git-clone", - "description": "Nodes: Psd2Png." - }, - { - "author": "IDGallagher", - "title": "IG Interpolation Nodes", - "reference": "https://github.com/IDGallagher/ComfyUI-IG-Nodes", - "files": [ - "https://github.com/IDGallagher/ComfyUI-IG-Nodes" - ], - "install_type": "git-clone", - "description": "Custom nodes to aid in the exploration of Latent Space" - }, - { - "author": "rcfcu2000", - "title": "zhihuige-nodes-comfyui", - "reference": "https://github.com/rcfcu2000/zhihuige-nodes-comfyui", - "files": [ - "https://github.com/rcfcu2000/zhihuige-nodes-comfyui" - ], - "install_type": "git-clone", - "description": "Nodes: Combine ZHGMasks, Cover ZHGMasks, ZHG FaceIndex, ZHG SaveImage, ZHG SmoothEdge, ZHG GetMaskArea, ..." } ] } diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 245ac1cd..570803e6 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -5089,7 +5089,9 @@ "InpaintPreprocessor_Provider_for_SEGS //Inspire", "KSampler //Inspire", "KSamplerAdvanced //Inspire", + "KSamplerAdvancedPipe //Inspire", "KSamplerAdvancedProgress //Inspire", + "KSamplerPipe //Inspire", "KSamplerProgress //Inspire", "LatentBatchSplitter //Inspire", "LeRes_DepthMap_Preprocessor_Provider_for_SEGS //Inspire", @@ -5798,6 +5800,7 @@ "CombineMasks_", "CombineSegMasks", "DynamicDelayProcessor", + "EmbeddingPrompt", "EnhanceImage", "FaceToMask", "FeatheredMask", From 019897eae2773e34a2434a93e1bfc8fadbeb2992 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 16:24:14 +0900 Subject: [PATCH 04/35] update DB --- alter-list.json | 5 +++++ custom-node-list.json | 11 +++++++++++ extension-node-map.json | 20 ++++++++++++++++++++ js/comfyui-manager.js | 9 +++++++++ node_db/new/custom-node-list.json | 10 ++++++++++ node_db/new/extension-node-map.json | 20 ++++++++++++++++++++ 6 files changed, 75 insertions(+) diff --git a/alter-list.json b/alter-list.json index f165a674..e79915c1 100644 --- a/alter-list.json +++ b/alter-list.json @@ -194,6 +194,11 @@ "id":"https://github.com/shiimizu/ComfyUI-TiledDiffusion", "tags":"multidiffusion", "description": "This extension provides custom nodes for [a/Mixture of Diffusers](https://github.com/albarji/mixture-of-diffusers) and [a/MultiDiffusion](https://github.com/omerbt/MultiDiffusion)" + }, + { + "id":"https://github.com/abyz22/image_control", + "tags":"BMAB", + "description": "This extension provides some alternative functionalities of the [a/sd-webui-bmab](https://github.com/portu-sim/sd-webui-bmab) extension." } ] } \ No newline at end of file diff --git a/custom-node-list.json b/custom-node-list.json index 0c381bbe..56d4c25e 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4234,6 +4234,17 @@ "install_type": "git-clone", "description": "A bunch of nodes that can be useful to manipulate primitive types (numbers, text, ...) Also some helpers to generate text and timestamps." }, + { + "author": "abyz22", + "title": "image_control", + "reference": "https://github.com/abyz22/image_control", + "files": [ + "https://github.com/abyz22/image_control" + ], + "install_type": "git-clone", + "description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor" + }, + { "author": "Ser-Hilary", diff --git a/extension-node-map.json b/extension-node-map.json index 570803e6..910662fd 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -2714,6 +2714,26 @@ "title_aux": "ComfyUI-AudioScheduler" } ], + "https://github.com/abyz22/image_control": [ + [ + "abyz22_FirstNonNull", + "abyz22_FromBasicPipe_v2", + "abyz22_ImpactWildcardEncode", + "abyz22_ImpactWildcardEncode_GetPrompt", + "abyz22_Ksampler", + "abyz22_Padding Image", + "abyz22_SaveImage", + "abyz22_SetQueue", + "abyz22_ToBasicPipe", + "abyz22_blend_onecolor", + "abyz22_blendimages", + "abyz22_drawmask", + "abyz22_setimageinfo" + ], + { + "title_aux": "image_control" + } + ], "https://github.com/adieyal/comfyui-dynamicprompts": [ [ "DPCombinatorialGenerator", diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index 4ebc2104..b0dd5355 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -16,6 +16,7 @@ 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, install_pip, rebootAPI, free_models } from "./common.js"; +import { save_as_component } from "./components-manager.js"; var docStyle = document.createElement('style'); docStyle.innerHTML = ` @@ -1184,6 +1185,14 @@ app.registerExtension({ const origGetExtraMenuOptions = node.prototype.getExtraMenuOptions; node.prototype.getExtraMenuOptions = function (_, options) { origGetExtraMenuOptions?.apply?.(this, arguments); + + if (node.comfyClass.startsWith('workflow/')) { + options.push({ + content: "Save As Component", + callback: (obj) => { save_as_component(node, app); } + }, null); + } + if (isOutputNode(node)) { const { potential_outputs } = getPotentialOutputsAndOutputNodes([this]); const hasOutput = potential_outputs.length > 0; diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 9f63f16a..13ca128c 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,16 @@ }, + { + "author": "abyz22", + "title": "image_control", + "reference": "https://github.com/abyz22/image_control", + "files": [ + "https://github.com/abyz22/image_control" + ], + "install_type": "git-clone", + "description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor" + }, { "author": "foxtrot-roger", "title": "RF Nodes", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 570803e6..910662fd 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -2714,6 +2714,26 @@ "title_aux": "ComfyUI-AudioScheduler" } ], + "https://github.com/abyz22/image_control": [ + [ + "abyz22_FirstNonNull", + "abyz22_FromBasicPipe_v2", + "abyz22_ImpactWildcardEncode", + "abyz22_ImpactWildcardEncode_GetPrompt", + "abyz22_Ksampler", + "abyz22_Padding Image", + "abyz22_SaveImage", + "abyz22_SetQueue", + "abyz22_ToBasicPipe", + "abyz22_blend_onecolor", + "abyz22_blendimages", + "abyz22_drawmask", + "abyz22_setimageinfo" + ], + { + "title_aux": "image_control" + } + ], "https://github.com/adieyal/comfyui-dynamicprompts": [ [ "DPCombinatorialGenerator", From 7f10374a9f7bcd9b4e4cf39efef5a580ec1bd277 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 18:48:23 +0900 Subject: [PATCH 05/35] feat: A functionality to save a group node as a component. --- __init__.py | 56 +++++++++++- components/.gitignore | 1 + js/comfyui-manager.js | 10 +- js/common.js | 2 +- js/components-manager.js | 191 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 components/.gitignore create mode 100644 js/components-manager.js diff --git a/__init__.py b/__init__.py index 69499083..9ebf8c77 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [1, 26, 1] +version = [2, 0] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") @@ -118,6 +118,7 @@ local_db_alter = os.path.join(comfyui_manager_path, "alter-list.json") local_db_custom_node_list = os.path.join(comfyui_manager_path, "custom-node-list.json") local_db_extension_node_mappings = os.path.join(comfyui_manager_path, "extension-node-map.json") git_script_path = os.path.join(os.path.dirname(__file__), "git_helper.py") +components_path = os.path.join(comfyui_manager_path, 'components') startup_script_path = os.path.join(comfyui_manager_path, "startup-scripts") config_path = os.path.join(os.path.dirname(__file__), "config.ini") @@ -1838,6 +1839,59 @@ def restart(self): return os.execv(sys.executable, [sys.executable] + sys.argv) +def sanitize_filename(input_string): + # 알파벳, 숫자, 및 밑줄 이외의 문자를 밑줄로 대체 + result_string = re.sub(r'[^a-zA-Z0-9_]', '_', input_string) + return result_string + + +@server.PromptServer.instance.routes.post("/manager/component/save") +async def save_component(request): + try: + data = await request.json() + name = data['name'] + workflow = data['workflow'] + + if not os.path.exists(components_path): + os.mkdir(components_path) + + sanitized_name = sanitize_filename(name) + + filepath = os.path.join(components_path, sanitized_name+'.json') + 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: + return web.Response(status=400) + + +@server.PromptServer.instance.routes.post("/manager/component/loads") +async def load_components(request): + try: + json_files = [f for f in os.listdir(components_path) if f.endswith('.json')] + + components = {} + for json_file in json_files: + file_path = os.path.join(components_path, json_file) + with open(file_path, 'r') as file: + try: + components.update(json.load(file)) + except json.JSONDecodeError as e: + print(f"[ComfyUI-Manager] Error decoding component file in file {json_file}: {e}") + + return web.json_response(components) + except Exception as e: + print(f"[ComfyUI-Manager] failed to load components\n{e}") + return web.Response(status=400) + + @server.PromptServer.instance.routes.get("/manager/share_option") async def share_option(request): if "value" in request.rel_url.query: diff --git a/components/.gitignore b/components/.gitignore new file mode 100644 index 00000000..a6c57f5f --- /dev/null +++ b/components/.gitignore @@ -0,0 +1 @@ +*.json diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index b0dd5355..191a9695 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -16,7 +16,7 @@ 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, install_pip, rebootAPI, free_models } from "./common.js"; -import { save_as_component } from "./components-manager.js"; +import { load_components, save_as_component } from "./components-manager.js"; var docStyle = document.createElement('style'); docStyle.innerHTML = ` @@ -1111,6 +1111,14 @@ 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"); diff --git a/js/common.js b/js/common.js index f118e145..8d0997d1 100644 --- a/js/common.js +++ b/js/common.js @@ -1,5 +1,5 @@ import { app } from "../../scripts/app.js"; -import { api } from "../../scripts/api.js" +import { api } from "../../scripts/api.js"; export async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); diff --git a/js/components-manager.js b/js/components-manager.js new file mode 100644 index 00000000..c510dc03 --- /dev/null +++ b/js/components-manager.js @@ -0,0 +1,191 @@ +import { app } from "../../scripts/app.js"; +import { api } from "../../scripts/api.js" +import { sleep } from "./common.js"; +import { GroupNodeConfig, GroupNodeHandler } from "../../extensions/core/groupNode.js"; + +function storeGroupNode(name, data) { + let extra = app.graph.extra; + if (!extra) app.graph.extra = extra = {}; + let groupNodes = extra.groupNodes; + if (!groupNodes) extra.groupNodes = groupNodes = {}; + groupNodes[name] = data; +} + +export async function load_components() { + let data = await api.fetchApi('/manager/component/loads', {method: "POST"}); + let components = await data.json(); + +// while(!app.graph) { +// await sleep(100); +// } + + let start_time = Date.now(); + let failed = []; + let failed2 = []; + + for(let name in components) { + if(app.graph.extra?.groupNodes?.[name]) { + continue; + } + + let nodeData = components[name]; + + storeGroupNode(name, nodeData); + + const config = new GroupNodeConfig(name, nodeData); + while(!success) { + var success = false; + try { + await config.registerType(); + } + catch { + let elapsed_time = Date.now() - start_time; + if (elapsed_time > 5000) { + failed.push(name); + success = true; + } else { + await sleep(100); + } + } + } + + const groupNode = LiteGraph.createNode(`workflow/${name}`); + } + + // 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(!success) { + var success = false; + try { + await config.registerType(); + } + catch { + let elapsed_time = Date.now() - start_time; + if (elapsed_time > 10000) { + failed2.push(name); + success = true; + } else { + await sleep(100); + } + } + } + + const groupNode = LiteGraph.createNode(`workflow/${name}`); + } + + // fallback2 + for(let name in failed2) { + let name = failed2[i]; + + let nodeData = components[name]; + + storeGroupNode(name, nodeData); + + const config = new GroupNodeConfig(name, nodeData); + while(!success) { + var success = false; + try { + await config.registerType(); + } + catch { + let elapsed_time = Date.now() - start_time; + if (elapsed_time > 30000) { + failed.push(name); + success = true; + } else { + await sleep(100); + } + } + } + + const groupNode = LiteGraph.createNode(`workflow/${name}`); + } +} + +export async function save_as_component(node, app) { + let pure_name = node.comfyClass.substring(9); + let subgraph = app.graph.extra?.groupNodes?.[pure_name]; + + if(!subgraph) { + app.ui.dialog.show(`Failed to retrieve the group node '${pure_name}'.`); + return; + } + + if(node.comfyClass.includes('::')) { + let component_name = node.comfyClass.substring(9); + + if(confirm(`Will you save/overwrite component '${component_name}'?`)) { + let subgraph = app.graph.extra?.groupNodes?.[component_name]; + let body = + { + name: component_name, + workflow: subgraph + }; + + const res = await api.fetchApi('/manager/component/save', { + method: "POST", + headers: { "Content-Type": "application/json", }, + body: JSON.stringify(body) + }); + + if(res.status == 200) { + storeGroupNode(name, subgraph); + const config = new GroupNodeConfig(name, subgraph); + await config.registerType(); + + let path = await res.text(); + app.ui.dialog.show(`Component '${component_name}' is saved into:\n${path}`); + } + else + app.ui.dialog.show(`Failed to save component.`); + } + + return; + } + + var prefix = prompt("To save as a component, a unique prefix is required. (e.g., the 'Impact' in Impact::MAKE_BASIC_PIPE)", "PREFIX"); + + if(!prefix) { + return; + } + + prefix = prefix.trim(); + + if(prefix == 'PREFIX') { + app.ui.dialog.show(`The placeholder 'PREFIX' isn't allowed for component prefix.`); + return; + } + + let component_name = prefix+'::'+pure_name; + let body = + { + name: component_name, + workflow: subgraph + }; + + const res = await api.fetchApi('/manager/component/save', { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if(res.status == 200) { + let path = await res.text(); + app.ui.dialog.show(`Component '${component_name}' is saved into:\n${path}`); + } + else + app.ui.dialog.show(`Failed to save component.`); +} \ No newline at end of file From 9eef99b868aa5d1470317370e50900c2e80f0e34 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 18:55:29 +0900 Subject: [PATCH 06/35] fix: direct reflect to 'Add Node' context menu after component saving --- __init__.py | 2 +- js/components-manager.js | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/__init__.py b/__init__.py index 9ebf8c77..e2c896ff 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [2, 0] +version = [2, 0, 1] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") diff --git a/js/components-manager.js b/js/components-manager.js index c510dc03..b22bc14e 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -140,8 +140,8 @@ export async function save_as_component(node, app) { }); if(res.status == 200) { - storeGroupNode(name, subgraph); - const config = new GroupNodeConfig(name, subgraph); + storeGroupNode(component_name, subgraph); + const config = new GroupNodeConfig(component_name, subgraph); await config.registerType(); let path = await res.text(); @@ -183,6 +183,10 @@ export async function save_as_component(node, app) { }); if(res.status == 200) { + storeGroupNode(component_name, subgraph); + const config = new GroupNodeConfig(component_name, subgraph); + await config.registerType(); + let path = await res.text(); app.ui.dialog.show(`Component '${component_name}' is saved into:\n${path}`); } From 3e918e838f407558b9ca5b927029d21e0dc42602 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 22:25:04 +0900 Subject: [PATCH 07/35] update DB --- extension-node-map.json | 36 +++++++++++++++++++++++++++-- node_db/new/extension-node-map.json | 36 +++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/extension-node-map.json b/extension-node-map.json index 910662fd..cab21191 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -1799,6 +1799,7 @@ "CR Aspect Ratio", "CR Aspect Ratio Banners", "CR Aspect Ratio SDXL", + "CR Aspect Ratio Social Media", "CR Batch Images From List", "CR Batch Process Switch", "CR Binary Pattern", @@ -3397,7 +3398,14 @@ "https://github.com/chaojie/ComfyUI-DragNUWA": [ [ "DragNUWA Run", - "Load CheckPoint DragNUWA" + "Get First Image", + "Get Last Image", + "Load CheckPoint DragNUWA", + "Load Pose KeyPoints", + "Loop", + "LoopEnd_IMAGE", + "LoopStart_IMAGE", + "Split Tracking Points" ], { "title_aux": "ComfyUI-DragNUWA" @@ -4152,10 +4160,33 @@ ], "https://github.com/fexli/fexli-util-node-comfyui": [ [ + "FEBCPrompt", + "FEBatchGenStringBCDocker", "FEColor2Image", "FEColorOut", + "FEDataInsertor", + "FEDataPacker", + "FEDataUnpacker", + "FEDeepClone", + "FEDictPacker", + "FEDictUnpacker", + "FEEncLoraLoader", + "FEExtraInfoAdd", + "FEGenStringBCDocker", + "FEGenStringGPT", + "FEImageNoiseGenerate", "FEImagePadForOutpaint", - "FERandomizedColor2Image" + "FEImagePadForOutpaintByImage", + "FEOperatorIf", + "FEPythonStrOp", + "FERandomLoraSelect", + "FERandomPrompt", + "FERandomizedColor2Image", + "FERandomizedColorOut", + "FERerouteWithName", + "FESaveEncryptImage", + "FETextCombine", + "FETextInput" ], { "title_aux": "fexli-util-node-comfyui" @@ -4799,6 +4830,7 @@ [ "ImageMerger", "UltimateVideoLoader", + "UltimateVideoLoader (simple)", "YouTubeVideoLoader" ], { diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 910662fd..cab21191 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -1799,6 +1799,7 @@ "CR Aspect Ratio", "CR Aspect Ratio Banners", "CR Aspect Ratio SDXL", + "CR Aspect Ratio Social Media", "CR Batch Images From List", "CR Batch Process Switch", "CR Binary Pattern", @@ -3397,7 +3398,14 @@ "https://github.com/chaojie/ComfyUI-DragNUWA": [ [ "DragNUWA Run", - "Load CheckPoint DragNUWA" + "Get First Image", + "Get Last Image", + "Load CheckPoint DragNUWA", + "Load Pose KeyPoints", + "Loop", + "LoopEnd_IMAGE", + "LoopStart_IMAGE", + "Split Tracking Points" ], { "title_aux": "ComfyUI-DragNUWA" @@ -4152,10 +4160,33 @@ ], "https://github.com/fexli/fexli-util-node-comfyui": [ [ + "FEBCPrompt", + "FEBatchGenStringBCDocker", "FEColor2Image", "FEColorOut", + "FEDataInsertor", + "FEDataPacker", + "FEDataUnpacker", + "FEDeepClone", + "FEDictPacker", + "FEDictUnpacker", + "FEEncLoraLoader", + "FEExtraInfoAdd", + "FEGenStringBCDocker", + "FEGenStringGPT", + "FEImageNoiseGenerate", "FEImagePadForOutpaint", - "FERandomizedColor2Image" + "FEImagePadForOutpaintByImage", + "FEOperatorIf", + "FEPythonStrOp", + "FERandomLoraSelect", + "FERandomPrompt", + "FERandomizedColor2Image", + "FERandomizedColorOut", + "FERerouteWithName", + "FESaveEncryptImage", + "FETextCombine", + "FETextInput" ], { "title_aux": "fexli-util-node-comfyui" @@ -4799,6 +4830,7 @@ [ "ImageMerger", "UltimateVideoLoader", + "UltimateVideoLoader (simple)", "YouTubeVideoLoader" ], { From bcdb05e03c3b72a011e1cdc5b49989a5e9cc793c Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 22:33:40 +0900 Subject: [PATCH 08/35] update DB --- custom-node-list.json | 2 +- node_db/dev/custom-node-list.json | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index 56d4c25e..a885989d 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4243,7 +4243,7 @@ ], "install_type": "git-clone", "description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor" - }, + } { diff --git a/node_db/dev/custom-node-list.json b/node_db/dev/custom-node-list.json index ccebd5f6..1135d9d2 100644 --- a/node_db/dev/custom-node-list.json +++ b/node_db/dev/custom-node-list.json @@ -9,7 +9,17 @@ "description": "If you see this message, your ComfyUI-Manager is outdated.\nDev channel provides only the list of the developing nodes. If you want to find the complete node list, please go to the Default channel." }, - + + { + "author": "poisenbery", + "title": "NudeNet-Detector-Provider [WIP]", + "reference": "https://github.com/poisenbery/NudeNet-Detector-Provider", + "files": [ + "https://github.com/poisenbery/NudeNet-Detector-Provider" + ], + "install_type": "git-clone", + "description": "BBOX Detector Provider for NudeNet. Bethesda version of NudeNet V3 detector provider to work with Impact Pack ComfyUI." + }, { "author": "LarryJane491", "title": "ComfyUI-ModelUnloader", From 8a165549f3f9d5ee65e307989be0e05975deb5bc Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 23:50:03 +0900 Subject: [PATCH 09/35] feat: support component paste feature --- README.md | 19 +++++++++++ __init__.py | 2 +- js/components-manager.js | 70 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0c171d74..c3fa0783 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,25 @@ NODE_CLASS_MAPPINGS.update({ * **All scripts are executed from the root path of the corresponding custom node.** +## Component Paste +* When pasting a component from the clipboard, it supports text in the following JSON format. (text/plain) +``` +{ + "kind": "ComyUI Components", + "timestamp": , + "components": + { + : + } +} +``` +* `` Ensure that the timestamp is always unique. +* "components" should have the same structure as the content of the file stored in ComfyUI-Manager/components. + * ``: The name should be in the format `::`. + * ``: In the nodedata of the group node. + + + ## Support of missing nodes installation ![missing-menu](misc/missing-menu.png) diff --git a/__init__.py b/__init__.py index e2c896ff..b58cab44 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [2, 0, 1] +version = [2, 1] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") diff --git a/js/components-manager.js b/js/components-manager.js index b22bc14e..92e20f85 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -127,11 +127,11 @@ export async function save_as_component(node, app) { if(confirm(`Will you save/overwrite component '${component_name}'?`)) { let subgraph = app.graph.extra?.groupNodes?.[component_name]; - let body = - { - name: component_name, - workflow: subgraph - }; + let body = + { + name: component_name, + workflow: subgraph + }; const res = await api.fetchApi('/manager/component/save', { method: "POST", @@ -192,4 +192,62 @@ export async function save_as_component(node, app) { } else app.ui.dialog.show(`Failed to save component.`); -} \ No newline at end of file +} + +async function import_component(component_name, subgraph) { + if(confirm("Will you save component?\n(If canceled, the component won't be saved and can only be used within the current workflow.)")) { + let body = + { + name: component_name, + workflow: subgraph + }; + + const res = await api.fetchApi('/manager/component/save', { + method: "POST", + headers: { "Content-Type": "application/json", }, + body: JSON.stringify(body) + }); + } + + storeGroupNode(component_name, subgraph); + const config = new GroupNodeConfig(component_name, subgraph); + await config.registerType(); +} + +// Using a timestamp prevents duplicate pastes and ensures the prevention of re-deletion of litegrapheditor_clipboard. +let last_paste_timestamp = null; + +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; + + let msg = 'Components are added:\n'; + for(let name in json_data.components) { + let subgraph = json_data.components[name]; + import_component(name, subgraph); + msg += ' - ' + name + '\n'; + } + app.ui.dialog.show(msg); + + // 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); \ No newline at end of file From 3d92470d5ee3ee51cb6aade681b1b0f47cbd0615 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Mon, 15 Jan 2024 23:53:07 +0900 Subject: [PATCH 10/35] update DB --- custom-node-list.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom-node-list.json b/custom-node-list.json index a885989d..56d4c25e 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4243,7 +4243,7 @@ ], "install_type": "git-clone", "description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor" - } + }, { From d23b01602c39afc6a79acca4b637e502835327de Mon Sep 17 00:00:00 2001 From: johnqiao Date: Mon, 15 Jan 2024 10:11:32 -0700 Subject: [PATCH 11/35] Fix typo --- README.md | 2 +- custom-node-list.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c3fa0783..5852df2a 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ NODE_CLASS_MAPPINGS.update({ * When pasting a component from the clipboard, it supports text in the following JSON format. (text/plain) ``` { - "kind": "ComyUI Components", + "kind": "ComfyUI Components", "timestamp": , "components": { diff --git a/custom-node-list.json b/custom-node-list.json index 56d4c25e..f399fb9b 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -2868,7 +2868,7 @@ "https://github.com/GTSuya-Studio/ComfyUI-Gtsuya-Nodes" ], "install_type": "git-clone", - "description": "ComfyUI-GTSuya-Nodes is a ComyUI extension designed to add several wildcards supports into ComfyUI. Wildcards allow you to use __name__ syntax in your prompt to get a random line from a file named name.txt in a wildcards directory." + "description": "ComfyUI-GTSuya-Nodes is a ComfyUI extension designed to add several wildcards supports into ComfyUI. Wildcards allow you to use __name__ syntax in your prompt to get a random line from a file named name.txt in a wildcards directory." }, { "author": "oyvindg", @@ -3529,7 +3529,7 @@ "https://github.com/vienteck/ComfyUI-Chat-GPT-Integration" ], "install_type": "git-clone", - + "description": "This extension is a reimagined version based on the [a/ComfyUI-QualityOfLifeSuit_Omar92](https://github.com/omar92/ComfyUI-QualityOfLifeSuit_Omar92) extension, and it supports integration with ChatGPT through the new OpenAI API.\nNOTE: See detailed installation instructions on the [a/repository](https://github.com/vienteck/ComfyUI-Chat-GPT-Integration)." }, { @@ -4244,7 +4244,7 @@ "install_type": "git-clone", "description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor" }, - + { "author": "Ser-Hilary", From 58a2494715a1de58c9c4c1494bc67436c45dd7e3 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Tue, 16 Jan 2024 10:45:24 +0900 Subject: [PATCH 12/35] code formatting update db --- custom-node-list.json | 10 ++ extension-node-map.json | 9 ++ js/comfyui-manager.js | 156 ++++++++++++++-------------- js/components-manager.js | 8 +- js/snapshot.js | 60 +++++------ node_db/dev/custom-node-list.json | 10 ++ node_db/new/custom-node-list.json | 10 ++ node_db/new/extension-node-map.json | 9 ++ 8 files changed, 159 insertions(+), 113 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index f399fb9b..47c50e09 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4244,6 +4244,16 @@ "install_type": "git-clone", "description": "Nodes:abyz22_Padding Image, abyz22_ImpactWildcardEncode, abyz22_setimageinfo, abyz22_SaveImage, abyz22_ImpactWildcardEncode_GetPrompt, abyz22_SetQueue, abyz22_drawmask, abyz22_FirstNonNull, abyz22_blendimages, abyz22_blend_onecolor" }, + { + "author": "HAL41", + "title": "ComfyUI aichemy nodes", + "reference": "https://github.com/HAL41/ComfyUI-aichemy-nodes", + "files": [ + "https://github.com/HAL41/ComfyUI-aichemy-nodes" + ], + "install_type": "git-clone", + "description": "Simple node to handle scaling of YOLOv8 segmentation masks" + }, { diff --git a/extension-node-map.json b/extension-node-map.json index cab21191..5ff51cbd 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -131,6 +131,7 @@ "VideoCut-badger", "deleteDir-badger", "findCenterOfMask-badger", + "frameToVideo-badger", "getImageSide-badger", "getParentDir-badger", "mkdir-badger" @@ -840,6 +841,14 @@ "title_aux": "ReActor Node for ComfyUI" } ], + "https://github.com/HAL41/ComfyUI-aichemy-nodes": [ + [ + "aichemyYOLOv8Segmentation" + ], + { + "title_aux": "ComfyUI aichemy nodes" + } + ], "https://github.com/Hangover3832/ComfyUI-Hangover-Nodes": [ [ "Image Scale Bounding Box", diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index 191a9695..85f1781a 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -15,7 +15,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, install_pip, rebootAPI, free_models } from "./common.js"; +import { manager_instance, setManagerInstance, install_via_git_url, install_pip, rebootAPI, free_models } from "./common.js"; import { load_components, save_as_component } from "./components-manager.js"; var docStyle = document.createElement('style'); @@ -925,12 +925,12 @@ class ManagerMenuDialog extends ComfyDialog { ]), $el("button", { - id: 'workflowgallery-button', - type: "button", + id: 'workflowgallery-button', + type: "button", style: { - ...(localStorage.getItem("wg_last_visited") ? {height: '50px'} : {}) + ...(localStorage.getItem("wg_last_visited") ? {height: '50px'} : {}) }, - onclick: (e) => { + onclick: (e) => { const last_visited_site = localStorage.getItem("wg_last_visited") if (!!last_visited_site) { window.open(last_visited_site, "comfyui-workflow-gallery"); @@ -940,15 +940,15 @@ class ManagerMenuDialog extends ComfyDialog { }, }, [ $el("p", { - textContent: 'Workflow Gallery', - style: { - 'text-align': 'center', - 'color': 'white', - 'font-size': '18px', - 'margin': 0, - 'padding': 0, - } - }, [ + textContent: 'Workflow Gallery', + style: { + 'text-align': 'center', + 'color': 'white', + 'font-size': '18px', + 'margin': 0, + 'padding': 0, + } + }, [ $el("p", { id: 'workflowgallery-button-last-visited-label', textContent: `(${localStorage.getItem("wg_last_visited") ? localStorage.getItem("wg_last_visited").split('/')[2] : ''})`, @@ -961,10 +961,10 @@ class ManagerMenuDialog extends ComfyDialog { } }) ]), - $el("div.pysssss-workflow-arrow-2", { - id: `comfyworkflows-button-arrow`, - onclick: this.handleWorkflowGalleryButtonClick - }) + $el("div.pysssss-workflow-arrow-2", { + id: `comfyworkflows-button-arrow`, + onclick: this.handleWorkflowGalleryButtonClick + }) ]), $el("button.cm-button", { @@ -1019,10 +1019,10 @@ class ManagerMenuDialog extends ComfyDialog { this.element.style.display = "block"; } - handleWorkflowGalleryButtonClick(e) { - e.preventDefault(); - e.stopPropagation(); - LiteGraph.closeAllContextMenus(); + handleWorkflowGalleryButtonClick(e) { + e.preventDefault(); + e.stopPropagation(); + LiteGraph.closeAllContextMenus(); // Modify the style of the button so that the UI can indicate the last // visited site right away. @@ -1033,72 +1033,72 @@ class ManagerMenuDialog extends ComfyDialog { lastVisitedLabel.textContent = `(${url.split('/')[2]})`; } - const menu = new LiteGraph.ContextMenu( - [ - { - title: "Share your art", - callback: () => { - if (share_option === 'openart') { - showOpenArtShareDialog(); - return; - } else if (share_option === 'matrix' || share_option === 'comfyworkflows') { - showShareDialog(share_option); - return; - } else if (share_option === 'youml') { - showYouMLShareDialog(); - return; - } + const menu = new LiteGraph.ContextMenu( + [ + { + title: "Share your art", + callback: () => { + if (share_option === 'openart') { + showOpenArtShareDialog(); + return; + } else if (share_option === 'matrix' || share_option === 'comfyworkflows') { + showShareDialog(share_option); + return; + } else if (share_option === 'youml') { + showYouMLShareDialog(); + return; + } - if (!ShareDialogChooser.instance) { - ShareDialogChooser.instance = new ShareDialogChooser(); - } - ShareDialogChooser.instance.show(); - }, - }, - { - title: "Open 'openart.ai'", + if (!ShareDialogChooser.instance) { + ShareDialogChooser.instance = new ShareDialogChooser(); + } + ShareDialogChooser.instance.show(); + }, + }, + { + title: "Open 'openart.ai'", callback: () => { const url = "https://openart.ai/workflows/dev"; localStorage.setItem("wg_last_visited", url); window.open(url, "comfyui-workflow-gallery"); modifyButtonStyle(url); }, - }, - { - title: "Open 'youml.com'", - callback: () => { - const url = "https://youml.com/?from=comfyui-share"; - localStorage.setItem("wg_last_visited", url); - window.open(url, "comfyui-workflow-gallery"); - modifyButtonStyle(url); - }, - }, - { - title: "Open 'comfyworkflows.com'", - callback: () => { + }, + { + title: "Open 'youml.com'", + callback: () => { + const url = "https://youml.com/?from=comfyui-share"; + localStorage.setItem("wg_last_visited", url); + window.open(url, "comfyui-workflow-gallery"); + modifyButtonStyle(url); + }, + }, + { + title: "Open 'comfyworkflows.com'", + callback: () => { const url = "https://comfyworkflows.com/"; localStorage.setItem("wg_last_visited", url); - window.open(url, "comfyui-workflow-gallery"); + window.open(url, "comfyui-workflow-gallery"); modifyButtonStyle(url); - }, - }, - { - title: "Close", - callback: () => { - LiteGraph.closeAllContextMenus(); - }, - } - ], - { - event: e, - scale: 1.3, - }, - window - ); - // set the id so that we can override the context menu's z-index to be above the comfyui manager menu - menu.root.id = "workflowgallery-button-menu"; - menu.root.classList.add("pysssss-workflow-popup-2"); - } + }, + }, + { + title: "Close", + callback: () => { + LiteGraph.closeAllContextMenus(); + }, + } + ], + { + event: e, + scale: 1.3, + }, + window + ); + // set the id so that we can override the context menu's z-index to be above the comfyui manager menu + menu.root.id = "workflowgallery-button-menu"; + menu.root.classList.add("pysssss-workflow-popup-2"); + } } diff --git a/js/components-manager.js b/js/components-manager.js index 92e20f85..8f90955c 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -15,10 +15,6 @@ export async function load_components() { let data = await api.fetchApi('/manager/component/loads', {method: "POST"}); let components = await data.json(); -// while(!app.graph) { -// await sleep(100); -// } - let start_time = Date.now(); let failed = []; let failed2 = []; @@ -250,4 +246,6 @@ function handlePaste(e) { } } -document.addEventListener("paste", handlePaste); \ No newline at end of file +document.addEventListener("paste", handlePaste); + + diff --git a/js/snapshot.js b/js/snapshot.js index e4a720ea..2e26df55 100644 --- a/js/snapshot.js +++ b/js/snapshot.js @@ -6,7 +6,7 @@ import { manager_instance, rebootAPI } from "./common.js"; async function restore_snapshot(target) { if(SnapshotManager.instance) { - try { + try { const response = await api.fetchApi(`/snapshot/restore?target=${target}`, { cache: "no-store" }); if(response.status == 400) { app.ui.dialog.show(`Restore snapshot failed: ${target.title} / ${exception}`); @@ -30,7 +30,7 @@ async function restore_snapshot(target) { async function remove_snapshot(target) { if(SnapshotManager.instance) { - try { + try { const response = await api.fetchApi(`/snapshot/remove?target=${target}`, { cache: "no-store" }); if(response.status == 400) { app.ui.dialog.show(`Remove snapshot failed: ${target.title} / ${exception}`); @@ -52,20 +52,20 @@ async function remove_snapshot(target) { } async function save_current_snapshot() { - try { - const response = await api.fetchApi('/snapshot/save', { cache: "no-store" }); - app.ui.dialog.close(); - return true; - } - catch(exception) { - app.ui.dialog.show(`Backup snapshot failed: ${exception}`); - app.ui.dialog.element.style.zIndex = 10010; - return false; - } - finally { - await SnapshotManager.instance.invalidateControl(); - SnapshotManager.instance.updateMessage("
Current snapshot saved."); - } + try { + const response = await api.fetchApi('/snapshot/save', { cache: "no-store" }); + app.ui.dialog.close(); + return true; + } + catch(exception) { + app.ui.dialog.show(`Backup snapshot failed: ${exception}`); + app.ui.dialog.element.style.zIndex = 10010; + return false; + } + finally { + await SnapshotManager.instance.invalidateControl(); + SnapshotManager.instance.updateMessage("
Current snapshot saved."); + } } async function getSnapshotList() { @@ -97,7 +97,7 @@ export class SnapshotManager extends ComfyDialog { async remove_item() { caller.disableButtons(); - await caller.invalidateControl(); + await caller.invalidateControl(); } createControls() { @@ -151,14 +151,14 @@ export class SnapshotManager extends ComfyDialog { var grid = document.createElement('table'); grid.setAttribute('id', 'snapshot-list-grid'); - var thead = document.createElement('thead'); - var tbody = document.createElement('tbody'); + var thead = document.createElement('thead'); + var tbody = document.createElement('tbody'); var headerRow = document.createElement('tr'); thead.style.position = "sticky"; thead.style.top = "0px"; - thead.style.borderCollapse = "collapse"; - thead.style.tableLayout = "fixed"; + thead.style.borderCollapse = "collapse"; + thead.style.tableLayout = "fixed"; var header1 = document.createElement('th'); header1.innerHTML = '  ID  '; @@ -170,7 +170,7 @@ export class SnapshotManager extends ComfyDialog { header_button.innerHTML = 'Action'; header_button.style.width = "100px"; - thead.appendChild(headerRow); + thead.appendChild(headerRow); headerRow.appendChild(header1); headerRow.appendChild(header2); headerRow.appendChild(header_button); @@ -231,17 +231,17 @@ export class SnapshotManager extends ComfyDialog { this.grid_rows[i] = {data:data, control:dataRow}; } - let self = this; + let self = this; const panel = document.createElement('div'); - panel.style.width = "100%"; + panel.style.width = "100%"; panel.appendChild(grid); - function handleResize() { - const parentHeight = self.element.clientHeight; - const gridHeight = parentHeight - 200; + function handleResize() { + const parentHeight = self.element.clientHeight; + const gridHeight = parentHeight - 200; - grid.style.height = gridHeight + "px"; - } + grid.style.height = gridHeight + "px"; + } window.addEventListener("resize", handleResize); grid.style.position = "relative"; @@ -253,7 +253,7 @@ export class SnapshotManager extends ComfyDialog { this.element.style.width = "80%"; this.element.appendChild(panel); - handleResize(); + handleResize(); } async createBottomControls() { diff --git a/node_db/dev/custom-node-list.json b/node_db/dev/custom-node-list.json index 1135d9d2..07951860 100644 --- a/node_db/dev/custom-node-list.json +++ b/node_db/dev/custom-node-list.json @@ -10,6 +10,16 @@ }, + { + "author": "ZHO-ZHO-ZHO", + "title": "ComfyUI PhotoMaker (WIP)", + "reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker", + "files": [ + "https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker" + ], + "install_type": "git-clone", + "description": "Unofficial implementation of [a/PhotoMaker](https://github.com/TencentARC/PhotoMaker) for ComfyUI(WIP) Testing……" + }, { "author": "poisenbery", "title": "NudeNet-Detector-Provider [WIP]", diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 13ca128c..2fa96461 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,16 @@ }, + { + "author": "HAL41", + "title": "ComfyUI aichemy nodes", + "reference": "https://github.com/HAL41/ComfyUI-aichemy-nodes", + "files": [ + "https://github.com/HAL41/ComfyUI-aichemy-nodes" + ], + "install_type": "git-clone", + "description": "Simple node to handle scaling of YOLOv8 segmentation masks" + }, { "author": "abyz22", "title": "image_control", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index cab21191..5ff51cbd 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -131,6 +131,7 @@ "VideoCut-badger", "deleteDir-badger", "findCenterOfMask-badger", + "frameToVideo-badger", "getImageSide-badger", "getParentDir-badger", "mkdir-badger" @@ -840,6 +841,14 @@ "title_aux": "ReActor Node for ComfyUI" } ], + "https://github.com/HAL41/ComfyUI-aichemy-nodes": [ + [ + "aichemyYOLOv8Segmentation" + ], + { + "title_aux": "ComfyUI aichemy nodes" + } + ], "https://github.com/Hangover3832/ComfyUI-Hangover-Nodes": [ [ "Image Scale Bounding Box", From 84f91189455f318ffef9a062634978a608bd0a55 Mon Sep 17 00:00:00 2001 From: chaojie Date: Tue, 16 Jan 2024 17:16:18 +0800 Subject: [PATCH 13/35] Update custom-node-list.json --- custom-node-list.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/custom-node-list.json b/custom-node-list.json index 47c50e09..eab47c0a 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4054,6 +4054,16 @@ "install_type": "git-clone", "description": "Nodes: Download the weights of MotionCtrl [a/motionctrl.pth](https://huggingface.co/TencentARC/MotionCtrl/blob/main/motionctrl.pth) and put it to ComfyUI/models/checkpoints" }, + { + "author": "chaojie", + "title": "ComfyUI-MotionCtrl-SVD", + "reference": "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD", + "files": [ + "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD" + ], + "install_type": "git-clone", + "description": "Nodes: Download the weights of MotionCtrl-SVD [a/motionctrl_svd.ckpt](https://huggingface.co/TencentARC/MotionCtrl/blob/main/motionctrl_svd.ckpt) and put it to ComfyUI/models/checkpoints" + }, { "author": "chaojie", "title": "ComfyUI-DragNUWA", From 4bdf7aabe4e0f7d71067db2eb2f5834815d3d29e Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Tue, 16 Jan 2024 16:03:40 +0900 Subject: [PATCH 14/35] feat: component pack builder - support drag & drop - add node if single component importing --- README.md | 14 +- __init__.py | 11 +- components/.gitignore | 1 + js/comfyui-manager.js | 61 ++++- js/common.js | 11 +- js/components-manager.js | 570 +++++++++++++++++++++++++++++++++------ misc/Impact.pack | 444 ++++++++++++++++++++++++++++++ 7 files changed, 1022 insertions(+), 90 deletions(-) create mode 100644 misc/Impact.pack diff --git a/README.md b/README.md index 5852df2a..7787bd2b 100644 --- a/README.md +++ b/README.md @@ -223,9 +223,17 @@ NODE_CLASS_MAPPINGS.update({ * `` Ensure that the timestamp is always unique. * "components" should have the same structure as the content of the file stored in ComfyUI-Manager/components. * ``: The name should be in the format `::`. - * ``: In the nodedata of the group node. - - + * ``: In the nodedata of the group node. + * ``: Only two formats are allowed: `major.minor.patch` or `major.minor`. (e.g. `1.0`, `2.2.1`) + * ``: Saved time + * ``: If the packname is not empty, the category becomes packname/workflow, and it is saved in the .pack file in ComfyUI-Manager/components. + * ``: If there is neither a category nor a packname, it is saved in the components category. + ``` + "version":"1.0", + "datetime": 1705390656516, + "packname": "mypack", + "category": "util/pipe", + ``` ## Support of missing nodes installation diff --git a/__init__.py b/__init__.py index b58cab44..83cc0999 100644 --- a/__init__.py +++ b/__init__.py @@ -1855,9 +1855,12 @@ async def save_component(request): if not os.path.exists(components_path): os.mkdir(components_path) - sanitized_name = sanitize_filename(name) + if 'packname' in workflow and workflow['packname'] != '': + sanitized_name = sanitize_filename(workflow['packname'])+'.pack' + else: + sanitized_name = sanitize_filename(name)+'.json' - filepath = os.path.join(components_path, sanitized_name+'.json') + filepath = os.path.join(components_path, sanitized_name) components = {} if os.path.exists(filepath): with open(filepath) as f: @@ -1876,12 +1879,14 @@ async def save_component(request): async def load_components(request): try: json_files = [f for f in os.listdir(components_path) if f.endswith('.json')] + pack_files = [f for f in os.listdir(components_path) if f.endswith('.pack')] components = {} - for json_file in json_files: + for json_file in json_files + pack_files: file_path = os.path.join(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: print(f"[ComfyUI-Manager] Error decoding component file in file {json_file}: {e}") diff --git a/components/.gitignore b/components/.gitignore index a6c57f5f..fab7a5e2 100644 --- a/components/.gitignore +++ b/components/.gitignore @@ -1 +1,2 @@ *.json +*.pack diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index 85f1781a..fe1233da 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -16,7 +16,7 @@ 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, install_pip, rebootAPI, free_models } from "./common.js"; -import { load_components, save_as_component } from "./components-manager.js"; +import { ComponentBuilderDialog, load_components } from "./components-manager.js"; var docStyle = document.createElement('style'); docStyle.innerHTML = ` @@ -27,6 +27,35 @@ docStyle.innerHTML = ` z-index: 10000; } +.cb-widget { + width: 400px; + height: 25px; + box-sizing: border-box; + z-index: 10000; + margin-top: 10px; + margin-bottom: 5px; +} + +.cb-widget-input { + width: 305px; + height: 25px; + box-sizing: border-box; +} +.cb-widget-input:disabled { + background-color: #444444; + color: white; +} + +.cb-widget-input-label { + width: 90px; + height: 25px; + box-sizing: border-box; + color: white; + text-align: right; + display: inline-block; + margin-right: 5px; +} + .cm-menu-container { column-gap: 20px; display: flex; @@ -251,6 +280,16 @@ const style = ` box-sizing: border-box; } +.cb-node-label { + width: 400px; + height:28px; + color: black; + background-color: #777777; + font-size: 18px; + text-align: center; + font-weight: bold; +} + #cm-close-button { width: calc(100% - 65px); bottom: 10px; @@ -258,6 +297,16 @@ const style = ` overflow: hidden; } +#cm-save-button { + width: calc(100% - 65px); + bottom:40px; + position: absolute; + overflow: hidden; +} +#cm-save-button:disabled { + background-color: #444444; +} + .pysssss-workflow-arrow-2 { position: absolute; top: 0; @@ -873,7 +922,7 @@ class ManagerMenuDialog extends ComfyDialog { }) ]), ]; -} + } createControlsRight() { const elts = [ @@ -1197,7 +1246,13 @@ app.registerExtension({ if (node.comfyClass.startsWith('workflow/')) { options.push({ content: "Save As Component", - callback: (obj) => { save_as_component(node, app); } + callback: (obj) => { + if (!ComponentBuilderDialog.instance) { + ComponentBuilderDialog.instance = new ComponentBuilderDialog(); + } + ComponentBuilderDialog.instance.target_node = node; + ComponentBuilderDialog.instance.show(); + } }, null); } diff --git a/js/common.js b/js/common.js index 8d0997d1..a45bf75f 100644 --- a/js/common.js +++ b/js/common.js @@ -48,8 +48,7 @@ export async function install_checked_custom_node(grid_rows, target_i, caller, m }); if(response.status == 400) { - app.ui.dialog.show(`${mode} failed: ${target.title}`); - app.ui.dialog.element.style.zIndex = 10010; + show_message(`${mode} failed: ${target.title}`); continue; } @@ -64,8 +63,7 @@ export async function install_checked_custom_node(grid_rows, target_i, caller, m } if(failed != '') { - app.ui.dialog.show(`${mode} failed: ${failed}`); - app.ui.dialog.element.style.zIndex = 10010; + show_message(`${mode} failed: ${failed}`); } await caller.invalidateControl(); @@ -160,4 +158,9 @@ export async function free_models() { app.ui.dialog.show('Unloading of models failed.

Installed ComfyUI may be an outdated version.') } app.ui.dialog.element.style.zIndex = 10010; +} + +export function show_message(msg) { + app.ui.dialog.show(msg); + app.ui.dialog.element.style.zIndex = 10010; } \ No newline at end of file diff --git a/js/components-manager.js b/js/components-manager.js index 8f90955c..d8bd84f5 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -1,7 +1,32 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js" -import { sleep } from "./common.js"; +import { sleep, show_message } from "./common.js"; import { GroupNodeConfig, GroupNodeHandler } from "../../extensions/core/groupNode.js"; +import { ComfyDialog, $el } from "../../scripts/ui.js"; + +let pack_map = {}; +let rpack_map = {}; + +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.packname, data.category, data.version, data.datetime]; + } + else { + rpack_map[name] = [data.packname, data.category, data.version, data.datetime]; + } +} function storeGroupNode(name, data) { let extra = app.graph.extra; @@ -9,6 +34,8 @@ function storeGroupNode(name, data) { let groupNodes = extra.groupNodes; if (!groupNodes) extra.groupNodes = groupNodes = {}; groupNodes[name] = data; + + register_pack_map(name, data); } export async function load_components() { @@ -21,6 +48,22 @@ export async function load_components() { 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 += "/" + data.category; + } + if(category == '') { + category = 'components'; + } + + const config = new GroupNodeConfig(name, data); + await config.registerType(category); + + register_pack_map(name, data); + } continue; } @@ -32,7 +75,16 @@ export async function load_components() { while(!success) { var success = false; try { - await config.registerType(); + let category = nodeData.packname; + if(nodeData.category) { + category += "/" + nodeData.category; + } + if(category == '') { + category = 'components'; + } + + await config.registerType(category); + register_pack_map(name, nodeData); } catch { let elapsed_time = Date.now() - start_time; @@ -44,8 +96,6 @@ export async function load_components() { } } } - - const groupNode = LiteGraph.createNode(`workflow/${name}`); } // fallback1 @@ -64,7 +114,16 @@ export async function load_components() { while(!success) { var success = false; try { - await config.registerType(); + let category = nodeData.packname; + if(nodeData.workflow.category) { + category += "/" + nodeData.category; + } + if(category == '') { + category = 'components'; + } + + await config.registerType(category); + register_pack_map(name, nodeData); } catch { let elapsed_time = Date.now() - start_time; @@ -76,8 +135,6 @@ export async function load_components() { } } } - - const groupNode = LiteGraph.createNode(`workflow/${name}`); } // fallback2 @@ -91,8 +148,18 @@ export async function load_components() { const config = new GroupNodeConfig(name, nodeData); while(!success) { var success = false; + try { - await config.registerType(); + let category = nodeData.workflow.packname; + if(nodeData.workflow.category) { + category += "/" + nodeData.category; + } + if(category == '') { + category = 'components'; + } + + await config.registerType(category); + register_pack_map(name, nodeData); } catch { let elapsed_time = Date.now() - start_time; @@ -104,72 +171,31 @@ export async function load_components() { } } } - - const groupNode = LiteGraph.createNode(`workflow/${name}`); } } -export async function save_as_component(node, app) { - let pure_name = node.comfyClass.substring(9); - let subgraph = app.graph.extra?.groupNodes?.[pure_name]; +async function save_as_component(node, version, prefix, nodename, packname, category) { + let component_name = `${prefix}::${nodename}`; + let subgraph = app.graph.extra?.groupNodes?.[component_name]; if(!subgraph) { - app.ui.dialog.show(`Failed to retrieve the group node '${pure_name}'.`); - return; + subgraph = app.graph.extra?.groupNodes?.[node.comfyClass.substring(9)]; } - if(node.comfyClass.includes('::')) { - let component_name = node.comfyClass.substring(9); + subgraph.version = version; + subgraph.datetime = Date.now(); + subgraph.packname = packname; + subgraph.category = category; - if(confirm(`Will you save/overwrite component '${component_name}'?`)) { - let subgraph = app.graph.extra?.groupNodes?.[component_name]; - let body = - { - name: component_name, - workflow: subgraph - }; - - const res = await api.fetchApi('/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); - await config.registerType(); - - let path = await res.text(); - app.ui.dialog.show(`Component '${component_name}' is saved into:\n${path}`); - } - else - app.ui.dialog.show(`Failed to save component.`); - } - - return; - } - - var prefix = prompt("To save as a component, a unique prefix is required. (e.g., the 'Impact' in Impact::MAKE_BASIC_PIPE)", "PREFIX"); - - if(!prefix) { - return; - } - - prefix = prefix.trim(); - - if(prefix == 'PREFIX') { - app.ui.dialog.show(`The placeholder 'PREFIX' isn't allowed for component prefix.`); - return; - } - - let component_name = prefix+'::'+pure_name; let body = { name: component_name, workflow: subgraph }; + pack_map[packname] = component_name; + rpack_map[component_name] = [body.pack_name, body.category, body.version, body.datetime]; + const res = await api.fetchApi('/manager/component/save', { method: "POST", headers: { @@ -181,21 +207,30 @@ export async function save_as_component(node, app) { if(res.status == 200) { storeGroupNode(component_name, subgraph); const config = new GroupNodeConfig(component_name, subgraph); - await config.registerType(); + + let category = body.workflow.packname; + if(body.workflow.category) { + category += "/" + body.workflow.category; + } + if(category == '') { + category = 'components'; + } + + await config.registerType(category); let path = await res.text(); - app.ui.dialog.show(`Component '${component_name}' is saved into:\n${path}`); + show_message(`Component '${component_name}' is saved into:\n${path}`); } else - app.ui.dialog.show(`Failed to save component.`); + show_message(`Failed to save component.`); } -async function import_component(component_name, subgraph) { - if(confirm("Will you save component?\n(If canceled, the component won't be saved and can only be used within the current workflow.)")) { +async function import_component(component_name, component, mode) { + if(mode) { let body = { name: component_name, - workflow: subgraph + workflow: component }; const res = await api.fetchApi('/manager/component/save', { @@ -205,14 +240,142 @@ async function import_component(component_name, subgraph) { }); } - storeGroupNode(component_name, subgraph); - const config = new GroupNodeConfig(component_name, subgraph); - await config.registerType(); + let category = component.packname; + if(component.category) { + category += "/" + component.category; + } + if(category == '') { + category = 'components'; + } + + storeGroupNode(component_name, component); + const config = new GroupNodeConfig(component_name, component); + await config.registerType(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][2]; + 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; +} + +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'; + if(confirm(msg)) { + let mode = confirm('\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/${last_name}`); + node.pos = [app.canvas.graph_mouse[0], app.canvas.graph_mouse[1]]; + app.canvas.graph.add(node, false); + } +} + function handlePaste(e) { let data = (e.clipboardData || window.clipboardData); const items = data.items; @@ -223,14 +386,7 @@ function handlePaste(e) { let json_data = JSON.parse(data); if(json_data.kind == 'ComfyUI Components' && last_paste_timestamp != json_data.timestamp) { last_paste_timestamp = json_data.timestamp; - - let msg = 'Components are added:\n'; - for(let name in json_data.components) { - let subgraph = json_data.components[name]; - import_component(name, subgraph); - msg += ' - ' + name + '\n'; - } - app.ui.dialog.show(msg); + handle_import_components(json_data.components); // disable paste node localStorage.removeItem("litegrapheditor_clipboard", null); @@ -249,3 +405,263 @@ function handlePaste(e) { 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 = 10001; + this.element.style.width = "500px"; + this.element.style.height = "450px"; + } + + 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.node_prefix.value.trim(), + self.getNodeName(), self.getPackName(), self.category.value.trim()); + } + }); + + let default_nodename = this.target_node.comfyClass.substring(9).trim(); + + let default_packname = ""; + if(rpack_map[default_nodename]) { + default_packname = rpack_map[default_nodename][0]; + } + if(!default_packname) { + default_packname = ''; + } + + let default_category = ""; + if(rpack_map[default_nodename]) { + default_category = rpack_map[default_nodename][1]; + } + if(!default_category) { + default_category = ''; + } + + if(rpack_map[default_nodename]) { + this.default_ver = rpack_map[default_nodename][2]; + } + if(!this.default_ver) { + this.default_ver = '0.0'; + } + + 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 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], + 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 this.target_node.comfyClass.substring(9); + } + + 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 { + alert('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'; + label.textContent = " _::" + this.target_node.comfyClass.substring(9); + 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; + +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) { + handle_import_components(jsonContent); + } + else { + orig_handleFile.call(app, file); + } + }; + reader.readAsText(file); + + return; + } + + orig_handleFile.call(app, file); +} + +app.handleFile = handleFile; diff --git a/misc/Impact.pack b/misc/Impact.pack new file mode 100644 index 00000000..93fd3284 --- /dev/null +++ b/misc/Impact.pack @@ -0,0 +1,444 @@ +{ + "Impact::MAKE_BASIC_PIPE": { + "category": "", + "config": { + "1": { + "input": { + "text": { + "name": "Positive prompt" + } + } + }, + "2": { + "input": { + "text": { + "name": "Negative prompt" + } + } + } + }, + "datetime": 1705418802481, + "external": [], + "links": [ + [ + 0, + 1, + 1, + 0, + 1, + "CLIP" + ], + [ + 0, + 1, + 2, + 0, + 1, + "CLIP" + ], + [ + 0, + 0, + 3, + 0, + 1, + "MODEL" + ], + [ + 0, + 1, + 3, + 1, + 1, + "CLIP" + ], + [ + 0, + 2, + 3, + 2, + 1, + "VAE" + ], + [ + 1, + 0, + 3, + 3, + 3, + "CONDITIONING" + ], + [ + 2, + 0, + 3, + 4, + 4, + "CONDITIONING" + ] + ], + "nodes": [ + { + "flags": {}, + "index": 0, + "mode": 0, + "order": 0, + "outputs": [ + { + "links": [], + "name": "MODEL", + "shape": 3, + "slot_index": 0, + "type": "MODEL" + }, + { + "links": [], + "name": "CLIP", + "shape": 3, + "slot_index": 1, + "type": "CLIP" + }, + { + "links": [], + "name": "VAE", + "shape": 3, + "slot_index": 2, + "type": "VAE" + } + ], + "pos": [ + 550, + 360 + ], + "properties": { + "Node name for S&R": "CheckpointLoaderSimple" + }, + "size": { + "0": 315, + "1": 98 + }, + "type": "CheckpointLoaderSimple", + "widgets_values": [ + "SDXL/sd_xl_base_1.0_0.9vae.safetensors" + ] + }, + { + "flags": {}, + "index": 1, + "inputs": [ + { + "link": null, + "name": "clip", + "type": "CLIP" + } + ], + "mode": 0, + "order": 1, + "outputs": [ + { + "links": [], + "name": "CONDITIONING", + "shape": 3, + "slot_index": 0, + "type": "CONDITIONING" + } + ], + "pos": [ + 940, + 480 + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "size": { + "0": 263, + "1": 99 + }, + "title": "Positive", + "type": "CLIPTextEncode", + "widgets_values": [ + "" + ] + }, + { + "flags": {}, + "index": 2, + "inputs": [ + { + "link": null, + "name": "clip", + "type": "CLIP" + } + ], + "mode": 0, + "order": 2, + "outputs": [ + { + "links": [], + "name": "CONDITIONING", + "shape": 3, + "slot_index": 0, + "type": "CONDITIONING" + } + ], + "pos": [ + 940, + 640 + ], + "properties": { + "Node name for S&R": "CLIPTextEncode" + }, + "size": { + "0": 263, + "1": 99 + }, + "title": "Negative", + "type": "CLIPTextEncode", + "widgets_values": [ + "" + ] + }, + { + "flags": {}, + "index": 3, + "inputs": [ + { + "link": null, + "name": "model", + "type": "MODEL" + }, + { + "link": null, + "name": "clip", + "type": "CLIP" + }, + { + "link": null, + "name": "vae", + "type": "VAE" + }, + { + "link": null, + "name": "positive", + "type": "CONDITIONING" + }, + { + "link": null, + "name": "negative", + "type": "CONDITIONING" + } + ], + "mode": 0, + "order": 3, + "outputs": [ + { + "links": null, + "name": "basic_pipe", + "shape": 3, + "slot_index": 0, + "type": "BASIC_PIPE" + } + ], + "pos": [ + 1320, + 360 + ], + "properties": { + "Node name for S&R": "ToBasicPipe" + }, + "size": { + "0": 241.79998779296875, + "1": 106 + }, + "type": "ToBasicPipe" + } + ], + "packname": "Impact", + "version": "1.0" + }, + "Impact::SIMPLE_DETAILER_PIPE": { + "category": "", + "config": { + "0": { + "output": { + "0": { + "visible": false + }, + "1": { + "visible": false + } + } + }, + "2": { + "input": { + "Select to add LoRA": { + "visible": false + }, + "Select to add Wildcard": { + "visible": false + }, + "wildcard": { + "visible": false + } + } + } + }, + "datetime": 1705419147116, + "external": [], + "links": [ + [ + null, + 0, + 2, + 0, + 6, + "BASIC_PIPE" + ], + [ + 0, + 0, + 2, + 1, + 13, + "BBOX_DETECTOR" + ], + [ + 1, + 0, + 2, + 2, + 15, + "SAM_MODEL" + ] + ], + "nodes": [ + { + "flags": {}, + "index": 0, + "mode": 0, + "order": 2, + "outputs": [ + { + "links": [], + "name": "BBOX_DETECTOR", + "shape": 3, + "type": "BBOX_DETECTOR" + }, + { + "links": null, + "name": "SEGM_DETECTOR", + "shape": 3, + "type": "SEGM_DETECTOR" + } + ], + "pos": [ + 590, + 830 + ], + "properties": { + "Node name for S&R": "UltralyticsDetectorProvider" + }, + "size": { + "0": 315, + "1": 78 + }, + "type": "UltralyticsDetectorProvider", + "widgets_values": [ + "bbox/Eyeful_v1.pt" + ] + }, + { + "flags": {}, + "index": 1, + "mode": 0, + "order": 3, + "outputs": [ + { + "links": [], + "name": "SAM_MODEL", + "shape": 3, + "type": "SAM_MODEL" + } + ], + "pos": [ + 590, + 960 + ], + "properties": { + "Node name for S&R": "SAMLoader" + }, + "size": { + "0": 315, + "1": 82 + }, + "type": "SAMLoader", + "widgets_values": [ + "sam_vit_b_01ec64.pth", + "AUTO" + ] + }, + { + "flags": {}, + "index": 2, + "inputs": [ + { + "link": null, + "name": "basic_pipe", + "type": "BASIC_PIPE" + }, + { + "link": null, + "name": "bbox_detector", + "slot_index": 1, + "type": "BBOX_DETECTOR" + }, + { + "link": null, + "name": "sam_model_opt", + "slot_index": 2, + "type": "SAM_MODEL" + }, + { + "link": null, + "name": "segm_detector_opt", + "type": "SEGM_DETECTOR" + }, + { + "link": null, + "name": "detailer_hook", + "type": "DETAILER_HOOK" + } + ], + "mode": 0, + "order": 5, + "outputs": [ + { + "links": null, + "name": "detailer_pipe", + "shape": 3, + "type": "DETAILER_PIPE" + } + ], + "pos": [ + 1044, + 812 + ], + "properties": { + "Node name for S&R": "BasicPipeToDetailerPipe" + }, + "size": { + "0": 400, + "1": 204 + }, + "type": "BasicPipeToDetailerPipe", + "widgets_values": [ + "", + "Select the LoRA to add to the text", + "Select the Wildcard to add to the text" + ] + } + ], + "packname": "Impact", + "version": "1.0" + } +} \ No newline at end of file From 961c2eeb534500c6d216f28d414d546a2facf471 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 17 Jan 2024 00:42:55 +0900 Subject: [PATCH 15/35] update DB --- custom-node-list.json | 21 +++++++++ extension-node-map.json | 70 ++++++++++++++++++++++++++++- node_db/new/custom-node-list.json | 30 +++++++++++++ node_db/new/extension-node-map.json | 70 ++++++++++++++++++++++++++++- 4 files changed, 187 insertions(+), 4 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index eab47c0a..c0ffd7eb 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4264,6 +4264,27 @@ "install_type": "git-clone", "description": "Simple node to handle scaling of YOLOv8 segmentation masks" }, + { + "author": "nkchocoai", + "title": "ComfyUI-SizeFromPresets", + "reference": "https://github.com/nkchocoai/ComfyUI-SizeFromPresets", + "files": [ + "https://github.com/nkchocoai/ComfyUI-SizeFromPresets" + ], + "install_type": "git-clone", + "description": "Add a node that outputs width and height of the size selected from the preset (.csv)." + }, + { + "author": "JaredTherriault", + "title": "ComfyUI-JNodes", + "reference": "https://github.com/JaredTherriault/ComfyUI-JNodes", + "files": [ + "https://github.com/JaredTherriault/ComfyUI-JNodes" + ], + "install_type": "git-clone", + "description": "python and web UX improvements for ComfyUI.\n[w/'DynamicPrompts.js' and 'EditAttention.js' from the core, along with 'ImageFeed.js' and 'favicon.js' from the custom scripts of pythongosssss, are not compatible. Therefore, manual deletion of these files is required to use this web extension.]" + }, + { diff --git a/extension-node-map.json b/extension-node-map.json index 5ff51cbd..8714c4dc 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -120,6 +120,9 @@ "FindThickLinesFromCanny-badger", "FloatToInt-badger", "FloatToString-badger", + "FrameToVideo-badger", + "GetDirName-badger", + "GetUUID-badger", "ImageNormalization-badger", "ImageOverlap-badger", "ImageScaleToSide-badger", @@ -128,10 +131,10 @@ "StringToFizz-badger", "TextListToString-badger", "TrimTransparentEdges-badger", - "VideoCut-badger", + "VideoCutFromDir-badger", + "VideoToFrame-badger", "deleteDir-badger", "findCenterOfMask-badger", - "frameToVideo-badger", "getImageSide-badger", "getParentDir-badger", "mkdir-badger" @@ -266,6 +269,7 @@ "ComfyUIDeployExternalImage", "ComfyUIDeployExternalImageAlpha", "ComfyUIDeployExternalNumber", + "ComfyUIDeployExternalNumberInt", "ComfyUIDeployExternalText" ], { @@ -958,6 +962,44 @@ "title_aux": "JPS Custom Nodes for ComfyUI" } ], + "https://github.com/JaredTherriault/ComfyUI-JNodes": [ + [ + "JNodes_AddOrSetPngInfoKey", + "JNodes_AppendReversedFrames", + "JNodes_BooleanSelectorWithString", + "JNodes_CheckpointSelectorWithString", + "JNodes_GetOutputDirectory", + "JNodes_GetParameterFromList", + "JNodes_GetParameterGlobal", + "JNodes_GetTempDirectory", + "JNodes_ImageFormatSelector", + "JNodes_ImageSizeSelector", + "JNodes_LoadVideo", + "JNodes_LoraExtractor", + "JNodes_OutVideoInfo", + "JNodes_ParseDynamicPrompts", + "JNodes_ParseParametersToGlobalList", + "JNodes_ParseWildcards", + "JNodes_PromptBuilderSingleSubject", + "JNodes_PromptEditor", + "JNodes_RemoveParseableDataForInference", + "JNodes_RemovePngInfoKey", + "JNodes_SamplerSelectorWithString", + "JNodes_SaveImageWithOutput", + "JNodes_SaveVideo", + "JNodes_SchedulerSelectorWithString", + "JNodes_SetNegativePromptInMetaData", + "JNodes_SetPositivePromptInMetaData", + "JNodes_StringLiteral", + "JNodes_SyncedStringLiteral", + "JNodes_TokenCounter", + "JNodes_UploadVideo", + "JNodes_VaeSelectorWithString" + ], + { + "title_aux": "ComfyUI-JNodes" + } + ], "https://github.com/Jcd1230/rembg-comfyui-node": [ [ "Image Remove Background (rembg)" @@ -1946,6 +1988,8 @@ "CR Seed to Int", "CR Select Font", "CR Select Model", + "CR Select Resize Method", + "CR Set Switch From String", "CR Set Value On Binary", "CR Set Value On Boolean", "CR Set Value on String", @@ -3015,6 +3059,7 @@ "ImageBridge", "LoadImageFromRequest", "LoadImageWithAlpha", + "LoadValueFromRequest", "SAM MultiLayer", "Save Image With Workflow" ], @@ -3239,6 +3284,7 @@ "RGB to HSV", "Rect Grab Cut", "Remap", + "RemapFromQuadrilateral (homography)", "RemapInsideParabolas", "RemapInsideParabolasAdvanced", "RemapToInnerCylinder", @@ -3434,6 +3480,16 @@ "title_aux": "ComfyUI-MotionCtrl" } ], + "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD": [ + [ + "Load Motionctrl-SVD Camera Preset", + "Load Motionctrl-SVD Checkpoint", + "Motionctrl-SVD Sample Simple" + ], + { + "title_aux": "ComfyUI-MotionCtrl-SVD" + } + ], "https://github.com/chflame163/ComfyUI_MSSpeech_TTS": [ [ "Input Trigger", @@ -5475,6 +5531,15 @@ "title_aux": "comfyui-NDI" } ], + "https://github.com/nkchocoai/ComfyUI-SizeFromPresets": [ + [ + "SizeFromPresetsSD15", + "SizeFromPresetsSDXL" + ], + { + "title_aux": "ComfyUI-SizeFromPresets" + } + ], "https://github.com/noembryo/ComfyUI-noEmbryo": [ [ "PromptTermList1", @@ -5883,6 +5948,7 @@ "MultiplicationNode", "NewLayer", "NoiseImage", + "OutlineMask", "PromptImage", "PromptSimplification", "PromptSlide", diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 2fa96461..32be8b2f 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,36 @@ }, + { + "author": "chaojie", + "title": "ComfyUI-MotionCtrl-SVD", + "reference": "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD", + "files": [ + "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD" + ], + "install_type": "git-clone", + "description": "Nodes: Download the weights of MotionCtrl-SVD [a/motionctrl_svd.ckpt](https://huggingface.co/TencentARC/MotionCtrl/blob/main/motionctrl_svd.ckpt) and put it to ComfyUI/models/checkpoints" + }, + { + "author": "JaredTherriault", + "title": "ComfyUI-JNodes", + "reference": "https://github.com/JaredTherriault/ComfyUI-JNodes", + "files": [ + "https://github.com/JaredTherriault/ComfyUI-JNodes" + ], + "install_type": "git-clone", + "description": "python and web UX improvements for ComfyUI.\n[w/'DynamicPrompts.js' and 'EditAttention.js' from the core, along with 'ImageFeed.js' and 'favicon.js' from the custom scripts of pythongosssss, are not compatible. Therefore, manual deletion of these files is required to use this web extension.]" + }, + { + "author": "nkchocoai", + "title": "ComfyUI-SizeFromPresets", + "reference": "https://github.com/nkchocoai/ComfyUI-SizeFromPresets", + "files": [ + "https://github.com/nkchocoai/ComfyUI-SizeFromPresets" + ], + "install_type": "git-clone", + "description": "Add a node that outputs width and height of the size selected from the preset (.csv)." + }, { "author": "HAL41", "title": "ComfyUI aichemy nodes", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 5ff51cbd..8714c4dc 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -120,6 +120,9 @@ "FindThickLinesFromCanny-badger", "FloatToInt-badger", "FloatToString-badger", + "FrameToVideo-badger", + "GetDirName-badger", + "GetUUID-badger", "ImageNormalization-badger", "ImageOverlap-badger", "ImageScaleToSide-badger", @@ -128,10 +131,10 @@ "StringToFizz-badger", "TextListToString-badger", "TrimTransparentEdges-badger", - "VideoCut-badger", + "VideoCutFromDir-badger", + "VideoToFrame-badger", "deleteDir-badger", "findCenterOfMask-badger", - "frameToVideo-badger", "getImageSide-badger", "getParentDir-badger", "mkdir-badger" @@ -266,6 +269,7 @@ "ComfyUIDeployExternalImage", "ComfyUIDeployExternalImageAlpha", "ComfyUIDeployExternalNumber", + "ComfyUIDeployExternalNumberInt", "ComfyUIDeployExternalText" ], { @@ -958,6 +962,44 @@ "title_aux": "JPS Custom Nodes for ComfyUI" } ], + "https://github.com/JaredTherriault/ComfyUI-JNodes": [ + [ + "JNodes_AddOrSetPngInfoKey", + "JNodes_AppendReversedFrames", + "JNodes_BooleanSelectorWithString", + "JNodes_CheckpointSelectorWithString", + "JNodes_GetOutputDirectory", + "JNodes_GetParameterFromList", + "JNodes_GetParameterGlobal", + "JNodes_GetTempDirectory", + "JNodes_ImageFormatSelector", + "JNodes_ImageSizeSelector", + "JNodes_LoadVideo", + "JNodes_LoraExtractor", + "JNodes_OutVideoInfo", + "JNodes_ParseDynamicPrompts", + "JNodes_ParseParametersToGlobalList", + "JNodes_ParseWildcards", + "JNodes_PromptBuilderSingleSubject", + "JNodes_PromptEditor", + "JNodes_RemoveParseableDataForInference", + "JNodes_RemovePngInfoKey", + "JNodes_SamplerSelectorWithString", + "JNodes_SaveImageWithOutput", + "JNodes_SaveVideo", + "JNodes_SchedulerSelectorWithString", + "JNodes_SetNegativePromptInMetaData", + "JNodes_SetPositivePromptInMetaData", + "JNodes_StringLiteral", + "JNodes_SyncedStringLiteral", + "JNodes_TokenCounter", + "JNodes_UploadVideo", + "JNodes_VaeSelectorWithString" + ], + { + "title_aux": "ComfyUI-JNodes" + } + ], "https://github.com/Jcd1230/rembg-comfyui-node": [ [ "Image Remove Background (rembg)" @@ -1946,6 +1988,8 @@ "CR Seed to Int", "CR Select Font", "CR Select Model", + "CR Select Resize Method", + "CR Set Switch From String", "CR Set Value On Binary", "CR Set Value On Boolean", "CR Set Value on String", @@ -3015,6 +3059,7 @@ "ImageBridge", "LoadImageFromRequest", "LoadImageWithAlpha", + "LoadValueFromRequest", "SAM MultiLayer", "Save Image With Workflow" ], @@ -3239,6 +3284,7 @@ "RGB to HSV", "Rect Grab Cut", "Remap", + "RemapFromQuadrilateral (homography)", "RemapInsideParabolas", "RemapInsideParabolasAdvanced", "RemapToInnerCylinder", @@ -3434,6 +3480,16 @@ "title_aux": "ComfyUI-MotionCtrl" } ], + "https://github.com/chaojie/ComfyUI-MotionCtrl-SVD": [ + [ + "Load Motionctrl-SVD Camera Preset", + "Load Motionctrl-SVD Checkpoint", + "Motionctrl-SVD Sample Simple" + ], + { + "title_aux": "ComfyUI-MotionCtrl-SVD" + } + ], "https://github.com/chflame163/ComfyUI_MSSpeech_TTS": [ [ "Input Trigger", @@ -5475,6 +5531,15 @@ "title_aux": "comfyui-NDI" } ], + "https://github.com/nkchocoai/ComfyUI-SizeFromPresets": [ + [ + "SizeFromPresetsSD15", + "SizeFromPresetsSDXL" + ], + { + "title_aux": "ComfyUI-SizeFromPresets" + } + ], "https://github.com/noembryo/ComfyUI-noEmbryo": [ [ "PromptTermList1", @@ -5883,6 +5948,7 @@ "MultiplicationNode", "NewLayer", "NoiseImage", + "OutlineMask", "PromptImage", "PromptSimplification", "PromptSlide", From 042d5b406ad46d4a9964ebc22f7756ae64d3fe51 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 17 Jan 2024 01:07:03 +0900 Subject: [PATCH 16/35] update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 7787bd2b..9e452e69 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,11 @@ NODE_CLASS_MAPPINGS.update({ "category": "util/pipe", ``` +* Drag & Drop support + * Dragging and dropping a `.pack` or `.json` file will add the corresponding components. + * Example pack: [Impact.pack](misc/Impact.pack) +* Dragging and dropping or pasting a single component will add a node. However, when adding multiple components, nodes will not be added. + ## Support of missing nodes installation ![missing-menu](misc/missing-menu.png) From 4649d216b1842aa48b95d3f064c679a1b698e506 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 17 Jan 2024 01:17:16 +0900 Subject: [PATCH 17/35] component builder - fix initial displayed node name --- js/components-manager.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/components-manager.js b/js/components-manager.js index d8bd84f5..4c7e69af 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -594,7 +594,10 @@ export class ComponentBuilderDialog extends ComfyDialog { createNodeLabel() { let label = $el('p'); label.className = 'cb-node-label'; - label.textContent = " _::" + this.target_node.comfyClass.substring(9); + if(this.target_node.comfyClass.includes('::')) + label.textContent = this.target_node.comfyClass.substring(9); + else + label.textContent = " _::" + this.target_node.comfyClass.substring(9); return label; } From 7342c3d1b47567d97317aac3414af7313c29a5ef Mon Sep 17 00:00:00 2001 From: prozacgod Date: Tue, 16 Jan 2024 15:29:59 -0600 Subject: [PATCH 18/35] Added ComfyUI Multi-Workspace --- custom-node-list.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/custom-node-list.json b/custom-node-list.json index c0ffd7eb..357efa8e 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4603,6 +4603,16 @@ ], "install_type": "unzip", "description": "This is a node to convert an image into a CMYK Halftone dot image." + }, + { + "author": "prozacgod", + "title": "ComfyUI Multi-Workspace", + "reference": "https://github.com/prozacgod/comfyui-pzc-multiworkspace", + "files": [ + "https://github.com/prozacgod/comfyui-pzc-multiworkspace" + ], + "install_type": "git-clone", + "description": "A simple, quick, and dirty implementation of multiple workspaces within ComfyUI." } ] } From 9215f37c02b24cd9d7fdc638a434cf89e7013058 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Wed, 17 Jan 2024 12:46:49 +0900 Subject: [PATCH 19/35] component system - bug fixes and refactor --- __init__.py | 23 +++++++- js/comfyui-manager.js | 56 ++++++++++++++---- js/components-manager.js | 124 ++++++++++++++++++++++++++++++++------- 3 files changed, 166 insertions(+), 37 deletions(-) diff --git a/__init__.py b/__init__.py index 83cc0999..e4bf8a17 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [2, 1] +version = [2, 2] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") @@ -172,6 +172,7 @@ def write_config(): 'share_option': get_config()['share_option'], 'bypass_ssl': get_config()['bypass_ssl'], 'default_ui': get_config()['default_ui'], + 'component_policy': get_config()['component_policy'], } with open(config_path, 'w') as configfile: config.write(configfile) @@ -191,6 +192,7 @@ def read_config(): 'share_option': default_conf['share_option'] if 'share_option' in default_conf else 'all', 'bypass_ssl': default_conf['bypass_ssl'] if 'bypass_ssl' in default_conf else False, 'default_ui': default_conf['default_ui'] if 'default_ui' in default_conf else 'none', + 'component_policy': default_conf['component_policy'] if 'component_policy' in default_conf else 'workflow', } except Exception: @@ -201,7 +203,8 @@ def read_config(): 'channel_url': 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main', 'share_option': 'all', 'bypass_ssl': False, - 'default_ui': 'none' + 'default_ui': 'none', + 'component_policy': 'workflow' } @@ -249,6 +252,10 @@ def set_default_ui_mode(mode): get_config()['default_ui'] = mode +def set_component_policy(mode): + get_config()['component_policy'] = mode + + def try_install_script(url, repo_path, install_cmd): int_comfyui_revision = 0 @@ -1767,6 +1774,18 @@ async def default_ui_mode(request): return web.Response(status=200) + +@server.PromptServer.instance.routes.get("/manager/component/policy") +async def component_policy(request): + if "value" in request.rel_url.query: + set_component_policy(request.rel_url.query['value']) + write_config() + else: + return web.Response(text=get_config()['component_policy'], status=200) + + return web.Response(status=200) + + @server.PromptServer.instance.routes.get("/manager/channel_url_list") async def channel_url_list(request): channels = get_channel_dict() diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index fe1233da..0dbce9d7 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -16,7 +16,7 @@ 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, install_pip, rebootAPI, free_models } from "./common.js"; -import { ComponentBuilderDialog, load_components } from "./components-manager.js"; +import { ComponentBuilderDialog, load_components, set_component_policy } from "./components-manager.js"; var docStyle = document.createElement('style'); docStyle.innerHTML = ` @@ -721,6 +721,18 @@ class ManagerMenuDialog extends ComfyDialog { } }), + $el("button.cm-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, self); + } + } + }), + $el("br", {}, []), update_all_button, update_comfyui_button, @@ -753,6 +765,7 @@ class ManagerMenuDialog extends ComfyDialog { // db mode this.datasrc_combo = document.createElement("select"); + this.datasrc_combo.setAttribute("title", "Configure where to retrieve node/model information. If set to 'local,' the channel is ignored, and if set to 'channel (remote),' it fetches the latest information each time the list is opened."); this.datasrc_combo.className = "cm-menu-combo"; this.datasrc_combo.appendChild($el('option', { value: 'cache', text: 'DB: Channel (1day cache)' }, [])); this.datasrc_combo.appendChild($el('option', { value: 'local', text: 'DB: Local' }, [])); @@ -760,6 +773,7 @@ class ManagerMenuDialog extends ComfyDialog { // 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"; preview_combo.appendChild($el('option', { value: 'auto', text: 'Preview method: Auto' }, [])); preview_combo.appendChild($el('option', { value: 'taesd', text: 'Preview method: TAESD (slow)' }, [])); @@ -776,6 +790,7 @@ class ManagerMenuDialog extends ComfyDialog { // nickname let badge_combo = document.createElement("select"); + badge_combo.setAttribute("title", "Configure the content to be displayed on the badge at the top right corner of the node. The ID is the identifier of the node. If 'hide built-in' is selected, both unknown nodes and built-in nodes will be omitted, making them indistinguishable"); badge_combo.className = "cm-menu-combo"; badge_combo.appendChild($el('option', { value: 'none', text: 'Badge: None' }, [])); badge_combo.appendChild($el('option', { value: 'nick', text: 'Badge: Nickname' }, [])); @@ -795,6 +810,7 @@ class ManagerMenuDialog extends ComfyDialog { // 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. Note that the badge utilizes local information."); channel_combo.className = "cm-menu-combo"; api.fetchApi('/manager/channel_url_list') .then(response => response.json()) @@ -821,6 +837,7 @@ class ManagerMenuDialog extends ComfyDialog { // default ui state let default_ui_combo = document.createElement("select"); + default_ui_combo.setAttribute("title", "Set the default state to be displayed in the main menu when the browser starts."); default_ui_combo.className = "cm-menu-combo"; default_ui_combo.appendChild($el('option', { value: 'none', text: 'Default UI: None' }, [])); default_ui_combo.appendChild($el('option', { value: 'history', text: 'Default UI: History' }, [])); @@ -836,6 +853,7 @@ class ManagerMenuDialog extends ComfyDialog { // share let share_combo = document.createElement("select"); + share_combo.setAttribute("title", "Hide the share button in the main menu or set the default action upon clicking it. Additionally, configure the default share site when sharing via the context menu's share button."); share_combo.className = "cm-menu-combo"; const share_options = [ ['none', 'None'], @@ -849,6 +867,25 @@ class ManagerMenuDialog extends ComfyDialog { share_combo.appendChild($el('option', { value: option[0], text: `Share: ${option[1]}` }, [])); } + // default ui state + 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"; + component_policy_combo.appendChild($el('option', { value: 'workflow', text: 'Component: Use workflow version' }, [])); + component_policy_combo.appendChild($el('option', { value: 'higher', text: 'Component: Use higher version' }, [])); + component_policy_combo.appendChild($el('option', { value: 'mine', text: 'Component: Use my version' }, [])); + api.fetchApi('/manager/component/policy') + .then(response => response.text()) + .then(data => { + component_policy_combo.value = data; + set_component_policy(data); + }); + + component_policy_combo.addEventListener('change', function (event) { + api.fetchApi(`/manager/component/policy?value=${event.target.value}`); + set_component_policy(event.target.value); + }); + api.fetchApi('/manager/share_option') .then(response => response.text()) .then(data => { @@ -877,18 +914,8 @@ class ManagerMenuDialog extends ComfyDialog { badge_combo, default_ui_combo, share_combo, + component_policy_combo, $el("br", {}, []), - $el("button.cm-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, self); - } - } - }), $el("br", {}, []), $el("filedset.cm-experimental", {}, [ @@ -1220,6 +1247,7 @@ app.registerExtension({ async beforeRegisterNodeDef(nodeType, nodeData, app) { this._addExtraNodeContextMenu(nodeType, app); }, + async nodeCreated(node, app) { if(!node.badge_enabled) { node.getNickname = function () { return getNickname(node, node.comfyClass.trim()) }; @@ -1230,6 +1258,7 @@ app.registerExtension({ node.badge_enabled = true; } }, + async loadedGraphNode(node, app) { if(!node.badge_enabled) { const orig = node.onDrawForeground; @@ -1240,10 +1269,11 @@ app.registerExtension({ _addExtraNodeContextMenu(node, app) { const origGetExtraMenuOptions = node.prototype.getExtraMenuOptions; + node.prototype.cm_menu_added = true; node.prototype.getExtraMenuOptions = function (_, options) { origGetExtraMenuOptions?.apply?.(this, arguments); - if (node.comfyClass.startsWith('workflow/')) { + if (node.category.startsWith('group nodes/')) { options.push({ content: "Save As Component", callback: (obj) => { diff --git a/js/components-manager.js b/js/components-manager.js index 4c7e69af..031196a7 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -7,6 +7,13 @@ import { ComfyDialog, $el } from "../../scripts/ui.js"; let pack_map = {}; let rpack_map = {}; +function getPureName(node) { + // group nodes/ + let category = node.category.substring(12); + let purename = node.comfyClass.substring(category.length+1); + return purename; +} + function isValidVersionString(version) { const versionPattern = /^(\d+)\.(\d+)(\.(\d+))?$/; @@ -21,21 +28,23 @@ function isValidVersionString(version) { function register_pack_map(name, data) { if(data.packname) { pack_map[data.packname] = name; - rpack_map[name] = [data.packname, data.category, data.version, data.datetime]; + rpack_map[name] = data; } else { - rpack_map[name] = [data.packname, data.category, data.version, data.datetime]; + rpack_map[name] = data; } } -function storeGroupNode(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; - register_pack_map(name, data); + if(register) { + register_pack_map(name, data); + } } export async function load_components() { @@ -179,7 +188,7 @@ async function save_as_component(node, version, prefix, nodename, packname, cate let subgraph = app.graph.extra?.groupNodes?.[component_name]; if(!subgraph) { - subgraph = app.graph.extra?.groupNodes?.[node.comfyClass.substring(9)]; + subgraph = app.graph.extra?.groupNodes?.[getPureName(node)]; } subgraph.version = version; @@ -194,7 +203,7 @@ async function save_as_component(node, version, prefix, nodename, packname, cate }; pack_map[packname] = component_name; - rpack_map[component_name] = [body.pack_name, body.category, body.version, body.datetime]; + rpack_map[component_name] = subgraph; const res = await api.fetchApi('/manager/component/save', { method: "POST", @@ -253,6 +262,15 @@ async function import_component(component_name, component, mode) { 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; @@ -306,7 +324,7 @@ function versionCompare(v1, v2) { function checkVersion(name, component) { let msg = ''; if(rpack_map[name]) { - let old_version = rpack_map[name][2]; + let old_version = rpack_map[name].version; if(!old_version || old_version == '') { msg = ` '${name}' Upgrade (V0.0 -> V${component.version})`; } @@ -439,27 +457,21 @@ export class ComponentBuilderDialog extends ComfyDialog { } }); - let default_nodename = this.target_node.comfyClass.substring(9).trim(); + let default_nodename = getPureName(this.target_node).trim(); + + let groupNode = app.graph.extra.groupNodes[default_nodename]; + let default_packname = groupNode.packname; - let default_packname = ""; - if(rpack_map[default_nodename]) { - default_packname = rpack_map[default_nodename][0]; - } if(!default_packname) { default_packname = ''; } - let default_category = ""; - if(rpack_map[default_nodename]) { - default_category = rpack_map[default_nodename][1]; - } + let default_category = groupNode.category; if(!default_category) { default_category = ''; } - if(rpack_map[default_nodename]) { - this.default_ver = rpack_map[default_nodename][2]; - } + this.default_ver = groupNode.version; if(!this.default_ver) { this.default_ver = '0.0'; } @@ -566,7 +578,7 @@ export class ComponentBuilderDialog extends ComfyDialog { return this.manual_nodename.value.trim(); } - return this.target_node.comfyClass.substring(9); + return getPureName(this.target_node); } createAuthorModeCheck() { @@ -595,9 +607,9 @@ export class ComponentBuilderDialog extends ComfyDialog { let label = $el('p'); label.className = 'cb-node-label'; if(this.target_node.comfyClass.includes('::')) - label.textContent = this.target_node.comfyClass.substring(9); + label.textContent = getPureName(this.target_node); else - label.textContent = " _::" + this.target_node.comfyClass.substring(9); + label.textContent = " _::" + getPureName(this.target_node); return label; } @@ -668,3 +680,71 @@ function handleFile(file) { } app.handleFile = handleFile; + +let current_component_policy = 'workflow'; +try { + api.fetchApi('/manager/component/policy') + .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 () { + const v = await loadGraphData.apply(this, arguments); + + if(arguments.length == 0) + return v; + + let groupNodes = arguments[0].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]; + restore_to_loaded_component(component_name); + } + } + } + else { + console.log('Empty components: policy ignored'); + } + + return v; +}; + +export function set_component_policy(v) { + current_component_policy = v; +} \ No newline at end of file From db081659fe9b37cc7aa33c7b676766a470a89000 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Wed, 17 Jan 2024 12:53:37 +0900 Subject: [PATCH 20/35] update DB --- custom-node-list.json | 31 +++++++++++++++++++---------- extension-node-map.json | 16 ++++++++++++++- node_db/new/custom-node-list.json | 20 +++++++++++++++++++ node_db/new/extension-node-map.json | 16 ++++++++++++++- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index 357efa8e..521ac52f 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4284,6 +4284,27 @@ "install_type": "git-clone", "description": "python and web UX improvements for ComfyUI.\n[w/'DynamicPrompts.js' and 'EditAttention.js' from the core, along with 'ImageFeed.js' and 'favicon.js' from the custom scripts of pythongosssss, are not compatible. Therefore, manual deletion of these files is required to use this web extension.]" }, + { + "author": "prozacgod", + "title": "ComfyUI Multi-Workspace", + "reference": "https://github.com/prozacgod/comfyui-pzc-multiworkspace", + "files": [ + "https://github.com/prozacgod/comfyui-pzc-multiworkspace" + ], + "install_type": "git-clone", + "description": "A simple, quick, and dirty implementation of multiple workspaces within ComfyUI." + }, + { + "author": "Siberpone", + "title": "Lazy Pony Prompter", + "reference": "https://github.com/Siberpone/lazy-pony-prompter", + "files": [ + "https://github.com/Siberpone/lazy-pony-prompter" + ], + "install_type": "git-clone", + "description": "A pony prompt helper extension for AUTOMATIC1111's Stable Diffusion Web UI and ComfyUI that utilizes the full power of your favorite booru query syntax. Currently supports [a/Derpibooru](https://derpibooru/org) and [a/E621](https://e621.net/)." + }, + @@ -4603,16 +4624,6 @@ ], "install_type": "unzip", "description": "This is a node to convert an image into a CMYK Halftone dot image." - }, - { - "author": "prozacgod", - "title": "ComfyUI Multi-Workspace", - "reference": "https://github.com/prozacgod/comfyui-pzc-multiworkspace", - "files": [ - "https://github.com/prozacgod/comfyui-pzc-multiworkspace" - ], - "install_type": "git-clone", - "description": "A simple, quick, and dirty implementation of multiple workspaces within ComfyUI." } ] } diff --git a/extension-node-map.json b/extension-node-map.json index 8714c4dc..f66ed7a3 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -1119,6 +1119,7 @@ "VHS_MergeImages", "VHS_MergeLatents", "VHS_MergeMasks", + "VHS_PruneOutputs", "VHS_SelectEveryNthImage", "VHS_SelectEveryNthLatent", "VHS_SelectEveryNthMask", @@ -1794,6 +1795,19 @@ "title_aux": "SDXL_sizing" } ], + "https://github.com/Siberpone/lazy-pony-prompter": [ + [ + "LPP_Deleter", + "LPP_Derpibooru", + "LPP_E621", + "LPP_Loader_Derpibooru", + "LPP_Loader_E621", + "LPP_Saver" + ], + { + "title_aux": "Lazy Pony Prompter" + } + ], "https://github.com/Smuzzies/comfyui_chatbox_overlay/raw/main/chatbox_overlay.py": [ [ "Chatbox Overlay" @@ -2813,7 +2827,7 @@ "Aegisflow SDXL Tuple Pass", "Aegisflow VAE Pass", "Aegisflow controlnet preprocessor bus", - "Brightness & Contrast_Ally", + "Brightness_Contrast_Ally", "Gaussian Blur_Ally", "Image Flip_ally", "Placeholder Tuple", diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 32be8b2f..4db09793 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,26 @@ }, + { + "author": "prozacgod", + "title": "ComfyUI Multi-Workspace", + "reference": "https://github.com/prozacgod/comfyui-pzc-multiworkspace", + "files": [ + "https://github.com/prozacgod/comfyui-pzc-multiworkspace" + ], + "install_type": "git-clone", + "description": "A simple, quick, and dirty implementation of multiple workspaces within ComfyUI." + }, + { + "author": "Siberpone", + "title": "Lazy Pony Prompter", + "reference": "https://github.com/Siberpone/lazy-pony-prompter", + "files": [ + "https://github.com/Siberpone/lazy-pony-prompter" + ], + "install_type": "git-clone", + "description": "A pony prompt helper extension for AUTOMATIC1111's Stable Diffusion Web UI and ComfyUI that utilizes the full power of your favorite booru query syntax. Currently supports [a/Derpibooru](https://derpibooru/org) and [a/E621](https://e621.net/)." + }, { "author": "chaojie", "title": "ComfyUI-MotionCtrl-SVD", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 8714c4dc..f66ed7a3 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -1119,6 +1119,7 @@ "VHS_MergeImages", "VHS_MergeLatents", "VHS_MergeMasks", + "VHS_PruneOutputs", "VHS_SelectEveryNthImage", "VHS_SelectEveryNthLatent", "VHS_SelectEveryNthMask", @@ -1794,6 +1795,19 @@ "title_aux": "SDXL_sizing" } ], + "https://github.com/Siberpone/lazy-pony-prompter": [ + [ + "LPP_Deleter", + "LPP_Derpibooru", + "LPP_E621", + "LPP_Loader_Derpibooru", + "LPP_Loader_E621", + "LPP_Saver" + ], + { + "title_aux": "Lazy Pony Prompter" + } + ], "https://github.com/Smuzzies/comfyui_chatbox_overlay/raw/main/chatbox_overlay.py": [ [ "Chatbox Overlay" @@ -2813,7 +2827,7 @@ "Aegisflow SDXL Tuple Pass", "Aegisflow VAE Pass", "Aegisflow controlnet preprocessor bus", - "Brightness & Contrast_Ally", + "Brightness_Contrast_Ally", "Gaussian Blur_Ally", "Image Flip_ally", "Placeholder Tuple", From e530f657e7510ef936e8fd13a83ec508784802e3 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Wed, 17 Jan 2024 13:48:25 +0900 Subject: [PATCH 21/35] unused group nodes filtering --- __init__.py | 2 +- js/components-manager.js | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/__init__.py b/__init__.py index e4bf8a17..d3b0751f 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [2, 2] +version = [2, 2, 1] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") diff --git a/js/components-manager.js b/js/components-manager.js index 031196a7..17cc9394 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -747,4 +747,37 @@ app.loadGraphData = async function () { export function set_component_policy(v) { current_component_policy = v; -} \ No newline at end of file +} + +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/')) { + 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; +} From 8ea2a744c2caad3860067f7a19134c517efaf492 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Wed, 17 Jan 2024 14:47:24 +0900 Subject: [PATCH 22/35] update DB --- extension-node-map.json | 1 + node_db/new/extension-node-map.json | 1 + 2 files changed, 2 insertions(+) diff --git a/extension-node-map.json b/extension-node-map.json index f66ed7a3..dce239d4 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -123,6 +123,7 @@ "FrameToVideo-badger", "GetDirName-badger", "GetUUID-badger", + "IdentifyLinesBasedOnBorderColor-badger", "ImageNormalization-badger", "ImageOverlap-badger", "ImageScaleToSide-badger", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index f66ed7a3..dce239d4 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -123,6 +123,7 @@ "FrameToVideo-badger", "GetDirName-badger", "GetUUID-badger", + "IdentifyLinesBasedOnBorderColor-badger", "ImageNormalization-badger", "ImageOverlap-badger", "ImageScaleToSide-badger", From b2fc36c5477f2f94263f4d2500bf96647b24644e Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Wed, 17 Jan 2024 16:21:03 +0900 Subject: [PATCH 23/35] update README.md --- README.md | 59 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 9e452e69..5fcfa2d0 100644 --- a/README.md +++ b/README.md @@ -208,38 +208,41 @@ NODE_CLASS_MAPPINGS.update({ * **All scripts are executed from the root path of the corresponding custom node.** -## Component Paste -* When pasting a component from the clipboard, it supports text in the following JSON format. (text/plain) -``` -{ - "kind": "ComfyUI Components", - "timestamp": , - "components": +## Component Sharing +* **Copy & Paste** + * [Demo Page](https://ltdrdata.github.io/component-demo/) + * When pasting a component from the clipboard, it supports text in the following JSON format. (text/plain) + ``` { - : + "kind": "ComfyUI Components", + "timestamp": , + "components": + { + : + } } -} -``` -* `` Ensure that the timestamp is always unique. -* "components" should have the same structure as the content of the file stored in ComfyUI-Manager/components. - * ``: The name should be in the format `::`. - * ``: In the nodedata of the group node. - * ``: Only two formats are allowed: `major.minor.patch` or `major.minor`. (e.g. `1.0`, `2.2.1`) - * ``: Saved time - * ``: If the packname is not empty, the category becomes packname/workflow, and it is saved in the .pack file in ComfyUI-Manager/components. - * ``: If there is neither a category nor a packname, it is saved in the components category. - ``` - "version":"1.0", - "datetime": 1705390656516, - "packname": "mypack", - "category": "util/pipe", - ``` - -* Drag & Drop support + ``` + * `` Ensure that the timestamp is always unique. + * "components" should have the same structure as the content of the file stored in ComfyUI-Manager/components. + * ``: The name should be in the format `::`. + * ``: In the nodedata of the group node. + * ``: Only two formats are allowed: `major.minor.patch` or `major.minor`. (e.g. `1.0`, `2.2.1`) + * ``: Saved time + * ``: If the packname is not empty, the category becomes packname/workflow, and it is saved in the .pack file in ComfyUI-Manager/components. + * ``: If there is neither a category nor a packname, it is saved in the components category. + ``` + "version":"1.0", + "datetime": 1705390656516, + "packname": "mypack", + "category": "util/pipe", + ``` +* **Drag & Drop** * Dragging and dropping a `.pack` or `.json` file will add the corresponding components. * Example pack: [Impact.pack](misc/Impact.pack) + * Dragging and dropping or pasting a single component will add a node. However, when adding multiple components, nodes will not be added. + ## Support of missing nodes installation ![missing-menu](misc/missing-menu.png) @@ -272,11 +275,11 @@ NODE_CLASS_MAPPINGS.update({ - [x] System displaying information about failed custom nodes import. - [x] Guide for missing nodes in ComfyUI vanilla nodes. - [x] Collision checking system for nodes with the same ID across extensions. +- [x] Template sharing system. (-> Component system based on Group Nodes) +- [x] 3rd party API system. - [ ] Auto migration for custom nodes with changed structures. - [ ] Version control feature for nodes. - [ ] List of currently used custom nodes. -- [ ] Template sharing system. -- [ ] 3rd party API system. - [ ] Download support multiple model download. - [ ] Model download via url. - [ ] List sorting. From c80ca12abd60620714690ed0513c6dcb19bd773b Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Wed, 17 Jan 2024 16:21:49 +0900 Subject: [PATCH 24/35] update DB --- extension-node-map.json | 1 + node_db/new/extension-node-map.json | 1 + 2 files changed, 2 insertions(+) diff --git a/extension-node-map.json b/extension-node-map.json index dce239d4..743812fa 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -4625,6 +4625,7 @@ "KSampler Adv. (Efficient)", "KSampler SDXL (Eff.)", "LatentUpscaler", + "LoRA Stack to String converter", "LoRA Stacker", "Manual XY Entry Info", "NNLatentUpscale", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index dce239d4..743812fa 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -4625,6 +4625,7 @@ "KSampler Adv. (Efficient)", "KSampler SDXL (Eff.)", "LatentUpscaler", + "LoRA Stack to String converter", "LoRA Stacker", "Manual XY Entry Info", "NNLatentUpscale", From d84301148af45da52cdc1b88abd00ccfb368d7cf Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 17 Jan 2024 22:39:14 +0900 Subject: [PATCH 25/35] update DB --- custom-node-list.json | 20 ++++++++++++++++++++ extension-node-map.json | 23 +++++++++++++++++++++++ node_db/dev/extension-node-map.json | 17 +++++++++++++++++ node_db/new/custom-node-list.json | 20 ++++++++++++++++++++ node_db/new/extension-node-map.json | 23 +++++++++++++++++++++++ 5 files changed, 103 insertions(+) diff --git a/custom-node-list.json b/custom-node-list.json index 521ac52f..c954ed14 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4304,6 +4304,26 @@ "install_type": "git-clone", "description": "A pony prompt helper extension for AUTOMATIC1111's Stable Diffusion Web UI and ComfyUI that utilizes the full power of your favorite booru query syntax. Currently supports [a/Derpibooru](https://derpibooru/org) and [a/E621](https://e621.net/)." }, + { + "author": "kijai", + "title": "ComfyUI-DDColor", + "reference": "https://github.com/kijai/ComfyUI-DDColor", + "files": [ + "https://github.com/kijai/ComfyUI-DDColor" + ], + "install_type": "git-clone", + "description": "Node to use [a/DDColor](https://github.com/piddnad/DDColor) in ComfyUI." + }, + { + "author": "chflame163", + "title": "ComfyUI Layer Style", + "reference": "https://github.com/chflame163/ComfyUI_LayerStyle", + "files": [ + "https://github.com/chflame163/ComfyUI_LayerStyle" + ], + "install_type": "git-clone", + "description": "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress." + }, diff --git a/extension-node-map.json b/extension-node-map.json index 743812fa..5f4a77f0 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -1616,7 +1616,11 @@ "ImageListSelect(FaceParsing)", "ImagePadWithBBox(FaceParsing)", "ImageResizeCalculator(FaceParsing)", + "ImageResizeWithBBox(FaceParsing)", "ImageSize(FaceParsing)", + "LatentCropWithBBox(FaceParsing)", + "LatentInsertWithBBox(FaceParsing)", + "LatentSize(FaceParsing)", "MaskComposite(FaceParsing)", "MaskListComposite(FaceParsing)", "MaskListSelect(FaceParsing)", @@ -2026,6 +2030,7 @@ "CR Split String", "CR Starburst Colors", "CR Starburst Lines", + "CR String To Boolean", "CR String To Combo", "CR String To Number", "CR Style Bars", @@ -3505,6 +3510,14 @@ "title_aux": "ComfyUI-MotionCtrl-SVD" } ], + "https://github.com/chflame163/ComfyUI_LayerStyle": [ + [ + "LayerStyle_DropShadow" + ], + { + "title_aux": "ComfyUI Layer Style" + } + ], "https://github.com/chflame163/ComfyUI_MSSpeech_TTS": [ [ "Input Trigger", @@ -4754,6 +4767,14 @@ "title_aux": "Knodes" } ], + "https://github.com/kijai/ComfyUI-DDColor": [ + [ + "DDColor_Colorize" + ], + { + "title_aux": "ComfyUI-DDColor" + } + ], "https://github.com/kijai/ComfyUI-KJNodes": [ [ "AddLabel", @@ -4990,6 +5011,7 @@ "Base64ToMask", "ImageToBase64", "ImageToBase64Advanced", + "LoadImageFromUrl", "LoadImageToBase64", "MaskImageToBase64", "MaskToBase64", @@ -5260,6 +5282,7 @@ "RegionalSeedExplorerMask //Inspire", "RemoveBackendData //Inspire", "RemoveBackendDataNumberKey //Inspire", + "RemoveControlNet //Inspire", "RetrieveBackendData //Inspire", "RetrieveBackendDataNumberKey //Inspire", "SeedExplorer //Inspire", diff --git a/node_db/dev/extension-node-map.json b/node_db/dev/extension-node-map.json index 6a420de5..a0983ca0 100644 --- a/node_db/dev/extension-node-map.json +++ b/node_db/dev/extension-node-map.json @@ -122,6 +122,15 @@ "title_aux": "ComfyUI-AnyText\uff08WIP\uff09" } ], + "https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker": [ + [ + "PhotoMaker_Batch_Zho", + "PhotoMaker_Zho" + ], + { + "title_aux": "ComfyUI PhotoMaker (WIP)" + } + ], "https://github.com/alt-key-project/comfyui-dream-video-batches": [ [ "Blended Transition [DVB]", @@ -632,6 +641,14 @@ "title_aux": "comfy-trt-test [WIP]" } ], + "https://github.com/poisenbery/NudeNet-Detector-Provider": [ + [ + "NudeNetDetectorProvider" + ], + { + "title_aux": "NudeNet-Detector-Provider [WIP]" + } + ], "https://github.com/solarpush/comfyui_sendimage_node": [ [ "Send_To_Pod" diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 4db09793..8e6fa89d 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,26 @@ }, + { + "author": "chflame163", + "title": "ComfyUI Layer Style", + "reference": "https://github.com/chflame163/ComfyUI_LayerStyle", + "files": [ + "https://github.com/chflame163/ComfyUI_LayerStyle" + ], + "install_type": "git-clone", + "description": "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress." + }, + { + "author": "kijai", + "title": "ComfyUI-DDColor", + "reference": "https://github.com/kijai/ComfyUI-DDColor", + "files": [ + "https://github.com/kijai/ComfyUI-DDColor" + ], + "install_type": "git-clone", + "description": "Node to use [a/DDColor](https://github.com/piddnad/DDColor) in ComfyUI." + }, { "author": "prozacgod", "title": "ComfyUI Multi-Workspace", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 743812fa..5f4a77f0 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -1616,7 +1616,11 @@ "ImageListSelect(FaceParsing)", "ImagePadWithBBox(FaceParsing)", "ImageResizeCalculator(FaceParsing)", + "ImageResizeWithBBox(FaceParsing)", "ImageSize(FaceParsing)", + "LatentCropWithBBox(FaceParsing)", + "LatentInsertWithBBox(FaceParsing)", + "LatentSize(FaceParsing)", "MaskComposite(FaceParsing)", "MaskListComposite(FaceParsing)", "MaskListSelect(FaceParsing)", @@ -2026,6 +2030,7 @@ "CR Split String", "CR Starburst Colors", "CR Starburst Lines", + "CR String To Boolean", "CR String To Combo", "CR String To Number", "CR Style Bars", @@ -3505,6 +3510,14 @@ "title_aux": "ComfyUI-MotionCtrl-SVD" } ], + "https://github.com/chflame163/ComfyUI_LayerStyle": [ + [ + "LayerStyle_DropShadow" + ], + { + "title_aux": "ComfyUI Layer Style" + } + ], "https://github.com/chflame163/ComfyUI_MSSpeech_TTS": [ [ "Input Trigger", @@ -4754,6 +4767,14 @@ "title_aux": "Knodes" } ], + "https://github.com/kijai/ComfyUI-DDColor": [ + [ + "DDColor_Colorize" + ], + { + "title_aux": "ComfyUI-DDColor" + } + ], "https://github.com/kijai/ComfyUI-KJNodes": [ [ "AddLabel", @@ -4990,6 +5011,7 @@ "Base64ToMask", "ImageToBase64", "ImageToBase64Advanced", + "LoadImageFromUrl", "LoadImageToBase64", "MaskImageToBase64", "MaskToBase64", @@ -5260,6 +5282,7 @@ "RegionalSeedExplorerMask //Inspire", "RemoveBackendData //Inspire", "RemoveBackendDataNumberKey //Inspire", + "RemoveControlNet //Inspire", "RetrieveBackendData //Inspire", "RetrieveBackendDataNumberKey //Inspire", "SeedExplorer //Inspire", From 491ad891bc8437431e8b437eb03d4e7304ab6986 Mon Sep 17 00:00:00 2001 From: chaojie Date: Thu, 18 Jan 2024 00:06:36 +0800 Subject: [PATCH 26/35] add Moore-AnimateAnyone --- custom-node-list.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/custom-node-list.json b/custom-node-list.json index c954ed14..dfdf62ce 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4074,6 +4074,16 @@ "install_type": "git-clone", "description": "Nodes: Download the weights of DragNUWA [a/drag_nuwa_svd.pth](https://drive.google.com/file/d/1Z4JOley0SJCb35kFF4PCc6N6P1ftfX4i/view) and put it to ComfyUI/models/checkpoints/drag_nuwa_svd.pth" }, + { + "author": "chaojie", + "title": "ComfyUI-Moore-AnimateAnyone", + "reference": "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone", + "files": [ + "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone" + ], + "install_type": "git-clone", + "description": "Nodes: Run python tools/download_weights.py first to download weights automatically" + }, { "author": "alexopus", "title": "ComfyUI Image Saver", From 29cb390f7bfffb2821cd6eb9db92eb722ca5198d Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Thu, 18 Jan 2024 10:39:16 +0900 Subject: [PATCH 27/35] update DB --- extension-node-map.json | 33 ++++++++++++++++++++++++++++- node_db/new/custom-node-list.json | 10 +++++++++ node_db/new/extension-node-map.json | 33 ++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/extension-node-map.json b/extension-node-map.json index 5f4a77f0..90c80545 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -269,6 +269,7 @@ [ "ComfyUIDeployExternalImage", "ComfyUIDeployExternalImageAlpha", + "ComfyUIDeployExternalLora", "ComfyUIDeployExternalNumber", "ComfyUIDeployExternalNumberInt", "ComfyUIDeployExternalText" @@ -3486,6 +3487,20 @@ "title_aux": "ComfyUI-DragNUWA" } ], + "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone": [ + [ + "Moore-AnimateAnyone Denoising Unet", + "Moore-AnimateAnyone Image Encoder", + "Moore-AnimateAnyone Pipeline Loader", + "Moore-AnimateAnyone Pose Guider", + "Moore-AnimateAnyone Reference Unet", + "Moore-AnimateAnyone Simple", + "Moore-AnimateAnyone VAE" + ], + { + "title_aux": "ComfyUI-Moore-AnimateAnyone" + } + ], "https://github.com/chaojie/ComfyUI-MotionCtrl": [ [ "Load Motion Camera Preset", @@ -3745,6 +3760,7 @@ "ImageCrop", "ImageInvert", "ImageOnlyCheckpointLoader", + "ImageOnlyCheckpointSave", "ImagePadForOutpaint", "ImageQuantize", "ImageScale", @@ -3953,7 +3969,20 @@ "https://github.com/daniel-lewis-ab/ComfyUI-Llama": [ [ "Call LLM", - "Load LLM Model" + "LLM_Create_Embedding", + "LLM_Detokenize", + "LLM_Embed", + "LLM_Eval", + "LLM_Generate", + "LLM_Load_State", + "LLM_Reset", + "LLM_Sample", + "LLM_Save_State", + "LLM_Token_BOS", + "LLM_Token_EOS", + "LLM_Tokenize", + "Load LLM Model", + "Load LLM Model Advanced" ], { "title_aux": "ComfyUI-Llama" @@ -4931,6 +4960,8 @@ "https://github.com/komojini/komojini-comfyui-nodes": [ [ "ImageMerger", + "KSamplerAdvancedCacheable", + "KSamplerCacheable", "UltimateVideoLoader", "UltimateVideoLoader (simple)", "YouTubeVideoLoader" diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 8e6fa89d..d7e9871e 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,16 @@ }, + { + "author": "chaojie", + "title": "ComfyUI-Moore-AnimateAnyone", + "reference": "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone", + "files": [ + "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone" + ], + "install_type": "git-clone", + "description": "Nodes: Run python tools/download_weights.py first to download weights automatically" + }, { "author": "chflame163", "title": "ComfyUI Layer Style", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 5f4a77f0..90c80545 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -269,6 +269,7 @@ [ "ComfyUIDeployExternalImage", "ComfyUIDeployExternalImageAlpha", + "ComfyUIDeployExternalLora", "ComfyUIDeployExternalNumber", "ComfyUIDeployExternalNumberInt", "ComfyUIDeployExternalText" @@ -3486,6 +3487,20 @@ "title_aux": "ComfyUI-DragNUWA" } ], + "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone": [ + [ + "Moore-AnimateAnyone Denoising Unet", + "Moore-AnimateAnyone Image Encoder", + "Moore-AnimateAnyone Pipeline Loader", + "Moore-AnimateAnyone Pose Guider", + "Moore-AnimateAnyone Reference Unet", + "Moore-AnimateAnyone Simple", + "Moore-AnimateAnyone VAE" + ], + { + "title_aux": "ComfyUI-Moore-AnimateAnyone" + } + ], "https://github.com/chaojie/ComfyUI-MotionCtrl": [ [ "Load Motion Camera Preset", @@ -3745,6 +3760,7 @@ "ImageCrop", "ImageInvert", "ImageOnlyCheckpointLoader", + "ImageOnlyCheckpointSave", "ImagePadForOutpaint", "ImageQuantize", "ImageScale", @@ -3953,7 +3969,20 @@ "https://github.com/daniel-lewis-ab/ComfyUI-Llama": [ [ "Call LLM", - "Load LLM Model" + "LLM_Create_Embedding", + "LLM_Detokenize", + "LLM_Embed", + "LLM_Eval", + "LLM_Generate", + "LLM_Load_State", + "LLM_Reset", + "LLM_Sample", + "LLM_Save_State", + "LLM_Token_BOS", + "LLM_Token_EOS", + "LLM_Tokenize", + "Load LLM Model", + "Load LLM Model Advanced" ], { "title_aux": "ComfyUI-Llama" @@ -4931,6 +4960,8 @@ "https://github.com/komojini/komojini-comfyui-nodes": [ [ "ImageMerger", + "KSamplerAdvancedCacheable", + "KSamplerCacheable", "UltimateVideoLoader", "UltimateVideoLoader (simple)", "YouTubeVideoLoader" From a7f4ce15822eb29346c8bb733078161bcad864e5 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Thu, 18 Jan 2024 11:39:45 +0900 Subject: [PATCH 28/35] windows async fix https://github.com/ltdrdata/ComfyUI-Manager/issues/339 --- prestartup_script.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/prestartup_script.py b/prestartup_script.py index 0328849a..35157d58 100644 --- a/prestartup_script.py +++ b/prestartup_script.py @@ -456,3 +456,12 @@ if os.path.exists(script_list_path): del processed_install del pip_list + +if platform.system() == 'Windows': + try: + import asyncio + import asyncio.windows_events + asyncio.set_event_loop_policy(asyncio.windows_events.WindowsSelectorEventLoopPolicy()) + print(f"[ComfyUI-Manager] Windows event loop policy mode enabled") + except Exception as e: + print(f"[ComfyUI-Manager] WARN: Windows initialization fail: {e}") \ No newline at end of file From ae743efd0c1d9ef9240f352244f83d3341d69ea8 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Thu, 18 Jan 2024 17:05:37 +0900 Subject: [PATCH 29/35] fix: component loading --- __init__.py | 2 +- js/comfyui-manager.js | 11 +++++++- js/components-manager.js | 58 ++++++++++++++++++++++++++-------------- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/__init__.py b/__init__.py index d3b0751f..00b460f4 100644 --- a/__init__.py +++ b/__init__.py @@ -28,7 +28,7 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [2, 2, 1] +version = [2, 2, 2] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js index 0dbce9d7..d059fb14 100644 --- a/js/comfyui-manager.js +++ b/js/comfyui-manager.js @@ -16,7 +16,7 @@ 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, install_pip, rebootAPI, free_models } from "./common.js"; -import { ComponentBuilderDialog, load_components, set_component_policy } from "./components-manager.js"; +import { ComponentBuilderDialog, load_components, set_component_policy, getPureName } from "./components-manager.js"; var docStyle = document.createElement('style'); docStyle.innerHTML = ` @@ -407,6 +407,15 @@ function getNickname(node, nodename) { if (nicknames[nodename]) { node.nickname = nicknames[nodename]; } + else if(node.getInnerNodes) { + let pure_name = getPureName(node); + let groupNode = app.graph.extra?.groupNodes?.[pure_name]; + if(groupNode) { + let packname = groupNode.packname; + node.nickname = packname; + } + return node.nickname; + } else { for(let i in nickname_patterns) { let item = nickname_patterns[i]; diff --git a/js/components-manager.js b/js/components-manager.js index 17cc9394..e5026711 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -7,11 +7,25 @@ import { ComfyDialog, $el } from "../../scripts/ui.js"; let pack_map = {}; let rpack_map = {}; -function getPureName(node) { +export function getPureName(node) { // group nodes/ - let category = node.category.substring(12); - let purename = node.comfyClass.substring(category.length+1); - return purename; + 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/')) { + return node.comfyClass.substring(9); + } + else { + return node.comfyClass; + } } function isValidVersionString(version) { @@ -72,6 +86,7 @@ export async function load_components() { await config.registerType(category); register_pack_map(name, data); + break; } continue; } @@ -81,8 +96,8 @@ export async function load_components() { storeGroupNode(name, nodeData); const config = new GroupNodeConfig(name, nodeData); - while(!success) { - var success = false; + + while(true) { try { let category = nodeData.packname; if(nodeData.category) { @@ -94,12 +109,13 @@ export async function load_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); - success = true; + break; } else { await sleep(100); } @@ -120,8 +136,7 @@ export async function load_components() { storeGroupNode(name, nodeData); const config = new GroupNodeConfig(name, nodeData); - while(!success) { - var success = false; + while(true) { try { let category = nodeData.packname; if(nodeData.workflow.category) { @@ -133,12 +148,13 @@ export async function load_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); - success = true; + break; } else { await sleep(100); } @@ -155,9 +171,7 @@ export async function load_components() { storeGroupNode(name, nodeData); const config = new GroupNodeConfig(name, nodeData); - while(!success) { - var success = false; - + while(true) { try { let category = nodeData.workflow.packname; if(nodeData.workflow.category) { @@ -169,12 +183,13 @@ export async function load_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); - success = true; + break; } else { await sleep(100); } @@ -708,12 +723,11 @@ function getChangedVersion(groupNodes) { const loadGraphData = app.loadGraphData; app.loadGraphData = async function () { - const v = await loadGraphData.apply(this, arguments); - if(arguments.length == 0) - return v; + return await loadGraphData.apply(this, arguments); - let groupNodes = arguments[0].extra?.groupNodes; + let graphData = arguments[0]; + let groupNodes = graphData.extra?.groupNodes; let res = getChangedVersion(groupNodes); if(res) { @@ -734,7 +748,10 @@ app.loadGraphData = async function () { if(target_components) { for(let i in target_components) { let component_name = target_components[i]; - restore_to_loaded_component(component_name); + let component = rpack_map[component_name]; + if(component && graphData.extra?.groupNodes) { + graphData.extra.groupNodes[component_name] = component; + } } } } @@ -742,7 +759,8 @@ app.loadGraphData = async function () { console.log('Empty components: policy ignored'); } - return v; + arguments[0] = graphData; + return await loadGraphData.apply(this, arguments); }; export function set_component_policy(v) { From 8d7a3aa1b3b9a4f306ff43187bde9c335d236c11 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Thu, 18 Jan 2024 17:07:09 +0900 Subject: [PATCH 30/35] fix: required ComfyUI revision --- __init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/__init__.py b/__init__.py index 00b460f4..544a30e0 100644 --- a/__init__.py +++ b/__init__.py @@ -28,12 +28,11 @@ except: print(f"[WARN] ComfyUI-Manager: Your ComfyUI version is outdated. Please update to the latest version.") -version = [2, 2, 2] +version = [2, 2, 3] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') print(f"### Loading: ComfyUI-Manager ({version_str})") -required_comfyui_revision = 1793 comfy_ui_hash = "-" cache_lock = threading.Lock() From 146e0480c0922e7e6d0fdfd252db29d53d43f5e2 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Thu, 18 Jan 2024 17:25:51 +0900 Subject: [PATCH 31/35] update DB --- custom-node-list.json | 10 +++ extension-node-map.json | 16 +++- node_db/dev/custom-node-list.json | 4 +- node_db/new/custom-node-list.json | 120 +++------------------------- node_db/new/extension-node-map.json | 16 +++- 5 files changed, 52 insertions(+), 114 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index dfdf62ce..de533fa3 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4334,6 +4334,16 @@ "install_type": "git-clone", "description": "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress." }, + { + "author": "dave-palt", + "title": "comfyui_DSP_imagehelpers", + "reference": "https://github.com/dave-palt/comfyui_DSP_imagehelpers", + "files": [ + "https://github.com/dave-palt/comfyui_DSP_imagehelpers" + ], + "install_type": "git-clone", + "description": "Nodes: DSP Image Concat" + }, diff --git a/extension-node-map.json b/extension-node-map.json index 90c80545..032c0149 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -121,6 +121,7 @@ "FloatToInt-badger", "FloatToString-badger", "FrameToVideo-badger", + "GarbageCollect-badger", "GetDirName-badger", "GetUUID-badger", "IdentifyLinesBasedOnBorderColor-badger", @@ -1528,10 +1529,13 @@ "Cached Image Load From URL", "Crop Center wigh SEGS", "Crop Center with SEGS", + "Dilate Mask for Each Face", "GW Number Formatting", "Image Crop Fit", "Image Resize Fit", "OFF SEGS to Image", + "Query Gender and Age", + "Safe Mask to Image", "VAE Encode For Inpaint V2", "Watermarking" ], @@ -3988,6 +3992,14 @@ "title_aux": "ComfyUI-Llama" } ], + "https://github.com/dave-palt/comfyui_DSP_imagehelpers": [ + [ + "dsp-imagehelpers-concat" + ], + { + "title_aux": "comfyui_DSP_imagehelpers" + } + ], "https://github.com/dawangraoming/ComfyUI_ksampler_gpu/raw/main/ksampler_gpu.py": [ [ "KSamplerAdvancedGPU", @@ -5042,8 +5054,9 @@ "Base64ToMask", "ImageToBase64", "ImageToBase64Advanced", - "LoadImageFromUrl", + "LoadImageFromURL", "LoadImageToBase64", + "LoadMaskFromURL", "MaskImageToBase64", "MaskToBase64", "MaskToBase64Image", @@ -6009,6 +6022,7 @@ "ImageColorTransfer", "ImageCropByAlpha", "IntNumber", + "JoinWithDelimiter", "LaMaInpainting", "LimitNumber", "LoadImagesFromPath", diff --git a/node_db/dev/custom-node-list.json b/node_db/dev/custom-node-list.json index 07951860..5a6578cf 100644 --- a/node_db/dev/custom-node-list.json +++ b/node_db/dev/custom-node-list.json @@ -43,9 +43,9 @@ { "author": "AIGODLIKE", "title": "AIGODLIKE/ComfyUI-Model-Manager [WIP]", - "reference": "https://github.com/AIGODLIKE/ComfyUI-Model-Manager", + "reference": "https://github.com/AIGODLIKE/ComfyUI-Studio", "files": [ - "https://github.com/AIGODLIKE/ComfyUI-Model-Manager" + "https://github.com/AIGODLIKE/ComfyUI-Studio" ], "install_type": "git-clone", "description": "WIP" diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index d7e9871e..08397bc4 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -10,6 +10,16 @@ }, + { + "author": "dave-palt", + "title": "comfyui_DSP_imagehelpers", + "reference": "https://github.com/dave-palt/comfyui_DSP_imagehelpers", + "files": [ + "https://github.com/dave-palt/comfyui_DSP_imagehelpers" + ], + "install_type": "git-clone", + "description": "Nodes: DSP Image Concat" + }, { "author": "chaojie", "title": "ComfyUI-Moore-AnimateAnyone", @@ -683,116 +693,6 @@ ], "install_type": "git-clone", "description": "The easiest way to run & share any ComfyUI workflow [a/https://comfyrun.com](https://comfyrun.com)" - }, - { - "author": "ceruleandeep", - "title": "ComfyUI LLaVA Captioner", - "reference": "https://github.com/ceruleandeep/ComfyUI-LLaVA-Captioner", - "files": [ - "https://github.com/ceruleandeep/ComfyUI-LLaVA-Captioner" - ], - "install_type": "git-clone", - "description": "A ComfyUI extension for chatting with your images. Runs on your own system, no external services used, no filter. Uses the [a/LLaVA multimodal LLM](https://llava-vl.github.io/) so you can give instructions or ask questions in natural language. It's maybe as smart as GPT3.5, and it can see." - }, - { - "author": "jitcoder", - "title": "LoraInfo", - "reference": "https://github.com/jitcoder/lora-info", - "files": [ - "https://github.com/jitcoder/lora-info" - ], - "install_type": "git-clone", - "description": "Shows Lora information from CivitAI and outputs trigger words and example prompt" - }, - { - "author": "ttulttul", - "title": "ComfyUI Iterative Mixing Nodes", - "reference": "https://github.com/ttulttul/ComfyUI-Iterative-Mixer", - "files": [ - "https://github.com/ttulttul/ComfyUI-Iterative-Mixer" - ], - "install_type": "git-clone", - "description": "Nodes: Iterative Mixing KSampler, Batch Unsampler, Iterative Mixing KSampler Advanced" - }, - { - "author": "OpenArt-AI", - "title": "ComfyUI Assistant", - "reference": "https://github.com/OpenArt-AI/ComfyUI-Assistant", - "files": [ - "https://github.com/OpenArt-AI/ComfyUI-Assistant" - ], - "install_type": "git-clone", - "description": "ComfyUI Assistant is your one stop plugin for everything you need to get started with comfy-ui. Now it provides useful courses, tutorials, and basic templates." - }, - { - "author": "shockz0rz", - "title": "comfy-easy-grids", - "reference": "https://github.com/shockz0rz/comfy-easy-grids", - "files": [ - "https://github.com/shockz0rz/comfy-easy-grids" - ], - "install_type": "git-clone", - "description": "A set of custom nodes for creating image grids, sequences, and batches in ComfyUI." - }, - { - "author": "CosmicLaca", - "title": "Primere nodes for ComfyUI", - "reference": "https://github.com/CosmicLaca/ComfyUI_Primere_Nodes", - "files": [ - "https://github.com/CosmicLaca/ComfyUI_Primere_Nodes" - ], - "install_type": "git-clone", - "description": "This extension provides various utility nodes. Inputs(prompt, styles, dynamic, merger, ...), Outputs(style pile), Dashboard(selectors, loader, switch, ...), Networks(LORA, Embedding, Hypernetwork), Visuals(visual selectors, )" - }, - { - "author": "ZHO-ZHO-ZHO", - "title": "ComfyUI-Gemini", - "reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-Gemini", - "files": [ - "https://github.com/ZHO-ZHO-ZHO/ComfyUI-Gemini" - ], - "install_type": "git-clone", - "description": "Using Gemini-pro & Gemini-pro-vision in ComfyUI." - }, - { - "author": "ZHO-ZHO-ZHO", - "title": "comfyui-portrait-master-zh-cn", - "reference": "https://github.com/ZHO-ZHO-ZHO/comfyui-portrait-master-zh-cn", - "files": [ - "https://github.com/ZHO-ZHO-ZHO/comfyui-portrait-master-zh-cn" - ], - "install_type": "git-clone", - "description": "ComfyUI Portrait Master 简体中文版." - }, - { - "author": "Continue7777", - "title": "comfyui-easyapi-nodes", - "reference": "https://github.com/Continue7777/comfyui-yoy", - "files": [ - "https://github.com/Continue7777/comfyui-yoy" - ], - "install_type": "git-clone", - "description": "This plugin gives you the ability to generate a real Product rendering, commonly referred to as the mockup.The most important is that we can provide it for you,cause we have a complete supply chain.You can buy products with your designs or sell them. We can provide you dropshipping services." - }, - { - "author": "RenderRift", - "title": "ComfyUI-RenderRiftNodes", - "reference": "https://github.com/RenderRift/ComfyUI-RenderRiftNodes", - "files": [ - "https://github.com/RenderRift/ComfyUI-RenderRiftNodes" - ], - "install_type": "git-clone", - "description": "Nodes:RR_Date_Folder_Format, RR_Image_Metadata_Overlay, RR_VideoPathMetaExtraction, RR_DisplayMetaOptions. This extension provides nodes designed to enhance the Animatediff workflow." - }, - { - "author": "Haoming02", - "title": "ComfyUI Floodgate", - "reference": "https://github.com/Haoming02/comfyui-floodgate", - "files": [ - "https://github.com/Haoming02/comfyui-floodgate" - ], - "install_type": "git-clone", - "description": "This is an Extension for ComfyUI, which allows you to control the logic flow with just one click!" } ] } diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 90c80545..032c0149 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -121,6 +121,7 @@ "FloatToInt-badger", "FloatToString-badger", "FrameToVideo-badger", + "GarbageCollect-badger", "GetDirName-badger", "GetUUID-badger", "IdentifyLinesBasedOnBorderColor-badger", @@ -1528,10 +1529,13 @@ "Cached Image Load From URL", "Crop Center wigh SEGS", "Crop Center with SEGS", + "Dilate Mask for Each Face", "GW Number Formatting", "Image Crop Fit", "Image Resize Fit", "OFF SEGS to Image", + "Query Gender and Age", + "Safe Mask to Image", "VAE Encode For Inpaint V2", "Watermarking" ], @@ -3988,6 +3992,14 @@ "title_aux": "ComfyUI-Llama" } ], + "https://github.com/dave-palt/comfyui_DSP_imagehelpers": [ + [ + "dsp-imagehelpers-concat" + ], + { + "title_aux": "comfyui_DSP_imagehelpers" + } + ], "https://github.com/dawangraoming/ComfyUI_ksampler_gpu/raw/main/ksampler_gpu.py": [ [ "KSamplerAdvancedGPU", @@ -5042,8 +5054,9 @@ "Base64ToMask", "ImageToBase64", "ImageToBase64Advanced", - "LoadImageFromUrl", + "LoadImageFromURL", "LoadImageToBase64", + "LoadMaskFromURL", "MaskImageToBase64", "MaskToBase64", "MaskToBase64Image", @@ -6009,6 +6022,7 @@ "ImageColorTransfer", "ImageCropByAlpha", "IntNumber", + "JoinWithDelimiter", "LaMaInpainting", "LimitNumber", "LoadImagesFromPath", From bfa7497443dfb52e3616a293fded1698a14e33c4 Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Thu, 18 Jan 2024 17:27:10 +0900 Subject: [PATCH 32/35] update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5fcfa2d0..6e439dc2 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ This repository provides Colab notebooks that allow you to install and use Comfy * Support for automatically installing dependencies of custom nodes upon restarting Colab notebooks. ## Changes +* **2.2.3** Support Components System * **0.29** Add `Update all` feature * **0.25** support db channel * You can directly modify the db channel settings in the `config.ini` file. From 5771bb25b5a541da576bae6bf478a30c33a686e0 Mon Sep 17 00:00:00 2001 From: chaojie Date: Thu, 18 Jan 2024 22:00:02 +0800 Subject: [PATCH 33/35] ComfyUI-I2VGEN-XL --- custom-node-list.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/custom-node-list.json b/custom-node-list.json index de533fa3..f84d555c 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4084,6 +4084,16 @@ "install_type": "git-clone", "description": "Nodes: Run python tools/download_weights.py first to download weights automatically" }, + { + "author": "chaojie", + "title": "ComfyUI-I2VGEN-XL", + "reference": "https://github.com/chaojie/ComfyUI-I2VGEN-XL", + "files": [ + "https://github.com/chaojie/ComfyUI-I2VGEN-XL" + ], + "install_type": "git-clone", + "description": "Nodes: Please read the github Readme for instructions." + }, { "author": "alexopus", "title": "ComfyUI Image Saver", From de5c7ee33fc943de6170dfd0297280228d65a89f Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Fri, 19 Jan 2024 09:55:38 +0900 Subject: [PATCH 34/35] update DB --- custom-node-list.json | 32 ++++++++++- extension-node-map.json | 57 +++++++++++++++++--- node_db/dev/custom-node-list.json | 11 +++- node_db/new/custom-node-list.json | 82 ++++++++++++++--------------- node_db/new/extension-node-map.json | 57 +++++++++++++++++--- 5 files changed, 182 insertions(+), 57 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index f84d555c..59259edb 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4092,7 +4092,7 @@ "https://github.com/chaojie/ComfyUI-I2VGEN-XL" ], "install_type": "git-clone", - "description": "Nodes: Please read the github Readme for instructions." + "description": "This is an implementation of [a/i2vgen-xl](https://github.com/ali-vilab/i2vgen-xl)" }, { "author": "alexopus", @@ -4124,6 +4124,16 @@ "install_type": "git-clone", "description": "An extensive node suite that enables ComfyUI to process 3D inputs (Mesh & UV Texture, etc) using cutting edge algorithms (3DGS, NeRF, etc.)" }, + { + "author": "MrForExample", + "title": "ComfyUI-AnimateAnyone-Evolved", + "reference": "https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved", + "files": [ + "https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved" + ], + "install_type": "git-clone", + "description": "Improved [a/AnimateAnyone](https://github.com/HumanAIGC/AnimateAnyone) implementation that allows you to use the opse image sequence and reference image to generate stylized video." + }, { "author": "Hangover3832", "title": "ComfyUI-Hangover-Nodes", @@ -4254,6 +4264,16 @@ "install_type": "git-clone", "description": "Instead of LoraLoader or HypernetworkLoader, it receives a prompt and loads and applies LoRA or HN based on the specifications within the prompt. The main purpose of this custom node is to allow changes without reconnecting the LoraLoader node when the prompt is randomly altered, etc." }, + { + "author": "Taremin", + "title": "ComfyUI String Tools", + "reference": "https://github.com/Taremin/comfyui-string-tools", + "files": [ + "https://github.com/Taremin/comfyui-string-tools" + ], + "install_type": "git-clone", + "description": " This extension provides the StringToolsConcat node, which concatenates multiple texts, and the StringToolsRandomChoice node, which selects one randomly from multiple texts." + }, { "author": "foxtrot-roger", "title": "RF Nodes", @@ -4353,6 +4373,16 @@ ], "install_type": "git-clone", "description": "Nodes: DSP Image Concat" + }, + { + "author": "Inzaniak", + "title": "Ranbooru for ComfyUI", + "reference": "https://github.com/Inzaniak/comfyui-ranbooru", + "files": [ + "https://github.com/Inzaniak/comfyui-ranbooru" + ], + "install_type": "git-clone", + "description": "Ranbooru is an extension for the comfyUI. The purpose of this extension is to add a node that gets a random set of tags from boorus pictures. This is mostly being used to help me test my checkpoints on a large variety of" }, diff --git a/extension-node-map.json b/extension-node-map.json index 032c0149..1786df5e 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -122,9 +122,11 @@ "FloatToString-badger", "FrameToVideo-badger", "GarbageCollect-badger", + "GetColorFromBorder-badger", "GetDirName-badger", "GetUUID-badger", - "IdentifyLinesBasedOnBorderColor-badger", + "IdentifyBorderColorToMask-badger", + "IdentifyColorToMask-badger", "ImageNormalization-badger", "ImageOverlap-badger", "ImageScaleToSide-badger", @@ -915,6 +917,15 @@ "title_aux": "IG Interpolation Nodes" } ], + "https://github.com/Inzaniak/comfyui-ranbooru": [ + [ + "Ranbooru", + "RandomPicturePath" + ], + { + "title_aux": "Ranbooru for ComfyUI" + } + ], "https://github.com/JPS-GER/ComfyUI_JPS-Nodes": [ [ "Conditioning Switch (JPS)", @@ -1964,7 +1975,6 @@ "CR Load Scheduled LoRAs", "CR Load Scheduled Models", "CR Load Text List", - "CR Loop List", "CR Mask Text", "CR Math Operation", "CR Model Input Switch", @@ -2011,6 +2021,7 @@ "CR Seed", "CR Seed to Int", "CR Select Font", + "CR Select ISO Size", "CR Select Model", "CR Select Resize Method", "CR Set Switch From String", @@ -2067,11 +2078,12 @@ "CR XY List", "CR XY Product", "CR XY Save Grid Image", - "CR XYZ Index" + "CR XYZ Index", + "CR_Aspect Ratio For Print" ], { "author": "Suzie1", - "description": "170 custom nodes for artists, designers and animators.", + "description": "175 custom nodes for artists, designers and animators.", "nickname": "Comfyroll Studio", "title": "Comfyroll Studio", "title_aux": "ComfyUI_Comfyroll_CustomNodes" @@ -2185,6 +2197,15 @@ "title_aux": "ComfyUI Prompt ExtraNetworks" } ], + "https://github.com/Taremin/comfyui-string-tools": [ + [ + "StringToolsConcat", + "StringToolsRandomChoice" + ], + { + "title_aux": "ComfyUI String Tools" + } + ], "https://github.com/TeaCrab/ComfyUI-TeaNodes": [ [ "TC_ColorFill", @@ -2842,7 +2863,8 @@ "Gaussian Blur_Ally", "Image Flip_ally", "Placeholder Tuple", - "aegisflow Multi_Pass" + "aegisflow Multi_Pass", + "aegisflow Multi_Pass XL" ], { "title_aux": "AegisFlow Utility Nodes" @@ -3491,6 +3513,15 @@ "title_aux": "ComfyUI-DragNUWA" } ], + "https://github.com/chaojie/ComfyUI-I2VGEN-XL": [ + [ + "I2VGEN-XL Simple", + "Modelscope Pipeline Loader" + ], + { + "title_aux": "ComfyUI-I2VGEN-XL" + } + ], "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone": [ [ "Moore-AnimateAnyone Denoising Unet", @@ -3531,7 +3562,10 @@ ], "https://github.com/chflame163/ComfyUI_LayerStyle": [ [ - "LayerStyle_DropShadow" + "LayerStyle_DropShadow", + "LayerStyle_ImageBlend", + "LayerStyle_ImageOpacity", + "LayerStyle_OuterGlow" ], { "title_aux": "ComfyUI Layer Style" @@ -4971,9 +5005,13 @@ ], "https://github.com/komojini/komojini-comfyui-nodes": [ [ + "FlowBuilder", + "Getter", + "ImageGetter", "ImageMerger", "KSamplerAdvancedCacheable", "KSamplerCacheable", + "Setter", "UltimateVideoLoader", "UltimateVideoLoader (simple)", "YouTubeVideoLoader" @@ -5580,6 +5618,7 @@ [ "NegiTools_CompositeImages", "NegiTools_DepthEstimationByMarigold", + "NegiTools_DetectFaceRotationForInpainting", "NegiTools_ImageProperties", "NegiTools_LatentProperties", "NegiTools_NoiseImageGenerator", @@ -6941,6 +6980,8 @@ "easy XYInputs: ControlNet", "easy XYInputs: Denoise", "easy XYInputs: ModelMergeBlocks", + "easy XYInputs: NegativeCond", + "easy XYInputs: PositiveCond", "easy XYInputs: PromptSR", "easy XYInputs: Sampler/Scheduler", "easy XYInputs: Seeds++ Batch", @@ -6962,13 +7003,14 @@ "easy imageSize", "easy imageSizeByLongerSide", "easy imageSizeBySide", + "easy imageToMask", "easy kSampler", "easy kSamplerDownscaleUnet", "easy kSamplerInpainting", "easy kSamplerSDTurbo", "easy kSamplerTiled", "easy latentCompositeMaskedWithCond", - "easy latentMultiplyBySigma", + "easy latentNoisy", "easy loraStack", "easy negative", "easy pipeIn", @@ -6985,6 +7027,7 @@ "easy samLoaderPipe", "easy seed", "easy showSpentTime", + "easy stylesSelector", "easy svdLoader", "easy ultralyticsDetectorPipe", "easy unSampler", diff --git a/node_db/dev/custom-node-list.json b/node_db/dev/custom-node-list.json index 5a6578cf..da538638 100644 --- a/node_db/dev/custom-node-list.json +++ b/node_db/dev/custom-node-list.json @@ -9,7 +9,16 @@ "description": "If you see this message, your ComfyUI-Manager is outdated.\nDev channel provides only the list of the developing nodes. If you want to find the complete node list, please go to the Default channel." }, - + { + "author": "DimaChaichan", + "title": "LAizypainter-Exporter-ComfyUI [WIP]", + "reference": "https://github.com/DimaChaichan/LAizypainter-Exporter-ComfyUI", + "files": [ + "https://github.com/DimaChaichan/LAizypainter-Exporter-ComfyUI" + ], + "install_type": "git-clone", + "description": "WIP" + }, { "author": "ZHO-ZHO-ZHO", "title": "ComfyUI PhotoMaker (WIP)", diff --git a/node_db/new/custom-node-list.json b/node_db/new/custom-node-list.json index 08397bc4..ae44049a 100644 --- a/node_db/new/custom-node-list.json +++ b/node_db/new/custom-node-list.json @@ -9,7 +9,48 @@ "description": "If you see this message, your ComfyUI-Manager is outdated.\nRecent channel provides only the list of the latest nodes. If you want to find the complete node list, please go to the Default channel.\nMaking LoRA has never been easier!" }, + + { + "author": "MrForExample", + "title": "ComfyUI-AnimateAnyone-Evolved", + "reference": "https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved", + "files": [ + "https://github.com/MrForExample/ComfyUI-AnimateAnyone-Evolved" + ], + "install_type": "git-clone", + "description": "Improved [a/AnimateAnyone](https://github.com/HumanAIGC/AnimateAnyone) implementation that allows you to use the opse image sequence and reference image to generate stylized video." + }, + { + "author": "chaojie", + "title": "ComfyUI-I2VGEN-XL", + "reference": "https://github.com/chaojie/ComfyUI-I2VGEN-XL", + "files": [ + "https://github.com/chaojie/ComfyUI-I2VGEN-XL" + ], + "install_type": "git-clone", + "description": "This is an implementation of [a/i2vgen-xl](https://github.com/ali-vilab/i2vgen-xl)" + }, + { + "author": "Inzaniak", + "title": "Ranbooru for ComfyUI", + "reference": "https://github.com/Inzaniak/comfyui-ranbooru", + "files": [ + "https://github.com/Inzaniak/comfyui-ranbooru" + ], + "install_type": "git-clone", + "description": "Ranbooru is an extension for the comfyUI. The purpose of this extension is to add a node that gets a random set of tags from boorus pictures. This is mostly being used to help me test my checkpoints on a large variety of" + }, + { + "author": "Taremin", + "title": "ComfyUI String Tools", + "reference": "https://github.com/Taremin/comfyui-string-tools", + "files": [ + "https://github.com/Taremin/comfyui-string-tools" + ], + "install_type": "git-clone", + "description": " This extension provides the StringToolsConcat node, which concatenates multiple texts, and the StringToolsRandomChoice node, which selects one randomly from multiple texts." + }, { "author": "dave-palt", "title": "comfyui_DSP_imagehelpers", @@ -652,47 +693,6 @@ ], "install_type": "git-clone", "description": "Nodes: Center Calculation. Improved Numerical Calculation for ComfyUI" - }, - { - "author": "Comfyui_GPT_Story", - "title": "junglehu", - "reference": "https://github.com/junglehu/Comfyui_Story_LLmA", - "files": [ - "https://github.com/junglehu/Comfyui_Story_LLmA" - ], - "install_type": "git-clone", - "description": "GPT+Comfyui Generate coherent pictures" - }, - { - "author": "HarroweD and quadmoon", - "title": "Harronode", - "reference": "https://github.com/NotHarroweD/Harronode", - "nodename_pattern": "Harronode", - "files": [ - "https://github.com/NotHarroweD/Harronode.git" - ], - "install_type": "git-clone", - "description": "Harronode is a custom node designed to build prompts easily for use with the Harrlogos SDXL LoRA. This Node simplifies the process of crafting prompts and makes all built in activation terms available at your fingertips." - }, - { - "author": "styler00dollar", - "title": "ComfyUI-sudo-latent-upscale", - "reference": "https://github.com/styler00dollar/ComfyUI-sudo-latent-upscale", - "files": [ - "https://github.com/styler00dollar/ComfyUI-sudo-latent-upscale" - ], - "install_type": "git-clone", - "description": "Directly upscaling inside the latent space. Model was trained for SD1.5 and drawn content. Might add new architectures or update models at some point. This took heavy inspriration from [city96/SD-Latent-Upscaler](https://github.com/city96/SD-Latent-Upscaler) and [Ttl/ComfyUi_NNLatentUpscale](https://github.com/Ttl/ComfyUi_NNLatentUpscale). " - }, - { - "author": "thecooltechguy", - "title": "ComfyUI-ComfyRun", - "reference": "https://github.com/thecooltechguy/ComfyUI-ComfyRun", - "files": [ - "https://github.com/thecooltechguy/ComfyUI-ComfyRun" - ], - "install_type": "git-clone", - "description": "The easiest way to run & share any ComfyUI workflow [a/https://comfyrun.com](https://comfyrun.com)" } ] } diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 032c0149..1786df5e 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -122,9 +122,11 @@ "FloatToString-badger", "FrameToVideo-badger", "GarbageCollect-badger", + "GetColorFromBorder-badger", "GetDirName-badger", "GetUUID-badger", - "IdentifyLinesBasedOnBorderColor-badger", + "IdentifyBorderColorToMask-badger", + "IdentifyColorToMask-badger", "ImageNormalization-badger", "ImageOverlap-badger", "ImageScaleToSide-badger", @@ -915,6 +917,15 @@ "title_aux": "IG Interpolation Nodes" } ], + "https://github.com/Inzaniak/comfyui-ranbooru": [ + [ + "Ranbooru", + "RandomPicturePath" + ], + { + "title_aux": "Ranbooru for ComfyUI" + } + ], "https://github.com/JPS-GER/ComfyUI_JPS-Nodes": [ [ "Conditioning Switch (JPS)", @@ -1964,7 +1975,6 @@ "CR Load Scheduled LoRAs", "CR Load Scheduled Models", "CR Load Text List", - "CR Loop List", "CR Mask Text", "CR Math Operation", "CR Model Input Switch", @@ -2011,6 +2021,7 @@ "CR Seed", "CR Seed to Int", "CR Select Font", + "CR Select ISO Size", "CR Select Model", "CR Select Resize Method", "CR Set Switch From String", @@ -2067,11 +2078,12 @@ "CR XY List", "CR XY Product", "CR XY Save Grid Image", - "CR XYZ Index" + "CR XYZ Index", + "CR_Aspect Ratio For Print" ], { "author": "Suzie1", - "description": "170 custom nodes for artists, designers and animators.", + "description": "175 custom nodes for artists, designers and animators.", "nickname": "Comfyroll Studio", "title": "Comfyroll Studio", "title_aux": "ComfyUI_Comfyroll_CustomNodes" @@ -2185,6 +2197,15 @@ "title_aux": "ComfyUI Prompt ExtraNetworks" } ], + "https://github.com/Taremin/comfyui-string-tools": [ + [ + "StringToolsConcat", + "StringToolsRandomChoice" + ], + { + "title_aux": "ComfyUI String Tools" + } + ], "https://github.com/TeaCrab/ComfyUI-TeaNodes": [ [ "TC_ColorFill", @@ -2842,7 +2863,8 @@ "Gaussian Blur_Ally", "Image Flip_ally", "Placeholder Tuple", - "aegisflow Multi_Pass" + "aegisflow Multi_Pass", + "aegisflow Multi_Pass XL" ], { "title_aux": "AegisFlow Utility Nodes" @@ -3491,6 +3513,15 @@ "title_aux": "ComfyUI-DragNUWA" } ], + "https://github.com/chaojie/ComfyUI-I2VGEN-XL": [ + [ + "I2VGEN-XL Simple", + "Modelscope Pipeline Loader" + ], + { + "title_aux": "ComfyUI-I2VGEN-XL" + } + ], "https://github.com/chaojie/ComfyUI-Moore-AnimateAnyone": [ [ "Moore-AnimateAnyone Denoising Unet", @@ -3531,7 +3562,10 @@ ], "https://github.com/chflame163/ComfyUI_LayerStyle": [ [ - "LayerStyle_DropShadow" + "LayerStyle_DropShadow", + "LayerStyle_ImageBlend", + "LayerStyle_ImageOpacity", + "LayerStyle_OuterGlow" ], { "title_aux": "ComfyUI Layer Style" @@ -4971,9 +5005,13 @@ ], "https://github.com/komojini/komojini-comfyui-nodes": [ [ + "FlowBuilder", + "Getter", + "ImageGetter", "ImageMerger", "KSamplerAdvancedCacheable", "KSamplerCacheable", + "Setter", "UltimateVideoLoader", "UltimateVideoLoader (simple)", "YouTubeVideoLoader" @@ -5580,6 +5618,7 @@ [ "NegiTools_CompositeImages", "NegiTools_DepthEstimationByMarigold", + "NegiTools_DetectFaceRotationForInpainting", "NegiTools_ImageProperties", "NegiTools_LatentProperties", "NegiTools_NoiseImageGenerator", @@ -6941,6 +6980,8 @@ "easy XYInputs: ControlNet", "easy XYInputs: Denoise", "easy XYInputs: ModelMergeBlocks", + "easy XYInputs: NegativeCond", + "easy XYInputs: PositiveCond", "easy XYInputs: PromptSR", "easy XYInputs: Sampler/Scheduler", "easy XYInputs: Seeds++ Batch", @@ -6962,13 +7003,14 @@ "easy imageSize", "easy imageSizeByLongerSide", "easy imageSizeBySide", + "easy imageToMask", "easy kSampler", "easy kSamplerDownscaleUnet", "easy kSamplerInpainting", "easy kSamplerSDTurbo", "easy kSamplerTiled", "easy latentCompositeMaskedWithCond", - "easy latentMultiplyBySigma", + "easy latentNoisy", "easy loraStack", "easy negative", "easy pipeIn", @@ -6985,6 +7027,7 @@ "easy samLoaderPipe", "easy seed", "easy showSpentTime", + "easy stylesSelector", "easy svdLoader", "easy ultralyticsDetectorPipe", "easy unSampler", From d44b0a1ef2f06b0f80a6630c968fe423f4cd6bcb Mon Sep 17 00:00:00 2001 From: "dr.lt.data" Date: Fri, 19 Jan 2024 15:03:08 +0900 Subject: [PATCH 35/35] update DB --- custom-node-list.json | 2 +- extension-node-map.json | 2 -- node_db/dev/custom-node-list.json | 11 +++++++++++ node_db/new/extension-node-map.json | 2 -- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/custom-node-list.json b/custom-node-list.json index 59259edb..c0ed1b77 100644 --- a/custom-node-list.json +++ b/custom-node-list.json @@ -4373,7 +4373,7 @@ ], "install_type": "git-clone", "description": "Nodes: DSP Image Concat" - }, + }, { "author": "Inzaniak", "title": "Ranbooru for ComfyUI", diff --git a/extension-node-map.json b/extension-node-map.json index 1786df5e..ce6eb616 100644 --- a/extension-node-map.json +++ b/extension-node-map.json @@ -2320,8 +2320,6 @@ "0246.ScriptNode", "0246.ScriptPile", "0246.ScriptRule", - "0246.StrAdd", - "0246.StrAddBatch", "0246.Stringify" ], { diff --git a/node_db/dev/custom-node-list.json b/node_db/dev/custom-node-list.json index da538638..d8b7d6af 100644 --- a/node_db/dev/custom-node-list.json +++ b/node_db/dev/custom-node-list.json @@ -9,6 +9,17 @@ "description": "If you see this message, your ComfyUI-Manager is outdated.\nDev channel provides only the list of the developing nodes. If you want to find the complete node list, please go to the Default channel." }, + + { + "author": "chaojie", + "title": "LightGlue ⚡️ [WIP]", + "reference": "https://github.com/chaojie/ComfyUI-LightGlue", + "files": [ + "https://github.com/chaojie/ComfyUI-LightGlue" + ], + "install_type": "git-clone", + "description": "This extension provides custom nodes for inference of LightGlue, a lightweight feature matcher with high accuracy and blazing fast inference. It takes as input a set of keypoints and descriptors for each image and returns the indices of corresponding points. The architecture is based on adaptive pruning techniques, in both network width and depth - [a/check out the paper for more details](https://arxiv.org/pdf/2306.13643.pdf)." + }, { "author": "DimaChaichan", "title": "LAizypainter-Exporter-ComfyUI [WIP]", diff --git a/node_db/new/extension-node-map.json b/node_db/new/extension-node-map.json index 1786df5e..ce6eb616 100644 --- a/node_db/new/extension-node-map.json +++ b/node_db/new/extension-node-map.json @@ -2320,8 +2320,6 @@ "0246.ScriptNode", "0246.ScriptPile", "0246.ScriptRule", - "0246.StrAdd", - "0246.StrAddBatch", "0246.Stringify" ], {