diff --git a/main.py b/main.py index 283b0bd2..f8361dc5 100644 --- a/main.py +++ b/main.py @@ -35,7 +35,7 @@ if __name__ == "__main__": import torch import nodes -def get_input_data(inputs, class_def, outputs={}, prompt={}, extra_data={}, server=None, unique_id=None): +def get_input_data(inputs, class_def, outputs={}, prompt={}, extra_data={}): valid_inputs = class_def.INPUT_TYPES() input_data_all = {} for x in inputs: @@ -57,10 +57,6 @@ def get_input_data(inputs, class_def, outputs={}, prompt={}, extra_data={}, serv if h[x] == "EXTRA_PNGINFO": if "extra_pnginfo" in extra_data: input_data_all[x] = extra_data['extra_pnginfo'] - if h[x] == "SERVER": - input_data_all[x] = server - if h[x] == "UNIQUE_ID": - input_data_all[x] = unique_id return input_data_all def recursive_execute(server, prompt, outputs, current_item, extra_data={}): @@ -84,10 +80,12 @@ def recursive_execute(server, prompt, outputs, current_item, extra_data={}): input_data_all = get_input_data(inputs, class_def, outputs, prompt, extra_data, server, unique_id) if server.client_id is not None: - server.send_sync("execute", { "node": unique_id }, server.client_id) + server.send_sync("executing", { "node": unique_id }, server.client_id) obj = class_def() outputs[unique_id] = getattr(obj, obj.FUNCTION)(**input_data_all) + if "ui" in outputs[unique_id] and server.client_id is not None: + server.send_sync("executed", { "node": unique_id, "output": outputs[unique_id]["ui"] }, server.client_id) return executed + [unique_id] def recursive_will_execute(prompt, outputs, current_item): @@ -195,7 +193,6 @@ class PromptExecutor: valid = False if valid: executed += recursive_execute(self.server, prompt, self.outputs, x, extra_data) - except Exception as e: print(traceback.format_exc()) to_delete = [] @@ -212,10 +209,9 @@ class PromptExecutor: executed = set(executed) for x in executed: self.old_prompt[x] = copy.deepcopy(prompt[x]) - finally: if self.server.client_id is not None: - self.server.send_sync("execute", { "node": None }, self.server.client_id) + self.server.send_sync("executing", { "node": None }, self.server.client_id) torch.cuda.empty_cache() @@ -307,7 +303,7 @@ def prompt_worker(q, server): while True: item, item_id = q.get() e.execute(item[-2], item[-1]) - q.task_done(item_id) + q.task_done(item_id, e.outputs) class PromptQueue: def __init__(self, server): @@ -317,6 +313,7 @@ class PromptQueue: self.task_counter = 0 self.queue = [] self.currently_running = {} + self.history = {} server.prompt_queue = self def put(self, item): @@ -336,9 +333,12 @@ class PromptQueue: self.server.queue_updated() return (item, i) - def task_done(self, item_id): + def task_done(self, item_id, outputs): with self.mutex: - self.currently_running.pop(item_id) + self.history[item_id] = { "prompt": self.currently_running.pop(item_id), "outputs": {} } + for o in outputs: + if "ui" in outputs[o]: + self.history[item_id]["outputs"][o] = outputs[o]["ui"] self.server.queue_updated() def get_current_queue(self): diff --git a/nodes.py b/nodes.py index 9e977878..48549745 100644 --- a/nodes.py +++ b/nodes.py @@ -623,7 +623,7 @@ class SaveImage: return {"required": {"images": ("IMAGE", ), "filename_prefix": ("STRING", {"default": "ComfyUI"})}, - "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "server": "SERVER", "unique_id": "UNIQUE_ID"}, + "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}, } RETURN_TYPES = () @@ -633,7 +633,7 @@ class SaveImage: CATEGORY = "image" - def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None, server=None, unique_id=None): + def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None): def map_filename(filename): prefix_len = len(filename_prefix) prefix = filename[:prefix_len + 1] @@ -662,10 +662,9 @@ class SaveImage: metadata.add_text(x, json.dumps(extra_pnginfo[x])) file = f"{filename_prefix}_{counter:05}_.png" img.save(os.path.join(self.output_dir, file), pnginfo=metadata, optimize=True) - paths.append(f"/view/{file}") + paths.append(file) counter += 1 - if server is not None: - server.send_sync("image", {"images": paths, "id": unique_id}) + return { "ui": { "images": paths } } class LoadImage: input_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "input") diff --git a/server.py b/server.py index 942d2495..56c7b9dd 100644 --- a/server.py +++ b/server.py @@ -77,6 +77,10 @@ class PromptServer(): out[x] = info return web.json_response(out) + @routes.get("/history") + async def get_history(request): + return web.json_response(self.prompt_queue.history) + @routes.get("/queue") async def get_queue(request): queue_info = {} @@ -133,6 +137,19 @@ class PromptServer(): self.prompt_queue.delete_queue_item(delete_func) return web.Response(status=200) + + @routes.post("/history") + async def post_history(request): + json_data = await request.json() + if "clear" in json_data: + if json_data["clear"]: + self.prompt_queue.history = {} + if "delete" in json_data: + to_delete = json_data['delete'] + for id_to_delete in to_delete: + self.prompt_queue.history.pop(id_to_delete, None) + + return web.Response(status=200) self.app.add_routes(routes) self.app.add_routes([ diff --git a/webshit/index.html b/webshit/index.html index 94e21c67..64b9618d 100644 --- a/webshit/index.html +++ b/webshit/index.html @@ -27,7 +27,7 @@ left: 50%; /* Center the modal horizontally */ top: 50%; /* Center the modal vertically */ transform: translate(-50%, -50%); /* Use this to center the modal */ - min-width: 50%; /* Set a width for the modal */ + width: 50%; /* Set a width for the modal */ height: auto; /* Set a height for the modal */ padding: 30px; background-color: #ff0000; /* Modal background */ @@ -59,18 +59,6 @@ white-space: pre-line; /* This will respect line breaks */ margin-bottom: 20px; /* Add some margin between the text and the close button*/ } - -#modal-text img { - max-width: calc(100vw - 96px - 36px); - max-height: calc(100vh - 96px - 36px); -} - -#images img { - width: 100%; - max-height: 300px; - object-fit: contain; - cursor: pointer; -} +