diff --git a/pype/lib/__init__.py b/pype/lib/__init__.py index 1ade97cd0e..78fd69da98 100644 --- a/pype/lib/__init__.py +++ b/pype/lib/__init__.py @@ -25,7 +25,12 @@ from .applications import ( _subprocess ) -from .plugin_tools import filter_pyblish_plugins, source_hash +from .plugin_tools import ( + filter_pyblish_plugins, + source_hash, + get_unique_layer_name, + get_background_layers +) from .path_tools import ( version_up, @@ -57,6 +62,8 @@ __all__ = [ "ApplicationAction", "filter_pyblish_plugins", + "get_unique_layer_name", + "get_background_layers", "version_up", "get_version_from_path", diff --git a/pype/lib/plugin_tools.py b/pype/lib/plugin_tools.py index 0b6ace807e..f5eb354ca3 100644 --- a/pype/lib/plugin_tools.py +++ b/pype/lib/plugin_tools.py @@ -3,6 +3,8 @@ import os import inspect import logging +import re +import json from ..api import config @@ -78,3 +80,57 @@ def source_hash(filepath, *args): time = str(os.path.getmtime(filepath)) size = str(os.path.getsize(filepath)) return "|".join([file_name, time, size] + list(args)).replace(".", ",") + + +def get_unique_layer_name(layers, name): + """ + Gets all layer names and if 'name' is present in them, increases + suffix by 1 (eg. creates unique layer name - for Loader) + Args: + layers (list): of strings, names only + name (string): checked value + + Returns: + (string): name_00X (without version) + """ + names = {} + for layer in layers: + layer_name = re.sub(r'_\d{3}$', '', layer) + if layer_name in names.keys(): + names[layer_name] = names[layer_name] + 1 + else: + names[layer_name] = 1 + occurrences = names.get(name, 0) + + return "{}_{:0>3d}".format(name, occurrences + 1) + + +def get_background_layers(file_url): + """ + Pulls file name from background json file, enrich with folder url for + AE to be able import files. + + Order is important, follows order in json. + + Args: + file_url (str): abs url of background json + + Returns: + (list): of abs paths to images + """ + with open(file_url) as json_file: + data = json.load(json_file) + + layers = list() + bg_folder = os.path.dirname(file_url) + for child in data['children']: + if child.get("filename"): + layers.append(os.path.join(bg_folder, child.get("filename")). + replace("\\", "/")) + else: + for layer in child['children']: + if layer.get("filename"): + layers.append(os.path.join(bg_folder, + layer.get("filename")). + replace("\\", "/")) + return layers diff --git a/pype/modules/websocket_server/stubs/aftereffects_server_stub.py b/pype/modules/websocket_server/stubs/aftereffects_server_stub.py index d4c1cf4512..9449d0b378 100644 --- a/pype/modules/websocket_server/stubs/aftereffects_server_stub.py +++ b/pype/modules/websocket_server/stubs/aftereffects_server_stub.py @@ -23,6 +23,10 @@ class AEItem(object): # all imported elements, single for # regular image, array for Backgrounds members = attr.ib(factory=list) + workAreaStart = attr.ib(default=None) + workAreaDuration = attr.ib(default=None) + frameRate = attr.ib(default=None) + file_name = attr.ib(default=None) class AfterEffectsServerStub(): @@ -66,7 +70,7 @@ class AfterEffectsServerStub(): metadata = json.loads(res) except json.decoder.JSONDecodeError: raise ValueError("Unparsable metadata {}".format(res)) - return metadata or {} + return metadata or [] def read(self, item, layers_meta=None): """ @@ -488,6 +492,11 @@ class AfterEffectsServerStub(): item = AEItem(d.get('id'), d.get('name'), d.get('type'), - d.get('members')) + d.get('members'), + d.get('workAreaStart'), + d.get('workAreaDuration'), + d.get('frameRate'), + d.get('file_name')) + ret.append(item) return ret diff --git a/pype/plugins/aftereffects/create/create_render.py b/pype/plugins/aftereffects/create/create_render.py index 1944cf9937..6d876e349d 100644 --- a/pype/plugins/aftereffects/create/create_render.py +++ b/pype/plugins/aftereffects/create/create_render.py @@ -35,7 +35,7 @@ class CreateRender(api.Creator): 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"]) diff --git a/pype/plugins/aftereffects/load/load_background.py b/pype/plugins/aftereffects/load/load_background.py index 14f75c2850..879734e4f9 100644 --- a/pype/plugins/aftereffects/load/load_background.py +++ b/pype/plugins/aftereffects/load/load_background.py @@ -2,7 +2,7 @@ import re from avalon import api, aftereffects -from pype.plugins.lib import get_background_layers, get_unique_layer_name +from pype.lib import get_background_layers, get_unique_layer_name stub = aftereffects.stub() @@ -51,6 +51,7 @@ class BackgroundLoader(api.Loader): def update(self, container, representation): """ Switch asset or change version """ context = representation.get("context", {}) + _ = container.pop("layer") # without iterator number (_001, 002...) namespace_from_container = re.sub(r'_\d{3}$', '', diff --git a/pype/plugins/aftereffects/load/load_file.py b/pype/plugins/aftereffects/load/load_file.py index 2e07e933f7..ba11856678 100644 --- a/pype/plugins/aftereffects/load/load_file.py +++ b/pype/plugins/aftereffects/load/load_file.py @@ -1,5 +1,5 @@ from avalon import api, aftereffects -from pype.plugins import lib +from pype import lib import re stub = aftereffects.stub() diff --git a/pype/plugins/aftereffects/publish/collect_render.py b/pype/plugins/aftereffects/publish/collect_render.py index 2dd447d03e..7f7d5a52bc 100644 --- a/pype/plugins/aftereffects/publish/collect_render.py +++ b/pype/plugins/aftereffects/publish/collect_render.py @@ -33,12 +33,16 @@ class CollectAERender(abstract_collect_render.AbstractCollectRender): compositions = aftereffects.stub().get_items(True) compositions_by_id = {item.id: item for item in compositions} - for item_id, inst in aftereffects.stub().get_metadata().items(): + for inst in aftereffects.stub().get_metadata(): schema = inst.get('schema') # loaded asset container skip it if schema and 'container' in schema: continue + if not inst["members"]: + raise ValueError("Couldn't find id, unable to publish. " + + "Please recreate instance.") + item_id = inst["members"][0] work_area_info = aftereffects.stub().get_work_area(int(item_id)) frameStart = work_area_info.workAreaStart diff --git a/pype/plugins/aftereffects/publish/submit_aftereffects_deadline.py b/pype/plugins/aftereffects/publish/submit_aftereffects_deadline.py index 9414bdd39d..5e5c00dec1 100644 --- a/pype/plugins/aftereffects/publish/submit_aftereffects_deadline.py +++ b/pype/plugins/aftereffects/publish/submit_aftereffects_deadline.py @@ -105,3 +105,13 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline deadline_plugin_info.Output = render_path.replace("\\", "/") return attr.asdict(deadline_plugin_info) + + def from_published_scene(self): + """ Do not overwrite expected files. + + Use published is set to True, so rendering will be triggered + from published scene (in 'publish' folder). Default implementation + of abstract class renames expected (eg. rendered) files accordingly + which is not needed here. + """ + return super().from_published_scene(False) diff --git a/pype/plugins/lib.py b/pype/plugins/lib.py deleted file mode 100644 index c0a4934439..0000000000 --- a/pype/plugins/lib.py +++ /dev/null @@ -1,57 +0,0 @@ -import re -import json -import os - - -def get_unique_layer_name(layers, name): - """ - Gets all layer names and if 'name' is present in them, increases - suffix by 1 (eg. creates unique layer name - for Loader) - Args: - layers (list): of strings, names only - name (string): checked value - - Returns: - (string): name_00X (without version) - """ - names = {} - for layer in layers: - layer_name = re.sub(r'_\d{3}$', '', layer) - if layer_name in names.keys(): - names[layer_name] = names[layer_name] + 1 - else: - names[layer_name] = 1 - occurrences = names.get(name, 0) - - return "{}_{:0>3d}".format(name, occurrences + 1) - - -def get_background_layers(file_url): - """ - Pulls file name from background json file, enrich with folder url for - AE to be able import files. - - Order is important, follows order in json. - - Args: - file_url (str): abs url of background json - - Returns: - (list): of abs paths to images - """ - with open(file_url) as json_file: - data = json.load(json_file) - - layers = list() - bg_folder = os.path.dirname(file_url) - for child in data['children']: - if child.get("filename"): - layers.append(os.path.join(bg_folder, child.get("filename")). - replace("\\", "/")) - else: - for layer in child['children']: - if layer.get("filename"): - layers.append(os.path.join(bg_folder, - layer.get("filename")). - replace("\\", "/")) - return layers