mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge 94a8ddbd0f into 92d4da9efa
This commit is contained in:
commit
24b84dcef3
2 changed files with 149 additions and 36 deletions
|
|
@ -1,7 +1,13 @@
|
|||
import pyblish.api
|
||||
from ayon_core.lib import BoolDef
|
||||
import ayon_api
|
||||
from ayon_core.pipeline import publish
|
||||
|
||||
|
||||
class CollectHierarchy(pyblish.api.ContextPlugin):
|
||||
class CollectHierarchy(
|
||||
pyblish.api.ContextPlugin,
|
||||
publish.AYONPyblishPluginMixin,
|
||||
):
|
||||
"""Collecting hierarchy from `parents`.
|
||||
|
||||
present in `clip` family instances coming from the request json data file
|
||||
|
|
@ -13,20 +19,40 @@ class CollectHierarchy(pyblish.api.ContextPlugin):
|
|||
|
||||
label = "Collect Hierarchy"
|
||||
order = pyblish.api.CollectorOrder - 0.076
|
||||
hosts = ["resolve", "hiero", "flame", "traypublisher"]
|
||||
settings_category = "core"
|
||||
|
||||
def process(self, context):
|
||||
project_name = context.data["projectName"]
|
||||
final_context = {
|
||||
project_name: {
|
||||
"entity_type": "project",
|
||||
"children": {}
|
||||
},
|
||||
}
|
||||
temp_context = {}
|
||||
ignore_shot_attributes_on_update = False
|
||||
|
||||
@classmethod
|
||||
def get_attr_defs_for_context(cls, create_context):
|
||||
return [
|
||||
BoolDef(
|
||||
"ignore_shot_attributes_on_update",
|
||||
label="Ignore shot attributes on update",
|
||||
default=cls.ignore_shot_attributes_on_update
|
||||
)
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def apply_settings(cls, project_settings):
|
||||
cls.ignore_shot_attributes_on_update = (
|
||||
project_settings
|
||||
["core"]
|
||||
["CollectHierarchy"]
|
||||
["ignore_shot_attributes_on_update"]
|
||||
)
|
||||
|
||||
def _get_shot_instances(self, context):
|
||||
"""Get shot instances from context.
|
||||
|
||||
Args:
|
||||
context (pyblish.api.Context): Context is a list of instances.
|
||||
|
||||
Returns:
|
||||
list[pyblish.api.Instance]: A list of shot instances.
|
||||
"""
|
||||
shot_instances = []
|
||||
for instance in context:
|
||||
self.log.debug("Processing instance: `{}` ...".format(instance))
|
||||
|
||||
# shot data dict
|
||||
product_type = instance.data["productType"]
|
||||
families = instance.data["families"]
|
||||
|
|
@ -41,6 +67,67 @@ class CollectHierarchy(pyblish.api.ContextPlugin):
|
|||
self.log.debug("Skipping not a shot from hero track")
|
||||
continue
|
||||
|
||||
shot_instances.append(instance)
|
||||
|
||||
return shot_instances
|
||||
|
||||
def get_existing_folder_entities(self, project_name, shot_instances):
|
||||
"""Get existing folder entities for given shot instances.
|
||||
|
||||
Args:
|
||||
project_name (str): The name of the project.
|
||||
shot_instances (list[pyblish.api.Instance]): A list of shot
|
||||
instances.
|
||||
|
||||
Returns:
|
||||
dict[str, dict]: A dictionary mapping folder paths to existing
|
||||
folder entities.
|
||||
"""
|
||||
# first we need to get all folder paths from shot instances
|
||||
folder_paths = {
|
||||
instance.data["folderPath"]
|
||||
for instance in shot_instances
|
||||
}
|
||||
# then we get all existing folder entities with one request
|
||||
existing_entities = {
|
||||
folder_entity["path"]: folder_entity
|
||||
for folder_entity in ayon_api.get_folders(
|
||||
project_name, folder_paths=folder_paths, fields={"path"})
|
||||
}
|
||||
for folder_path in folder_paths:
|
||||
# add None value to non-existing folder entities
|
||||
existing_entities.setdefault(folder_path, None)
|
||||
|
||||
return existing_entities
|
||||
|
||||
def process(self, context):
|
||||
# get only shot instances from context
|
||||
shot_instances = self._get_shot_instances(context)
|
||||
|
||||
if not shot_instances:
|
||||
return
|
||||
|
||||
# get user input
|
||||
values = self.get_attr_values_from_data(context.data)
|
||||
ignore_shot_attributes_on_update = values.get(
|
||||
"ignore_shot_attributes_on_update", None)
|
||||
|
||||
project_name = context.data["projectName"]
|
||||
final_context = {
|
||||
project_name: {
|
||||
"entity_type": "project",
|
||||
"children": {}
|
||||
},
|
||||
}
|
||||
temp_context = {}
|
||||
existing_entities = self.get_existing_folder_entities(
|
||||
project_name, shot_instances)
|
||||
|
||||
for instance in shot_instances:
|
||||
folder_path = instance.data["folderPath"]
|
||||
self.log.debug(
|
||||
f"Processing instance: `{folder_path} {instance}` ...")
|
||||
|
||||
shot_data = {
|
||||
"entity_type": "folder",
|
||||
# WARNING unless overwritten, default folder type is hardcoded
|
||||
|
|
@ -51,32 +138,43 @@ class CollectHierarchy(pyblish.api.ContextPlugin):
|
|||
}
|
||||
|
||||
shot_data["attributes"] = {}
|
||||
SHOT_ATTRS = (
|
||||
"handleStart",
|
||||
"handleEnd",
|
||||
"frameStart",
|
||||
"frameEnd",
|
||||
"clipIn",
|
||||
"clipOut",
|
||||
"fps",
|
||||
"resolutionWidth",
|
||||
"resolutionHeight",
|
||||
"pixelAspect",
|
||||
)
|
||||
for shot_attr in SHOT_ATTRS:
|
||||
attr_value = instance.data.get(shot_attr)
|
||||
if attr_value is None:
|
||||
# Shot attribute might not be defined (e.g. CSV ingest)
|
||||
self.log.debug(
|
||||
"%s shot attribute is not defined for instance.",
|
||||
shot_attr
|
||||
)
|
||||
continue
|
||||
# we need to check if the shot entity already exists
|
||||
# and if not the attributes needs to be added in case the option
|
||||
# is disabled by settings
|
||||
if (
|
||||
existing_entities.get(folder_path)
|
||||
and not ignore_shot_attributes_on_update
|
||||
):
|
||||
SHOT_ATTRS = (
|
||||
"handleStart",
|
||||
"handleEnd",
|
||||
"frameStart",
|
||||
"frameEnd",
|
||||
"clipIn",
|
||||
"clipOut",
|
||||
"fps",
|
||||
"resolutionWidth",
|
||||
"resolutionHeight",
|
||||
"pixelAspect",
|
||||
)
|
||||
for shot_attr in SHOT_ATTRS:
|
||||
attr_value = instance.data.get(shot_attr)
|
||||
if attr_value is None:
|
||||
# Shot attribute might not be defined (e.g. CSV ingest)
|
||||
self.log.debug(
|
||||
"%s shot attribute is not defined for instance.",
|
||||
shot_attr
|
||||
)
|
||||
continue
|
||||
|
||||
shot_data["attributes"][shot_attr] = attr_value
|
||||
shot_data["attributes"][shot_attr] = attr_value
|
||||
else:
|
||||
self.log.debug(
|
||||
"Shot attributes will not be updated."
|
||||
)
|
||||
|
||||
# Split by '/' for AYON where asset is a path
|
||||
name = instance.data["folderPath"].split("/")[-1]
|
||||
name = folder_path.split("/")[-1]
|
||||
actual = {name: shot_data}
|
||||
|
||||
for parent in reversed(instance.data["parents"]):
|
||||
|
|
|
|||
|
|
@ -49,6 +49,14 @@ class CollectAudioModel(BaseSettingsModel):
|
|||
)
|
||||
|
||||
|
||||
class CollectHierarchyModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
ignore_shot_attributes_on_update: bool = SettingsField(
|
||||
False,
|
||||
title="Ignore shot attributes on update"
|
||||
)
|
||||
|
||||
|
||||
class CollectSceneVersionModel(BaseSettingsModel):
|
||||
_isGroup = True
|
||||
hosts: list[str] = SettingsField(
|
||||
|
|
@ -1269,6 +1277,10 @@ class PublishPuginsModel(BaseSettingsModel):
|
|||
default_factory=CollectExplicitResolutionModel,
|
||||
title="Collect Explicit Resolution"
|
||||
)
|
||||
CollectHierarchy: CollectHierarchyModel = SettingsField(
|
||||
default_factory=CollectHierarchyModel,
|
||||
title="Collect Hierarchy"
|
||||
)
|
||||
ValidateEditorialAssetName: ValidateBaseModel = SettingsField(
|
||||
default_factory=ValidateBaseModel,
|
||||
title="Validate Editorial Asset Name"
|
||||
|
|
@ -1466,6 +1478,9 @@ DEFAULT_PUBLISH_VALUES = {
|
|||
],
|
||||
"options": []
|
||||
},
|
||||
"CollectHierarchy": {
|
||||
"ignore_shot_attributes_on_update": False,
|
||||
},
|
||||
"ValidateEditorialAssetName": {
|
||||
"enabled": True,
|
||||
"optional": False,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue