Skip to content

Commit

Permalink
Merge pull request #193 from ynput/enhancement/AY-1112_Editorial-data…
Browse files Browse the repository at this point in the history
…-in-hierarchyContext

Editorial: Data in hierarchy context cleanup
  • Loading branch information
iLLiCiTiT authored Mar 27, 2024
2 parents 4e94d0d + d073f1a commit c0291e6
Show file tree
Hide file tree
Showing 13 changed files with 109 additions and 190 deletions.
10 changes: 5 additions & 5 deletions client/ayon_core/hosts/flame/api/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,13 +644,13 @@ def _solve_tag_hierarchy_data(self, hierarchy_formatting_data):
"families": [self.base_product_type, self.product_type]
}

def _convert_to_entity(self, type, template):
def _convert_to_entity(self, src_type, template):
""" Converting input key to key with type. """
# convert to entity type
entity_type = self.types.get(type, None)
folder_type = self.types.get(src_type, None)

assert entity_type, "Missing entity type for `{}`".format(
type
assert folder_type, "Missing folder type for `{}`".format(
src_type
)

# first collect formatting data to use for formatting template
Expand All @@ -661,7 +661,7 @@ def _convert_to_entity(self, type, template):
formatting_data[_k] = value

return {
"entity_type": entity_type,
"folder_type": folder_type,
"entity_name": template.format(
**formatting_data
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ def process(self, context):
marker_data["handleEnd"] = min(
marker_data["handleEnd"], tail)

# Backward compatibility fix of 'entity_type' > 'folder_type'
if "parents" in marker_data:
for parent in marker_data["parents"]:
if "entity_type" in parent:
parent["folder_type"] = parent.pop("entity_type")

workfile_start = self._set_workfile_start(marker_data)

with_audio = bool(marker_data.pop("audio"))
Expand Down
12 changes: 6 additions & 6 deletions client/ayon_core/hosts/hiero/api/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -905,16 +905,16 @@ def _solve_tag_hierarchy_data(self, hierarchy_formatting_data):
"hierarchyData": hierarchy_formatting_data,
"productName": self.product_name,
"productType": self.product_type,
"families": [self.product_type, self.data["family"]]
"families": [self.product_type, self.data["productType"]]
}

def _convert_to_entity(self, type, template):
def _convert_to_entity(self, src_type, template):
""" Converting input key to key with type. """
# convert to entity type
entity_type = self.types.get(type, None)
folder_type = self.types.get(src_type, None)

assert entity_type, "Missing entity type for `{}`".format(
type
assert folder_type, "Missing folder type for `{}`".format(
src_type
)

# first collect formatting data to use for formatting template
Expand All @@ -925,7 +925,7 @@ def _convert_to_entity(self, type, template):
formatting_data[_k] = value

return {
"entity_type": entity_type,
"folder_type": folder_type,
"entity_name": template.format(
**formatting_data
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ def process(self, context):
k: v for k, v in tag_data.items()
if k not in ("id", "applieswhole", "label")
})
# Backward compatibility fix of 'entity_type' > 'folder_type'
if "parents" in data:
for parent in data["parents"]:
if "entity_type" in parent:
parent["folder_type"] = parent.pop("entity_type")

asset, asset_name = self._get_folder_data(tag_data)

Expand Down
6 changes: 3 additions & 3 deletions client/ayon_core/hosts/resolve/api/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -875,14 +875,14 @@ def _solve_tag_hierarchy_data(self, hierarchy_formatting_data):
def _convert_to_entity(self, key):
""" Converting input key to key with type. """
# convert to entity type
entity_type = self.types.get(key)
folder_type = self.types.get(key)

assert entity_type, "Missing entity type for `{}`".format(
assert folder_type, "Missing folder type for `{}`".format(
key
)

return {
"entity_type": entity_type,
"folder_type": folder_type,
"entity_name": self.hierarchy_data[key]["value"].format(
**self.timeline_item_default_data
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ def process(self, context):
})

folder_path = tag_data["folder_path"]
# Backward compatibility fix of 'entity_type' > 'folder_type'
if "parents" in data:
for parent in data["parents"]:
if "entity_type" in parent:
parent["folder_type"] = parent.pop("entity_type")

# TODO: remove backward compatibility
product_name = tag_data.get("productName")
Expand Down
8 changes: 5 additions & 3 deletions client/ayon_core/hosts/traypublisher/api/editorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,15 @@ def _create_parents_from_settings(self, parents, data):
# in case first parent is project then start parents from start
if (
_index == 0
and parent_token_type == "project"
and parent_token_type.lower() == "project"
):
project_parent = parents[0]
parents = [project_parent]
continue

parents.append({
"entity_type": parent_token_type,
"entity_type": "folder",
"folder_type": parent_token_type.lower(),
"entity_name": parent_name
})

Expand Down Expand Up @@ -264,7 +265,8 @@ def _get_parents_from_selected_folder(
}]
for entity in folders_hierarchy:
output.append({
"entity_type": entity["folderType"],
"entity_type": "folder",
"folder_type": entity["folderType"],
"entity_name": entity["name"]
})
return output
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ def _get_base_instance_data(
base_instance_data = {
"shotName": shot_name,
"variant": variant_name,
"task": "",
"task": None,
"newAssetPublishing": True,
"trackStartFrame": track_start_frame,
"timelineOffset": timeline_offset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,9 @@ def _solve_hierarchy_context(self, instance):
handle_end = int(instance.data["handleEnd"])

in_info = {
"entity_type": "Shot",
"custom_attributes": {
"entity_type": "folder",
"folder_type": "Shot",
"attributes": {
"handleStart": handle_start,
"handleEnd": handle_end,
"frameStart": instance.data["frameStart"],
Expand All @@ -174,13 +175,13 @@ def _solve_hierarchy_context(self, instance):

for parent in reversed(parents):
parent_name = parent["entity_name"]
next_dict = {
parent_name: {
"entity_type": parent["entity_type"],
"childs": actual
}
parent_info = {
"entity_type": parent["entity_type"],
"children": actual,
}
actual = next_dict
if parent_info["entity_type"] == "folder":
parent_info["folder_type"] = parent["folder_type"]
actual = {parent_name: parent_info}

final_context = self._update_dict(final_context, actual)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,11 @@ def _fill_task_data(self, instance, task_types_by_name, anatomy_data):
current_data = hierarchy_context.get(project_name, {})
for key in folder_path.split("/"):
if key:
current_data = current_data.get("childs", {}).get(key, {})
current_data = (
current_data
.get("children", {})
.get(key, {})
)
tasks_info = current_data.get("tasks", {})

task_info = tasks_info.get(task_name, {})
Expand Down Expand Up @@ -529,5 +533,5 @@ def _find_tasks_info_in_hierarchy(self, hierarchy_context, folder_name):
return item[folder_name].get("tasks") or {}

for subitem in item.values():
hierarchy_queue.extend(subitem.get("childs") or [])
hierarchy_queue.extend(subitem.get("children") or [])
return {}
66 changes: 35 additions & 31 deletions client/ayon_core/plugins/publish/collect_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ class CollectHierarchy(pyblish.api.ContextPlugin):
hosts = ["resolve", "hiero", "flame"]

def process(self, context):
temp_context = {}
project_name = context.data["projectName"]
final_context = {}
final_context[project_name] = {}
final_context[project_name]["entity_type"] = "project"

final_context = {
project_name: {
"entity_type": "project",
"children": {}
},
}
temp_context = {}
for instance in context:
self.log.debug("Processing instance: `{}` ...".format(instance))

# shot data dict
shot_data = {}
product_type = instance.data["productType"]
families = instance.data["families"]

Expand All @@ -41,34 +42,38 @@ def process(self, context):
if not instance.data.get("heroTrack"):
continue

# suppose that all instances are Shots
shot_data['entity_type'] = 'Shot'
shot_data['tasks'] = instance.data.get("tasks") or {}
shot_data["comments"] = instance.data.get("comments", [])

shot_data['custom_attributes'] = {
"handleStart": instance.data["handleStart"],
"handleEnd": instance.data["handleEnd"],
"frameStart": instance.data["frameStart"],
"frameEnd": instance.data["frameEnd"],
"clipIn": instance.data["clipIn"],
"clipOut": instance.data["clipOut"],
"fps": instance.data["fps"],
"resolutionWidth": instance.data["resolutionWidth"],
"resolutionHeight": instance.data["resolutionHeight"],
"pixelAspect": instance.data["pixelAspect"]
shot_data = {
"entity_type": "folder",
# WARNING Default folder type is hardcoded
# suppose that all instances are Shots
"folder_type": "Shot",
"tasks": instance.data.get("tasks") or {},
"comments": instance.data.get("comments", []),
"attributes": {
"handleStart": instance.data["handleStart"],
"handleEnd": instance.data["handleEnd"],
"frameStart": instance.data["frameStart"],
"frameEnd": instance.data["frameEnd"],
"clipIn": instance.data["clipIn"],
"clipOut": instance.data["clipOut"],
"fps": instance.data["fps"],
"resolutionWidth": instance.data["resolutionWidth"],
"resolutionHeight": instance.data["resolutionHeight"],
"pixelAspect": instance.data["pixelAspect"],
},
}
# Split by '/' for AYON where asset is a path
name = instance.data["folderPath"].split("/")[-1]
actual = {name: shot_data}

for parent in reversed(instance.data["parents"]):
next_dict = {}
parent_name = parent["entity_name"]
next_dict[parent_name] = {}
next_dict[parent_name]["entity_type"] = parent[
"entity_type"].capitalize()
next_dict[parent_name]["childs"] = actual
next_dict = {
parent["entity_name"]: {
"entity_type": "folder",
"folder_type": parent["folder_type"],
"children": actual,
}
}
actual = next_dict

temp_context = self._update_dict(temp_context, actual)
Expand All @@ -77,16 +82,15 @@ def process(self, context):
if not temp_context:
return

final_context[project_name]['childs'] = temp_context
final_context[project_name]["children"] = temp_context

# adding hierarchy context to context
context.data["hierarchyContext"] = final_context
self.log.debug("context.data[hierarchyContext] is: {}".format(
context.data["hierarchyContext"]))

def _update_dict(self, parent_dict, child_dict):
"""
Nesting each children into its parent.
"""Nesting each child into its parent.
Args:
parent_dict (dict): parent dict wich should be nested with children
Expand Down
32 changes: 23 additions & 9 deletions client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ def _create_hierarchy(self, context, project_name):

entity_hub = EntityHub(project_name)
project = entity_hub.project_entity
folder_type_name_by_low_name = {
folder_type_item["name"].lower(): folder_type_item["name"]
for folder_type_item in project.get_folder_types()
}

hierarchy_match_queue = collections.deque()
hierarchy_match_queue.append((project, hierarchy_context))
Expand Down Expand Up @@ -167,8 +171,18 @@ def _create_hierarchy(self, context, project_name):
# TODO check if existing entity have 'folder' type
child_entity = children_by_low_name.get(child_name.lower())
if child_entity is None:
folder_type = folder_type_name_by_low_name.get(
child_info["folder_type"].lower()
)
if folder_type is None:
# TODO add validator for folder type validations
self.log.warning((
"Couldn't find folder type '{}'"
).format(child_info["folder_type"]))
folder_type = "Folder"

child_entity = entity_hub.add_new_folder(
child_info["entity_type"],
folder_type,
parent_id=entity.id,
name=child_name
)
Expand Down Expand Up @@ -223,12 +237,11 @@ def _filter_hierarchy(self, context):
# filter only the active publishing instances
active_folder_paths = set()
for instance in context:
if instance.data.get("publish") is not False:
if instance.data.get("publish", True) is not False:
active_folder_paths.add(instance.data.get("folderPath"))

active_folder_paths.discard(None)

self.log.debug("Active folder paths: {}".format(active_folder_paths))
if not active_folder_paths:
return None

Expand All @@ -237,11 +250,11 @@ def _filter_hierarchy(self, context):
hierarchy_context = copy.deepcopy(context.data["hierarchyContext"])
for key, value in hierarchy_context.items():
project_item = copy.deepcopy(value)
project_children_context = project_item.pop("childs", None)
project_children_context = project_item.pop("children", None)
project_item["name"] = key
project_item["tasks"] = []
project_item["attributes"] = project_item.pop(
"custom_attributes", {}
"attributes", {}
)
project_item["children"] = []

Expand All @@ -265,22 +278,23 @@ def _filter_hierarchy(self, context):
folder_path = "{}/{}".format(parent_path, folder_name)
if (
folder_path not in active_folder_paths
and not folder_info.get("childs")
and not folder_info.get("children")
):
continue

item_id = uuid.uuid4().hex
new_item = copy.deepcopy(folder_info)
new_children_context = new_item.pop("children", None)
tasks = new_item.pop("tasks", {})

new_item["name"] = folder_name
new_item["children"] = []
new_children_context = new_item.pop("childs", None)
tasks = new_item.pop("tasks", {})
task_items = []
for task_name, task_info in tasks.items():
task_info["name"] = task_name
task_items.append(task_info)
new_item["tasks"] = task_items
new_item["attributes"] = new_item.pop("custom_attributes", {})
new_item["attributes"] = new_item.pop("attributes", {})

items_by_id[item_id] = new_item
parent_id_by_item_id[item_id] = parent_id
Expand Down
Loading

0 comments on commit c0291e6

Please sign in to comment.