From 2ebbefdec052f5fa88a7a9237da84103fb3be5fa Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 14:27:11 +0100 Subject: [PATCH 01/22] reversed condition of raising exception --- .../plugins/publish/collect_matching_asset.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py index 48065c4662..089ca32561 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py @@ -31,20 +31,20 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): matching_asset_doc = asset_doc break - if matching_asset_doc: - instance.data["asset"] = matching_asset_doc["name"] - instance.data["assetEntity"] = matching_asset_doc - self.log.info( - f"Matching asset found: {pformat(matching_asset_doc)}" - ) - - else: + if not matching_asset_doc: # TODO better error message raise AssertionError(( "Filename \"{}\" does not match" " any name of asset documents in database for your selection." ).format(instance.data["source"])) + instance.data["asset"] = matching_asset_doc["name"] + instance.data["assetEntity"] = matching_asset_doc + + self.log.info( + f"Matching asset found: {pformat(matching_asset_doc)}" + ) + def selection_children_by_name(self, instance): storing_key = "childrenDocsForSelection" From dc4757b38f710f3125ed7fc2857f0b202ebc0244 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 14:27:33 +0100 Subject: [PATCH 02/22] added regex for version check in source filename --- .../plugins/publish/collect_matching_asset.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py index 089ca32561..cdb5403caa 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py @@ -1,4 +1,5 @@ import os +import re import collections import pyblish.api from avalon import io @@ -16,6 +17,9 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): hosts = ["standalonepublisher"] families = ["background_batch"] + # Version regex to parse asset name and version from filename + version_regex = re.compile(r"^(.+)_v([0-9]+)$") + def process(self, instance): source_file = os.path.basename(instance.data["source"]).lower() self.log.info("Looking for asset document for file \"{}\"".format( From 0769eda05f21e2007a8a4c17b9a8efa31ee260e1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 14:29:06 +0100 Subject: [PATCH 03/22] use the regex to try check if filename contain asset name --- .../plugins/publish/collect_matching_asset.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py index cdb5403caa..93551f1c4c 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py @@ -28,7 +28,18 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): asset_docs_by_name = self.selection_children_by_name(instance) + version_number = None + # Always first check if source filename is in assets matching_asset_doc = asset_docs_by_name.get(source_file) + if matching_asset_doc is None: + # Check if source file contain version in name + regex_result = self.version_regex.findall(source_file) + if regex_result: + asset_name, _version_number = regex_result[0] + matching_asset_doc = asset_docs_by_name.get(asset_name) + if matching_asset_doc: + version_number = int(_version_number) + if matching_asset_doc is None: for asset_name_low, asset_doc in asset_docs_by_name.items(): if asset_name_low in source_file: From ba4f62a3fba13d203267b73671eaa7c5f49c6053 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 14:29:17 +0100 Subject: [PATCH 04/22] store version to instance data if is found --- .../plugins/publish/collect_matching_asset.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py index 93551f1c4c..8a845e60d7 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py @@ -55,6 +55,8 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): instance.data["asset"] = matching_asset_doc["name"] instance.data["assetEntity"] = matching_asset_doc + if version_number is not None: + instance.data["version"] = version_number self.log.info( f"Matching asset found: {pformat(matching_asset_doc)}" From 406c665d1d36a4deb129b09397c7854ed1c0e230 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 14:46:12 +0100 Subject: [PATCH 05/22] created copy of psb bulk plugin but for render mov batch # Conflicts: # pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py --- .../plugins/publish/collect_mov_instances.py | 54 +++++++++++++++++++ .../plugins/publish/collect_psd_instances.py | 1 - 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py new file mode 100644 index 0000000000..0dcbd119d9 --- /dev/null +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py @@ -0,0 +1,54 @@ +import copy +import pyblish.api +from pprint import pformat + + +class CollectMovInstances(pyblish.api.InstancePlugin): + """Collect all available instances from render mov batch.""" + + label = "Collect Mov Instances" + order = pyblish.api.CollectorOrder + 0.489 + hosts = ["standalonepublisher"] + families = ["render_mov_batch"] + + # presets + subsets = { + "render": { + "task": "compositing", + "family": "render" + } + } + unchecked_by_default = [] + + def process(self, instance): + context = instance.context + asset_name = instance.data["asset"] + for subset_name, subset_data in self.subsets.items(): + instance_name = f"{asset_name}_{subset_name}" + task_name = subset_data["task"] + + # create new instance + new_instance = context.create_instance(instance_name) + + # add original instance data except name key + for key, value in instance.data.items(): + if key not in ["name"]: + # Make sure value is copy since value may be object which + # can be shared across all new created objects + new_instance.data[key] = copy.deepcopy(value) + + # add subset data from preset + new_instance.data.update(subset_data) + + new_instance.data["label"] = instance_name + new_instance.data["subset"] = subset_name + new_instance.data["task"] = task_name + + if subset_name in self.unchecked_by_default: + new_instance.data["publish"] = False + + self.log.info(f"Created new instance: {instance_name}") + self.log.debug(f"New instance data: {pformat(new_instance.data)}") + + # delete original instance + context.remove(instance) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py index b5db437473..11cedc30b9 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py @@ -55,7 +55,6 @@ class CollectPsdInstances(pyblish.api.InstancePlugin): new_instance.data["subset"] = subset_name new_instance.data["task"] = task - if subset_name in self.unchecked_by_default: new_instance.data["publish"] = False From 82646f712625bb091bebba775896562f14b23b12 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 14:52:15 +0100 Subject: [PATCH 06/22] added render_mov_batch to collect matching asset --- .../plugins/publish/collect_matching_asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py index 8a845e60d7..16147dc738 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py @@ -15,7 +15,7 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): label = "Collect Matching Asset to Instance" order = pyblish.api.CollectorOrder - 0.05 hosts = ["standalonepublisher"] - families = ["background_batch"] + families = ["background_batch", "render_mov_batch"] # Version regex to parse asset name and version from filename version_regex = re.compile(r"^(.+)_v([0-9]+)$") From 6ec18b00ea8dca105b3e8ae9141b3355f2f70342 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 15:29:54 +0100 Subject: [PATCH 07/22] single collector for batch instances # Conflicts: # pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py --- .../plugins/publish/collect_mov_instances.py | 54 ------------------- .../plugins/publish/collect_psd_instances.py | 34 +++++++----- 2 files changed, 22 insertions(+), 66 deletions(-) delete mode 100644 pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py deleted file mode 100644 index 0dcbd119d9..0000000000 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_mov_instances.py +++ /dev/null @@ -1,54 +0,0 @@ -import copy -import pyblish.api -from pprint import pformat - - -class CollectMovInstances(pyblish.api.InstancePlugin): - """Collect all available instances from render mov batch.""" - - label = "Collect Mov Instances" - order = pyblish.api.CollectorOrder + 0.489 - hosts = ["standalonepublisher"] - families = ["render_mov_batch"] - - # presets - subsets = { - "render": { - "task": "compositing", - "family": "render" - } - } - unchecked_by_default = [] - - def process(self, instance): - context = instance.context - asset_name = instance.data["asset"] - for subset_name, subset_data in self.subsets.items(): - instance_name = f"{asset_name}_{subset_name}" - task_name = subset_data["task"] - - # create new instance - new_instance = context.create_instance(instance_name) - - # add original instance data except name key - for key, value in instance.data.items(): - if key not in ["name"]: - # Make sure value is copy since value may be object which - # can be shared across all new created objects - new_instance.data[key] = copy.deepcopy(value) - - # add subset data from preset - new_instance.data.update(subset_data) - - new_instance.data["label"] = instance_name - new_instance.data["subset"] = subset_name - new_instance.data["task"] = task_name - - if subset_name in self.unchecked_by_default: - new_instance.data["publish"] = False - - self.log.info(f"Created new instance: {instance_name}") - self.log.debug(f"New instance data: {pformat(new_instance.data)}") - - # delete original instance - context.remove(instance) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py index 11cedc30b9..09ec78af39 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py @@ -11,21 +11,29 @@ class CollectPsdInstances(pyblish.api.InstancePlugin): label = "Collect Psd Instances" order = pyblish.api.CollectorOrder + 0.489 hosts = ["standalonepublisher"] - families = ["background_batch"] + families = ["background_batch", "render_mov_batch"] # presets subsets = { - "backgroundLayout": { - "task": "background", - "family": "backgroundLayout" + "background_batch": { + "backgroundLayout": { + "task": "background", + "family": "backgroundLayout" + }, + "backgroundComp": { + "task": "background", + "family": "backgroundComp" + }, + "workfileBackground": { + "task": "background", + "family": "workfile" + } }, - "backgroundComp": { - "task": "background", - "family": "backgroundComp" - }, - "workfileBackground": { - "task": "background", - "family": "workfile" + "render_mov_batch": { + "renderCompositingDefault": { + "task": "Compositing", + "family": "render" + } } } unchecked_by_default = [] @@ -34,7 +42,9 @@ class CollectPsdInstances(pyblish.api.InstancePlugin): context = instance.context asset_data = instance.data["assetEntity"] asset_name = instance.data["asset"] - for subset_name, subset_data in self.subsets.items(): + family = instance.data["family"] + + for subset_name, subset_data in self.subsets[family].items(): instance_name = f"{asset_name}_{subset_name}" task = subset_data.get("task", "background") From d119373dc12441f6a59900060467401e9c387cdf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 15:30:15 +0100 Subject: [PATCH 08/22] renamed collect psd instances to collect batch instances # Conflicts: # pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py # pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py # pype/plugins/standalonepublisher/publish/collect_psd_instances.py --- .../{collect_psd_instances.py => collect_batch_instances.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename pype/hosts/standalonepublisher/plugins/publish/{collect_psd_instances.py => collect_batch_instances.py} (96%) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py similarity index 96% rename from pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py rename to pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py index 09ec78af39..3e83a7dcac 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_psd_instances.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py @@ -3,12 +3,12 @@ import pyblish.api from pprint import pformat -class CollectPsdInstances(pyblish.api.InstancePlugin): +class CollectBatchInstances(pyblish.api.InstancePlugin): """ Collect all available instances from psd batch. """ - label = "Collect Psd Instances" + label = "Collect Batch Instances" order = pyblish.api.CollectorOrder + 0.489 hosts = ["standalonepublisher"] families = ["background_batch", "render_mov_batch"] From 0257e04192b40fb3df7b65f12a15fcbcf76cb753 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 16:15:03 +0100 Subject: [PATCH 09/22] fixed asset name lookup --- .../plugins/publish/collect_matching_asset.py | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py index 16147dc738..f1686dc42f 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py @@ -21,19 +21,23 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): version_regex = re.compile(r"^(.+)_v([0-9]+)$") def process(self, instance): - source_file = os.path.basename(instance.data["source"]).lower() + source_filename = self.get_source_filename(instance) self.log.info("Looking for asset document for file \"{}\"".format( - instance.data["source"] + source_filename )) + asset_name = os.path.splitext(source_filename)[0].lower() asset_docs_by_name = self.selection_children_by_name(instance) version_number = None # Always first check if source filename is in assets - matching_asset_doc = asset_docs_by_name.get(source_file) + matching_asset_doc = asset_docs_by_name.get(asset_name) if matching_asset_doc is None: # Check if source file contain version in name - regex_result = self.version_regex.findall(source_file) + self.log.debug(( + "Asset doc by \"{}\" was not found trying version regex." + ).format(asset_name)) + regex_result = self.version_regex.findall(asset_name) if regex_result: asset_name, _version_number = regex_result[0] matching_asset_doc = asset_docs_by_name.get(asset_name) @@ -42,16 +46,19 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): if matching_asset_doc is None: for asset_name_low, asset_doc in asset_docs_by_name.items(): - if asset_name_low in source_file: + if asset_name_low in asset_name: matching_asset_doc = asset_doc break if not matching_asset_doc: + self.log.debug("Available asset names {}".format( + str(list(asset_docs_by_name.keys())) + )) # TODO better error message raise AssertionError(( "Filename \"{}\" does not match" " any name of asset documents in database for your selection." - ).format(instance.data["source"])) + ).format(source_filename)) instance.data["asset"] = matching_asset_doc["name"] instance.data["assetEntity"] = matching_asset_doc @@ -62,6 +69,25 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): f"Matching asset found: {pformat(matching_asset_doc)}" ) + def get_source_filename(self, instance): + if instance.data["family"] == "background_batch": + return os.path.basename(instance.data["source"]) + + if len(instance.data["representations"]) != 1: + raise ValueError(( + "Implementation bug: Instance data contain" + " more than one representation." + )) + + repre = instance.data["representations"][0] + repre_files = repre["files"] + if not isinstance(repre_files, str): + raise ValueError(( + "Implementation bug: Instance's representation contain" + " unexpected value (expected single file). {}" + ).format(str(repre_files))) + return repre_files + def selection_children_by_name(self, instance): storing_key = "childrenDocsForSelection" From 256f28f3a74ca94e7e61129b90632de6ca696815 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 16:15:21 +0100 Subject: [PATCH 10/22] added mov batch specific method # Conflicts: # pype/plugins/standalonepublisher/publish/collect_context.py --- .../plugins/publish/collect_context.py | 101 +++++++++++++++--- 1 file changed, 84 insertions(+), 17 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py index b40c081fcc..f6c102f2cb 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py @@ -48,8 +48,12 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): self.log.debug(f"_ in_data: {pformat(in_data)}") # exception for editorial - if in_data["family"] in ["editorial", "background_batch"]: + if in_data["family"] == "render_mov_batch": + in_data_list = self.prepare_mov_batch_instances(context, in_data) + + elif in_data["family"] in ["editorial", "background_batch"]: in_data_list = self.multiple_instances(context, in_data) + else: in_data_list = [in_data] @@ -66,38 +70,38 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): in_data_list = list() representations = in_data.pop("representations") - for repre in representations: + for repr in representations: in_data_copy = copy.deepcopy(in_data) - ext = repre["ext"][1:] + ext = repr["ext"][1:] subset = in_data_copy["subset"] # filter out non editorial files if ext not in self.batch_extensions: - in_data_copy["representations"] = [repre] + in_data_copy["representations"] = [repr] in_data_copy["subset"] = f"{ext}{subset}" in_data_list.append(in_data_copy) - files = repre.get("files") + files = repr.get("files") # delete unneeded keys delete_repr_keys = ["frameStart", "frameEnd"] for k in delete_repr_keys: - if repre.get(k): - repre.pop(k) + if repr.get(k): + repr.pop(k) # convert files to list if it isnt if not isinstance(files, (tuple, list)): files = [files] self.log.debug(f"_ files: {files}") - for index, _file in enumerate(files): + for index, f in enumerate(files): index += 1 # copy dictionaries in_data_copy = copy.deepcopy(in_data_copy) - new_repre = copy.deepcopy(repre) + repr_new = copy.deepcopy(repr) - new_repre["files"] = _file - new_repre["name"] = ext - in_data_copy["representations"] = [new_repre] + repr_new["files"] = f + repr_new["name"] = ext + in_data_copy["representations"] = [repr_new] # create subset Name new_subset = f"{ext}{index}{subset}" @@ -112,6 +116,73 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): return in_data_list + def prepare_mov_batch_instances(self, context, in_data): + """Copy of `multiple_instances` method. + + Method was copied because `batch_extensions` is used in + `multiple_instances` but without any family filtering. Since usage + of the filtering is unknown and modification of that part may break + editorial or PSD batch publishing it was decided to create a copy with + this family specific filtering. + + TODO: + - Merge logic with `multiple_instances` method. + """ + self.log.info("Preparing data for mov batch processing.") + in_data_list = [] + + representations = in_data.pop("representations") + for repre in representations: + self.log.debug("Processing representation with files {}".format( + str(repre["files"]) + )) + ext = repre["ext"][1:] + # Skip files that are not available for mov batch publishing + # TODO add dynamic expected extensions by family from `in_data` + # - with this modification it would be possible to use only + # `multiple_instances` method + expected_exts = ["mov"] + if ext not in expected_exts: + self.log.warning(( + "Skipping representation." + " Does not match expected extensions <{}>. {}" + ).format(", ".join(expected_exts), str(repre))) + continue + + # Delete key from representation + # QUESTION is this needed in mov batch processing? + delete_repr_keys = ["frameStart", "frameEnd"] + for key in delete_repr_keys: + repre.pop(key, None) + + files = repre["files"] + # Convert files to list if it isnt + if not isinstance(files, (tuple, list)): + files = [files] + + # Loop through files and create new instance per each file + for filename in files: + # Create copy of representation and change it's files and name + new_repre = copy.deepcopy(repre) + new_repre["files"] = filename + new_repre["name"] = ext + + # Prepare new subset name (temporary name) + # - subset name will be changed in batch specific plugins + new_subset_name = "{}{}".format( + in_data["subset"], + os.path.basename(filename) + ) + # Create copy of instance data as new instance and pass in new + # representation + in_data_copy = copy.deepcopy(in_data) + in_data_copy["representations"] = [new_repre] + in_data_copy["subset"] = new_subset_name + + in_data_list.append(in_data_copy) + + return in_data_list + def create_instance(self, context, in_data): subset = in_data["subset"] @@ -145,16 +216,12 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): component["stagingDir"] = component["stagingDir"] if isinstance(component["files"], list): - collections, _remainder = clique.assemble(component["files"]) + collections, remainder = clique.assemble(component["files"]) self.log.debug("collecting sequence: {}".format(collections)) instance.data["frameStart"] = int(component["frameStart"]) instance.data["frameEnd"] = int(component["frameEnd"]) instance.data["fps"] = int(component["fps"]) - ext = component["ext"] - if ext.startswith("."): - component["ext"] = ext[1:] - if component["preview"]: instance.data["families"].append("review") instance.data["repreProfiles"] = ["h264"] From a351c54e2740582a43614f70272bc9e0587d77ee Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 16:31:05 +0100 Subject: [PATCH 11/22] dont remove frame start and frame end from instance data --- .../plugins/publish/collect_context.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py index f6c102f2cb..318335a6d2 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py @@ -123,7 +123,8 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): `multiple_instances` but without any family filtering. Since usage of the filtering is unknown and modification of that part may break editorial or PSD batch publishing it was decided to create a copy with - this family specific filtering. + this family specific filtering. Also "frameStart" and "frameEnd" keys + are removed from instance which is needed for this processing. TODO: - Merge logic with `multiple_instances` method. @@ -149,12 +150,6 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): ).format(", ".join(expected_exts), str(repre))) continue - # Delete key from representation - # QUESTION is this needed in mov batch processing? - delete_repr_keys = ["frameStart", "frameEnd"] - for key in delete_repr_keys: - repre.pop(key, None) - files = repre["files"] # Convert files to list if it isnt if not isinstance(files, (tuple, list)): From b44f8c40dae99be9d42e14dcc6b7f25e8eb81ad8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 16:31:17 +0100 Subject: [PATCH 12/22] removed unused variable --- .../plugins/publish/collect_batch_instances.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py index 3e83a7dcac..5820fc6247 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py @@ -31,7 +31,7 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): }, "render_mov_batch": { "renderCompositingDefault": { - "task": "Compositing", + "task": "compositing", "family": "render" } } @@ -40,7 +40,6 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): def process(self, instance): context = instance.context - asset_data = instance.data["assetEntity"] asset_name = instance.data["asset"] family = instance.data["family"] From c20261693a4ce0f85181278098c8e6283c87f27e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 16:59:25 +0100 Subject: [PATCH 13/22] added message before logged values # Conflicts: # pype/plugins/global/publish/integrate_new.py --- pype/plugins/publish/integrate_new.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/plugins/publish/integrate_new.py b/pype/plugins/publish/integrate_new.py index 14b25b9c46..3fb9f668de 100644 --- a/pype/plugins/publish/integrate_new.py +++ b/pype/plugins/publish/integrate_new.py @@ -812,7 +812,9 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): matching_profiles = {} highest_value = -1 - self.log.info(self.template_name_profiles) + self.log.debug( + "Template name profiles:\n{}".format(self.template_name_profiles) + ) for name, filters in self.template_name_profiles.items(): value = 0 families = filters.get("families") From a898e5bd2b3eae8b32b496d120f9428ec24b3f75 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 16:59:51 +0100 Subject: [PATCH 14/22] added definitions of default task names --- .../plugins/publish/collect_batch_instances.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py index 5820fc6247..94574ad19c 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py @@ -14,6 +14,10 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): families = ["background_batch", "render_mov_batch"] # presets + default_subset_task = { + "background_batch": "background", + "render_mov_batch": "compositing" + } subsets = { "background_batch": { "backgroundLayout": { @@ -43,9 +47,10 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): asset_name = instance.data["asset"] family = instance.data["family"] + default_task_name = self.default_subset_task.get(family) for subset_name, subset_data in self.subsets[family].items(): instance_name = f"{asset_name}_{subset_name}" - task = subset_data.get("task", "background") + task_name = subset_data.get("task") or default_task_name # create new instance new_instance = context.create_instance(instance_name) @@ -62,7 +67,7 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): new_instance.data["label"] = f"{instance_name}" new_instance.data["subset"] = subset_name - new_instance.data["task"] = task + new_instance.data["task"] = task_name if subset_name in self.unchecked_by_default: new_instance.data["publish"] = False From 5ee3e848747295307dbb0e4050ab7747517603b5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 9 Mar 2021 18:13:35 +0100 Subject: [PATCH 15/22] fix variable override --- .../plugins/publish/collect_matching_asset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py index f1686dc42f..0d629b1b44 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_matching_asset.py @@ -39,8 +39,8 @@ class CollectMatchingAssetToInstance(pyblish.api.InstancePlugin): ).format(asset_name)) regex_result = self.version_regex.findall(asset_name) if regex_result: - asset_name, _version_number = regex_result[0] - matching_asset_doc = asset_docs_by_name.get(asset_name) + _asset_name, _version_number = regex_result[0] + matching_asset_doc = asset_docs_by_name.get(_asset_name) if matching_asset_doc: version_number = int(_version_number) From d866e819d0152369636c571d6697142fb0f5b55e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 10 Mar 2021 15:37:36 +0100 Subject: [PATCH 16/22] cleanup plugin can skip filpaths defined in context data --- pype/plugins/publish/cleanup.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pype/plugins/publish/cleanup.py b/pype/plugins/publish/cleanup.py index 5fded85ccb..b8104078d9 100644 --- a/pype/plugins/publish/cleanup.py +++ b/pype/plugins/publish/cleanup.py @@ -37,9 +37,16 @@ class CleanUp(pyblish.api.InstancePlugin): ) ) + _skip_cleanup_filepaths = instance.context.data.get( + "skipCleanupFilepaths" + ) or [] + skip_cleanup_filepaths = set() + for path in _skip_cleanup_filepaths: + skip_cleanup_filepaths.add(os.path.normpath(path)) + if self.remove_temp_renders: self.log.info("Cleaning renders new...") - self.clean_renders(instance) + self.clean_renders(instance, skip_cleanup_filepaths) if [ef for ef in self.exclude_families if instance.data["family"] in ef]: @@ -65,7 +72,7 @@ class CleanUp(pyblish.api.InstancePlugin): self.log.info("Removing staging directory {}".format(staging_dir)) shutil.rmtree(staging_dir) - def clean_renders(self, instance): + def clean_renders(self, instance, skip_cleanup_filepaths): transfers = instance.data.get("transfers", list()) current_families = instance.data.get("families", list()) @@ -84,6 +91,12 @@ class CleanUp(pyblish.api.InstancePlugin): # add dest dir into clearing dir paths (regex paterns) transfers_dirs.append(os.path.dirname(dest)) + if src in skip_cleanup_filepaths: + self.log.debug(( + "Source file is marked to be skipped in cleanup. {}" + ).format(src)) + continue + if os.path.normpath(src) != os.path.normpath(dest): if instance_family == 'render' or 'render' in current_families: self.log.info("Removing src: `{}`...".format(src)) @@ -116,6 +129,9 @@ class CleanUp(pyblish.api.InstancePlugin): # remove all files which match regex patern for f in files: + if os.path.normpath(f) in skip_cleanup_filepaths: + continue + for p in self.paterns: patern = re.compile(p) if not patern.findall(f): From edb868a64dcf5c8627979f7d290efde9c29ac80c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 10 Mar 2021 15:38:20 +0100 Subject: [PATCH 17/22] all filepaths from standalone publisher are added to list of filepaths that won't be deleted during cleanup --- .../plugins/publish/collect_context.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py index 318335a6d2..8930bedab8 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py @@ -45,8 +45,9 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): with open(input_json_path, "r") as f: in_data = json.load(f) - self.log.debug(f"_ in_data: {pformat(in_data)}") + self.log.debug(f"_ in_data: {pformat(in_data)}") + self.add_files_to_ignore_cleanup(in_data, context) # exception for editorial if in_data["family"] == "render_mov_batch": in_data_list = self.prepare_mov_batch_instances(context, in_data) @@ -63,6 +64,21 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): # create instance self.create_instance(context, in_data) + def add_files_to_ignore_cleanup(self, in_data, context): + all_filepaths = context.data.get("skipCleanupFilepaths") or [] + for repre in in_data["representations"]: + files = repre["files"] + if not isinstance(files, list): + files = [files] + + dirpath = repre["stagingDir"] + for filename in files: + filepath = os.path.normpath(os.path.join(dirpath, filename)) + if filepath not in all_filepaths: + all_filepaths.append(filepath) + + context.data["skipCleanupFilepaths"] = all_filepaths + def multiple_instances(self, context, in_data): # avoid subset name duplicity if not context.data.get("subsetNamesCheck"): From a794398b23c2f52bbfade3d6099e6aa28b838887 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 10 Mar 2021 16:12:16 +0100 Subject: [PATCH 18/22] added back pype 3 changes --- .../standalonepublisher/plugins/publish/collect_context.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py index 8930bedab8..f7f3f00ebe 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py @@ -227,12 +227,16 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): component["stagingDir"] = component["stagingDir"] if isinstance(component["files"], list): - collections, remainder = clique.assemble(component["files"]) + collections, _remainder = clique.assemble(component["files"]) self.log.debug("collecting sequence: {}".format(collections)) instance.data["frameStart"] = int(component["frameStart"]) instance.data["frameEnd"] = int(component["frameEnd"]) instance.data["fps"] = int(component["fps"]) + ext = component["ext"] + if ext.startswith("."): + component["ext"] = ext[1:] + if component["preview"]: instance.data["families"].append("review") instance.data["repreProfiles"] = ["h264"] From fb453a3a9f6846c40695ecd565d7b6138d1b0d87 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 15:34:16 +0100 Subject: [PATCH 19/22] collect ftrack api collect entities for all instances --- .../plugins/publish/collect_ftrack_api.py | 131 ++++++++++++++++-- 1 file changed, 121 insertions(+), 10 deletions(-) diff --git a/pype/modules/ftrack/plugins/publish/collect_ftrack_api.py b/pype/modules/ftrack/plugins/publish/collect_ftrack_api.py index 1683ec4bb7..28815ca010 100644 --- a/pype/modules/ftrack/plugins/publish/collect_ftrack_api.py +++ b/pype/modules/ftrack/plugins/publish/collect_ftrack_api.py @@ -1,16 +1,16 @@ import os import logging import pyblish.api +import avalon.api class CollectFtrackApi(pyblish.api.ContextPlugin): """ Collects an ftrack session and the current task id. """ - order = pyblish.api.CollectorOrder + order = pyblish.api.CollectorOrder + 0.4999 label = "Collect Ftrack Api" def process(self, context): - ftrack_log = logging.getLogger('ftrack_api') ftrack_log.setLevel(logging.WARNING) ftrack_log = logging.getLogger('ftrack_api_old') @@ -22,28 +22,27 @@ class CollectFtrackApi(pyblish.api.ContextPlugin): session = ftrack_api.Session(auto_connect_event_hub=True) self.log.debug("Ftrack user: \"{0}\"".format(session.api_user)) - context.data["ftrackSession"] = session # Collect task - project_name = os.environ.get('AVALON_PROJECT', '') - asset_name = os.environ.get('AVALON_ASSET', '') - task_name = os.environ.get('AVALON_TASK', None) + project_name = avalon.api.Session["AVALON_PROJECT"] + asset_name = avalon.api.Session["AVALON_ASSET"] + task_name = avalon.api.Session["AVALON_TASK"] # Find project entity project_query = 'Project where full_name is "{0}"'.format(project_name) self.log.debug("Project query: < {0} >".format(project_query)) - project_entity = list(session.query(project_query).all()) - if len(project_entity) == 0: + project_entities = list(session.query(project_query).all()) + if len(project_entities) == 0: raise AssertionError( "Project \"{0}\" not found in Ftrack.".format(project_name) ) # QUESTION Is possible to happen? - elif len(project_entity) > 1: + elif len(project_entities) > 1: raise AssertionError(( "Found more than one project with name \"{0}\" in Ftrack." ).format(project_name)) - project_entity = project_entity[0] + project_entity = project_entities[0] self.log.debug("Project found: {0}".format(project_entity)) # Find asset entity @@ -93,7 +92,119 @@ class CollectFtrackApi(pyblish.api.ContextPlugin): task_entity = None self.log.warning("Task name is not set.") + context.data["ftrackSession"] = session context.data["ftrackPythonModule"] = ftrack_api context.data["ftrackProject"] = project_entity context.data["ftrackEntity"] = asset_entity context.data["ftrackTask"] = task_entity + + self.per_instance_process(context, asset_name, task_name) + + def per_instance_process( + self, context, context_asset_name, context_task_name + ): + instance_by_asset_and_task = {} + for instance in context: + self.log.debug( + "Checking entities of instance \"{}\"".format(str(instance)) + ) + instance_asset_name = instance.data.get("asset") + instance_task_name = instance.data.get("task") + + if not instance_asset_name and not instance_task_name: + self.log.debug("Instance does not have set context keys.") + continue + + elif instance_asset_name and instance_task_name: + if ( + instance_asset_name == context_asset_name + and instance_task_name == context_task_name + ): + self.log.debug(( + "Instance's context is same as in publish context." + " Asset: {} | Task: {}" + ).format(context_asset_name, context_task_name)) + continue + asset_name = instance_asset_name + task_name = instance_task_name + + elif instance_task_name: + if instance_task_name == context_task_name: + self.log.debug(( + "Instance's context task is same as in publish" + " context. Task: {}" + ).format(context_task_name)) + continue + + asset_name = context_asset_name + task_name = instance_task_name + + elif instance_asset_name: + if instance_asset_name == context_asset_name: + self.log.debug(( + "Instance's context asset is same as in publish" + " context. Asset: {}" + ).format(context_asset_name)) + continue + + # Do not use context's task name + task_name = instance_task_name + asset_name = instance_asset_name + + if asset_name not in instance_by_asset_and_task: + instance_by_asset_and_task[asset_name] = {} + + if task_name not in instance_by_asset_and_task[asset_name]: + instance_by_asset_and_task[asset_name][task_name] = [] + instance_by_asset_and_task[asset_name][task_name].append(instance) + + if not instance_by_asset_and_task: + return + + session = context.data["ftrackSession"] + project_entity = context.data["ftrackProject"] + asset_names = set() + for asset_name in instance_by_asset_and_task.keys(): + asset_names.add(asset_name) + + joined_asset_names = ",".join([ + "\"{}\"".format(name) + for name in asset_names + ]) + entities = session.query(( + "TypedContext where project_id is \"{}\" and name in ({})" + ).format(project_entity["id"], joined_asset_names)).all() + + entities_by_name = { + entity["name"]: entity + for entity in entities + } + + for asset_name, by_task_data in instance_by_asset_and_task.items(): + entity = entities_by_name.get(asset_name) + task_entity_by_name = {} + if not entity: + self.log.warning(( + "Didn't find entity with name \"{}\" in Project \"{}\"" + ).format(asset_name, project_entity["full_name"])) + else: + task_entities = session.query(( + "select id, name from Task where parent_id is \"{}\"" + ).format(entity["id"])).all() + for task_entity in task_entities: + task_name_low = task_entity["name"].lower() + task_entity_by_name[task_name_low] = task_entity + + for task_name, instances in by_task_data.items(): + task_entity = None + if task_name and entity: + task_entity = task_entity_by_name.get(task_name.lower()) + + for instance in instances: + instance.data["ftrackEntity"] = entity + instance.data["ftrackTask"] = task_entity + + self.log.debug(( + "Instance {} has own ftrack entities" + " as has different context. TypedContext: {} Task: {}" + ).format(str(instance), str(entity), str(task_entity))) From c34eee3eebd8e640dacf927166a0609668546245 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 15:36:28 +0100 Subject: [PATCH 20/22] integrate ftrack api use right entities from instance --- .../plugins/publish/integrate_ftrack_api.py | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/pype/modules/ftrack/plugins/publish/integrate_ftrack_api.py b/pype/modules/ftrack/plugins/publish/integrate_ftrack_api.py index 2c8e06a099..6c25b9191e 100644 --- a/pype/modules/ftrack/plugins/publish/integrate_ftrack_api.py +++ b/pype/modules/ftrack/plugins/publish/integrate_ftrack_api.py @@ -102,25 +102,37 @@ class IntegrateFtrackApi(pyblish.api.InstancePlugin): def process(self, instance): session = instance.context.data["ftrackSession"] - if instance.data.get("ftrackTask"): - task = instance.data["ftrackTask"] - name = task - parent = task["parent"] - elif instance.data.get("ftrackEntity"): - task = None - name = instance.data.get("ftrackEntity")['name'] - parent = instance.data.get("ftrackEntity") - elif instance.context.data.get("ftrackTask"): - task = instance.context.data["ftrackTask"] - name = task - parent = task["parent"] - elif instance.context.data.get("ftrackEntity"): - task = None - name = instance.context.data.get("ftrackEntity")['name'] - parent = instance.context.data.get("ftrackEntity") + context = instance.context - info_msg = "Created new {entity_type} with data: {data}" - info_msg += ", metadata: {metadata}." + name = None + # If instance has set "ftrackEntity" or "ftrackTask" then use them from + # instance. Even if they are set to None. If they are set to None it + # has a reason. (like has different context) + if "ftrackEntity" in instance.data or "ftrackTask" in instance.data: + task = instance.data.get("ftrackTask") + parent = instance.data.get("ftrackEntity") + + elif "ftrackEntity" in context.data or "ftrackTask" in context.data: + task = context.data.get("ftrackTask") + parent = context.data.get("ftrackEntity") + + if task: + parent = task["parent"] + name = task + elif parent: + name = parent["name"] + + if not name: + self.log.info(( + "Skipping ftrack integration. Instance \"{}\" does not" + " have specified ftrack entities." + ).format(str(instance))) + return + + info_msg = ( + "Created new {entity_type} with data: {data}" + ", metadata: {metadata}." + ) used_asset_versions = [] From afe4d48615e6ebce1d182a210c6a22d56f5382ed Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 15:40:02 +0100 Subject: [PATCH 21/22] formatting changes --- .../plugins/publish/collect_batch_instances.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py index 94574ad19c..545efcb303 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_batch_instances.py @@ -4,9 +4,7 @@ from pprint import pformat class CollectBatchInstances(pyblish.api.InstancePlugin): - """ - Collect all available instances from psd batch. - """ + """Collect all available instances for batch publish.""" label = "Collect Batch Instances" order = pyblish.api.CollectorOrder + 0.489 @@ -65,7 +63,7 @@ class CollectBatchInstances(pyblish.api.InstancePlugin): # add subset data from preset new_instance.data.update(subset_data) - new_instance.data["label"] = f"{instance_name}" + new_instance.data["label"] = instance_name new_instance.data["subset"] = subset_name new_instance.data["task"] = task_name From 1aef1c78b76c0d5dd5cb895f1ae05f29bfbbfb3b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 18 Mar 2021 15:43:25 +0100 Subject: [PATCH 22/22] added review and thumbnail for bulk mov --- .../plugins/publish/collect_context.py | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py index f7f3f00ebe..43ab13cd79 100644 --- a/pype/hosts/standalonepublisher/plugins/publish/collect_context.py +++ b/pype/hosts/standalonepublisher/plugins/publish/collect_context.py @@ -14,12 +14,12 @@ Provides: """ import os -import pyblish.api -from avalon import io import json import copy -import clique from pprint import pformat +import clique +import pyblish.api +from avalon import io class CollectContextDataSAPublish(pyblish.api.ContextPlugin): @@ -50,7 +50,7 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): self.add_files_to_ignore_cleanup(in_data, context) # exception for editorial if in_data["family"] == "render_mov_batch": - in_data_list = self.prepare_mov_batch_instances(context, in_data) + in_data_list = self.prepare_mov_batch_instances(in_data) elif in_data["family"] in ["editorial", "background_batch"]: in_data_list = self.multiple_instances(context, in_data) @@ -132,7 +132,7 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): return in_data_list - def prepare_mov_batch_instances(self, context, in_data): + def prepare_mov_batch_instances(self, in_data): """Copy of `multiple_instances` method. Method was copied because `batch_extensions` is used in @@ -142,8 +142,10 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): this family specific filtering. Also "frameStart" and "frameEnd" keys are removed from instance which is needed for this processing. + Instance data will also care about families. + TODO: - - Merge logic with `multiple_instances` method. + - Merge possible logic with `multiple_instances` method. """ self.log.info("Preparing data for mov batch processing.") in_data_list = [] @@ -154,6 +156,11 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): str(repre["files"]) )) ext = repre["ext"][1:] + + # Rename representation name + repre_name = repre["name"] + if repre_name.startswith(ext + "_"): + repre["name"] = ext # Skip files that are not available for mov batch publishing # TODO add dynamic expected extensions by family from `in_data` # - with this modification it would be possible to use only @@ -177,6 +184,11 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): new_repre = copy.deepcopy(repre) new_repre["files"] = filename new_repre["name"] = ext + new_repre["thumbnail"] = True + + if "tags" not in new_repre: + new_repre["tags"] = [] + new_repre["tags"].append("review") # Prepare new subset name (temporary name) # - subset name will be changed in batch specific plugins @@ -189,6 +201,9 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): in_data_copy = copy.deepcopy(in_data) in_data_copy["representations"] = [new_repre] in_data_copy["subset"] = new_subset_name + if "families" not in in_data_copy: + in_data_copy["families"] = [] + in_data_copy["families"].append("review") in_data_list.append(in_data_copy) @@ -196,6 +211,12 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): def create_instance(self, context, in_data): subset = in_data["subset"] + # If instance data already contain families then use it + instance_families = in_data.get("families") or [] + # Make sure default families are in instance + for default_family in self.default_families or []: + if default_family not in instance_families: + instance_families.append(default_family) instance = context.create_instance(subset) instance.data.update( @@ -212,7 +233,7 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): "frameEnd": in_data.get("representations", [None])[0].get( "frameEnd", None ), - "families": self.default_families or [], + "families": instance_families } ) self.log.info("collected instance: {}".format(pformat(instance.data))) @@ -239,7 +260,6 @@ class CollectContextDataSAPublish(pyblish.api.ContextPlugin): if component["preview"]: instance.data["families"].append("review") - instance.data["repreProfiles"] = ["h264"] component["tags"] = ["review"] self.log.debug("Adding review family")