Files
2026-03-18 16:20:23 -04:00

116 lines
5.2 KiB
Python
Executable File

import os
import folder_paths # ComfyUI utility to get model paths
# Define the main class for your custom node.
# The class name will be used in NODE_CLASS_MAPPINGS.
class EmAySee_LoraFilePicker:
"""
A ComfyUI custom node to pick LORA files from configured paths.
It provides a dropdown list of available LORA files and outputs
the selected filename and its full file path.
"""
def __init__(self):
# Constructor for the node. No special initialization needed for this node.
pass
@classmethod
def INPUT_TYPES(s):
"""
Defines the input types (widgets and connections) for the node.
This method is a class method and must return a dictionary.
"""
# Get all LORA files from ComfyUI's configured LORA paths.
# This will return a list of relative filenames (e.g., "my_lora.safetensors",
# "subdir/another_lora.pt"). The 'return_full_paths=True' argument is removed
# for compatibility with older ComfyUI versions.
lora_files = folder_paths.get_filename_list("loras")
# Add a "None" option at the beginning of the list.
# This allows the user to explicitly select no LORA.
lora_files.insert(0, "None")
return {
"required": {
# "lora_name" is the name of the input port that will appear on the node.
# (lora_files,) creates a dropdown widget in the ComfyUI interface,
# populated with the list of LORA files.
"lora_name": (lora_files,),
},
}
# Define the types of data that this node will output.
# RETURN_TYPES must be a tuple of ComfyUI data types (e.g., "STRING", "IMAGE", "MODEL").
RETURN_TYPES = ("STRING", "STRING",) # Outputs two strings.
# Define the names for the output ports. These names will appear on the node.
RETURN_NAMES = ("filename", "full_filepath",)
# Specifies the Python function within this class that ComfyUI should call
# when the node is executed in a workflow.
FUNCTION = "pick_lora_file"
# Defines the category under which this node will appear in the ComfyUI "Add Node" menu.
# Using "EmAySee/" as a prefix helps organize your custom nodes.
CATEGORY = "EmAySee/File Utilities"
def pick_lora_file(self, lora_name):
"""
The core logic of the node. This function is executed when the node runs.
It takes the selected LORA filename as input and returns the filename
and its corresponding full file path.
"""
# If the "None" option is selected in the dropdown, return empty strings.
if lora_name == "None":
return ("", "")
full_lora_path = None
# Get all configured base directories for LORAs.
# folder_paths.get_folder_paths("loras") returns a list of absolute paths
# to the directories where LORAs are stored.
lora_folders = folder_paths.get_folder_paths("loras")
# Iterate through each LORA folder to find the selected LORA file.
for folder in lora_folders:
# Construct a potential full path by joining the base folder and the selected LORA name.
potential_path = os.path.join(folder, lora_name)
# Verify if this constructed path actually exists and points to a file.
if os.path.exists(potential_path) and os.path.isfile(potential_path):
full_lora_path = potential_path
break
# Also check if the lora_name itself contains subdirectories (e.g., "subdir/lora.safetensors")
# and the folder is a base path.
# This handles cases where the dropdown might show "subdir/lora.safetensors" directly.
if os.path.exists(os.path.join(folder, lora_name)) and os.path.isfile(os.path.join(folder, lora_name)):
full_lora_path = os.path.join(folder, lora_name)
break
# If after all attempts, the file still cannot be located, print a warning
# and return empty strings to ensure the workflow doesn't crash.
if full_lora_path is None:
print(f"Warning: LORA file '{lora_name}' not found in known ComfyUI LORA paths.")
return ("", "")
# Return the selected filename and its successfully determined full path.
return (lora_name, full_lora_path)
# NODE_CLASS_MAPPINGS is a mandatory dictionary that ComfyUI uses to discover
# and register your custom nodes. The keys are internal identifiers, and the
# values are the Python classes that define your nodes.
NODE_CLASS_MAPPINGS = {
"EmAySee_LoraFilePicker": EmAySee_LoraFilePicker,
}
# NODE_DISPLAY_NAME_MAPPINGS is an optional dictionary that provides
# more user-friendly names for your nodes in the ComfyUI interface.
# This name will appear in the "Add Node" menu.
NODE_DISPLAY_NAME_MAPPINGS = {
"EmAySee_LoraFilePicker": "EmAySee Lora File Picker",
}
# WEB_DIRECTORY can be defined if your node has custom web components (JavaScript/CSS).
# For this node, it's not strictly necessary, but it's a common practice to include it
# if you plan to extend the node with a custom UI later.
# WEB_DIRECTORY = "./web" # Uncomment and create a 'web' folder if needed for JS/CSS