Merge branch 'release/v0.0.1'
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
|
||||
v0.0.1 / 2024-01-19
|
||||
==================
|
||||
|
||||
* Initial release
|
||||
@@ -1,8 +1,26 @@
|
||||
DarkPrompts
|
||||
-----------
|
||||
|
||||
A better input for the WAS Text Concatenate box
|
||||
A slightly better tool for generating random prompts.
|
||||
|
||||
DarkReader allows you to load lines from a file and/or lines from a text box, and pick a random line based on the seed.
|
||||
DarkPrompt
|
||||
==========
|
||||
DarkPrompt reads lines from a file and/or a text input, combines them together, optionally strips out comments and blank lines, and then selects a random line for use in generating your prompt based on a seed input. It also has a "prefix" and "suffix" field so you can easily include additional information with each prompt or wrap it inside a weight. For example a prefix of '(' and a suffix of ':1.2)' could return a string: ```(walking a dog:1.2)``` from an file named ```activities.txt``` that contains a line ```walking a dog```.
|
||||
|
||||
DarkReader also allows stripping out comments and blank lines during processing
|
||||
Unlike several other ComfyUI projects, the box is somewhat more compact and gives you an easy way to combine file and text sources for prompt generation.
|
||||
|
||||
DarkCombiner
|
||||
============
|
||||
DarkCombiner accepts up to 7 text inputs and combines them with an optional delimiter (\n by default) with a string output. This allows you to easily combine multiple DarkPrompt nodes to generate complex prompts.
|
||||
|
||||
Screenshot
|
||||
==========
|
||||

