From 4866f20f866607cccd8a01b024bb9ed59742b376 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 8 Dec 2023 12:59:50 +0100 Subject: [PATCH 01/31] Refactor colorspace handling in CollectColorspace plugin - Refactored the code to use more descriptive variable names - Added a helper method `_colorspace_name_by_type` to retrieve the colorspace name based on its type - Updated logging statements for better clarity and readability Fix validation error in ValidateColorspace plugin - Added a check to ensure that the OCIO config contains at least one colorspace - If no colorspaces are found, an error is raised with appropriate messages and descriptions - Updated logging statement to include a pretty-printed representation of the config's colorspaces --- .../publish/collect_explicit_colorspace.py | 31 ++++++++++++++++--- .../plugins/publish/validate_colorspace.py | 14 ++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py index 5db2b0cbad..3b62ed7e55 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py @@ -26,20 +26,43 @@ class CollectColorspace(pyblish.api.InstancePlugin, def process(self, instance): values = self.get_attr_values_from_data(instance.data) - colorspace = values.get("colorspace", None) - if colorspace is None: + colorspace_value = values.get("colorspace", None) + if colorspace_value is None: return - self.log.debug("Explicit colorspace set to: {}".format(colorspace)) + color_data = colorspace.convert_colorspace_enumerator_item( + colorspace_value, self.config_items) + + colorspace_name = self._colorspace_name_by_type(color_data) + self.log.debug("Explicit colorspace name: {}".format(colorspace_name)) context = instance.context + context.data["colorspaceConfigItems"] = self.config_items for repre in instance.data.get("representations", {}): self.set_representation_colorspace( representation=repre, context=context, - colorspace=colorspace + colorspace=colorspace_name ) + def _colorspace_name_by_type(self, colorspace_data): + """ + Returns colorspace name by type + + Arguments: + colorspace_data (dict): colorspace data + + Returns: + str: colorspace name + """ + if colorspace_data["type"] == "colorspaces": + return colorspace_data["name"] + elif colorspace_data["type"] == "roles": + return colorspace_data["colorspace"] + else: + raise KeyError("Unknown colorspace type: {}".format( + colorspace_data["type"])) + @classmethod def apply_settings(cls, project_settings): host = registered_host() diff --git a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py index 03f9f299b2..c2eee7c515 100644 --- a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py @@ -1,3 +1,4 @@ +from pprint import pformat import pyblish.api from openpype.pipeline import ( @@ -33,13 +34,24 @@ class ValidateColorspace(pyblish.api.InstancePlugin, config_path = colorspace_data["config"]["path"] if config_path not in config_colorspaces: colorspaces = get_ocio_config_colorspaces(config_path) - config_colorspaces[config_path] = set(colorspaces) + if not colorspaces.get("colorspaces"): + raise PublishValidationError( + title="Colorspace validation", + message=f"OCIO config '{config_path}' does not contain " + f"any colorspaces. This is error in config. " + "Contact your pipeline TD.", + description=f"OCIO config '{config_path}' does not " + f"contain any colorspaces. This is error " + "in config. Contact your pipeline TD." + ) + config_colorspaces[config_path] = set(colorspaces["colorspaces"]) colorspace = colorspace_data["colorspace"] self.log.debug( f"Validating representation '{repre['name']}' " f"colorspace '{colorspace}'" ) + self.log.debug(pformat(config_colorspaces[config_path])) if colorspace not in config_colorspaces[config_path]: message = ( f"Representation '{repre['name']}' colorspace " From 764775bf006304939ffe59104f0e503e1b8297db Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 8 Dec 2023 13:06:19 +0100 Subject: [PATCH 02/31] hound --- .../traypublisher/plugins/publish/validate_colorspace.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py index c2eee7c515..74d8956986 100644 --- a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py @@ -37,14 +37,15 @@ class ValidateColorspace(pyblish.api.InstancePlugin, if not colorspaces.get("colorspaces"): raise PublishValidationError( title="Colorspace validation", - message=f"OCIO config '{config_path}' does not contain " + message=f"OCIO config '{config_path}' does not contain " # noqa f"any colorspaces. This is error in config. " "Contact your pipeline TD.", description=f"OCIO config '{config_path}' does not " f"contain any colorspaces. This is error " "in config. Contact your pipeline TD." ) - config_colorspaces[config_path] = set(colorspaces["colorspaces"]) + config_colorspaces[config_path] = set( + colorspaces["colorspaces"]) colorspace = colorspace_data["colorspace"] self.log.debug( From 760adc87bae8de1f99d217d9d9e9d5e98562ab19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Tue, 12 Dec 2023 16:55:03 +0100 Subject: [PATCH 03/31] Update openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py Co-authored-by: Roy Nieterau --- .../hosts/traypublisher/plugins/publish/validate_colorspace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py index 74d8956986..6ee39584be 100644 --- a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py @@ -52,7 +52,6 @@ class ValidateColorspace(pyblish.api.InstancePlugin, f"Validating representation '{repre['name']}' " f"colorspace '{colorspace}'" ) - self.log.debug(pformat(config_colorspaces[config_path])) if colorspace not in config_colorspaces[config_path]: message = ( f"Representation '{repre['name']}' colorspace " From ed3a2556e2dcff2cc5f08aafe7799146aab85333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Tue, 12 Dec 2023 16:55:40 +0100 Subject: [PATCH 04/31] Update openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py Co-authored-by: Roy Nieterau --- .../plugins/publish/validate_colorspace.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py index 6ee39584be..9b870617fb 100644 --- a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py @@ -35,14 +35,15 @@ class ValidateColorspace(pyblish.api.InstancePlugin, if config_path not in config_colorspaces: colorspaces = get_ocio_config_colorspaces(config_path) if not colorspaces.get("colorspaces"): + message = ( + f"OCIO config '{config_path}' does not contain any " + "colorspaces. This is an error in the OCIO config. " + "Contact your pipeline TD.", + ) raise PublishValidationError( title="Colorspace validation", - message=f"OCIO config '{config_path}' does not contain " # noqa - f"any colorspaces. This is error in config. " - "Contact your pipeline TD.", - description=f"OCIO config '{config_path}' does not " - f"contain any colorspaces. This is error " - "in config. Contact your pipeline TD." + message=message, + description=message ) config_colorspaces[config_path] = set( colorspaces["colorspaces"]) From d5866bf7810733e2e4c21384f25619e7b236881c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 12 Dec 2023 17:06:29 +0100 Subject: [PATCH 05/31] hound --- .../hosts/traypublisher/plugins/publish/validate_colorspace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py index 9b870617fb..58c40938d2 100644 --- a/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/validate_colorspace.py @@ -1,4 +1,3 @@ -from pprint import pformat import pyblish.api from openpype.pipeline import ( From 4da0bcd5cd80406e98d67d4d3889d4a8a0c6422c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 12 Dec 2023 17:07:01 +0100 Subject: [PATCH 06/31] improving error comunication --- .../plugins/publish/collect_explicit_colorspace.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py index 3b62ed7e55..5dcc252f03 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py @@ -5,6 +5,7 @@ from openpype.pipeline import ( ) from openpype.lib import EnumDef from openpype.pipeline import colorspace +from openpype.pipeline.publish import KnownPublishError class CollectColorspace(pyblish.api.InstancePlugin, @@ -37,7 +38,6 @@ class CollectColorspace(pyblish.api.InstancePlugin, self.log.debug("Explicit colorspace name: {}".format(colorspace_name)) context = instance.context - context.data["colorspaceConfigItems"] = self.config_items for repre in instance.data.get("representations", {}): self.set_representation_colorspace( representation=repre, @@ -60,8 +60,11 @@ class CollectColorspace(pyblish.api.InstancePlugin, elif colorspace_data["type"] == "roles": return colorspace_data["colorspace"] else: - raise KeyError("Unknown colorspace type: {}".format( - colorspace_data["type"])) + raise KnownPublishError( + "Collecting of colorspace failed. used config is missing " + "colorspace type: '{}' .".format(colorspace_data["type"]) + "Please contact your pipeline TD." + ) @classmethod def apply_settings(cls, project_settings): From 7e883fc1674e6ca46bad5cca1fa64d4d9484289c Mon Sep 17 00:00:00 2001 From: Jack P Date: Fri, 15 Dec 2023 10:25:24 +0000 Subject: [PATCH 07/31] feat: added new saver output ext validator --- .../validate_saver_output_extension.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py new file mode 100644 index 0000000000..8ece175344 --- /dev/null +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -0,0 +1,59 @@ +import os + +import pyblish.api +from openpype.pipeline import PublishValidationError +from openpype.pipeline.publish import RepairAction +from openpype.hosts.fusion.api.action import SelectInvalidAction + + +class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): + """ + Temp docstring + """ + + order = pyblish.api.ValidatorOrder + label = "Validate Saver Output Extension" + families = ["render"] + hosts = ["fusion"] + actions = [SelectInvalidAction, RepairAction] + + @classmethod + def get_invalid(cls, instance): + saver = instance.data["tool"] + output_path = saver.Clip[1] + current_ext = get_file_extension(output_path) + ext = instance.data["image_format"] + if not current_ext == ext: + return (saver, current_ext, ext) + + def process(self, instance): + saver = instance.data["tool"] + current_ext = get_file_extension(saver.Clip[1]) + expected_ext = instance.data["image_format"] + + if not current_ext == expected_ext: + raise PublishValidationError( + f"Instance {saver.Name} output image format does not match the current publish selection.\n\n" + f"Current: {current_ext}\n\n" + f"Expected: {expected_ext}\n\n" + "You can use the repair action to update this instance.", + title=self.label, + ) + + @classmethod + def repair(cls, instance): + saver = instance.data["tool"] + output_path = saver.Clip[1] + ext = get_file_extension(output_path) + output_path = output_path.replace( + f".{ext}", f".{instance.data['image_format']}" + ) + saver.SetData( + "openpype.creator_attributes.image_format", + instance.data["image_format"], + ) + saver.Clip[1] = output_path + + +def get_file_extension(full_path): + return os.path.splitext(full_path)[1].replace(".", "") From 19fe8e0c1b5d2803cd7644253cd3ebedc2ddae55 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 10:50:17 +0000 Subject: [PATCH 08/31] chore: removed redunant function + small refactor --- .../publish/validate_saver_output_extension.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index 8ece175344..7c668d4467 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -17,21 +17,12 @@ class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): hosts = ["fusion"] actions = [SelectInvalidAction, RepairAction] - @classmethod - def get_invalid(cls, instance): - saver = instance.data["tool"] - output_path = saver.Clip[1] - current_ext = get_file_extension(output_path) - ext = instance.data["image_format"] - if not current_ext == ext: - return (saver, current_ext, ext) - def process(self, instance): saver = instance.data["tool"] - current_ext = get_file_extension(saver.Clip[1]) - expected_ext = instance.data["image_format"] + current_extension = get_file_extension(saver.Clip[1]) + expected_extension = instance.data["image_format"] - if not current_ext == expected_ext: + if current_ext != expected_ext: raise PublishValidationError( f"Instance {saver.Name} output image format does not match the current publish selection.\n\n" f"Current: {current_ext}\n\n" From 1cc824c099119234031b7770b653b5bf89185df5 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 10:50:28 +0000 Subject: [PATCH 09/31] chore: updated docstring --- .../plugins/publish/validate_saver_output_extension.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index 7c668d4467..b96a136a9d 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -8,7 +8,10 @@ from openpype.hosts.fusion.api.action import SelectInvalidAction class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): """ - Temp docstring + Validate Saver Output Extension matches Publish menu + + This ensures that if the user tweaks the 'Output File Extension' in the publish menu, + it is respected during the publish. """ order = pyblish.api.ValidatorOrder From f7a1a029c768e167e2fe001e4b9030f4f6396433 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 10:50:55 +0000 Subject: [PATCH 10/31] refactor: get_file_ext to use lstrip instead of replace --- .../fusion/plugins/publish/validate_saver_output_extension.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index b96a136a9d..ce2e671d4b 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -46,8 +46,7 @@ class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): "openpype.creator_attributes.image_format", instance.data["image_format"], ) - saver.Clip[1] = output_path def get_file_extension(full_path): - return os.path.splitext(full_path)[1].replace(".", "") + return os.path.splitext(full_path)[1].lstrip(".") From fb90d78160703aab838c16ce88026e0372c7abcf Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 10:51:28 +0000 Subject: [PATCH 11/31] refactor: improved repair function --- .../publish/validate_saver_output_extension.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index ce2e671d4b..2b6d4f2f19 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -1,5 +1,4 @@ import os - import pyblish.api from openpype.pipeline import PublishValidationError from openpype.pipeline.publish import RepairAction @@ -38,10 +37,13 @@ class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): def repair(cls, instance): saver = instance.data["tool"] output_path = saver.Clip[1] - ext = get_file_extension(output_path) - output_path = output_path.replace( - f".{ext}", f".{instance.data['image_format']}" - ) + + root, old_extension = os.path.splitext(output_path) + new_extension = instance.data["image_format"] + + new_output_path = f"{root}.{new_extension}" + saver.Clip[1] = new_output_path + saver.SetData( "openpype.creator_attributes.image_format", instance.data["image_format"], From 9e69e5d48e75d8b47bb0317fc78bb848f04ac9c0 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 11:23:03 +0000 Subject: [PATCH 12/31] fix: typo --- .../fusion/plugins/publish/validate_saver_output_extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index 2b6d4f2f19..c19c297f97 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -24,7 +24,7 @@ class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): current_extension = get_file_extension(saver.Clip[1]) expected_extension = instance.data["image_format"] - if current_ext != expected_ext: + if current_extension != expected_extension: raise PublishValidationError( f"Instance {saver.Name} output image format does not match the current publish selection.\n\n" f"Current: {current_ext}\n\n" From e4b24189d1d84be4af09652a9f2533b336d51af4 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 11:25:12 +0000 Subject: [PATCH 13/31] fix: more typos.. love when my lsp isn't working --- .../fusion/plugins/publish/validate_saver_output_extension.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index c19c297f97..f10f1d68ba 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -27,8 +27,8 @@ class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): if current_extension != expected_extension: raise PublishValidationError( f"Instance {saver.Name} output image format does not match the current publish selection.\n\n" - f"Current: {current_ext}\n\n" - f"Expected: {expected_ext}\n\n" + f"Current: {current_extension}\n\n" + f"Expected: {expected_extension}\n\n" "You can use the repair action to update this instance.", title=self.label, ) From b5b1be262e760ba01406468a9d4d643f1bfb9919 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 11:28:54 +0000 Subject: [PATCH 14/31] chore: added optional tag for testing --- .../fusion/plugins/publish/validate_saver_output_extension.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index f10f1d68ba..0862e0ac61 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -17,6 +17,7 @@ class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): label = "Validate Saver Output Extension" families = ["render"] hosts = ["fusion"] + optional = True actions = [SelectInvalidAction, RepairAction] def process(self, instance): From 437246c090af27eacd65af52e0d8e28bb7d6ec30 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 11:36:15 +0000 Subject: [PATCH 15/31] chore: added optional class inherit for testing --- .../plugins/publish/validate_saver_output_extension.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index 0862e0ac61..ea55832288 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -1,11 +1,16 @@ import os import pyblish.api -from openpype.pipeline import PublishValidationError +from openpype.pipeline import ( + PublishValidationError, + OptionalPyblishPluginMixin, +) from openpype.pipeline.publish import RepairAction from openpype.hosts.fusion.api.action import SelectInvalidAction -class ValidateSaverOutputExtension(pyblish.api.InstancePlugin): +class ValidateSaverOutputExtension( + pyblish.api.InstancePlugin, OptionalPyblishPluginMixin +): """ Validate Saver Output Extension matches Publish menu From 289eb1f4c8e6d11f34fc66157ed38b3d86ede9ac Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 11:46:18 +0000 Subject: [PATCH 16/31] fix: added check for optional behaviour --- .../fusion/plugins/publish/validate_saver_output_extension.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py index ea55832288..746bb5eb6f 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py @@ -26,6 +26,9 @@ class ValidateSaverOutputExtension( actions = [SelectInvalidAction, RepairAction] def process(self, instance): + if not self.is_active(instance.data): + return + saver = instance.data["tool"] current_extension = get_file_extension(saver.Clip[1]) expected_extension = instance.data["image_format"] From 839e8153e384055b5f990975491ab01301b5857d Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 14:30:32 +0000 Subject: [PATCH 17/31] feat: create_saver now respects changes to creator_attributes --- openpype/hosts/fusion/plugins/create/create_saver.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/fusion/plugins/create/create_saver.py b/openpype/hosts/fusion/plugins/create/create_saver.py index 6e71b41541..c75a780a2a 100644 --- a/openpype/hosts/fusion/plugins/create/create_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_saver.py @@ -119,10 +119,9 @@ class CreateSaver(NewCreator): if "subset" not in data: return - original_subset = tool.GetData("openpype.subset") - subset = data["subset"] - if original_subset != subset: - self._configure_saver_tool(data, tool, subset) + original_data = tool.GetData("openpype") + if original_data != data["creator_attributes"]: + self._configure_saver_tool(data, tool, data["subset"]) def _configure_saver_tool(self, data, tool, subset): formatting_data = deepcopy(data) From 23d0c166dfc55ba6e276993d1c967715a70484c3 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 14:33:38 +0000 Subject: [PATCH 18/31] chore: removed redundant validator this is no longer needed since the creator now respects changes to attributes --- .../validate_saver_output_extension.py | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py b/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py deleted file mode 100644 index 746bb5eb6f..0000000000 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_output_extension.py +++ /dev/null @@ -1,63 +0,0 @@ -import os -import pyblish.api -from openpype.pipeline import ( - PublishValidationError, - OptionalPyblishPluginMixin, -) -from openpype.pipeline.publish import RepairAction -from openpype.hosts.fusion.api.action import SelectInvalidAction - - -class ValidateSaverOutputExtension( - pyblish.api.InstancePlugin, OptionalPyblishPluginMixin -): - """ - Validate Saver Output Extension matches Publish menu - - This ensures that if the user tweaks the 'Output File Extension' in the publish menu, - it is respected during the publish. - """ - - order = pyblish.api.ValidatorOrder - label = "Validate Saver Output Extension" - families = ["render"] - hosts = ["fusion"] - optional = True - actions = [SelectInvalidAction, RepairAction] - - def process(self, instance): - if not self.is_active(instance.data): - return - - saver = instance.data["tool"] - current_extension = get_file_extension(saver.Clip[1]) - expected_extension = instance.data["image_format"] - - if current_extension != expected_extension: - raise PublishValidationError( - f"Instance {saver.Name} output image format does not match the current publish selection.\n\n" - f"Current: {current_extension}\n\n" - f"Expected: {expected_extension}\n\n" - "You can use the repair action to update this instance.", - title=self.label, - ) - - @classmethod - def repair(cls, instance): - saver = instance.data["tool"] - output_path = saver.Clip[1] - - root, old_extension = os.path.splitext(output_path) - new_extension = instance.data["image_format"] - - new_output_path = f"{root}.{new_extension}" - saver.Clip[1] = new_output_path - - saver.SetData( - "openpype.creator_attributes.image_format", - instance.data["image_format"], - ) - - -def get_file_extension(full_path): - return os.path.splitext(full_path)[1].lstrip(".") From 3c272e4a7db54366c7c171b530de5688b947a5a9 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 14:48:36 +0000 Subject: [PATCH 19/31] fix: typo in comparison of data --- openpype/hosts/fusion/plugins/create/create_saver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/create/create_saver.py b/openpype/hosts/fusion/plugins/create/create_saver.py index c75a780a2a..b2235bd2b6 100644 --- a/openpype/hosts/fusion/plugins/create/create_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_saver.py @@ -119,7 +119,7 @@ class CreateSaver(NewCreator): if "subset" not in data: return - original_data = tool.GetData("openpype") + original_data = tool.GetData("openpype.creator_attributes") if original_data != data["creator_attributes"]: self._configure_saver_tool(data, tool, data["subset"]) From 940103feeeb233d933d71d552d0e3e0ab8744480 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 15 Dec 2023 15:50:11 +0000 Subject: [PATCH 20/31] refactor: more accurately specified the conditions of '_configure_saver_tool' calls --- .../hosts/fusion/plugins/create/create_saver.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/fusion/plugins/create/create_saver.py b/openpype/hosts/fusion/plugins/create/create_saver.py index b2235bd2b6..5870828b41 100644 --- a/openpype/hosts/fusion/plugins/create/create_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_saver.py @@ -119,9 +119,17 @@ class CreateSaver(NewCreator): if "subset" not in data: return - original_data = tool.GetData("openpype.creator_attributes") - if original_data != data["creator_attributes"]: - self._configure_saver_tool(data, tool, data["subset"]) + original_subset = tool.GetData("openpype.subset") + original_format = tool.GetData( + "openpype.creator_attributes.image_format" + ) + + subset = data["subset"] + if ( + original_subset != subset + or original_format != data["creator_attributes"]["image_format"] + ): + self._configure_saver_tool(data, tool, subset) def _configure_saver_tool(self, data, tool, subset): formatting_data = deepcopy(data) From a21ba52cdbcbed26ecfbfd07a7461c63cb7c9c1e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 16 Dec 2023 03:25:45 +0000 Subject: [PATCH 21/31] chore(): update bug report / version --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 38b5a79232..be0a6e1299 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -35,6 +35,7 @@ body: label: Version description: What version are you running? Look to OpenPype Tray options: + - 3.18.2-nightly.1 - 3.18.1 - 3.18.1-nightly.1 - 3.18.0 @@ -134,7 +135,6 @@ body: - 3.15.4-nightly.3 - 3.15.4-nightly.2 - 3.15.4-nightly.1 - - 3.15.3 validations: required: true - type: dropdown From a26e575ce01ed9e36ecab74bbae1a81181fd4357 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 18 Dec 2023 11:54:45 +0100 Subject: [PATCH 22/31] Photoshop: fix layer publish thumbnail missing in loader (#6061) * OP-1645 - explicitly add thumbnail path to be integrated to Ayon Thumbnail representation is set to 'delete', eg wont be integrated, another source of thumbnail must be used. This will effectively limit option of NOT pushing thumbnail to Ayon, which use case I am actuall not seeing. * OP-1645 - added more description * Remove comment It works even for OP. Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> * Update openpype/plugins/publish/integrate_thumbnail_ayon.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> * Updates to docstring Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> * Update openpype/plugins/publish/integrate_thumbnail_ayon.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> * OP-1645 - fix formatting --------- Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../photoshop/plugins/publish/extract_review.py | 1 + .../plugins/publish/integrate_thumbnail_ayon.py | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/photoshop/plugins/publish/extract_review.py b/openpype/hosts/photoshop/plugins/publish/extract_review.py index d5dac417d7..c2773b2a20 100644 --- a/openpype/hosts/photoshop/plugins/publish/extract_review.py +++ b/openpype/hosts/photoshop/plugins/publish/extract_review.py @@ -224,6 +224,7 @@ class ExtractReview(publish.Extractor): "stagingDir": staging_dir, "tags": ["thumbnail", "delete"] }) + instance.data["thumbnailPath"] = thumbnail_path def _check_and_resize(self, processed_img_names, source_files_pattern, staging_dir): diff --git a/openpype/plugins/publish/integrate_thumbnail_ayon.py b/openpype/plugins/publish/integrate_thumbnail_ayon.py index 1947c9dd4c..fc77a803fc 100644 --- a/openpype/plugins/publish/integrate_thumbnail_ayon.py +++ b/openpype/plugins/publish/integrate_thumbnail_ayon.py @@ -5,7 +5,21 @@ pull into a scene. This one is used only as image describing content of published item and - shows up only in Loader in right column section. + shows up only in Loader or WebUI. + + Instance must have 'published_representations' to + be able to integrate thumbnail. + Possible sources of thumbnail paths: + - instance.data["thumbnailPath"] + - representation with 'thumbnail' name in 'published_representations' + - context.data["thumbnailPath"] + + Notes: + Issue with 'thumbnail' representation is that we most likely don't + want to integrate it as representation. Integrated representation + is polluting Loader and database without real usage. That's why + they usually have 'delete' tag to skip the integration. + """ import os From 443d107b0ecbd9c2c49352375b19b52dcc0c920c Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 18 Dec 2023 12:28:44 +0100 Subject: [PATCH 23/31] OP-7470 - fix for single frame rendering (#6056) --- .../hosts/fusion/plugins/publish/extract_render_local.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/extract_render_local.py b/openpype/hosts/fusion/plugins/publish/extract_render_local.py index 08d608139d..068df22c06 100644 --- a/openpype/hosts/fusion/plugins/publish/extract_render_local.py +++ b/openpype/hosts/fusion/plugins/publish/extract_render_local.py @@ -146,11 +146,15 @@ class FusionRenderLocal( staging_dir = os.path.dirname(path) + files = [os.path.basename(f) for f in expected_files] + if len(expected_files) == 1: + files = files[0] + repre = { "name": ext[1:], "ext": ext[1:], "frameStart": f"%0{padding}d" % start, - "files": [os.path.basename(f) for f in expected_files], + "files": files, "stagingDir": staging_dir, } From 0252c9e137e77d0395afc1b0bfe01d1042dcb944 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 18 Dec 2023 16:02:39 +0100 Subject: [PATCH 24/31] OP-7606 - fix creation of .mov (#6064) --- openpype/hosts/photoshop/plugins/publish/extract_review.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/photoshop/plugins/publish/extract_review.py b/openpype/hosts/photoshop/plugins/publish/extract_review.py index c2773b2a20..09c5d63aa5 100644 --- a/openpype/hosts/photoshop/plugins/publish/extract_review.py +++ b/openpype/hosts/photoshop/plugins/publish/extract_review.py @@ -170,8 +170,7 @@ class ExtractReview(publish.Extractor): # Generate mov. mov_path = os.path.join(staging_dir, "review.mov") self.log.info(f"Generate mov review: {mov_path}") - args = [ - ffmpeg_path, + args = ffmpeg_path + [ "-y", "-i", source_files_pattern, "-vf", "pad=ceil(iw/2)*2:ceil(ih/2)*2", From 263f1a0adbf8b73f62ea7824d6aea50e89fb1308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Mon, 18 Dec 2023 16:09:28 +0100 Subject: [PATCH 25/31] :bug: fix wrong nuke version constant name --- openpype/hosts/nuke/api/pipeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py index 7bc17ff504..12562a6b6f 100644 --- a/openpype/hosts/nuke/api/pipeline.py +++ b/openpype/hosts/nuke/api/pipeline.py @@ -260,7 +260,7 @@ def _install_menu(): "Create...", lambda: host_tools.show_publisher( parent=( - main_window if nuke.NUKE_VERSION_RELEASE >= 14 else None + main_window if nuke.NUKE_VERSION_MAJOR >= 14 else None ), tab="create" ) @@ -271,7 +271,7 @@ def _install_menu(): "Publish...", lambda: host_tools.show_publisher( parent=( - main_window if nuke.NUKE_VERSION_RELEASE >= 14 else None + main_window if nuke.NUKE_VERSION_MAJOR >= 14 else None ), tab="publish" ) From 1aca2d3befbb4e969f37347d1ada03e305c54678 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 18 Dec 2023 16:19:14 +0100 Subject: [PATCH 26/31] expect 'ayon' group as one of option to get custom attributes --- openpype/modules/ftrack/lib/custom_attributes.py | 2 +- .../ftrack/plugins/publish/integrate_hierarchy_ftrack.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/modules/ftrack/lib/custom_attributes.py b/openpype/modules/ftrack/lib/custom_attributes.py index 3e40bb02f2..76c7bcd403 100644 --- a/openpype/modules/ftrack/lib/custom_attributes.py +++ b/openpype/modules/ftrack/lib/custom_attributes.py @@ -66,7 +66,7 @@ def get_openpype_attr(session, split_hierarchical=True, query_keys=None): "select {}" " from CustomAttributeConfiguration" # Kept `pype` for Backwards Compatibility - " where group.name in (\"pype\", \"{}\")" + " where group.name in (\"pype\", \"ayon\", \"{}\")" ).format(", ".join(query_keys), CUST_ATTR_GROUP) all_avalon_attr = session.query(cust_attrs_query).all() for cust_attr in all_avalon_attr: diff --git a/openpype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py b/openpype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py index a1aa7c0daa..68a31035f6 100644 --- a/openpype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py +++ b/openpype/modules/ftrack/plugins/publish/integrate_hierarchy_ftrack.py @@ -21,7 +21,7 @@ def get_pype_attr(session, split_hierarchical=True): "select id, entity_type, object_type_id, is_hierarchical, default" " from CustomAttributeConfiguration" # Kept `pype` for Backwards Compatibility - " where group.name in (\"pype\", \"{}\")" + " where group.name in (\"pype\", \"ayon\", \"{}\")" ).format(CUST_ATTR_GROUP) all_avalon_attr = session.query(cust_attrs_query).all() for cust_attr in all_avalon_attr: From 8c387c30432d29d576bd702637382571bbc6f8b9 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 18 Dec 2023 16:39:29 +0100 Subject: [PATCH 27/31] Photoshop: fix Collect Color Coded settings (#6065) * OP-7609 - fix Photoshop publish plugin model Was causing issues when saving settings for `Collect Color Coded Instances` * OP-7609 - bump up version for Photoshop addon Caused by change of Settings model. --- server_addon/photoshop/server/settings/publish_plugins.py | 2 +- server_addon/photoshop/server/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/photoshop/server/settings/publish_plugins.py b/server_addon/photoshop/server/settings/publish_plugins.py index 2863979ca9..21e7d670f0 100644 --- a/server_addon/photoshop/server/settings/publish_plugins.py +++ b/server_addon/photoshop/server/settings/publish_plugins.py @@ -29,7 +29,7 @@ class ColorCodeMappings(BaseSettingsModel): ) layer_name_regex: list[str] = Field( - "", + default_factory=list, title="Layer name regex" ) diff --git a/server_addon/photoshop/server/version.py b/server_addon/photoshop/server/version.py index d4b9e2d7f3..a242f0e757 100644 --- a/server_addon/photoshop/server/version.py +++ b/server_addon/photoshop/server/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring addon version.""" -__version__ = "0.1.0" +__version__ = "0.1.1" From cd2e907dc2bc8302af37c668546e05d7ffedca28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Mon, 18 Dec 2023 17:06:40 +0100 Subject: [PATCH 28/31] :bug: fix AYON settings for Maya workspace --- server_addon/maya/server/settings/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/maya/server/settings/main.py b/server_addon/maya/server/settings/main.py index 62fd12ec8a..a5b573a75e 100644 --- a/server_addon/maya/server/settings/main.py +++ b/server_addon/maya/server/settings/main.py @@ -97,7 +97,7 @@ DEFAULT_MEL_WORKSPACE_SETTINGS = "\n".join(( 'workspace -fr "renderData" "renderData";', 'workspace -fr "sourceImages" "sourceimages";', 'workspace -fr "fileCache" "cache/nCache";', - 'workspace -fr "autoSave" "autosave"', + 'workspace -fr "autoSave" "autosave";', '', )) From c964f1411af3fe7c34c9ed067a143f9502bdf605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Mon, 18 Dec 2023 17:07:13 +0100 Subject: [PATCH 29/31] :recycle: sync defaults with AYON --- openpype/settings/defaults/project_settings/maya.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 7719a5e255..34452eb8ce 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -436,7 +436,7 @@ "viewTransform": "sRGB gamma" } }, - "mel_workspace": "workspace -fr \"shaders\" \"renderData/shaders\";\nworkspace -fr \"images\" \"renders/maya\";\nworkspace -fr \"particles\" \"particles\";\nworkspace -fr \"mayaAscii\" \"\";\nworkspace -fr \"mayaBinary\" \"\";\nworkspace -fr \"scene\" \"\";\nworkspace -fr \"alembicCache\" \"cache/alembic\";\nworkspace -fr \"renderData\" \"renderData\";\nworkspace -fr \"sourceImages\" \"sourceimages\";\nworkspace -fr \"fileCache\" \"cache/nCache\";\n", + "mel_workspace": "workspace -fr \"shaders\" \"renderData/shaders\";\nworkspace -fr \"images\" \"renders/maya\";\nworkspace -fr \"particles\" \"particles\";\nworkspace -fr \"mayaAscii\" \"\";\nworkspace -fr \"mayaBinary\" \"\";\nworkspace -fr \"scene\" \"\";\nworkspace -fr \"alembicCache\" \"cache/alembic\";\nworkspace -fr \"renderData\" \"renderData\";\nworkspace -fr \"sourceImages\" \"sourceimages\";\nworkspace -fr \"fileCache\" \"cache/nCache\";\nworkspace -fr \"autoSave\" \"autosave\";", "ext_mapping": { "model": "ma", "mayaAscii": "ma", From 4db853ec03342da8d4a1e8ecaef32080cc804b6d Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 19 Dec 2023 11:24:55 +0100 Subject: [PATCH 30/31] do not use thumbnailSource for integration (#6063) --- openpype/plugins/publish/integrate_thumbnail_ayon.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openpype/plugins/publish/integrate_thumbnail_ayon.py b/openpype/plugins/publish/integrate_thumbnail_ayon.py index fc77a803fc..e56c567667 100644 --- a/openpype/plugins/publish/integrate_thumbnail_ayon.py +++ b/openpype/plugins/publish/integrate_thumbnail_ayon.py @@ -106,11 +106,8 @@ class IntegrateThumbnailsAYON(pyblish.api.ContextPlugin): continue # Find thumbnail path on instance - thumbnail_source = instance.data.get("thumbnailSource") - thumbnail_path = instance.data.get("thumbnailPath") thumbnail_path = ( - thumbnail_source - or thumbnail_path + instance.data.get("thumbnailPath") or self._get_instance_thumbnail_path(published_repres) ) if thumbnail_path: From 3ef475fcd3641dc2faf0fd1d76f7f44b4cdbeccd Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 19 Dec 2023 14:05:47 +0100 Subject: [PATCH 31/31] hound catch --- .../plugins/publish/collect_explicit_colorspace.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py b/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py index 5dcc252f03..75c26ac958 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_explicit_colorspace.py @@ -61,9 +61,10 @@ class CollectColorspace(pyblish.api.InstancePlugin, return colorspace_data["colorspace"] else: raise KnownPublishError( - "Collecting of colorspace failed. used config is missing " - "colorspace type: '{}' .".format(colorspace_data["type"]) - "Please contact your pipeline TD." + ( + "Collecting of colorspace failed. used config is missing " + "colorspace type: '{}' . Please contact your pipeline TD." + ).format(colorspace_data['type']) ) @classmethod