198 lines
4.7 KiB
Python
198 lines
4.7 KiB
Python
import base64
|
|
import json
|
|
import lzma
|
|
from io import BytesIO
|
|
|
|
import torch
|
|
|
|
NODE_CLASS_MAPPINGS = {}
|
|
NODE_DISPLAY_NAME_MAPPINGS = {}
|
|
|
|
|
|
def register_node(identifier: str, display_name: str):
|
|
def decorator(cls):
|
|
NODE_CLASS_MAPPINGS[identifier] = cls
|
|
NODE_DISPLAY_NAME_MAPPINGS[identifier] = display_name
|
|
|
|
return cls
|
|
|
|
return decorator
|
|
|
|
|
|
def compress(x: bytes):
|
|
comp = lzma.LZMACompressor()
|
|
out = comp.compress(x)
|
|
return out + comp.flush()
|
|
|
|
|
|
def decompress(x: bytes):
|
|
decomp = lzma.LZMADecompressor()
|
|
return decomp.decompress(x)
|
|
|
|
|
|
def base85_encode(x: bytes):
|
|
return base64.b85encode(x)
|
|
|
|
|
|
def base85_decode(x: bytes):
|
|
return base64.b85decode(x)
|
|
|
|
|
|
def torch_save_to_bytes(obj):
|
|
with BytesIO() as f:
|
|
torch.save(obj, f)
|
|
return f.getvalue()
|
|
|
|
|
|
def torch_load_from_bytes(text: bytes):
|
|
with BytesIO(text) as f:
|
|
return torch.load(f)
|
|
|
|
|
|
def torch_save_to_blob(obj):
|
|
return base85_encode(compress(torch_save_to_bytes(obj)))
|
|
|
|
|
|
def torch_load_from_blob(text: bytes):
|
|
return torch_load_from_bytes(decompress(base85_decode(text)))
|
|
|
|
|
|
@register_node("RCReceiveLatent", "Remote Call: Receive Latent")
|
|
class _:
|
|
CATEGORY = "jamesWalker55/rc"
|
|
INPUT_TYPES = lambda: {
|
|
"required": {
|
|
"key": (
|
|
"STRING",
|
|
{"default": "input_latent", "multiline": False},
|
|
),
|
|
"value": (
|
|
"STRING",
|
|
{"default": "Don't touch this field!", "multiline": False},
|
|
),
|
|
}
|
|
}
|
|
RETURN_TYPES = ("LATENT",)
|
|
FUNCTION = "execute"
|
|
|
|
def execute(self, key: str, value: str):
|
|
latent = torch_load_from_blob(value)
|
|
val = {"samples": latent}
|
|
# { "samples": <Latent: [1, 4, 64, 64]> }
|
|
return (val,)
|
|
|
|
|
|
@register_node("RCReceiveInt", "Remote Call: Receive Integer")
|
|
class _:
|
|
CATEGORY = "jamesWalker55/rc"
|
|
INPUT_TYPES = lambda: {
|
|
"required": {
|
|
"key": (
|
|
"STRING",
|
|
{"default": "input_integer", "multiline": False},
|
|
),
|
|
"value": ("INT", {"default": 0, "min": -99999999999, "max": 99999999999}),
|
|
}
|
|
}
|
|
RETURN_TYPES = ("INT",)
|
|
FUNCTION = "execute"
|
|
|
|
def execute(self, key: str, value):
|
|
return (value,)
|
|
|
|
|
|
@register_node("RCReceiveFloat", "Remote Call: Receive Float")
|
|
class _:
|
|
CATEGORY = "jamesWalker55/rc"
|
|
INPUT_TYPES = lambda: {
|
|
"required": {
|
|
"key": (
|
|
"STRING",
|
|
{"default": "input_float", "multiline": False},
|
|
),
|
|
"value": ("FLOAT", {"default": 0, "min": -99999999999, "max": 99999999999}),
|
|
}
|
|
}
|
|
RETURN_TYPES = ("FLOAT",)
|
|
FUNCTION = "execute"
|
|
|
|
def execute(self, key: str, value):
|
|
return (value,)
|
|
|
|
|
|
@register_node("RCReceiveIntList", "Remote Call: Receive Integer List")
|
|
class _:
|
|
CATEGORY = "jamesWalker55/rc"
|
|
INPUT_TYPES = lambda: {
|
|
"required": {
|
|
"key": (
|
|
"STRING",
|
|
{"default": "input_integer_list", "multiline": False},
|
|
),
|
|
"value": (
|
|
"STRING",
|
|
{"default": "[1, 2, 3]", "multiline": False},
|
|
),
|
|
}
|
|
}
|
|
RETURN_TYPES = ("INT_LIST",)
|
|
FUNCTION = "execute"
|
|
|
|
def execute(self, key: str, value):
|
|
value = json.loads(value)
|
|
return (value,)
|
|
|
|
|
|
@register_node("RCReceiveFloatList", "Remote Call: Receive Float List")
|
|
class _:
|
|
CATEGORY = "jamesWalker55/rc"
|
|
INPUT_TYPES = lambda: {
|
|
"required": {
|
|
"key": (
|
|
"STRING",
|
|
{"default": "input_float_list", "multiline": False},
|
|
),
|
|
"value": (
|
|
"STRING",
|
|
{"default": "[1.0, 2.0, 3.0]", "multiline": False},
|
|
),
|
|
}
|
|
}
|
|
RETURN_TYPES = ("FLOAT_LIST",)
|
|
FUNCTION = "execute"
|
|
|
|
def execute(self, key: str, value):
|
|
value = json.loads(value)
|
|
return (value,)
|
|
|
|
|
|
@register_node("RCSendLatent", "Remote Call: Send Latent")
|
|
class _:
|
|
CATEGORY = "jamesWalker55/rc"
|
|
INPUT_TYPES = lambda: {
|
|
"required": {
|
|
"key": (
|
|
"STRING",
|
|
{"default": "input_latent", "multiline": False},
|
|
),
|
|
"latent": ("LATENT",),
|
|
}
|
|
}
|
|
FUNCTION = "execute"
|
|
RETURN_TYPES = ()
|
|
OUTPUT_NODE = True
|
|
|
|
def execute(self, key: str, latent: str):
|
|
blob = torch_save_to_blob(latent["samples"])
|
|
|
|
return {
|
|
"ui": {
|
|
"jw_rc": (
|
|
{
|
|
"type": "latent",
|
|
"value": blob.decode(),
|
|
},
|
|
),
|
|
}
|
|
}
|