Merge branch 'release/v0.0.1'

This commit is contained in:
Aaron C. de Bruyn
2024-01-19 21:26:57 -08:00
4 changed files with 225 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
v0.0.1 / 2024-01-19
==================
* Initial release
+21 -3
View File
@@ -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
==========
![DarkPrompt](assets/workflow.png "DarkPrompt")
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
View File
@@ -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