164 lines
5.6 KiB
Python
164 lines
5.6 KiB
Python
__version__ = "0.0.7"
|
|
|
|
from folder_paths import get_output_directory
|
|
import glob
|
|
import logging
|
|
import os
|
|
import os.path
|
|
import random
|
|
import re
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_full_path(prefix):
|
|
"""Normalize the prefix into a full path"""
|
|
if not os.path.isabs(prefix):
|
|
path = os.path.join(get_output_directory(), prefix)
|
|
else:
|
|
path = prefix
|
|
return path
|
|
|
|
|
|
def get_count_from_path(path):
|
|
"""Given an absolute path, return the number of items in that folder."""
|
|
path = get_full_path(path)
|
|
try:
|
|
count = len(
|
|
[
|
|
name
|
|
for name in os.listdir(path)
|
|
if os.path.isfile(os.path.join(path, name))
|
|
]
|
|
)
|
|
except FileNotFoundError:
|
|
# Folder does not exist yet, give it a zero count
|
|
count = 0
|
|
logger.info("Folder %s has a count of %s" % (path, count))
|
|
return count
|
|
|
|
|
|
def get_existing_folder_numbers_matching_prefix(prefix):
|
|
"""Return a sorted list of integers that match the prefix."""
|
|
prefix_matches = glob.glob(get_full_path(prefix) + "*")
|
|
used = []
|
|
for m in prefix_matches:
|
|
if os.path.isdir(m):
|
|
used.append(int(m.replace(get_full_path(prefix), "")))
|
|
used.sort()
|
|
return used
|
|
|
|
|
|
class DarkFolders(object):
|
|
"""
|
|
Calculate a folder prefix for saving based on a maximum number of files in the folder.
|
|
This allows creating folder names that 'roll over' when they reach a certain number of images.
|
|
Since this is executed once per batch, it is possible to end up with slightly more images in a folder when the folder is under the maximum number of images and the batch size will cause it to go over the maximum number of images.
|
|
"""
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
# For some dumb reason the module doesn't get called every time a
|
|
# batch is run unless some of the data changes. Because of this, we
|
|
# require a seed input even though we don't do anything with it.
|
|
# When the seed changes, DarkFolders is re-evaluated.
|
|
# There is probably a better way of dealing with this, I just haven't
|
|
# bothered to dig for it yet.
|
|
|
|
return {
|
|
"required": {
|
|
"seed": (
|
|
"INT",
|
|
{
|
|
"default": 0,
|
|
"min": 0,
|
|
"max": 0xFFFFFFFFFFFFFFFF,
|
|
"forceInput": True,
|
|
},
|
|
),
|
|
"folder_prefix": ("STRING", {"default": "batch-"}),
|
|
"folder_size": (
|
|
"INT",
|
|
{
|
|
"default": 500,
|
|
"min": 1,
|
|
},
|
|
),
|
|
"selection_method": (
|
|
["Fill Gaps", "Highest Not Full", "New Every Generation"],
|
|
),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ("STRING",)
|
|
FUNCTION = "get_prefix"
|
|
|
|
CATEGORY = "DarkPrompt"
|
|
|
|
def get_prefix(self, seed, folder_prefix, folder_size, selection_method):
|
|
prefix_to_use = folder_prefix
|
|
|
|
existing_folder_numbers = get_existing_folder_numbers_matching_prefix(
|
|
folder_prefix
|
|
)
|
|
|
|
if selection_method == "Fill Gaps":
|
|
# Find the first available
|
|
for i in range(0, 100000):
|
|
item_count = get_count_from_path(get_full_path(folder_prefix + str(i)))
|
|
if item_count < folder_size:
|
|
prefix_to_use = folder_prefix + str(i)
|
|
break
|
|
elif selection_method == "Highest Not Full":
|
|
logger.debug("Using selection method: %s" % (selection_method))
|
|
highest_used_number = 0
|
|
# Loop through all existing folders
|
|
try:
|
|
while existing_folder_numbers:
|
|
# Grab the highest number from the list and pop it
|
|
i = existing_folder_numbers.pop()
|
|
# If the folder number is greater than the highest_used_number AND
|
|
# it has files in it, update the highest_used_number
|
|
if (
|
|
i > highest_used_number
|
|
and get_count_from_path(get_full_path(folder_prefix + str(i)))
|
|
> 0
|
|
):
|
|
if (
|
|
get_count_from_path(get_full_path(folder_prefix + str(i)))
|
|
>= folder_size
|
|
):
|
|
highest_used_number = i + 1
|
|
else:
|
|
highest_used_number = i
|
|
except IndexError:
|
|
# The list of folders is empty
|
|
pass
|
|
|
|
logger.debug(
|
|
"The highest folder number with items in it is: %s"
|
|
% (highest_used_number)
|
|
)
|
|
|
|
for i in range(highest_used_number, highest_used_number + 100):
|
|
fldr = "%s%s" % (folder_prefix, i)
|
|
size = get_count_from_path(fldr)
|
|
if size < folder_size:
|
|
logger.debug("Using folder prefix: %s" % (fldr))
|
|
prefix_to_use = fldr
|
|
break
|
|
elif selection_method == "New Every Generation":
|
|
prefix_to_use = folder_prefix + str(
|
|
existing_folder_numbers.pop() + 1 if existing_folder_numbers else 0
|
|
)
|
|
pass
|
|
else:
|
|
raise Exception("Unknown selection method: %s" % (selection_method))
|
|
|
|
logger.info("Using prefix: %s" % (prefix_to_use))
|
|
|
|
return (prefix_to_use,)
|