Skip to content

Commit

Permalink
improved: extra_model_paths.yaml support for prompt files
Browse files Browse the repository at this point in the history
- You can use `inspire_prompts`

#177
  • Loading branch information
ltdrdata committed Oct 22, 2024
1 parent d29c418 commit bfaaa6c
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 46 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ This repository offers various extension nodes for ComfyUI. Nodes here have diff
* e.g. `prompts/example`
* `Load Prompts From File (Inspire)`: It sequentially reads prompts from the specified file. The output it returns is ZIPPED_PROMPT.
* Specify the file located under `ComfyUI-Inspire-Pack/prompts/`
* e.g. `prompts/example/prompt2.txt`
* e.g. `prompts/example/prompt2.txt`
* `Load Single Prompt From File (Inspire)`: Loads a single prompt from a file containing multiple prompts by using an index.
* The prompts file directory can be specified as `inspire_prompts` in `extra_model_paths.yaml`
* `Unzip Prompt (Inspire)`: Separate ZIPPED_PROMPT into `positive`, `negative`, and name components.
* `positive` and `negative` represent text prompts, while `name` represents the name of the prompt. When loaded from a file using `Load Prompts From File (Inspire)`, the name corresponds to the file name.
* `Zip Prompt (Inspire)`: Create ZIPPED_PROMPT from positive, negative, and name_opt.
Expand Down
2 changes: 1 addition & 1 deletion __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import importlib

version_code = [1, 5, 1]
version_code = [1, 6]
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
print(f"### Loading: ComfyUI-Inspire-Pack ({version_str})")

Expand Down
2 changes: 0 additions & 2 deletions inspire/conditioning_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ def __contains__(self, item):
return True

def __getitem__(self, key):
# Return a default value appropriate for your use case
# Adjust the return value as needed
return "FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}

return {
Expand Down
133 changes: 92 additions & 41 deletions inspire/prompt_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@
from .libs import utils, common
from .backend_support import CheckpointLoaderSimpleShared


model_path = folder_paths.models_dir
utils.add_folder_path_and_extensions("inspire_prompts", [os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "prompts"))], {'.txt'})


prompt_builder_preset = {}


resource_path = os.path.join(os.path.dirname(__file__), "..", "resources")
resource_path = os.path.abspath(resource_path)

prompts_path = os.path.join(os.path.dirname(__file__), "..", "prompts")
prompts_path = os.path.abspath(prompts_path)


try:
pb_yaml_path = os.path.join(resource_path, 'prompt-builder.yaml')
Expand All @@ -44,9 +46,12 @@
class LoadPromptsFromDir:
@classmethod
def INPUT_TYPES(cls):
global prompts_path
try:
prompt_dirs = [d for d in os.listdir(prompts_path) if os.path.isdir(os.path.join(prompts_path, d))]
prompt_dirs = []
for x in folder_paths.get_folder_paths('inspire_prompts'):
for d in os.listdir(x):
if os.path.isdir(os.path.join(x, d)):
prompt_dirs.append(d)
except Exception:
prompt_dirs = []

Expand All @@ -70,16 +75,24 @@ def IS_CHANGED(prompt_dir, reload=False):
if not reload:
return prompt_dir
else:
global prompts_path
prompt_dir = os.path.join(prompts_path, prompt_dir)
files = [f for f in os.listdir(prompt_dir) if f.endswith(".txt")]
candidates = []
for d in folder_paths.get_folder_paths('inspire_prompts'):
candidates.append(os.path.join(d, prompt_dir))

prompt_files = []
for x in candidates:
for root, dirs, files in os.walk(x):
for file in files:
if file.endswith(".txt"):
prompt_files.append(os.path.join(root, file))

prompt_files.sort()

md5 = hashlib.md5()
files.sort()

for file in files:
md5.update(file.encode('utf-8'))
with open(os.path.join(prompt_dir, file), 'rb') as f:
for file_name in prompt_files:
md5.update(file_name.encode('utf-8'))
with open(folder_paths.get_full_path('inspire_prompts', file_name), 'rb') as f:
while True:
chunk = f.read(4096)
if not chunk:
Expand All @@ -90,16 +103,24 @@ def IS_CHANGED(prompt_dir, reload=False):

@staticmethod
def doit(prompt_dir, reload=False):
global prompts_path
prompt_dir = os.path.join(prompts_path, prompt_dir)
files = [f for f in os.listdir(prompt_dir) if f.endswith(".txt")]
files.sort()
candidates = []
for d in folder_paths.get_folder_paths('inspire_prompts'):
candidates.append(os.path.join(d, prompt_dir))

prompt_files = []
for x in candidates:
for root, dirs, files in os.walk(x):
for file in files:
if file.endswith(".txt"):
prompt_files.append(os.path.join(root, file))

