diff --git a/src/comfyui_ino_nodes/helper_cloudreve.py b/src/comfyui_ino_nodes/helper_cloudreve.py new file mode 100644 index 0000000..97370d7 --- /dev/null +++ b/src/comfyui_ino_nodes/helper_cloudreve.py @@ -0,0 +1,37 @@ +import io +import base64 +import requests + +import torch +import numpy as np +from PIL import Image + +def rc_get_captcha(api_url: str = "http://your-cloudreve-domain/api/v3/captcha"): + try: + response = requests.get(api_url + "/site/captcha") + response.raise_for_status() + data = response.json() + + if data["code"] != 0 or "data" not in data: + raise ValueError("Invalid response format or failed to get captcha") + + image_base64 = data["data"]["image"].split(",")[1] + ticket = data["data"]["ticket"] + + image_bytes = base64.b64decode(image_base64) + + # 🛑 Make sure it's 3-channel RGB image + image = Image.open(io.BytesIO(image_bytes)).convert("RGB") # shape: [H, W, 3] + + # Convert to NumPy float32 in [0,1] + np_image = np.array(image).astype(np.float32) / 255.0 # shape: [H, W, 3] + + # Convert to torch tensor: [1, 3, H, W] + torch_image = torch.from_numpy(np_image).permute(2, 0, 1).unsqueeze(0) # [1, 3, H, W] + + return torch_image, ticket + + except Exception as e: + print(f"[Captcha Error] {e}") + dummy = torch.zeros((1, 3, 64, 64), dtype=torch.float32) + return dummy, "" diff --git a/src/comfyui_ino_nodes/node_cloudreve.py b/src/comfyui_ino_nodes/node_cloudreve.py new file mode 100644 index 0000000..1bbbc4b --- /dev/null +++ b/src/comfyui_ino_nodes/node_cloudreve.py @@ -0,0 +1,47 @@ +import torch + +from .helper_cloudreve import rc_get_captcha + +from inspect import cleandoc + +class Cloudreve_Get_Captcha: + """ + Cloudreve Get Captcha + """ + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "enabled": ("BOOLEAN", {"default": True, "label_off": "OFF", "label_on": "ON"}), + "server_address": ("STRING", { + "multiline": False, + "default": "token" + }) + } + } + + RETURN_TYPES = ("STRING", "STRING", "IMAGE") + RETURN_NAMES = ("status", "ticket", "image") + DESCRIPTION = cleandoc(__doc__) + FUNCTION = "function" + + # OUTPUT_NODE = True + # OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node + + CATEGORY = "InoNodes" + + def __init__(self): + pass + + + def function(self, enabled, server_address): + if not enabled: + return ("Disabled", "", torch.zeros((1, 3, 64, 64), dtype=torch.float32)) + + img, ticket = rc_get_captcha(server_address) + return ("Fetched", ticket, img) + + # @classmethod + # def IS_CHANGED(s, image, string_field, int_field, float_field, print_to_screen): + # return ""