Files
T

190 lines
5.2 KiB
Python

import os
import torch
import comfy.model_management
class _AnyType(str):
"""Always equal in != comparisons — allows ComfyUI to accept any input type."""
def __ne__(self, other): return False
_any_type = _AnyType("*")
class _FlexibleOptionalInputType(dict):
"""Makes INPUT_TYPES accept dynamic unknown keys (e.g. file_1, file_2, ...)."""
def __init__(self, type):
self.type = type
def __getitem__(self, key):
return (self.type,)
def __contains__(self, key):
return True
def load_strings_from_files(file_paths):
all_lines = []
for file_path in file_paths:
if not os.path.exists(file_path):
print(f"[BishaNodes] Файл не найден: {file_path}")
continue
try:
with open(file_path, 'r', encoding='utf-8') as f:
all_lines.extend(line.strip() for line in f if line.strip())
except UnicodeDecodeError:
try:
with open(file_path, 'r', encoding='cp1251') as f:
all_lines.extend(line.strip() for line in f if line.strip())
except Exception as e:
print(f"[BishaNodes] Не удалось прочитать файл {file_path}: {e}")
except Exception as e:
print(f"[BishaNodes] Ошибка при обработке файла {file_path}: {e}")
return all_lines
square_resolutions = [
"512 x 512 (1:1)",
"768 x 768 (1:1)",
"1024 x 1024 (1:1)",
"1536 x 1536 (1:1)",
"2048 x 2048 (1:1)"
]
portrait_resolutions = [
"512 x 768 (2:3)",
"768 x 1152 (2:3)",
"1024 x 1536 (2:3)",
"1152 x 1728 (2:3)",
"832 x 1216 (≈3:4)",
"1024 x 1360 (≈3:4)",
"1080 x 1920 (9:16)"
]
landscape_resolutions = [
"768 x 512 (3:2)",
"1152 x 768 (3:2)",
"1536 x 1024 (3:2)",
"1216 x 832 (≈4:3)",
"1360 x 1024 (≈4:3)",
"1920 x 1080 (16:9)",
"2048 x 1152 (16:9)",
"2560 x 1440 (16:9)",
"3840 x 2160 (16:9)"
]
widescreen_resolutions = [
"1344 x 768 (16:9)",
"1792 x 1024 (16:9)",
"2048 x 1080 (≈17:9, DCI 2K)"
]
ultrawide_resolutions = [
"2560 x 1080 (64:27 ≈ 21:9)",
"3440 x 1440 (43:18 ≈ 21.5:9)",
"3840 x 1600 (12:5 = 21.6:9)",
"5120 x 2160 (64:27 ≈ 21:9, 5K UW)"
]
super_ultrawide_resolutions = [
"3840 x 1080 (32:9, Dual Full HD)",
"5120 x 1440 (32:9, Dual QHD)",
"7680 x 2160 (32:9, 8K Ultra Wide)"
]
panoramic_resolutions = [
"5760 x 1080 (48:9 = 16:3, Triple Full HD)",
"7680 x 1440 (48:9 = 16:3, Triple QHD)",
"9600 x 1200 (8:1, Custom Ultra Panoramic)"
]
resolutions = (
square_resolutions +
portrait_resolutions +
landscape_resolutions +
widescreen_resolutions +
ultrawide_resolutions +
super_ultrawide_resolutions +
panoramic_resolutions
)
class SimpleSizePicker:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"resolution": (resolutions, {"default": square_resolutions[0]}),
}
}
RETURN_TYPES = ("INT", "INT",)
RETURN_NAMES = ("width", "height",)
FUNCTION = "execute"
CATEGORY = "BishaNodes"
def execute(self, resolution):
width, height = map(int, resolution.split(" (")[0].split(" x "))
return (width, height,)
class EmptyLatentSizePicker:
def __init__(self):
self.device = comfy.model_management.intermediate_device()
@classmethod
def INPUT_TYPES(cls):
return {"required": {
"resolution": (resolutions, {"default": "1024x1024 (1.0)"}),
"batch_size": ("INT", {"default": 1, "min": 1, "max": 4096}),
}}
RETURN_TYPES = ("LATENT", "INT", "INT",)
RETURN_NAMES = ("LATENT", "width", "height",)
FUNCTION = "execute"
CATEGORY = "BishaNodes"
def execute(self, resolution, batch_size):
width, height = map(int, resolution.split(" (")[0].split(" x "))
latent = torch.zeros([batch_size, 4, height // 8, width // 8], device=self.device)
return ({"samples": latent}, width, height,)
class LoadDataFromFiles:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {},
"optional": _FlexibleOptionalInputType(_any_type),
}
RETURN_TYPES = ("STRING", "STRING", "INT",)
RETURN_NAMES = ("values list", "values", "count")
OUTPUT_IS_LIST = (True, False, False)
FUNCTION = "execute"
CATEGORY = "BishaNodes"
def execute(self, **kwargs):
# Collect all active file paths from dynamic widgets: {"on": bool, "file": str}
files = [
v["file"]
for k, v in kwargs.items()
if k.startswith("file_") and isinstance(v, dict)
and v.get("on") and v.get("file", "").strip()
]
lines_list = load_strings_from_files(files)
line_count = len(lines_list)
lines = ", ".join(lines_list)
return (lines_list, lines, line_count,)
MISC_CLASS_MAPPINGS = {
"SimpleSizePicker": SimpleSizePicker,
"EmptyLatentSizePicker": EmptyLatentSizePicker,
"LoadDataFromFiles": LoadDataFromFiles,
}
MISC_NAME_MAPPINGS = {
"SimpleSizePicker": "Simple Size Picker",
"EmptyLatentSizePicker": "Empty Latent Size Picker",
"LoadDataFromFiles": "Load Data From Files",
}