Files
RiceRound-ComfyUI_CryptoCat/crypto_node.py
T
RiceRound e614d4e974 Major version update with enhanced functionality
Added environment-based configuration to streamline deployments
Improved data validation logic for more robust CRUD operations
Refined folder structure to optimize code organization
2025-01-14 04:20:56 +08:00

266 lines
8.2 KiB
Python

import json
import os
import random
import uuid
import torch
from comfy_execution.graph import ExecutionBlocker
from comfy_execution.graph_utils import GraphBuilder
from .updown_workflow import UploadWorkflow
from server import PromptServer
from .trim_workflow import CryptoWorkflow, DecodeCryptoWorkflow
from .auth_unit import AuthUnit
class SaveCryptoNode:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {"template_id": ("STRING", {"default": uuid.uuid4().hex})},
"optional": {"input_anything": ("*", {})},
"hidden": {
"unique_id": "UNIQUE_ID",
"prompt": "PROMPT",
"extra_pnginfo": "EXTRA_PNGINFO",
},
}
RETURN_TYPES = ()
OUTPUT_NODE = True
FUNCTION = "crypto"
CATEGORY = "advanced/CryptoCat"
@classmethod
def IS_CHANGED(s, **kwargs):
return float("NaN")
@classmethod
def VALIDATE_INPUTS(s, input_types):
return True
def crypto(self, template_id, **kwargs):
unique_id = kwargs.pop("unique_id", None)
prompt = kwargs.pop("prompt", None)
extra_pnginfo = kwargs.pop("extra_pnginfo", None)
if unique_id is None:
raise Exception("Warning: 'unique_id' is missing.")
if prompt is None:
raise Exception("Warning: 'prompt' is missing.")
if len(template_id) != 32:
raise Exception("Warning: 'template_id' length is not 32.")
crypto_workflow = CryptoWorkflow(extra_pnginfo["workflow"], prompt, template_id)
crypto_workflow.invalid_workflow()
crypto_workflow.load_workflow()
crypto_workflow.load_prompt()
crypto_workflow.analysis_node()
crypto_dir = crypto_workflow.calculate_crypto_result(
f"crypto_{template_id}.json"
)
output_dir = crypto_workflow.output_workflow_simple_shell(
f"cryptocat_{template_id}.json"
)
crypto_workflow.save_original_workflow(
f"original_workflow_{template_id}.json", crypto_dir
)
crypto_workflow.save_original_prompt(
f"original_prompt_{template_id}.json", crypto_dir
)
user_token, error_msg = AuthUnit().get_user_token()
if not user_token:
if error_msg == "no token found" or error_msg == "login failed":
AuthUnit().login_dialog("输出CryptoCat加密工作流,请先完成登录")
else:
PromptServer.instance.send_sync(
"cryptocat_toast",
{"content": "无法完成鉴权登录,请检查网络或完成登录步骤", "type": "error"},
)
return (ExecutionBlocker(None),)
upload = UploadWorkflow(user_token)
ret = upload.upload_workflow(template_id, crypto_dir)
if not ret:
print("crypto cat upload failed")
return (ExecutionBlocker(None),)
serial_numbers = upload.generate_serial_number(template_id, 10)
if serial_numbers:
sn_file_path = os.path.join(output_dir, f"serial_numbers_{template_id}.txt")
with open(sn_file_path, "w", encoding="utf-8") as f:
f.write("\n".join(serial_numbers))
PromptServer.instance.send_sync(
"cryptocat_toast",
{
"content": f"加密完成,在{sn_file_path}中查看序列号",
"type": "info",
"duration": 5000,
},
)
return (template_id,)
class AnyType(str):
def __ne__(self, __value: object) -> bool:
return False
any = AnyType("*")
class SaveCryptoBridgeNode:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {"required": {"value": (any,)}}
@classmethod
def VALIDATE_INPUTS(s, input_types):
return True
@classmethod
def IS_CHANGED(cls, **kwargs):
return float("NaN")
RETURN_TYPES = (any,)
FUNCTION = "doit"
CATEGORY = "advanced/CryptoCat"
def doit(self, value):
return (value,)
def is_link(obj):
if not isinstance(obj, list):
return False
if len(obj) != 2:
return False
if not isinstance(obj[0], str):
return False
if (
not isinstance(obj[1], int)
and not isinstance(obj[1], float)
and not isinstance(obj[1], str)
):
return False
return True
class AlwaysEqualProxy(str):
def __eq__(self, _):
return True
def __ne__(self, _):
return False
class AlwaysTupleZero(tuple):
def __getitem__(self, _):
return AlwaysEqualProxy(super().__getitem__(0))
class DecodeCryptoNode:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"template_id": ("STRING",),
"serial_number": (
"STRING",
{"multiline": True, "placeholder": "请输入序列号"},
),
},
"optional": {"input_anything": (any,)},
"hidden": {
"unique_id": "UNIQUE_ID",
"prompt": "PROMPT",
"extra_pnginfo": "EXTRA_PNGINFO",
},
}
@classmethod
def VALIDATE_INPUTS(s, input_types):
return True
@classmethod
def IS_CHANGED(cls, **kwargs):
return float("NaN")
RETURN_TYPES = AlwaysTupleZero(AlwaysEqualProxy("*"))
FUNCTION = "decode"
CATEGORY = "advanced/CryptoCat"
OUTPUT_NODE = False
def decode(self, template_id, serial_number, **kwargs):
unique_id = kwargs.pop("unique_id", None)
prompt = kwargs.pop("prompt", None)
extra_pnginfo = kwargs.pop("extra_pnginfo", None)
decode_crypto_workflow = DecodeCryptoWorkflow(
prompt, extra_pnginfo["workflow"], template_id
)
crypto_prompt = decode_crypto_workflow.load_crypto_prompt(serial_number)
decode_crypto_workflow.calculate_input_anything_map()
processed_nodes = {}
graph = GraphBuilder()
def get_node_result(nodeData, id):
inputKeys = []
for ikey in nodeData["inputs"].keys():
input_value = nodeData["inputs"][ikey]
if (
is_link(input_value)
and decode_crypto_workflow.get_hidden_input(input_value) is None
and input_value[0] not in processed_nodes
):
inputKeys.append(input_value[0])
for ikey in inputKeys:
if ikey not in crypto_prompt:
continue
node = get_node_result(crypto_prompt[ikey], ikey)
processed_nodes[ikey] = node
inputs = nodeData["inputs"]
newInputs = {}
for ikey in inputs.keys():
if is_link(inputs[ikey]):
hidden_input_name = decode_crypto_workflow.get_hidden_input(
inputs[ikey]
)
if hidden_input_name:
if hidden_input_name in kwargs:
newInputs[ikey] = kwargs[hidden_input_name]
elif inputs[ikey][0] in processed_nodes:
newInputs[ikey] = processed_nodes[inputs[ikey][0]].out(
inputs[ikey][1]
)
else:
newInputs[ikey] = inputs[ikey]
return graph.node(nodeData["class_type"], id, **newInputs)
node_id, link_idx = decode_crypto_workflow.get_outputs()
nodeData = crypto_prompt[node_id]
node = get_node_result(nodeData, node_id)
value = node.out(link_idx)
return {"result": tuple([value]), "expand": graph.finalize()}
class RandomSeedNode:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {"required": {}, "optional": {}, "hidden": {}}
RETURN_TYPES = ("INT",)
FUNCTION = "random"
CATEGORY = "advanced/CryptoCat"
def IS_CHANGED():
return float("NaN")
def random(self):
return (random.randint(0, 999999),)