From 9ba9db55c601e1efd9e8fd4be96a299573218adf Mon Sep 17 00:00:00 2001 From: ethanfel Date: Fri, 2 Jan 2026 01:08:39 +0100 Subject: [PATCH] Refactor JSON loader classes for better structure --- json_loader.py | 304 ++++++++++++++++++++++++------------------------- 1 file changed, 147 insertions(+), 157 deletions(-) diff --git a/json_loader.py b/json_loader.py index ce74a34..d3eafb3 100644 --- a/json_loader.py +++ b/json_loader.py @@ -23,23 +23,16 @@ class JSONLoaderLoRA: return {"required": {"json_path": ("STRING", {"default": "", "multiline": False})}} RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "STRING") - RETURN_NAMES = ( - "lora_1_high", "lora_1_low", - "lora_2_high", "lora_2_low", - "lora_3_high", "lora_3_low" - ) + RETURN_NAMES = ("lora_1_high", "lora_1_low", "lora_2_high", "lora_2_low", "lora_3_high", "lora_3_low") FUNCTION = "load_loras" CATEGORY = "utils/json" def load_loras(self, json_path): data = read_json_data(json_path) return ( - str(data.get("lora 1 high", "")), - str(data.get("lora 1 low", "")), - str(data.get("lora 2 high", "")), - str(data.get("lora 2 low", "")), - str(data.get("lora 3 high", "")), - str(data.get("lora 3 low", "")) + str(data.get("lora 1 high", "")), str(data.get("lora 1 low", "")), + str(data.get("lora 2 high", "")), str(data.get("lora 2 low", "")), + str(data.get("lora 3 high", "")), str(data.get("lora 3 low", "")) ) class JSONLoaderStandard: @@ -47,16 +40,8 @@ class JSONLoaderStandard: def INPUT_TYPES(s): return {"required": {"json_path": ("STRING", {"default": "", "multiline": False})}} - RETURN_TYPES = ( - "STRING", "STRING", "STRING", "STRING", - "STRING", "FLOAT", "INT", - "STRING", "STRING", "STRING" - ) - RETURN_NAMES = ( - "general_prompt", "general_negative", "current_prompt", "negative", - "camera", "flf", "seed", - "video_file_path", "reference_image_path", "flf_image_path" - ) + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "INT", "STRING", "STRING", "STRING") + RETURN_NAMES = ("general_prompt", "general_negative", "current_prompt", "negative", "camera", "flf", "seed", "video_file_path", "reference_image_path", "flf_image_path") FUNCTION = "load_standard" CATEGORY = "utils/json" @@ -70,16 +55,11 @@ class JSONLoaderStandard: except: return 0 return ( - str(data.get("general_prompt", "")), - str(data.get("general_negative", "")), - str(data.get("current_prompt", "")), - str(data.get("negative", "")), - str(data.get("camera", "")), - to_float(data.get("flf", 0.0)), - to_int(data.get("seed", 0)), - str(data.get("video file path", "")), - str(data.get("reference image path", "")), - str(data.get("flf image path", "")) + str(data.get("general_prompt", "")), str(data.get("general_negative", "")), + str(data.get("current_prompt", "")), str(data.get("negative", "")), + str(data.get("camera", "")), to_float(data.get("flf", 0.0)), + to_int(data.get("seed", 0)), str(data.get("video file path", "")), + str(data.get("reference image path", "")), str(data.get("flf image path", "")) ) class JSONLoaderVACE: @@ -87,18 +67,8 @@ class JSONLoaderVACE: def INPUT_TYPES(s): return {"required": {"json_path": ("STRING", {"default": "", "multiline": False})}} - RETURN_TYPES = ( - "STRING", "STRING", "STRING", "STRING", - "STRING", "FLOAT", "INT", - "INT", "INT", "INT", "STRING", "INT", "INT", - "STRING", "STRING" - ) - RETURN_NAMES = ( - "general_prompt", "general_negative", "current_prompt", "negative", - "camera", "flf", "seed", - "frame_to_skip", "input_a_frames", "input_b_frames", "reference_path", "reference_switch", "vace_schedule", - "video_file_path", "reference_image_path" - ) + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "INT", "INT", "INT", "INT", "STRING", "INT", "INT", "STRING", "STRING") + RETURN_NAMES = ("general_prompt", "general_negative", "current_prompt", "negative", "camera", "flf", "seed", "frame_to_skip", "input_a_frames", "input_b_frames", "reference_path", "reference_switch", "vace_schedule", "video_file_path", "reference_image_path") FUNCTION = "load_vace" CATEGORY = "utils/json" @@ -112,88 +82,47 @@ class JSONLoaderVACE: except: return 0 return ( - str(data.get("general_prompt", "")), - str(data.get("general_negative", "")), - str(data.get("current_prompt", "")), - str(data.get("negative", "")), - str(data.get("camera", "")), - to_float(data.get("flf", 0.0)), + str(data.get("general_prompt", "")), str(data.get("general_negative", "")), + str(data.get("current_prompt", "")), str(data.get("negative", "")), + str(data.get("camera", "")), to_float(data.get("flf", 0.0)), to_int(data.get("seed", 0)), - - to_int(data.get("frame_to_skip", 81)), - to_int(data.get("input_a_frames", 0)), - to_int(data.get("input_b_frames", 0)), - str(data.get("reference path", "")), - to_int(data.get("reference switch", 1)), - to_int(data.get("vace schedule", 1)), - - str(data.get("video file path", "")), - str(data.get("reference image path", "")) + to_int(data.get("frame_to_skip", 81)), to_int(data.get("input_a_frames", 0)), + to_int(data.get("input_b_frames", 0)), str(data.get("reference path", "")), + to_int(data.get("reference switch", 1)), to_int(data.get("vace schedule", 1)), + str(data.get("video file path", "")), str(data.get("reference image path", "")) ) # ========================================== -# 3. BATCH NODES (Sequence Support) +# 2. BATCH NODES # ========================================== -# --- NEW: BATCH LORA --- class JSONLoaderBatchLoRA: @classmethod def INPUT_TYPES(s): - return { - "required": { - "json_path": ("STRING", {"default": "", "multiline": False}), - "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999}) - } - } - + return {"required": {"json_path": ("STRING", {"default": "", "multiline": False}), "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999})}} RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "STRING") - RETURN_NAMES = ( - "lora_1_high", "lora_1_low", - "lora_2_high", "lora_2_low", - "lora_3_high", "lora_3_low" - ) + RETURN_NAMES = ("lora_1_high", "lora_1_low", "lora_2_high", "lora_2_low", "lora_3_high", "lora_3_low") FUNCTION = "load_batch_loras" CATEGORY = "utils/json" def load_batch_loras(self, json_path, sequence_number): data = read_json_data(json_path) - - # Batch Logic target_data = data if "batch_data" in data and isinstance(data["batch_data"], list) and len(data["batch_data"]) > 0: - idx = sequence_number - 1 - idx = idx % len(data["batch_data"]) + idx = (sequence_number - 1) % len(data["batch_data"]) target_data = data["batch_data"][idx] - return ( - str(target_data.get("lora 1 high", "")), - str(target_data.get("lora 1 low", "")), - str(target_data.get("lora 2 high", "")), - str(target_data.get("lora 2 low", "")), - str(target_data.get("lora 3 high", "")), - str(target_data.get("lora 3 low", "")) + str(target_data.get("lora 1 high", "")), str(target_data.get("lora 1 low", "")), + str(target_data.get("lora 2 high", "")), str(target_data.get("lora 2 low", "")), + str(target_data.get("lora 3 high", "")), str(target_data.get("lora 3 low", "")) ) class JSONLoaderBatchI2V: @classmethod def INPUT_TYPES(s): - return { - "required": { - "json_path": ("STRING", {"default": "", "multiline": False}), - "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999}) - } - } - - RETURN_TYPES = ( - "STRING", "STRING", "STRING", "STRING", - "STRING", "FLOAT", "INT", - "STRING", "STRING", "STRING" - ) - RETURN_NAMES = ( - "general_prompt", "general_negative", "current_prompt", "negative", - "camera", "flf", "seed", - "video_file_path", "reference_image_path", "flf_image_path" - ) + return {"required": {"json_path": ("STRING", {"default": "", "multiline": False}), "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999})}} + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "INT", "STRING", "STRING", "STRING") + RETURN_NAMES = ("general_prompt", "general_negative", "current_prompt", "negative", "camera", "flf", "seed", "video_file_path", "reference_image_path", "flf_image_path") FUNCTION = "load_batch_i2v" CATEGORY = "utils/json" @@ -201,53 +130,28 @@ class JSONLoaderBatchI2V: data = read_json_data(json_path) target_data = data if "batch_data" in data and isinstance(data["batch_data"], list) and len(data["batch_data"]) > 0: - idx = sequence_number - 1 - idx = idx % len(data["batch_data"]) + idx = (sequence_number - 1) % len(data["batch_data"]) target_data = data["batch_data"][idx] - def to_float(val): try: return float(val) except: return 0.0 def to_int(val): try: return int(float(val)) except: return 0 - return ( - str(target_data.get("general_prompt", "")), - str(target_data.get("general_negative", "")), - str(target_data.get("current_prompt", "")), - str(target_data.get("negative", "")), - str(target_data.get("camera", "")), - to_float(target_data.get("flf", 0.0)), - to_int(target_data.get("seed", 0)), - str(target_data.get("video file path", "")), - str(target_data.get("reference image path", "")), - str(target_data.get("flf image path", "")) + str(target_data.get("general_prompt", "")), str(target_data.get("general_negative", "")), + str(target_data.get("current_prompt", "")), str(target_data.get("negative", "")), + str(target_data.get("camera", "")), to_float(target_data.get("flf", 0.0)), + to_int(target_data.get("seed", 0)), str(target_data.get("video file path", "")), + str(target_data.get("reference image path", "")), str(target_data.get("flf image path", "")) ) - class JSONLoaderBatchVACE: @classmethod def INPUT_TYPES(s): - return { - "required": { - "json_path": ("STRING", {"default": "", "multiline": False}), - "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999}) - } - } - - RETURN_TYPES = ( - "STRING", "STRING", "STRING", "STRING", - "STRING", "FLOAT", "INT", - "INT", "INT", "INT", "STRING", "INT", "INT", - "STRING", "STRING" - ) - RETURN_NAMES = ( - "general_prompt", "general_negative", "current_prompt", "negative", - "camera", "flf", "seed", - "frame_to_skip", "input_a_frames", "input_b_frames", "reference_path", "reference_switch", "vace_schedule", - "video_file_path", "reference_image_path" - ) + return {"required": {"json_path": ("STRING", {"default": "", "multiline": False}), "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999})}} + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "FLOAT", "INT", "INT", "INT", "INT", "STRING", "INT", "INT", "STRING", "STRING") + RETURN_NAMES = ("general_prompt", "general_negative", "current_prompt", "negative", "camera", "flf", "seed", "frame_to_skip", "input_a_frames", "input_b_frames", "reference_path", "reference_switch", "vace_schedule", "video_file_path", "reference_image_path") FUNCTION = "load_batch_vace" CATEGORY = "utils/json" @@ -255,37 +159,117 @@ class JSONLoaderBatchVACE: data = read_json_data(json_path) target_data = data if "batch_data" in data and isinstance(data["batch_data"], list) and len(data["batch_data"]) > 0: - idx = sequence_number - 1 - idx = idx % len(data["batch_data"]) + idx = (sequence_number - 1) % len(data["batch_data"]) target_data = data["batch_data"][idx] - def to_float(val): try: return float(val) except: return 0.0 def to_int(val): try: return int(float(val)) except: return 0 - return ( - str(target_data.get("general_prompt", "")), - str(target_data.get("general_negative", "")), - str(target_data.get("current_prompt", "")), - str(target_data.get("negative", "")), - str(target_data.get("camera", "")), - to_float(target_data.get("flf", 0.0)), - to_int(target_data.get("seed", 0)), - - to_int(target_data.get("frame_to_skip", 81)), - to_int(target_data.get("input_a_frames", 0)), - to_int(target_data.get("input_b_frames", 0)), - str(target_data.get("reference path", "")), - to_int(target_data.get("reference switch", 1)), - to_int(target_data.get("vace schedule", 1)), - - str(target_data.get("video file path", "")), + str(target_data.get("general_prompt", "")), str(target_data.get("general_negative", "")), + str(target_data.get("current_prompt", "")), str(target_data.get("negative", "")), + str(target_data.get("camera", "")), to_float(target_data.get("flf", 0.0)), + to_int(target_data.get("seed", 0)), to_int(target_data.get("frame_to_skip", 81)), + to_int(target_data.get("input_a_frames", 0)), to_int(target_data.get("input_b_frames", 0)), + str(target_data.get("reference path", "")), to_int(target_data.get("reference switch", 1)), + to_int(target_data.get("vace schedule", 1)), str(target_data.get("video file path", "")), str(target_data.get("reference image path", "")) ) +# ========================================== +# 3. UNIVERSAL CUSTOM NODES (1, 3, 6 Slots) +# ========================================== + +class JSONLoaderCustom1: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "json_path": ("STRING", {"default": "", "multiline": False}), + "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999}), + }, + "optional": { "key_1": ("STRING", {"default": "", "multiline": False}) } + } + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("val_1",) + FUNCTION = "load_custom" + CATEGORY = "utils/json" + + def load_custom(self, json_path, sequence_number, key_1=""): + data = read_json_data(json_path) + target_data = data + if "batch_data" in data and isinstance(data["batch_data"], list) and len(data["batch_data"]) > 0: + idx = (sequence_number - 1) % len(data["batch_data"]) + target_data = data["batch_data"][idx] + return (str(target_data.get(key_1, "")),) + +class JSONLoaderCustom3: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "json_path": ("STRING", {"default": "", "multiline": False}), + "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999}), + }, + "optional": { + "key_1": ("STRING", {"default": "", "multiline": False}), + "key_2": ("STRING", {"default": "", "multiline": False}), + "key_3": ("STRING", {"default": "", "multiline": False}) + } + } + RETURN_TYPES = ("STRING", "STRING", "STRING") + RETURN_NAMES = ("val_1", "val_2", "val_3") + FUNCTION = "load_custom" + CATEGORY = "utils/json" + + def load_custom(self, json_path, sequence_number, key_1="", key_2="", key_3=""): + data = read_json_data(json_path) + target_data = data + if "batch_data" in data and isinstance(data["batch_data"], list) and len(data["batch_data"]) > 0: + idx = (sequence_number - 1) % len(data["batch_data"]) + target_data = data["batch_data"][idx] + return ( + str(target_data.get(key_1, "")), + str(target_data.get(key_2, "")), + str(target_data.get(key_3, "")) + ) + +class JSONLoaderCustom6: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "json_path": ("STRING", {"default": "", "multiline": False}), + "sequence_number": ("INT", {"default": 1, "min": 1, "max": 9999}), + }, + "optional": { + "key_1": ("STRING", {"default": "", "multiline": False}), + "key_2": ("STRING", {"default": "", "multiline": False}), + "key_3": ("STRING", {"default": "", "multiline": False}), + "key_4": ("STRING", {"default": "", "multiline": False}), + "key_5": ("STRING", {"default": "", "multiline": False}), + "key_6": ("STRING", {"default": "", "multiline": False}) + } + } + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "STRING") + RETURN_NAMES = ("val_1", "val_2", "val_3", "val_4", "val_5", "val_6") + FUNCTION = "load_custom" + CATEGORY = "utils/json" + + def load_custom(self, json_path, sequence_number, key_1="", key_2="", key_3="", key_4="", key_5="", key_6=""): + data = read_json_data(json_path) + target_data = data + if "batch_data" in data and isinstance(data["batch_data"], list) and len(data["batch_data"]) > 0: + idx = (sequence_number - 1) % len(data["batch_data"]) + target_data = data["batch_data"][idx] + return ( + str(target_data.get(key_1, "")), str(target_data.get(key_2, "")), + str(target_data.get(key_3, "")), str(target_data.get(key_4, "")), + str(target_data.get(key_5, "")), str(target_data.get(key_6, "")) + ) + # --- Mappings --- NODE_CLASS_MAPPINGS = { "JSONLoaderLoRA": JSONLoaderLoRA, @@ -293,7 +277,10 @@ NODE_CLASS_MAPPINGS = { "JSONLoaderVACE": JSONLoaderVACE, "JSONLoaderBatchLoRA": JSONLoaderBatchLoRA, "JSONLoaderBatchI2V": JSONLoaderBatchI2V, - "JSONLoaderBatchVACE": JSONLoaderBatchVACE + "JSONLoaderBatchVACE": JSONLoaderBatchVACE, + "JSONLoaderCustom1": JSONLoaderCustom1, + "JSONLoaderCustom3": JSONLoaderCustom3, + "JSONLoaderCustom6": JSONLoaderCustom6 } NODE_DISPLAY_NAME_MAPPINGS = { @@ -302,5 +289,8 @@ NODE_DISPLAY_NAME_MAPPINGS = { "JSONLoaderVACE": "JSON Loader (VACE Full)", "JSONLoaderBatchLoRA": "JSON Batch Loader (LoRAs)", "JSONLoaderBatchI2V": "JSON Batch Loader (I2V)", - "JSONLoaderBatchVACE": "JSON Batch Loader (VACE)" + "JSONLoaderBatchVACE": "JSON Batch Loader (VACE)", + "JSONLoaderCustom1": "JSON Loader (Custom 1)", + "JSONLoaderCustom3": "JSON Loader (Custom 3)", + "JSONLoaderCustom6": "JSON Loader (Custom 6)" }