|
||||
|
||||
Installation Using ComfyUI Manager
|
||||
==================================
|
||||
If you are using ComfyUI Manager, copy the URL of this repo and paste it into the "Install via Git URL" box and restart ComfyUI.
|
||||
|
||||
Installation into ComfyUI
|
||||
=========================
|
||||
Go into your custom_nodes directory and run a 'git clone https://github.com/darkpixel/darkprompts.git' and then restart ComfyUI.
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
__version__ = "0.0.1"
|
||||
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def strip_blanks_from_lines(lines):
|
||||
cleaned = []
|
||||
for line in lines:
|
||||
if len(str(line).strip()) == 0:
|
||||
pass
|
||||
else:
|
||||
cleaned.append(line.strip())
|
||||
return cleaned
|
||||
|
||||
|
||||
def strip_comments_from_lines(lines):
|
||||
cleaned = []
|
||||
for line in lines:
|
||||
if "#" in line:
|
||||
cleaned.append(re.sub(r"#.*$|//.*$", "", str(line)))
|
||||
else:
|
||||
cleaned.append(line)
|
||||
return cleaned
|
||||
|
||||
|
||||
class DarkCombine(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {},
|
||||
"optional": {
|
||||
"delimiter": ("STRING", {"default": "\n"}),
|
||||
"text_a": (
|
||||
"STRING",
|
||||
{"forceInput": True},
|
||||
),
|
||||
"text_b": (
|
||||
"STRING",
|
||||
{"forceInput": True},
|
||||
),
|
||||
"text_c": (
|
||||
"STRING",
|
||||
{"forceInput": True},
|
||||
),
|
||||
"text_d": (
|
||||
"STRING",
|
||||
{"forceInput": True},
|
||||
),
|
||||
"text_e": (
|
||||
"STRING",
|
||||
{"forceInput": True},
|
||||
),
|
||||
"text_f": (
|
||||
"STRING",
|
||||
{"forceInput": True},
|
||||
),
|
||||
"text_g": (
|
||||
"STRING",
|
||||
{"forceInput": True},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "concatenate_inputs"
|
||||
|
||||
CATEGORY = "DarkPrompt"
|
||||
|
||||
def concatenate_inputs(self, delimiter="\n", **kwargs):
|
||||
text = []
|
||||
if delimiter == "\\n":
|
||||
delimiter = "\n"
|
||||
|
||||
for key in sorted(kwargs.keys()):
|
||||
val = kwargs[key]
|
||||
if len(val.strip()) > 0:
|
||||
text.append(val)
|
||||
|
||||
print(delimiter.join(text))
|
||||
return (delimiter.join(text),)
|
||||
|
||||
|
||||
class DarkPrompt(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
logger.info("darkloader init")
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
"""
|
||||
Return a dictionary which contains config for all input fields.
|
||||
Some types (string): "MODEL", "VAE", "CLIP", "CONDITIONING", "LATENT", "IMAGE", "INT", "STRING", "FLOAT".
|
||||
Input types "INT", "STRING" or "FLOAT" are special values for fields on the node.
|
||||
The type can be a list for selection.
|
||||
|
||||
Returns: `dict`:
|
||||
- Key input_fields_group (`string`): Can be either required, hidden or optional. A node class must have property `required`
|
||||
- Value input_fields (`dict`): Contains input fields config:
|
||||
* Key field_name (`string`): Name of a entry-point method's argument
|
||||
* Value field_config (`tuple`):
|
||||
+ First value is a string indicate the type of field or a list for selection.
|
||||
+ Secound value is a config for type "INT", "STRING" or "FLOAT".
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"strip_blank_lines": ("BOOLEAN", {"default": 1}),
|
||||
"strip_comments": ("BOOLEAN", {"default": 1}),
|
||||
"seed": (
|
||||
"INT",
|
||||
{
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"max": 0xFFFFFFFFFFFFFFFF,
|
||||
"forceInput": True,
|
||||
},
|
||||
),
|
||||
},
|
||||
"optional": {
|
||||
"filename": ("STRING", {"default": None}),
|
||||
"prefix": ("STRING", {"default": None}),
|
||||
"suffix": ("STRING", {"default": None}),
|
||||
"text": ("STRING", {"default": None, "multiline": True}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("string",)
|
||||
FUNCTION = "dark_prompt"
|
||||
# OUTPUT_NODE = False
|
||||
CATEGORY = "DarkPrompt"
|
||||
|
||||
def dark_prompt(
|
||||
self,
|
||||
strip_blank_lines,
|
||||
strip_comments,
|
||||
seed,
|
||||
filename=None,
|
||||
text=None,
|
||||
prefix=None,
|
||||
suffix=None,
|
||||
):
|
||||
logger.info("DarkPrompt called with filename %s" % (filename))
|
||||
|
||||
lines = []
|
||||
|
||||
if not text and not filename:
|
||||
raise ValueError("DarkPrompt text and filename can not both be blank")
|
||||
|
||||
if filename:
|
||||
print("Trying to read %s" % (filename))
|
||||
try:
|
||||
f = open(filename, "r")
|
||||
file_lines = f.read().splitlines()
|
||||
for line in file_lines:
|
||||
lines.append(line)
|
||||
print("Successfully read %s" % (filename))
|
||||
except FileNotFoundError:
|
||||
logger.error("File not found: %s" % (filename))
|
||||
|
||||
if text:
|
||||
for text_line in text.splitlines():
|
||||
lines.append(text_line)
|
||||
|
||||
if strip_comments:
|
||||
lines = strip_comments_from_lines(lines)
|
||||
|
||||
if strip_blank_lines:
|
||||
lines = strip_blanks_from_lines(lines)
|
||||
|
||||
random.seed(seed)
|
||||
ret = str(random.choice(lines))
|
||||
|
||||
if prefix:
|
||||
ret = prefix + ret
|
||||
|
||||
if suffix:
|
||||
ret = ret + suffix
|
||||
|
||||
return (ret,)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"DarkCombine": DarkCombine,
|
||||
"DarkPrompt": DarkPrompt,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"DarkCombine": "Dark Combiner",
|
||||
"DarkPrompt": "Dark Prompt",
|
||||
}
|
||||
|
||||
__all__ = [NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS]
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
Reference in New Issue
Block a user