prompt_files.sort()

prompts = []
for file_name in files:
for file_name in prompt_files:
print(f"file_name: {file_name}")
try:
with open(os.path.join(prompt_dir, file_name), "r", encoding="utf-8") as file:
with open(file_name, "r", encoding="utf-8") as file:
prompt_data = file.read()
prompt_list = re.split(r'\n\s*-+\s*\n', prompt_data)

Expand All @@ -123,15 +144,16 @@ def doit(prompt_dir, reload=False):
class LoadPromptsFromFile:
@classmethod
def INPUT_TYPES(cls):
global prompts_path
prompt_files = []
try:
prompt_files = []
for root, dirs, files in os.walk(prompts_path):
for file in files:
if file.endswith(".txt"):
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, prompts_path)
prompt_files.append(rel_path)
prompts_paths = folder_paths.get_folder_paths('inspire_prompts')
for prompts_path in prompts_paths:
for root, dirs, files in os.walk(prompts_path):
for file in files:
if file.endswith(".txt"):
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, prompts_path)
prompt_files.append(rel_path)
except Exception:
prompt_files = []

Expand Down Expand Up @@ -161,9 +183,18 @@ def IS_CHANGED(prompt_file, text_data_opt=None, reload=False):
elif not reload:
return prompt_file
else:
prompt_path = os.path.join(prompts_path, prompt_file)
matched_path = None
for x in folder_paths.get_folder_paths('inspire_prompts'):
matched_path = os.path.join(x, prompt_file)
if not os.path.exists(matched_path):
matched_path = None
else:
break

with open(prompt_path, 'rb') as f:
if matched_path is None:
return float('NaN')

with open(matched_path, 'rb') as f:
while True:
chunk = f.read(4096)
if not chunk:
Expand All @@ -174,12 +205,21 @@ def IS_CHANGED(prompt_file, text_data_opt=None, reload=False):

@staticmethod
def doit(prompt_file, text_data_opt=None, reload=False):
prompt_path = os.path.join(prompts_path, prompt_file)
matched_path = None
for d in folder_paths.get_folder_paths('inspire_prompts'):
matched_path = os.path.join(d, prompt_file)
if not os.path.exists(matched_path):
matched_path = None
else:
break

if matched_path:
print(f"[WARN] LoadPromptsFromFile: file not found '{prompt_file}'")

prompts = []
try:
if not text_data_opt:
with open(prompt_path, "r", encoding="utf-8") as file:
with open(matched_path, "r", encoding="utf-8") as file:
prompt_data = file.read()
else:
prompt_data = text_data_opt
Expand All @@ -188,8 +228,8 @@ def doit(prompt_file, text_data_opt=None, reload=False):

pattern = r"positive:(.*?)(?:\n*|$)negative:(.*)"

for prompt in prompt_list:
matches = re.search(pattern, prompt, re.DOTALL)
for p in prompt_list:
matches = re.search(pattern, p, re.DOTALL)

if matches:
positive_text = matches.group(1).strip()
Expand All @@ -207,15 +247,16 @@ def doit(prompt_file, text_data_opt=None, reload=False):
class LoadSinglePromptFromFile:
@classmethod
def INPUT_TYPES(cls):
global prompts_path
prompt_files = []
try:
prompt_files = []
for root, dirs, files in os.walk(prompts_path):
for file in files:
if file.endswith(".txt"):
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, prompts_path)
prompt_files.append(rel_path)
prompts_paths = folder_paths.get_folder_paths('inspire_prompts')
for prompts_path in prompts_paths:
for root, dirs, files in os.walk(prompts_path):
for file in files:
if file.endswith(".txt"):
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, prompts_path)
prompt_files.append(rel_path)
except Exception:
prompt_files = []

Expand All @@ -235,7 +276,17 @@ def INPUT_TYPES(cls):

@staticmethod
def doit(prompt_file, index, text_data_opt=None):
prompt_path = os.path.join(prompts_path, prompt_file)
prompt_path = None
prompts_paths = folder_paths.get_folder_paths('inspire_prompts')
for d in prompts_paths:
prompt_path = os.path.join(d, prompt_file)
if os.path.exists(prompt_path):
break
else:
prompt_path = None

if prompt_path:
print(f"[WARN] LoadSinglePromptFromFile: file not found '{prompt_file}'")

prompts = []
try:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "comfyui-inspire-pack"
description = "This extension provides various nodes to support Lora Block Weight and the Impact Pack. Provides many easily applicable regional features and applications for Variation Seed."
version = "1.5.1"
version = "1.6"
license = { file = "LICENSE" }
dependencies = ["matplotlib", "cachetools"]

Expand Down

0 comments on commit bfaaa6c

Please sign in to comment.