From 49a0ccc0d5506f49335c886ca5f56dc9ca2de7ec Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Jul 2024 23:28:17 +0200 Subject: [PATCH 01/20] Allow passing CollectSceneVersion but with a logged error so validators can catch a nicer error report instead --- client/ayon_core/plugins/publish/collect_scene_version.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_scene_version.py b/client/ayon_core/plugins/publish/collect_scene_version.py index ea4823d62a..8d643062bc 100644 --- a/client/ayon_core/plugins/publish/collect_scene_version.py +++ b/client/ayon_core/plugins/publish/collect_scene_version.py @@ -47,8 +47,9 @@ class CollectSceneVersion(pyblish.api.ContextPlugin): return if not context.data.get('currentFile'): - raise KnownPublishError("Cannot get current workfile path. " - "Make sure your scene is saved.") + self.log.error("Cannot get current workfile path. " + "Make sure your scene is saved.") + return filename = os.path.basename(context.data.get('currentFile')) From 412cc595cce900d1697146e30fdc3fb3203881f3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 18 Jul 2024 23:31:29 +0200 Subject: [PATCH 02/20] Use regular `dict.get()` access on `instance.data.get("version")` for less confusion --- .../ayon_core/plugins/publish/collect_anatomy_instance_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py index b6636696c1..97bc47dc11 100644 --- a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py +++ b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py @@ -321,7 +321,7 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): use_context_version = instance.data["followWorkfileVersion"] if use_context_version: - version_number = context.data("version") + version_number = context.data.get("version") # Even if 'follow_workfile_version' is enabled, it may not be set # because workfile version was not collected to 'context.data' From 30c32b8fa7a0dce477206ade54ecfa06940b8da4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 19 Jul 2024 00:23:12 +0200 Subject: [PATCH 03/20] Improve Validate File Saved report and provide repair actions --- .../plugins/publish/validate_file_saved.py | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/plugins/publish/validate_file_saved.py b/client/ayon_core/plugins/publish/validate_file_saved.py index d459ba7ed4..976f78aa2f 100644 --- a/client/ayon_core/plugins/publish/validate_file_saved.py +++ b/client/ayon_core/plugins/publish/validate_file_saved.py @@ -1,6 +1,30 @@ +import inspect + import pyblish.api from ayon_core.pipeline.publish import PublishValidationError +from ayon_core.tools.utils.host_tools import show_workfiles +from ayon_core.pipeline.context_tools import version_up_current_workfile + + +class SaveByVersionUpAction(pyblish.api.Action): + """Save Workfile.""" + label = "Save Workfile" + on = "failed" + icon = "save" + + def process(self, context, plugin): + version_up_current_workfile() + + +class ShowWorkfilesAction(pyblish.api.Action): + """Save Workfile.""" + label = "Show Workfiles Tool..." + on = "failed" + icon = "files-o" + + def process(self, context, plugin): + show_workfiles() class ValidateCurrentSaveFile(pyblish.api.ContextPlugin): @@ -8,10 +32,26 @@ class ValidateCurrentSaveFile(pyblish.api.ContextPlugin): label = "Validate File Saved" order = pyblish.api.ValidatorOrder - 0.1 - hosts = ["maya", "houdini", "nuke"] + hosts = ["maya", "houdini", "nuke", "fusion"] + actions = [SaveByVersionUpAction, ShowWorkfilesAction] def process(self, context): current_file = context.data["currentFile"] if not current_file: - raise PublishValidationError("File not saved") + raise PublishValidationError( + "File not saved", + title="File not saved", + description=self.get_description()) + + def get_description(self): + return inspect.cleandoc(""" + ### File not saved + + Your workfile must be saved to continue publishing. + + Please save your scene. + + The **Save Workfile** action will save it for you with the first + available workfile version number in your current context. + """) From 6b7ece95e69e753dcefe46061b558b0ab960a606 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 19 Jul 2024 00:25:19 +0200 Subject: [PATCH 04/20] Improve Validate File Saved report and provide repair actions --- client/ayon_core/plugins/publish/validate_file_saved.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/validate_file_saved.py b/client/ayon_core/plugins/publish/validate_file_saved.py index 976f78aa2f..bff835fd33 100644 --- a/client/ayon_core/plugins/publish/validate_file_saved.py +++ b/client/ayon_core/plugins/publish/validate_file_saved.py @@ -40,7 +40,7 @@ class ValidateCurrentSaveFile(pyblish.api.ContextPlugin): current_file = context.data["currentFile"] if not current_file: raise PublishValidationError( - "File not saved", + "Workfile is not saved. Please save your scene to continue.", title="File not saved", description=self.get_description()) @@ -50,8 +50,6 @@ class ValidateCurrentSaveFile(pyblish.api.ContextPlugin): Your workfile must be saved to continue publishing. - Please save your scene. - The **Save Workfile** action will save it for you with the first available workfile version number in your current context. """) From 86b1b4d208261bf987668b7d3655e46c832efaac Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 19 Jul 2024 00:31:12 +0200 Subject: [PATCH 05/20] Improve docstring --- client/ayon_core/plugins/publish/validate_file_saved.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/validate_file_saved.py b/client/ayon_core/plugins/publish/validate_file_saved.py index bff835fd33..e4f009615a 100644 --- a/client/ayon_core/plugins/publish/validate_file_saved.py +++ b/client/ayon_core/plugins/publish/validate_file_saved.py @@ -28,7 +28,11 @@ class ShowWorkfilesAction(pyblish.api.Action): class ValidateCurrentSaveFile(pyblish.api.ContextPlugin): - """File must be saved before publishing""" + """File must be saved before publishing + + This does not validate for unsaved changes. It only validates whether + the current context was able to identify any 'currentFile'. + """ label = "Validate File Saved" order = pyblish.api.ValidatorOrder - 0.1 From cc74f25e7a182363a82f319a97f4a24a61b80c02 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Wed, 14 Aug 2024 14:12:24 +0200 Subject: [PATCH 06/20] Provided unique file prefix Limits overwrites from multiple instances --- .../plugins/publish/extract_otio_review.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_otio_review.py b/client/ayon_core/plugins/publish/extract_otio_review.py index be365520c7..8c7719ceb6 100644 --- a/client/ayon_core/plugins/publish/extract_otio_review.py +++ b/client/ayon_core/plugins/publish/extract_otio_review.py @@ -49,7 +49,6 @@ class ExtractOTIOReview(publish.Extractor): hosts = ["resolve", "hiero", "flame"] # plugin default attributes - temp_file_head = "tempFile." to_width = 1280 to_height = 720 output_ext = ".jpg" @@ -62,6 +61,8 @@ class ExtractOTIOReview(publish.Extractor): make_sequence_collection ) + self.temp_file_head = self._get_unique_file_prefix(instance) + # TODO: convert resulting image sequence to mp4 # get otio clip and other time info from instance clip @@ -491,3 +492,19 @@ class ExtractOTIOReview(publish.Extractor): out_frame_start = self.used_frames[-1] return output_path, out_frame_start + + def _get_unique_file_prefix(self, instance): + """Creates unique human readable file prefix to differentiate. + + Multiple instances might share same temp folder, this will provide + unique prefix for intermediate file for burnins. + """ + folder_path = instance.data["folderPath"] + folder_name = folder_path.split("/")[-1] + folder_path = folder_path.replace("/", "_").lstrip("_") + + file_prefix = f"{folder_path}_{folder_name}." + self.log.debug(f"file_prefix::{file_prefix}") + + return file_prefix + From 3245a74534a38bd795721810dbc2b20eda05134f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 28 Aug 2024 20:53:12 +0200 Subject: [PATCH 07/20] Add `max` and `substancepainter` + sort the host names --- client/ayon_core/plugins/publish/validate_file_saved.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/validate_file_saved.py b/client/ayon_core/plugins/publish/validate_file_saved.py index e4f009615a..8f956f586b 100644 --- a/client/ayon_core/plugins/publish/validate_file_saved.py +++ b/client/ayon_core/plugins/publish/validate_file_saved.py @@ -36,7 +36,7 @@ class ValidateCurrentSaveFile(pyblish.api.ContextPlugin): label = "Validate File Saved" order = pyblish.api.ValidatorOrder - 0.1 - hosts = ["maya", "houdini", "nuke", "fusion"] + hosts = ["fusion", "houdini", "max", "maya", "nuke", "substancepainter"] actions = [SaveByVersionUpAction, ShowWorkfilesAction] def process(self, context): From f6477b98f1b25907d399a0966f90a4a7ce28ab09 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:24:08 +0200 Subject: [PATCH 08/20] added pycodestyle warnings to ruff validation --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f8f840d2c9..cb2991fe44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,7 @@ target-version = "py39" [tool.ruff.lint] # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. -select = ["E4", "E7", "E9", "F"] +select = ["E4", "E7", "E9", "F", "W"] ignore = [] # Allow fix for all enabled rules (when `--fix`) is provided. From a1b9d48c129321510ed29107a0dad4474879246b Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:24:25 +0200 Subject: [PATCH 09/20] remove not existing path from ignore paths --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cb2991fe44..35d0df0964 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,7 +84,6 @@ exclude = [ [tool.ruff.lint.per-file-ignores] "client/ayon_core/lib/__init__.py" = ["E402"] -"client/ayon_core/hosts/max/startup/startup.py" = ["E402"] [tool.ruff.format] # Like Black, use double quotes for strings. From 9fa4144feb1f7abfab068dd87619e2539406e04b Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:28:51 +0200 Subject: [PATCH 10/20] remove trailing spaces --- client/ayon_core/lib/path_templates.py | 2 +- .../plugins/publish/extract_usd_layer_contributions.py | 2 +- client/ayon_core/tools/tray/lib.py | 2 +- server/settings/publish_plugins.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/lib/path_templates.py b/client/ayon_core/lib/path_templates.py index ba0d26d5c1..dc88ec956b 100644 --- a/client/ayon_core/lib/path_templates.py +++ b/client/ayon_core/lib/path_templates.py @@ -503,7 +503,7 @@ class FormattingPart: # ensure key is properly formed [({})] properly closed. if not self.validate_key_is_matched(key): result.add_missing_key(key) - result.add_output(self.template) + result.add_output(self.template) return result # check if key expects subdictionary keys (e.g. project[name]) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 68f2a8f00d..03ea66f418 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -83,7 +83,7 @@ def get_representation_path_in_publish_context( Allow resolving 'latest' paths from a publishing context's instances as if they will exist after publishing without them being integrated yet. - + Use first instance that has same folder path and product name, and contains representation with passed name. diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index 5f92e8a04f..39fcc2cdd3 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -578,7 +578,7 @@ def make_sure_tray_is_running( args = get_ayon_launcher_args("tray", "--force") if env is None: env = os.environ.copy() - + # Make sure 'QT_API' is not set env.pop("QT_API", None) diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 8e6b60f0d7..61972e64c4 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -57,7 +57,7 @@ class CollectFramesFixDefModel(BaseSettingsModel): True, title="Show 'Rewrite latest version' toggle" ) - + class ContributionLayersModel(BaseSettingsModel): _layout = "compact" From 809cb34171ff0e0c5c1f4c7c7d88706fa4be2366 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:29:03 +0200 Subject: [PATCH 11/20] add new line characters --- client/ayon_core/hooks/pre_global_host_data.py | 2 +- client/ayon_core/plugins/publish/collect_context_entities.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hooks/pre_global_host_data.py b/client/ayon_core/hooks/pre_global_host_data.py index e93b512742..12da6f12f8 100644 --- a/client/ayon_core/hooks/pre_global_host_data.py +++ b/client/ayon_core/hooks/pre_global_host_data.py @@ -94,4 +94,4 @@ class GlobalHostDataHook(PreLaunchHook): task_entity = get_task_by_name( project_name, folder_entity["id"], task_name ) - self.data["task_entity"] = task_entity \ No newline at end of file + self.data["task_entity"] = task_entity diff --git a/client/ayon_core/plugins/publish/collect_context_entities.py b/client/ayon_core/plugins/publish/collect_context_entities.py index f340178e4f..c8d25bc3e6 100644 --- a/client/ayon_core/plugins/publish/collect_context_entities.py +++ b/client/ayon_core/plugins/publish/collect_context_entities.py @@ -113,4 +113,4 @@ class CollectContextEntities(pyblish.api.ContextPlugin): "Task '{}' was not found in project '{}'.".format( task_path, project_name) ) - return task_entity \ No newline at end of file + return task_entity From 7a1950f98e01b28c0ae05360714c7101fff285e0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:33:29 +0200 Subject: [PATCH 12/20] use correct escape sequence --- client/ayon_core/plugins/publish/extract_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index c2793f98a2..4390b00754 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -1900,7 +1900,7 @@ class OverscanCrop: string_value = re.sub(r"([ ]+)?px", " ", string_value) string_value = re.sub(r"([ ]+)%", "%", string_value) # Make sure +/- sign at the beginning of string is next to number - string_value = re.sub(r"^([\+\-])[ ]+", "\g<1>", string_value) + string_value = re.sub(r"^([\+\-])[ ]+", r"\g<1>", string_value) # Make sure +/- sign in the middle has zero spaces before number under # which belongs string_value = re.sub( From 614f2d4f6334186ee7d9673e61d9f4617534743f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 3 Sep 2024 22:18:16 +0200 Subject: [PATCH 13/20] Avoid double quotes around paths --- .../plugins/publish/collect_anatomy_instance_data.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py index 5b750a5232..925e14166e 100644 --- a/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py +++ b/client/ayon_core/plugins/publish/collect_anatomy_instance_data.py @@ -217,9 +217,8 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): joined_paths = ", ".join( ["\"{}\"".format(path) for path in not_found_task_paths] ) - self.log.warning(( - "Not found task entities with paths \"{}\"." - ).format(joined_paths)) + self.log.warning( + f"Not found task entities with paths {joined_paths}.") def fill_latest_versions(self, context, project_name): """Try to find latest version for each instance's product name. From 73e125639bbeab03649022322d1165b54084937a Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 4 Sep 2024 10:29:56 +0200 Subject: [PATCH 14/20] remove trailing spaces --- client/ayon_core/plugins/publish/validate_file_saved.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/validate_file_saved.py b/client/ayon_core/plugins/publish/validate_file_saved.py index 8f956f586b..d132ba8d3a 100644 --- a/client/ayon_core/plugins/publish/validate_file_saved.py +++ b/client/ayon_core/plugins/publish/validate_file_saved.py @@ -51,9 +51,9 @@ class ValidateCurrentSaveFile(pyblish.api.ContextPlugin): def get_description(self): return inspect.cleandoc(""" ### File not saved - + Your workfile must be saved to continue publishing. - - The **Save Workfile** action will save it for you with the first + + The **Save Workfile** action will save it for you with the first available workfile version number in your current context. """) From 916c9a625783522366778ce170bf882ec832a137 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 5 Sep 2024 12:48:32 +0200 Subject: [PATCH 15/20] Added todo note to get rid of instance variable --- .../plugins/publish/extract_otio_review.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_otio_review.py b/client/ayon_core/plugins/publish/extract_otio_review.py index 8c7719ceb6..c1cf50333c 100644 --- a/client/ayon_core/plugins/publish/extract_otio_review.py +++ b/client/ayon_core/plugins/publish/extract_otio_review.py @@ -61,7 +61,8 @@ class ExtractOTIOReview(publish.Extractor): make_sequence_collection ) - self.temp_file_head = self._get_unique_file_prefix(instance) + # TODO refactore from using instance variable + self.temp_file_head = self._get_folder_name_based_prefix(instance) # TODO: convert resulting image sequence to mp4 @@ -493,11 +494,13 @@ class ExtractOTIOReview(publish.Extractor): return output_path, out_frame_start - def _get_unique_file_prefix(self, instance): - """Creates unique human readable file prefix to differentiate. + def _get_folder_name_based_prefix(self, instance): + """Creates 'unique' human readable file prefix to differentiate. - Multiple instances might share same temp folder, this will provide - unique prefix for intermediate file for burnins. + Multiple instances might share same temp folder, but each instance + would be differentiated by asset, eg. folder name. + + It ix expected that there won't be multiple instances for same asset. """ folder_path = instance.data["folderPath"] folder_name = folder_path.split("/")[-1] From b636658f43d89cb093948363486f1ea5d70f75ea Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 5 Sep 2024 20:57:20 +0200 Subject: [PATCH 16/20] Allow placeholder representation name to be set as an empty value to load all representations --- .../pipeline/workfile/workfile_template_builder.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 7b15dff049..be5b7437de 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -1519,9 +1519,10 @@ class PlaceholderLoadMixin(object): if "asset" in placeholder.data: return [] - representation_name = placeholder.data["representation"] - if not representation_name: - return [] + representation_names = None + representation_name: str = placeholder.data["representation"] + if representation_name: + representation_names = [representation_name] project_name = self.builder.project_name current_folder_entity = self.builder.current_folder_entity @@ -1578,7 +1579,7 @@ class PlaceholderLoadMixin(object): ) return list(get_representations( project_name, - representation_names={representation_name}, + representation_names=representation_names, version_ids=version_ids )) From 2e039af0151c9ee8920c51a6d3dba1ff8b383122 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 6 Sep 2024 10:30:51 +0200 Subject: [PATCH 17/20] Fix if statement --- client/ayon_core/vendor/python/scriptsmenu/launchformaya.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/vendor/python/scriptsmenu/launchformaya.py b/client/ayon_core/vendor/python/scriptsmenu/launchformaya.py index c8b0c777de..496278ac6f 100644 --- a/client/ayon_core/vendor/python/scriptsmenu/launchformaya.py +++ b/client/ayon_core/vendor/python/scriptsmenu/launchformaya.py @@ -130,7 +130,7 @@ def main(title="Scripts", parent=None, objectName=None): # Register control + shift callback to add to shelf (maya behavior) modifiers = QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier - if int(cmds.about(version=True)) <= 2025: + if int(cmds.about(version=True)) < 2025: modifiers = int(modifiers) menu.register_callback(modifiers, to_shelf) From f0af0a5700c8f18113099381d37ccfe73e222689 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 6 Sep 2024 17:17:45 +0200 Subject: [PATCH 18/20] Allow custom `resolve_template_path` to be implemented by AYON addon integrations --- .../workfile/workfile_template_builder.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index be5b7437de..b65355fe8b 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -876,6 +876,8 @@ class AbstractTemplateBuilder(ABC): if result.solved: path = result.normalized() + path = self.resolve_template_path(path) + if path and os.path.exists(path): self.log.info("Found template at: '{}'".format(path)) return { @@ -914,6 +916,23 @@ class AbstractTemplateBuilder(ABC): "create_first_version": create_first_version } + def resolve_template_path(self, path: str) -> str: + """Resolve the template path. + + By default, this does nothing except returning the path directly. + But, this allows additional resolving over the template path inside + a custom AYON integration. Like, in Houdini using + `hou.text.expandString` + + Arguments: + path (str): The input path. + + Returns: + str: The resolved path. + + """ + return path + def emit_event(self, topic, data=None, source=None) -> Event: return self._event_system.emit(topic, data, source) From a8a69766ad00ea56b51f5e0c8dd3bdffebc1c67d Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 9 Sep 2024 16:22:29 +0200 Subject: [PATCH 19/20] Move more logic into the `resolve_template_path` method --- .../workfile/workfile_template_builder.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index b65355fe8b..51dcb48420 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -872,11 +872,7 @@ class AbstractTemplateBuilder(ABC): "code": anatomy.project_code, } - result = StringTemplate.format_template(path, fill_data) - if result.solved: - path = result.normalized() - - path = self.resolve_template_path(path) + path = self.resolve_template_path(path, fill_data) if path and os.path.exists(path): self.log.info("Found template at: '{}'".format(path)) @@ -916,21 +912,25 @@ class AbstractTemplateBuilder(ABC): "create_first_version": create_first_version } - def resolve_template_path(self, path: str) -> str: + def resolve_template_path(self, path, fill_data) -> str: """Resolve the template path. By default, this does nothing except returning the path directly. - But, this allows additional resolving over the template path inside - a custom AYON integration. Like, in Houdini using - `hou.text.expandString` + + This can be overridden in host integrations to perform additional + resolving over the template. Like, `hou.text.expandString` in Houdini. Arguments: path (str): The input path. + fill_data (dict[str, str]): Data to use for template formatting. Returns: str: The resolved path. """ + result = StringTemplate.format_template(path, fill_data) + if result.solved: + path = result.normalized() return path def emit_event(self, topic, data=None, source=None) -> Event: From 0f0b7db2e1f01c57911baa323bedfb77b4922474 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 9 Sep 2024 16:22:37 +0200 Subject: [PATCH 20/20] Fix grammar in comment --- client/ayon_core/pipeline/workfile/workfile_template_builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 51dcb48420..c38725ffba 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -859,7 +859,7 @@ class AbstractTemplateBuilder(ABC): "Settings\\Profiles" ).format(host_name.title())) - # Try fill path with environments and anatomy roots + # Try to fill path with environments and anatomy roots anatomy = Anatomy(project_name) fill_data = { key: value