Changed node behavior to support text file uploads.
This commit is contained in:
+8
-1
@@ -1 +1,8 @@
|
||||
from .nodes import *
|
||||
# Import our node classes
|
||||
from .nodes import *
|
||||
|
||||
# This tells ComfyUI to look for a 'js' folder in our directory
|
||||
WEB_DIRECTORY = "js"
|
||||
|
||||
# Tell ComfyUI about all the parts of our node
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,101 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
// This file just needs to register the new widget type
|
||||
function textUploadWidget(node, inputName, inputData, app) {
|
||||
const widget = {
|
||||
type: inputData[0], // "TEXTUPLOAD"
|
||||
name: inputName,
|
||||
size: [128, 88], // Widget size
|
||||
draw(ctx, node, width, y) {}, // No need to draw anything
|
||||
computeSize(...args) {
|
||||
return [128, 88]; // Match the size
|
||||
},
|
||||
async serializeValue(nodeId, widgetIndex) {
|
||||
return node.widgets[widgetIndex].value;
|
||||
},
|
||||
};
|
||||
|
||||
// Create the "Choose File" button
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.type = "file";
|
||||
fileInput.accept = "text/plain,.txt"; // <--- This is the important change
|
||||
fileInput.style.display = "none";
|
||||
|
||||
// Handle file selection
|
||||
fileInput.addEventListener("change", (event) => {
|
||||
if (fileInput.files.length) {
|
||||
uploadFile(fileInput.files[0]);
|
||||
}
|
||||
});
|
||||
|
||||
// Create the button that opens the file picker
|
||||
const uploadButton = document.createElement("button");
|
||||
uploadButton.type = "button";
|
||||
uploadButton.innerText = "Choose .txt File to Upload";
|
||||
uploadButton.className = "comfy-btn";
|
||||
uploadButton.style.width = "100%"; // Make button fill widget
|
||||
uploadButton.style.marginTop = "10px";
|
||||
uploadButton.addEventListener("click", () => {
|
||||
fileInput.click();
|
||||
});
|
||||
|
||||
// Function to handle the upload
|
||||
async function uploadFile(file) {
|
||||
const body = new FormData();
|
||||
// We use "image" to match the server's /upload/image endpoint
|
||||
// The server doesn't care about the file type, just saves it.
|
||||
body.append("image", file);
|
||||
body.append("overwrite", "true");
|
||||
widget.value = file.name; // Store the filename for the backend
|
||||
|
||||
uploadButton.innerText = "Uploading...";
|
||||
|
||||
try {
|
||||
const response = await fetch("/upload/image", {
|
||||
method: "POST",
|
||||
body: body,
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
uploadButton.innerText = file.name; // Show the new filename
|
||||
node.setValue(file.name); // Set the node's internal value
|
||||
} else {
|
||||
alert(response.status + " - " + response.statusText);
|
||||
uploadButton.innerText = "Choose .txt File to Upload";
|
||||
}
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
uploadButton.innerText = "Choose .txt File to Upload";
|
||||
}
|
||||
}
|
||||
|
||||
// Add the button to the node's widget area
|
||||
node.addDOMWidget(inputName, "button", uploadButton, widget);
|
||||
document.body.appendChild(fileInput); // Add the hidden file input
|
||||
|
||||
// Handle drag and drop
|
||||
node.onDragOver = function (e) {
|
||||
if (e.dataTransfer.items.length > 0) {
|
||||
const item = e.dataTransfer.items[0];
|
||||
// Allow .txt files (which often have no MIME type) or text/plain
|
||||
return item.kind === 'file' && (item.type === "text/plain" || item.type === "");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
node.onDragDrop = function (e) {
|
||||
let handled = false;
|
||||
for (const file of e.dataTransfer.files) {
|
||||
if (file.type === "text/plain" || file.name.endsWith(".txt")) {
|
||||
uploadFile(file);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
};
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
// Register our new "TEXTUPLOAD" widget with ComfyUI
|
||||
app.registerWidget("TEXTUPLOAD", textUploadWidget);
|
||||
@@ -1,66 +1,61 @@
|
||||
import os
|
||||
import folder_paths
|
||||
|
||||
# --- Get Text Files ---
|
||||
# 1. Get the ComfyUI 'input' directory
|
||||
input_dir = folder_paths.get_input_directory()
|
||||
|
||||
# 2. Find all .txt files in that directory
|
||||
# We os.path.isfile to make sure we don't grab directories
|
||||
text_files = [
|
||||
f for f in os.listdir(input_dir)
|
||||
if os.path.isfile(os.path.join(input_dir, f)) and f.endswith(".txt")
|
||||
]
|
||||
|
||||
# --- The Node Class ---
|
||||
class LoadTextFile:
|
||||
"""
|
||||
A node that loads text from a file in the ComfyUI/input/ directory.
|
||||
A node that loads text from a file.
|
||||
It uses a custom widget to upload a .txt file.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
# This creates the dropdown widget with our file list
|
||||
"file_name": (text_files, )
|
||||
# This string "image" MUST match the name in the
|
||||
# FormData.append("image", file) in the JS.
|
||||
# It tells ComfyUI to use our new "TEXTUPLOAD" widget.
|
||||
"image": ("TEXTUPLOAD", )
|
||||
}
|
||||
}
|
||||
|
||||
# What the node will output
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("text",) # Optional, but good practice
|
||||
RETURN_NAMES = ("text",)
|
||||
|
||||
# The function that runs when the node is executed
|
||||
FUNCTION = "load_text"
|
||||
|
||||
# The category in the right-click menu
|
||||
CATEGORY = "Rathius_ComfyNodes/Utils"
|
||||
|
||||
# We don't want this node to run on file load, only when queued
|
||||
def IS_CHANGED(self, **kwargs):
|
||||
return float("inf")
|
||||
|
||||
def load_text(self, file_name):
|
||||
# Get the full path to the file
|
||||
file_path = os.path.join(input_dir, file_name)
|
||||
def load_text(self, image):
|
||||
# 'image' is the filename (e.g., "my_prompt.txt")
|
||||
# The widget has already uploaded it to the 'input' folder.
|
||||
file_path = os.path.join(folder_paths.get_input_directory(), image)
|
||||
|
||||
try:
|
||||
# Open and read the file
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
text_content = f.read()
|
||||
|
||||
# Nodes must return their outputs as a tuple
|
||||
# Return the text content as a tuple
|
||||
return (text_content, )
|
||||
|
||||
except Exception as e:
|
||||
print(f"[LoadTextFile] Error: {e}")
|
||||
# Return the error as a string so you can see it in ComfyUI
|
||||
return (f"Error loading file: {e}", )
|
||||
|
||||
# --- Node Registration ---
|
||||
# This tells ComfyUI about our new node
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"LoadTextFile_Rathius": LoadTextFile
|
||||
}
|
||||
|
||||
# This sets the name that appears in the Add Node menu
|
||||
# I updated the display name to reflect its new function
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"LoadTextFile_Rathius": "Load Text from File"
|
||||
"LoadTextFile_Rathius": "Load Text from File (Upload)"
|
||||
}
|
||||
Reference in New Issue
Block a user