From 5684c941deb0f2f62cf71f69667f786217ded612 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 28 Jan 2025 11:51:17 +0100 Subject: [PATCH 1/9] 'CreatedInstance' allows to pass in transient data --- .../ayon_core/pipeline/create/structures.py | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/pipeline/create/structures.py b/client/ayon_core/pipeline/create/structures.py index a45e053cca..17bb85b720 100644 --- a/client/ayon_core/pipeline/create/structures.py +++ b/client/ayon_core/pipeline/create/structures.py @@ -1,6 +1,7 @@ import copy import collections from uuid import uuid4 +import typing from typing import Optional, Dict, List, Any from ayon_core.lib.attribute_definitions import ( @@ -17,6 +18,9 @@ from ayon_core.pipeline import ( from .exceptions import ImmutableKeyError from .changes import TrackChangesItem +if typing.TYPE_CHECKING: + from .creator_plugins import BaseCreator + class ConvertorItem: """Item representing convertor plugin. @@ -444,10 +448,11 @@ class CreatedInstance: def __init__( self, - product_type, - product_name, - data, - creator, + product_type: str, + product_name: str, + data: Dict[str, Any], + creator: "BaseCreator", + transient_data: Optional[Dict[str, Any]] = None, ): self._creator = creator creator_identifier = creator.identifier @@ -462,7 +467,9 @@ class CreatedInstance: self._members = [] # Data that can be used for lifetime of object - self._transient_data = {} + if transient_data is None: + transient_data = {} + self._transient_data = transient_data # Create a copy of passed data to avoid changing them on the fly data = copy.deepcopy(data or {}) @@ -787,16 +794,26 @@ class CreatedInstance: self._create_context.instance_create_attr_defs_changed(self.id) @classmethod - def from_existing(cls, instance_data, creator): + def from_existing( + cls, + instance_data: Dict[str, Any], + creator: "BaseCreator", + transient_data: Optional[Dict[str, Any]] = None, + ) -> "CreatedInstance": """Convert instance data from workfile to CreatedInstance. Args: instance_data (Dict[str, Any]): Data in a structure ready for 'CreatedInstance' object. creator (BaseCreator): Creator plugin which is creating the - instance of for which the instance belong. - """ + instance of for which the instance belongs. + transient_data (Optional[dict[str, Any]]): Instance transient + data. + Returns: + CreatedInstance: Instance object. + + """ instance_data = copy.deepcopy(instance_data) product_type = instance_data.get("productType") @@ -809,7 +826,11 @@ class CreatedInstance: product_name = instance_data.get("subset") return cls( - product_type, product_name, instance_data, creator + product_type, + product_name, + instance_data, + creator, + transient_data=transient_data, ) def attribute_value_changed(self, key, changes): From d25c4701d1ec09f1aa81b9a80b356e79e3215456 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Wed, 29 Jan 2025 12:04:38 +0100 Subject: [PATCH 2/9] Fix Version follow up from Workfile set by hosts. --- .../ayon_core/pipeline/create/creator_plugins.py | 15 +++++++++++++-- .../plugins/publish/collect_scene_version.py | 7 +++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/pipeline/create/creator_plugins.py b/client/ayon_core/pipeline/create/creator_plugins.py index 445b41cb4b..f29d67f263 100644 --- a/client/ayon_core/pipeline/create/creator_plugins.py +++ b/client/ayon_core/pipeline/create/creator_plugins.py @@ -858,13 +858,24 @@ class Creator(BaseCreator): ["CollectAnatomyInstanceData"] ["follow_workfile_version"] ) + follow_version_hosts = ( + publish_settings + ["CollectSceneVersion"] + ["hosts"] + ) + + current_host = create_ctx.host.name + follow_workfile_version = ( + follow_workfile_version and + current_host in follow_version_hosts + ) # Gather version number provided from the instance. + current_workfile = create_ctx.get_current_workfile_path() version = instance.get("version") # If follow workfile, gather version from workfile path. - if version is None and follow_workfile_version: - current_workfile = self.create_context.get_current_workfile_path() + if version is None and follow_workfile_version and current_workfile: workfile_version = get_version_from_path(current_workfile) version = int(workfile_version) diff --git a/client/ayon_core/plugins/publish/collect_scene_version.py b/client/ayon_core/plugins/publish/collect_scene_version.py index 8d643062bc..8758bc2181 100644 --- a/client/ayon_core/plugins/publish/collect_scene_version.py +++ b/client/ayon_core/plugins/publish/collect_scene_version.py @@ -46,6 +46,13 @@ class CollectSceneVersion(pyblish.api.ContextPlugin): self.log.debug("Skipping for headless publishing") return + if context.data["hostName"] not in self.hosts: + self.log.debug( + f"Host {context.data['hostName']} is" + " not setup for following version." + ) + return + if not context.data.get('currentFile'): self.log.error("Cannot get current workfile path. " "Make sure your scene is saved.") From 3731e1226a840996f68dd61579f8bb0a5ba38063 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Wed, 29 Jan 2025 12:36:00 +0100 Subject: [PATCH 3/9] Fix lint + log message. --- client/ayon_core/pipeline/create/creator_plugins.py | 2 +- client/ayon_core/plugins/publish/collect_scene_version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/pipeline/create/creator_plugins.py b/client/ayon_core/pipeline/create/creator_plugins.py index f29d67f263..a7f191bc44 100644 --- a/client/ayon_core/pipeline/create/creator_plugins.py +++ b/client/ayon_core/pipeline/create/creator_plugins.py @@ -866,7 +866,7 @@ class Creator(BaseCreator): current_host = create_ctx.host.name follow_workfile_version = ( - follow_workfile_version and + follow_workfile_version and current_host in follow_version_hosts ) diff --git a/client/ayon_core/plugins/publish/collect_scene_version.py b/client/ayon_core/plugins/publish/collect_scene_version.py index 8758bc2181..fcd57f4110 100644 --- a/client/ayon_core/plugins/publish/collect_scene_version.py +++ b/client/ayon_core/plugins/publish/collect_scene_version.py @@ -49,7 +49,7 @@ class CollectSceneVersion(pyblish.api.ContextPlugin): if context.data["hostName"] not in self.hosts: self.log.debug( f"Host {context.data['hostName']} is" - " not setup for following version." + " not setup for collecting scene version." ) return From 1b109d761feb890a732b0995ead852c0a54db0e5 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Wed, 29 Jan 2025 14:03:23 +0100 Subject: [PATCH 4/9] Fix host refresh in publish/lib.py --- client/ayon_core/pipeline/publish/lib.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index 25495ed38b..62a68bc841 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -460,8 +460,19 @@ def filter_pyblish_plugins(plugins): ) apply_plugin_settings_automatically(plugin, plugin_settins, log) + # Pyblish already operated a filter based on host. + # But applying settings might have changed "hosts" + # value in plugin so re-filter. + plugin_hosts = getattr(plugin, "hosts", None) + if ( + plugin_hosts + and "*" not in plugin_hosts + and host_name not in plugin_hosts + ): + plugins.remove(plugin) + # Remove disabled plugins - if getattr(plugin, "enabled", True) is False: + elif getattr(plugin, "enabled", True) is False: plugins.remove(plugin) From fd63c97f4e9baf75027895c9460b548ed453ed8a Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Wed, 29 Jan 2025 19:56:34 +0100 Subject: [PATCH 5/9] Address feedback from PR. --- client/ayon_core/pipeline/publish/lib.py | 7 +----- .../plugins/publish/collect_scene_version.py | 25 +------------------ 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index 62a68bc841..9adfc5e9e2 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -463,12 +463,7 @@ def filter_pyblish_plugins(plugins): # Pyblish already operated a filter based on host. # But applying settings might have changed "hosts" # value in plugin so re-filter. - plugin_hosts = getattr(plugin, "hosts", None) - if ( - plugin_hosts - and "*" not in plugin_hosts - and host_name not in plugin_hosts - ): + if not pyblish.plugin.host_is_compatible(plugin): plugins.remove(plugin) # Remove disabled plugins diff --git a/client/ayon_core/plugins/publish/collect_scene_version.py b/client/ayon_core/plugins/publish/collect_scene_version.py index fcd57f4110..7979b66abe 100644 --- a/client/ayon_core/plugins/publish/collect_scene_version.py +++ b/client/ayon_core/plugins/publish/collect_scene_version.py @@ -14,23 +14,7 @@ class CollectSceneVersion(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder label = 'Collect Scene Version' # configurable in Settings - hosts = [ - "aftereffects", - "blender", - "celaction", - "fusion", - "harmony", - "hiero", - "houdini", - "maya", - "max", - "nuke", - "photoshop", - "resolve", - "tvpaint", - "motionbuilder", - "substancepainter" - ] + hosts = ["*"] # in some cases of headless publishing (for example webpublisher using PS) # you want to ignore version from name and let integrate use next version @@ -46,13 +30,6 @@ class CollectSceneVersion(pyblish.api.ContextPlugin): self.log.debug("Skipping for headless publishing") return - if context.data["hostName"] not in self.hosts: - self.log.debug( - f"Host {context.data['hostName']} is" - " not setup for collecting scene version." - ) - return - if not context.data.get('currentFile'): self.log.error("Cannot get current workfile path. " "Make sure your scene is saved.") From ca03c4d86d2c08b347f4363030ec32b0a96b7721 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 30 Jan 2025 12:05:39 +0100 Subject: [PATCH 6/9] Add support for `optional_tooltip` attribute on `OptionalPyblishPluginMixin` --- client/ayon_core/pipeline/publish/publish_plugins.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/publish/publish_plugins.py b/client/ayon_core/pipeline/publish/publish_plugins.py index 57215eff68..94c0307ca0 100644 --- a/client/ayon_core/pipeline/publish/publish_plugins.py +++ b/client/ayon_core/pipeline/publish/publish_plugins.py @@ -304,8 +304,11 @@ class OptionalPyblishPluginMixin(AYONPyblishPluginMixin): active = getattr(cls, "active", True) # Return boolean stored under 'active' key with label of the class name label = cls.label or cls.__name__ + # Allow exposing tooltip from class with `optional_tooltip` attribute + tooltip = getattr(cls, "optional_tooltip", None) + return [ - BoolDef("active", default=active, label=label) + BoolDef("active", default=active, label=label, tooltip=tooltip) ] def is_active(self, data): From 64b6729eec537862bf05a515837936c5dff6b9a5 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 30 Jan 2025 12:40:53 +0100 Subject: [PATCH 7/9] Expose `optional_tooltip` directly as attribute on the `OptionalPyblishPluginMixin` for better auto-complete in IDEs --- client/ayon_core/pipeline/publish/publish_plugins.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/pipeline/publish/publish_plugins.py b/client/ayon_core/pipeline/publish/publish_plugins.py index 94c0307ca0..65a5a474ea 100644 --- a/client/ayon_core/pipeline/publish/publish_plugins.py +++ b/client/ayon_core/pipeline/publish/publish_plugins.py @@ -292,6 +292,9 @@ class OptionalPyblishPluginMixin(AYONPyblishPluginMixin): ``` """ + # Allow exposing tooltip from class with `optional_tooltip` attribute + optional_tooltip: Optional[str] = None + @classmethod def get_attribute_defs(cls): """Attribute definitions based on plugin's optional attribute.""" @@ -304,11 +307,12 @@ class OptionalPyblishPluginMixin(AYONPyblishPluginMixin): active = getattr(cls, "active", True) # Return boolean stored under 'active' key with label of the class name label = cls.label or cls.__name__ - # Allow exposing tooltip from class with `optional_tooltip` attribute - tooltip = getattr(cls, "optional_tooltip", None) return [ - BoolDef("active", default=active, label=label, tooltip=tooltip) + BoolDef("active", + default=active, + label=label, + tooltip=cls.optional_tooltip) ] def is_active(self, data): From e1438ed597550ee5b55e46efab3354838a42088a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 31 Jan 2025 23:30:04 +0100 Subject: [PATCH 8/9] Update client/ayon_core/pipeline/publish/publish_plugins.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/pipeline/publish/publish_plugins.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/pipeline/publish/publish_plugins.py b/client/ayon_core/pipeline/publish/publish_plugins.py index 65a5a474ea..cc6887e762 100644 --- a/client/ayon_core/pipeline/publish/publish_plugins.py +++ b/client/ayon_core/pipeline/publish/publish_plugins.py @@ -309,10 +309,12 @@ class OptionalPyblishPluginMixin(AYONPyblishPluginMixin): label = cls.label or cls.__name__ return [ - BoolDef("active", - default=active, - label=label, - tooltip=cls.optional_tooltip) + BoolDef( + "active", + default=active, + label=label, + tooltip=cls.optional_tooltip, + ) ] def is_active(self, data): From 5c53d201244b1bf5d5914a23c936472b594fb6d9 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Mon, 3 Feb 2025 10:51:59 +0100 Subject: [PATCH 9/9] Address feedback from PR. --- client/ayon_core/pipeline/create/creator_plugins.py | 5 +++-- client/ayon_core/pipeline/publish/lib.py | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/pipeline/create/creator_plugins.py b/client/ayon_core/pipeline/create/creator_plugins.py index a7f191bc44..69cd3894af 100644 --- a/client/ayon_core/pipeline/create/creator_plugins.py +++ b/client/ayon_core/pipeline/create/creator_plugins.py @@ -877,10 +877,11 @@ class Creator(BaseCreator): # If follow workfile, gather version from workfile path. if version is None and follow_workfile_version and current_workfile: workfile_version = get_version_from_path(current_workfile) - version = int(workfile_version) + if workfile_version is not None: + version = int(workfile_version) # Fill-up version with next version available. - elif version is None: + if version is None: versions = self.get_next_versions_for_instances( [instance] ) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index 9adfc5e9e2..cc5f67c74b 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -460,14 +460,14 @@ def filter_pyblish_plugins(plugins): ) apply_plugin_settings_automatically(plugin, plugin_settins, log) + # Remove disabled plugins + if getattr(plugin, "enabled", True) is False: + plugins.remove(plugin) + # Pyblish already operated a filter based on host. # But applying settings might have changed "hosts" # value in plugin so re-filter. - if not pyblish.plugin.host_is_compatible(plugin): - plugins.remove(plugin) - - # Remove disabled plugins - elif getattr(plugin, "enabled", True) is False: + elif not pyblish.plugin.host_is_compatible(plugin): plugins.remove(plugin)