From e9f5ac08c45c70f54254d516cfea35a829516011 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 31 Mar 2021 12:42:18 +0200 Subject: [PATCH] AE - added SubsetManager --- .../websocket_server/hosts/aftereffects.py | 3 ++ .../stubs/aftereffects_server_stub.py | 41 ++++++++++++++++++- .../aftereffects/create/create_render.py | 31 +++++++++----- .../aftereffects/load/load_background.py | 5 ++- pype/plugins/aftereffects/load/load_file.py | 5 ++- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/pype/modules/websocket_server/hosts/aftereffects.py b/pype/modules/websocket_server/hosts/aftereffects.py index 14d2c04338d..9ffb9407c23 100644 --- a/pype/modules/websocket_server/hosts/aftereffects.py +++ b/pype/modules/websocket_server/hosts/aftereffects.py @@ -54,6 +54,9 @@ async def sceneinventory_route(self): async def projectmanager_route(self): self._tool_route("projectmanager") + async def subsetmanager_route(self): + self._tool_route("subsetmanager") + def _tool_route(self, tool_name): """The address accessed when clicking on the buttons.""" partial_method = functools.partial(aftereffects.show, tool_name) diff --git a/pype/modules/websocket_server/stubs/aftereffects_server_stub.py b/pype/modules/websocket_server/stubs/aftereffects_server_stub.py index 9449d0b3780..5d8debf2296 100644 --- a/pype/modules/websocket_server/stubs/aftereffects_server_stub.py +++ b/pype/modules/websocket_server/stubs/aftereffects_server_stub.py @@ -36,6 +36,8 @@ class AfterEffectsServerStub(): is opened). 'self.websocketserver.call' is used as async wrapper """ + PUBLISH_ICON = '\u2117 ' + LOADED_ICON = '\u25bc' def __init__(self): self.websocketserver = WebSocketServer.get_instance() @@ -61,7 +63,7 @@ def get_metadata(self): by Creator. Returns: - (dict) + (list) """ res = self.websocketserver.call(self.client.call ('AfterEffects.get_metadata') @@ -212,6 +214,19 @@ def get_selected_items(self, comps, folders=False, footages=False): ) return self._to_records(res) + def get_item(self, item_id): + """ + Returns metadata for particular 'item_id' or None + + Args: + item_id (int, or string) + """ + for item in self.get_items(True, True, True): + if str(item.id) == str(item_id): + return item + + return None + def import_file(self, path, item_name, import_options=None): """ Imports file as a FootageItem. Used in Loader @@ -272,6 +287,30 @@ def delete_item(self, item_id): item_id=item_id )) + def remove_instance(self, instance_id): + """ + Removes instance with 'instance_id' from file's metadata and + saves them. + + Keep matching item in file though. + + Args: + instance_id(string): instance uuid + """ + cleaned_data = [] + + for instance in self.get_metadata(): + uuid_val = instance.get("uuid") + if not uuid_val: + uuid_val = instance.get("members")[0] # legacy + if uuid_val != instance_id: + cleaned_data.append(instance) + + payload = json.dumps(cleaned_data, indent=4) + self.websocketserver.call(self.client.call + ('AfterEffects.imprint', payload=payload) + ) + def is_saved(self): # TODO return True diff --git a/pype/plugins/aftereffects/create/create_render.py b/pype/plugins/aftereffects/create/create_render.py index b346bc60d82..70abd364065 100644 --- a/pype/plugins/aftereffects/create/create_render.py +++ b/pype/plugins/aftereffects/create/create_render.py @@ -8,7 +8,13 @@ class CreateRender(pype.api.Creator): - """Render folder for publish.""" + """Render folder for publish. + + Creates subsets in format 'familyTaskSubsetname', + eg 'renderCompositingMain'. + + Create only single instance from composition at a time. + """ name = "renderDefault" label = "Render on Farm" @@ -20,7 +26,7 @@ def process(self): items = stub.get_selected_items(comps=True, folders=False, footages=False) - else: + if len(items) > 1: self._show_msg("Please select only single composition at time.") return False @@ -30,15 +36,20 @@ def process(self): "one composition.") return False - for item in items: + existing_subsets = [instance['subset'].lower() + for instance in aftereffects.list_instances()] + + item = items.pop() + if self.name.lower() in existing_subsets: txt = "Instance with name \"{}\" already exists.".format(self.name) - if self.name.lower() == item.name.lower(): - self._show_msg(txt) - return False - self.data["members"] = [item.id] - stub.imprint(item, self.data) - stub.set_label_color(item.id, 14) # Cyan options 0 - 16 - stub.rename_item(item, self.data["subset"]) + self._show_msg(txt) + return False + + self.data["members"] = [item.id] + self.data["uuid"] = item.id # for SubsetManager + stub.imprint(item, self.data) + stub.set_label_color(item.id, 14) # Cyan options 0 - 16 + stub.rename_item(item, stub.PUBLISH_ICON + self.data["subset"]) def _show_msg(self, txt): msg = Qt.QtWidgets.QMessageBox() diff --git a/pype/plugins/aftereffects/load/load_background.py b/pype/plugins/aftereffects/load/load_background.py index 879734e4f9a..e6f8b6a0326 100644 --- a/pype/plugins/aftereffects/load/load_background.py +++ b/pype/plugins/aftereffects/load/load_background.py @@ -29,7 +29,8 @@ def load(self, context, name=None, namespace=None, data=None): "{}_{}".format(context["asset"]["name"], name)) layers = get_background_layers(self.fname) - comp = stub.import_background(None, comp_name, layers) + comp = stub.import_background(None, stub.LOADED_ICON + comp_name, + layers) if not comp: self.log.warning( @@ -72,7 +73,7 @@ def update(self, container, representation): layers = get_background_layers(path) comp = stub.reload_background(container["members"][1], - comp_name, + stub.LOADED_ICON + comp_name, layers) # update container diff --git a/pype/plugins/aftereffects/load/load_file.py b/pype/plugins/aftereffects/load/load_file.py index ba118566789..500a53a69b8 100644 --- a/pype/plugins/aftereffects/load/load_file.py +++ b/pype/plugins/aftereffects/load/load_file.py @@ -48,7 +48,8 @@ def load(self, context, name=None, namespace=None, data=None): if '.psd' in file: import_options['ImportAsType'] = 'ImportAsType.COMP' - comp = stub.import_file(self.fname, comp_name, import_options) + comp = stub.import_file(self.fname, stub.LOADED_ICON + comp_name, + import_options) if not comp: self.log.warning( @@ -87,7 +88,7 @@ def update(self, container, representation): layer_name = container["namespace"] path = api.get_representation_path(representation) # with aftereffects.maintained_selection(): # TODO - stub.replace_item(layer, path, layer_name) + stub.replace_item(layer, path, stub.LOADED_ICON + layer_name) stub.imprint( layer, {"representation": str(representation["_id"]), "name": context["subset"],