From 0151540fdd91f92c51b78a21a529c2ae913b69a9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 5 Dec 2022 19:24:56 +0100 Subject: [PATCH 1/7] added collector which can add comment per instance --- openpype/plugins/publish/collect_comment.py | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/openpype/plugins/publish/collect_comment.py b/openpype/plugins/publish/collect_comment.py index 062142ace9c..a2aef7fc1c0 100644 --- a/openpype/plugins/publish/collect_comment.py +++ b/openpype/plugins/publish/collect_comment.py @@ -6,6 +6,28 @@ """ import pyblish.api +from openpype.lib.attribute_definitions import TextDef +from openpype.pipeline.publish import OpenPypePyblishPluginMixin + + +class CollectInstanceCommentDef( + pyblish.api.ContextPlugin, + OpenPypePyblishPluginMixin +): + label = "Comment per instance" + targets = ["local"] + # Disable plugin by default + families = ["*"] + enabled = True + + def process(self, instance): + pass + + @classmethod + def get_attribute_defs(cls): + return [ + TextDef("comment", label="Comment") + ] class CollectComment(pyblish.api.ContextPlugin): From f7f5019401adf912cfba48d9d939af7492c9e3a6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 5 Dec 2022 19:25:14 +0100 Subject: [PATCH 2/7] CollectComment plugin also store comment on each instance --- openpype/plugins/publish/collect_comment.py | 86 ++++++++++++++++++--- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/openpype/plugins/publish/collect_comment.py b/openpype/plugins/publish/collect_comment.py index a2aef7fc1c0..a1b4e1364a4 100644 --- a/openpype/plugins/publish/collect_comment.py +++ b/openpype/plugins/publish/collect_comment.py @@ -1,8 +1,26 @@ -""" -Requires: - None -Provides: - context -> comment (str) +"""Collect comment and add option to enter comment per instance. + +Combination of plugins. One define optional input for instances in Publisher +UI (CollectInstanceCommentDef) and second cares that each instance during +collection has available "comment" key in data (CollectComment). + +Plugin 'CollectInstanceCommentDef' define "comment" attribute which won't be +filled with any value if instance does not match families filter or when +plugin is disabled. + +Plugin 'CollectComment' makes sure that each instance in context has +available "comment" key in data which can be set to 'str' or 'None' if is not +set. +- In case instance already has filled comment the plugin's logic is skipped +- The comment is always set and value should be always 'str' even if is empty + +Why are separated: +- 'CollectInstanceCommentDef' can have specific settings to show comment + attribute only to defined families in publisher UI +- 'CollectComment' will run all the time + +Todos: + The comment per instance is not sent via farm. """ import pyblish.api @@ -31,11 +49,59 @@ def get_attribute_defs(cls): class CollectComment(pyblish.api.ContextPlugin): - """This plug-ins displays the comment dialog box per default""" + """Collect comment per each instance. - label = "Collect Comment" - order = pyblish.api.CollectorOrder + Plugin makes sure each instance to publish has set "comment" in data so any + further plugin can use it directly. + """ + + label = "Collect Instance Comment" + order = pyblish.api.CollectorOrder + 0.49 def process(self, context): - comment = (context.data.get("comment") or "").strip() - context.data["comment"] = comment + context_comment = self.cleanup_comment(context.data.get("comment")) + # Set it back + context.data["comment"] = context_comment + for instance in context: + instance_label = str(instance) + # Check if comment is already set + instance_comment = self.cleanup_comment( + instance.data.get("comment")) + + # If comment on instance is not set then look for attributes + if not instance_comment: + attr_values = self.get_attr_values_from_data_for_plugin( + CollectInstanceCommentDef, instance.data + ) + instance_comment = self.cleanup_comment( + attr_values.get("comment") + ) + + # Use context comment if instance has all options of comment + # empty + if not instance_comment: + instance_comment = context_comment + + instance.data["comment"] = instance_comment + if instance_comment: + msg_end = " has comment set to: \"{}\"".format( + instance_comment) + else: + msg_end = " does not have set comment" + self.log.debug("Instance {} {}".format(instance_label, msg_end)) + + def cleanup_comment(self, comment): + """Cleanup comment value. + + Args: + comment (Union[str, None]): Comment value from data. + + Returns: + str: Cleaned comment which is stripped or empty string if input + was 'None'. + """ + + if comment: + return comment.strip() + return "" + From fd5ac3be1bc975d9e3329c835d583d269ec7c575 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 5 Dec 2022 19:29:01 +0100 Subject: [PATCH 3/7] added settings for the attribute collector --- openpype/plugins/publish/collect_comment.py | 18 ++++++++++++++-- .../defaults/project_settings/global.json | 4 ++++ .../schemas/schema_global_publish.json | 21 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/collect_comment.py b/openpype/plugins/publish/collect_comment.py index a1b4e1364a4..db5a04681bc 100644 --- a/openpype/plugins/publish/collect_comment.py +++ b/openpype/plugins/publish/collect_comment.py @@ -35,12 +35,26 @@ class CollectInstanceCommentDef( label = "Comment per instance" targets = ["local"] # Disable plugin by default - families = ["*"] - enabled = True + families = [] + enabled = False def process(self, instance): pass + @classmethod + def apply_settings(cls, project_setting, _): + plugin_settings = project_setting["global"]["publish"].get( + "collect_comment_per_instance" + ) + if not plugin_settings: + return + + if plugin_settings.get("enabled") is not None: + cls.enabled = plugin_settings["enabled"] + + if plugin_settings.get("families") is not None: + cls.families = plugin_settings["families"] + @classmethod def get_attribute_defs(cls): return [ diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 46b8b1b0c80..89d7cf08b74 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -24,6 +24,10 @@ ], "skip_hosts_headless_publish": [] }, + "collect_comment_per_instance": { + "enabled": false, + "families": [] + }, "ValidateEditorialAssetName": { "enabled": true, "optional": false diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 742437fbded..f2ada5fd8dd 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -60,6 +60,27 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "key": "collect_comment_per_instance", + "label": "Collect comment per instance", + "checkbox_key": "enabled", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "families", + "label": "Families", + "type": "list", + "object_type": "text" + } + ] + }, { "type": "dict", "collapsible": true, From 1f05a3952262a342a72e8308643c6d1a7a0ffdba Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 5 Dec 2022 19:31:09 +0100 Subject: [PATCH 4/7] use comment from instance where possible --- openpype/hosts/nuke/plugins/publish/extract_slate_frame.py | 2 +- .../deadline/plugins/publish/submit_celaction_deadline.py | 2 +- openpype/modules/deadline/plugins/publish/submit_publish_job.py | 1 + .../ftrack/plugins/publish/integrate_ftrack_description.py | 2 +- .../modules/ftrack/plugins/publish/integrate_ftrack_note.py | 2 +- openpype/plugins/publish/extract_burnin.py | 2 +- openpype/plugins/publish/integrate.py | 2 +- openpype/plugins/publish/integrate_legacy.py | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py b/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py index e7197b4fa81..06c086b10dd 100644 --- a/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py +++ b/openpype/hosts/nuke/plugins/publish/extract_slate_frame.py @@ -298,7 +298,7 @@ def _render_slate_to_sequence(self, instance): def add_comment_slate_node(self, instance, node): - comment = instance.context.data.get("comment") + comment = instance.data["comment"] intent = instance.context.data.get("intent") if not isinstance(intent, dict): intent = { diff --git a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py index ea44a244593..038ee4fc034 100644 --- a/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_celaction_deadline.py @@ -38,7 +38,7 @@ def process(self, instance): assert deadline_url, "Requires Deadline Webservice URL" self.deadline_url = "{}/api/jobs".format(deadline_url) - self._comment = context.data.get("comment", "") + self._comment = instance.data["comment"] self._deadline_user = context.data.get( "deadlineUser", getpass.getuser()) self._frame_start = int(instance.data["frameStart"]) diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 249211e9656..45688e85849 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -777,6 +777,7 @@ def process(self, instance): "handleEnd": handle_end, "frameStartHandle": start - handle_start, "frameEndHandle": end + handle_end, + "comment": instance.data["comment"], "fps": fps, "source": source, "extendFrames": data.get("extendFrames"), diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_description.py b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_description.py index e7c265988ee..6ed02bc8b65 100644 --- a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_description.py +++ b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_description.py @@ -38,7 +38,7 @@ def process(self, instance): self.log.info("There are any integrated AssetVersions") return - comment = (instance.context.data.get("comment") or "").strip() + comment = instance.data["comment"] if not comment: self.log.info("Comment is not set.") else: diff --git a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_note.py b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_note.py index ac3fa874e00..6776509ddae 100644 --- a/openpype/modules/ftrack/plugins/publish/integrate_ftrack_note.py +++ b/openpype/modules/ftrack/plugins/publish/integrate_ftrack_note.py @@ -45,7 +45,7 @@ def process(self, instance): host_name = context.data["hostName"] app_name = context.data["appName"] app_label = context.data["appLabel"] - comment = (context.data.get("comment") or "").strip() + comment = instance.data["comment"] if not comment: self.log.info("Comment is not set.") else: diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index 4179199317e..fd8dfdece97 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -468,7 +468,7 @@ def prepare_basic_data(self, instance): burnin_data.update({ "version": int(version), - "comment": context.data.get("comment") or "" + "comment": instance.data["comment"] }) intent_label = context.data.get("intent") or "" diff --git a/openpype/plugins/publish/integrate.py b/openpype/plugins/publish/integrate.py index 7e4fc846580..57a642c6351 100644 --- a/openpype/plugins/publish/integrate.py +++ b/openpype/plugins/publish/integrate.py @@ -772,7 +772,7 @@ def create_version_data(self, instance): "time": context.data["time"], "author": context.data["user"], "source": source, - "comment": context.data.get("comment"), + "comment": instance.data["comment"], "machine": context.data.get("machine"), "fps": instance.data.get("fps", context.data.get("fps")) } diff --git a/openpype/plugins/publish/integrate_legacy.py b/openpype/plugins/publish/integrate_legacy.py index 536ab83f2c1..670b637faa5 100644 --- a/openpype/plugins/publish/integrate_legacy.py +++ b/openpype/plugins/publish/integrate_legacy.py @@ -968,7 +968,7 @@ def create_version_data(self, context, instance): "time": context.data["time"], "author": context.data["user"], "source": source, - "comment": context.data.get("comment"), + "comment": instance.data["comment"], "machine": context.data.get("machine"), "fps": context.data.get( "fps", instance.data.get("fps") From 5d24bfcf6318fa4fec1267612c933989fa2beb22 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 5 Dec 2022 19:31:31 +0100 Subject: [PATCH 5/7] commit forgotten change of getting attribute values from plugin --- openpype/pipeline/publish/publish_plugins.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/openpype/pipeline/publish/publish_plugins.py b/openpype/pipeline/publish/publish_plugins.py index 6e2be1ce2c3..47dfaf6b981 100644 --- a/openpype/pipeline/publish/publish_plugins.py +++ b/openpype/pipeline/publish/publish_plugins.py @@ -1,3 +1,4 @@ +import inspect from abc import ABCMeta import pyblish.api @@ -132,19 +133,34 @@ def convert_attribute_values(cls, attribute_values): ) return attribute_values - def get_attr_values_from_data(self, data): + @staticmethod + def get_attr_values_from_data_for_plugin(plugin, data): """Get attribute values for attribute definitions from data. Args: + plugin (Union[publish.api.Plugin, Type[publish.api.Plugin]]): The + plugin for which attributes are extracted. data(dict): Data from instance or context. """ + if not inspect.isclass(plugin): + plugin = plugin.__class__ + return ( data .get("publish_attributes", {}) - .get(self.__class__.__name__, {}) + .get(plugin.__name__, {}) ) + def get_attr_values_from_data(self, data): + """Get attribute values for attribute definitions from data. + + Args: + data(dict): Data from instance or context. + """ + + return self.get_attr_values_from_data_for_plugin(self.__class__, data) + class OptionalPyblishPluginMixin(OpenPypePyblishPluginMixin): """Prepare mixin for optional plugins. From e6585be6772006ca748c8fbf5697f981bcd0de12 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 5 Dec 2022 19:35:03 +0100 Subject: [PATCH 6/7] fix missing method --- openpype/plugins/publish/collect_comment.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/collect_comment.py b/openpype/plugins/publish/collect_comment.py index db5a04681bc..83609a04bd7 100644 --- a/openpype/plugins/publish/collect_comment.py +++ b/openpype/plugins/publish/collect_comment.py @@ -62,7 +62,10 @@ def get_attribute_defs(cls): ] -class CollectComment(pyblish.api.ContextPlugin): +class CollectComment( + pyblish.api.ContextPlugin, + OpenPypePyblishPluginMixin +): """Collect comment per each instance. Plugin makes sure each instance to publish has set "comment" in data so any From 6e520f564bfe58aa23c1430d175d30dccd95eb40 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 6 Dec 2022 09:52:36 +0100 Subject: [PATCH 7/7] removed redundant line --- openpype/plugins/publish/collect_comment.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/plugins/publish/collect_comment.py b/openpype/plugins/publish/collect_comment.py index 83609a04bd7..12579cd9572 100644 --- a/openpype/plugins/publish/collect_comment.py +++ b/openpype/plugins/publish/collect_comment.py @@ -121,4 +121,3 @@ def cleanup_comment(self, comment): if comment: return comment.strip() return "" -