Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General: Comment per instance in Publisher #4178

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion openpype/hosts/nuke/plugins/publish/extract_slate_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
20 changes: 18 additions & 2 deletions openpype/pipeline/publish/publish_plugins.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import inspect
from abc import ABCMeta

import pyblish.api
Expand Down Expand Up @@ -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.
Expand Down
126 changes: 115 additions & 11 deletions openpype/plugins/publish/collect_comment.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,123 @@
"""
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
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 = 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"]

class CollectComment(pyblish.api.ContextPlugin):
"""This plug-ins displays the comment dialog box per default"""
@classmethod
def get_attribute_defs(cls):
return [
TextDef("comment", label="Comment")
]

label = "Collect Comment"
order = pyblish.api.CollectorOrder

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
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 ""
2 changes: 1 addition & 1 deletion openpype/plugins/publish/extract_burnin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
Expand Down
2 changes: 1 addition & 1 deletion openpype/plugins/publish/integrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
}
Expand Down
2 changes: 1 addition & 1 deletion openpype/plugins/publish/integrate_legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
4 changes: 4 additions & 0 deletions openpype/settings/defaults/project_settings/global.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
],
"skip_hosts_headless_publish": []
},
"collect_comment_per_instance": {
"enabled": false,
"families": []
},
"ValidateEditorialAssetName": {
"enabled": true,
"optional": false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down