mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge branch 'feature/OP-7190_Use-folder-path-as-identifier-in-editorial' into feature/OP-7176_Use-folder-path-as-unique-identifier
This commit is contained in:
commit
ee85ee80a2
7 changed files with 117 additions and 66 deletions
|
|
@ -19,7 +19,7 @@ from .menu import load_stylesheet
|
|||
class CreatorWidget(QtWidgets.QDialog):
|
||||
|
||||
# output items
|
||||
items = dict()
|
||||
items = {}
|
||||
|
||||
def __init__(self, name, info, ui_inputs, parent=None):
|
||||
super(CreatorWidget, self).__init__(parent)
|
||||
|
|
@ -101,7 +101,7 @@ class CreatorWidget(QtWidgets.QDialog):
|
|||
self.close()
|
||||
|
||||
def value(self, data, new_data=None):
|
||||
new_data = new_data or dict()
|
||||
new_data = new_data or {}
|
||||
for k, v in data.items():
|
||||
new_data[k] = {
|
||||
"target": None,
|
||||
|
|
@ -290,7 +290,7 @@ class Spacer(QtWidgets.QWidget):
|
|||
class ClipLoader:
|
||||
|
||||
active_bin = None
|
||||
data = dict()
|
||||
data = {}
|
||||
|
||||
def __init__(self, loader_obj, context, **options):
|
||||
""" Initialize object
|
||||
|
|
@ -588,8 +588,8 @@ class PublishClip:
|
|||
Returns:
|
||||
hiero.core.TrackItem: hiero track item object with openpype tag
|
||||
"""
|
||||
vertical_clip_match = dict()
|
||||
tag_data = dict()
|
||||
vertical_clip_match = {}
|
||||
tag_data = {}
|
||||
types = {
|
||||
"shot": "shot",
|
||||
"folder": "folder",
|
||||
|
|
@ -665,15 +665,23 @@ class PublishClip:
|
|||
new_name = self.tag_data.pop("newClipName")
|
||||
|
||||
if self.rename:
|
||||
self.tag_data["asset"] = new_name
|
||||
self.tag_data["asset_name"] = new_name
|
||||
else:
|
||||
self.tag_data["asset"] = self.ti_name
|
||||
self.tag_data["asset_name"] = self.ti_name
|
||||
|
||||
# AYON unique identifier
|
||||
folder_path = "/{}/{}".format(
|
||||
self.tag_data["hierarchy"],
|
||||
self.tag_data["asset_name"]
|
||||
)
|
||||
self.tag_data["folder_path"] = folder_path
|
||||
|
||||
# create new name for track item
|
||||
if not lib.pype_marker_workflow:
|
||||
# create compound clip workflow
|
||||
lib.create_compound_clip(
|
||||
self.timeline_item_data,
|
||||
self.tag_data["asset"],
|
||||
self.tag_data["asset_name"],
|
||||
self.mp_folder
|
||||
)
|
||||
|
||||
|
|
@ -765,7 +773,7 @@ class PublishClip:
|
|||
# increasing steps by index of rename iteration
|
||||
self.count_steps *= self.rename_index
|
||||
|
||||
hierarchy_formatting_data = dict()
|
||||
hierarchy_formatting_data = {}
|
||||
_data = self.timeline_item_default_data.copy()
|
||||
if self.ui_inputs:
|
||||
# adding tag metadata from ui
|
||||
|
|
@ -854,8 +862,7 @@ class PublishClip:
|
|||
"parents": self.parents,
|
||||
"hierarchyData": hierarchy_formatting_data,
|
||||
"subset": self.subset,
|
||||
"family": self.subset_family,
|
||||
"families": ["clip"]
|
||||
"family": self.subset_family
|
||||
}
|
||||
|
||||
def _convert_to_entity(self, key):
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class ExtractWorkfile(publish.Extractor):
|
|||
|
||||
resolve_workfile_ext = ".drp"
|
||||
drp_file_name = name + resolve_workfile_ext
|
||||
|
||||
drp_file_path = os.path.normpath(
|
||||
os.path.join(staging_dir, drp_file_name))
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from openpype.hosts.resolve.api.lib import (
|
|||
get_publish_attribute,
|
||||
get_otio_clip_instance_data,
|
||||
)
|
||||
from openpype import AYON_SERVER_ENABLED
|
||||
|
||||
|
||||
class PrecollectInstances(pyblish.api.ContextPlugin):
|
||||
|
|
@ -29,7 +30,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
|
|||
|
||||
for timeline_item_data in selected_timeline_items:
|
||||
|
||||
data = dict()
|
||||
data = {}
|
||||
timeline_item = timeline_item_data["clip"]["item"]
|
||||
|
||||
# get pype tag data
|
||||
|
|
@ -60,24 +61,25 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
|
|||
if k not in ("id", "applieswhole", "label")
|
||||
})
|
||||
|
||||
asset = tag_data["asset"]
|
||||
if AYON_SERVER_ENABLED:
|
||||
asset = tag_data["folder_path"]
|
||||
else:
|
||||
asset = tag_data["asset_name"]
|
||||
|
||||
subset = tag_data["subset"]
|
||||
|
||||
# insert family into families
|
||||
family = tag_data["family"]
|
||||
families = [str(f) for f in tag_data["families"]]
|
||||
families.insert(0, str(family))
|
||||
|
||||
data.update({
|
||||
"name": "{} {} {}".format(asset, subset, families),
|
||||
"name": "{}_{}".format(asset, subset),
|
||||
"label": "{} {}".format(asset, subset),
|
||||
"asset": asset,
|
||||
"item": timeline_item,
|
||||
"families": families,
|
||||
"publish": get_publish_attribute(timeline_item),
|
||||
"fps": context.data["fps"],
|
||||
"handleStart": handle_start,
|
||||
"handleEnd": handle_end,
|
||||
"newAssetPublishing": True
|
||||
"newAssetPublishing": True,
|
||||
"families": ["clip"],
|
||||
"isEditorial": True
|
||||
})
|
||||
|
||||
# otio clip data
|
||||
|
|
@ -135,7 +137,8 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
|
|||
family = "shot"
|
||||
|
||||
data.update({
|
||||
"name": "{} {} {}".format(asset, subset, family),
|
||||
"name": "{}_{}".format(asset, subset),
|
||||
"label": "{} {}".format(asset, subset),
|
||||
"subset": subset,
|
||||
"asset": asset,
|
||||
"family": family,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from pprint import pformat
|
|||
|
||||
from openpype import AYON_SERVER_ENABLED
|
||||
from openpype.pipeline import get_current_asset_name
|
||||
|
||||
from openpype.hosts.resolve import api as rapi
|
||||
from openpype.hosts.resolve.otio import davinci_export
|
||||
|
||||
|
|
@ -14,14 +15,12 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin):
|
|||
order = pyblish.api.CollectorOrder - 0.5
|
||||
|
||||
def process(self, context):
|
||||
current_asset = get_current_asset_name()
|
||||
if AYON_SERVER_ENABLED:
|
||||
# AYON compatibility split name and use last piece
|
||||
asset_name = current_asset.split("/")[-1]
|
||||
else:
|
||||
asset_name = current_asset
|
||||
current_asset_name = asset_name = get_current_asset_name()
|
||||
|
||||
subset = "workfile"
|
||||
if AYON_SERVER_ENABLED:
|
||||
asset_name = current_asset_name.split("/")[-1]
|
||||
|
||||
subset = "workfileMain"
|
||||
project = rapi.get_current_project()
|
||||
fps = project.GetSetting("timelineFrameRate")
|
||||
video_tracks = rapi.get_video_track_names()
|
||||
|
|
@ -31,8 +30,9 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin):
|
|||
|
||||
instance_data = {
|
||||
"name": "{}_{}".format(asset_name, subset),
|
||||
"asset": current_asset,
|
||||
"subset": "{}{}".format(asset_name, subset.capitalize()),
|
||||
"label": "{} {}".format(current_asset_name, subset),
|
||||
"asset": current_asset_name,
|
||||
"subset": subset,
|
||||
"item": project,
|
||||
"family": "workfile",
|
||||
"families": []
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ class ShotMetadataSolver:
|
|||
try:
|
||||
# format to new shot name
|
||||
return shot_rename_template.format(**data)
|
||||
except KeyError as _E:
|
||||
except KeyError as _error:
|
||||
raise CreatorError((
|
||||
"Make sure all keys in settings are correct:: \n\n"
|
||||
f"From template string {shot_rename_template} > "
|
||||
f"`{_E}` has no equivalent in \n"
|
||||
f"`{_error}` has no equivalent in \n"
|
||||
f"{list(data.keys())} input formatting keys!"
|
||||
))
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ class ShotMetadataSolver:
|
|||
"at your project settings..."
|
||||
))
|
||||
|
||||
# QUESTION:how to refactory `match[-1]` to some better way?
|
||||
# QUESTION:how to refactor `match[-1]` to some better way?
|
||||
output_data[token_key] = match[-1]
|
||||
|
||||
return output_data
|
||||
|
|
@ -130,10 +130,10 @@ class ShotMetadataSolver:
|
|||
parent_token["name"]: parent_token["value"].format(**data)
|
||||
for parent_token in hierarchy_parents
|
||||
}
|
||||
except KeyError as _E:
|
||||
except KeyError as _error:
|
||||
raise CreatorError((
|
||||
"Make sure all keys in settings are correct : \n"
|
||||
f"`{_E}` has no equivalent in \n{list(data.keys())}"
|
||||
f"`{_error}` has no equivalent in \n{list(data.keys())}"
|
||||
))
|
||||
|
||||
_parent_tokens_type = {
|
||||
|
|
@ -147,10 +147,10 @@ class ShotMetadataSolver:
|
|||
try:
|
||||
parent_name = _parent.format(
|
||||
**_parent_tokens_formatting_data)
|
||||
except KeyError as _E:
|
||||
except KeyError as _error:
|
||||
raise CreatorError((
|
||||
"Make sure all keys in settings are correct : \n\n"
|
||||
f"`{_E}` from template string "
|
||||
f"`{_error}` from template string "
|
||||
f"{shot_hierarchy['parents_path']}, "
|
||||
f" has no equivalent in \n"
|
||||
f"{list(_parent_tokens_formatting_data.keys())} parents"
|
||||
|
|
@ -319,8 +319,16 @@ class ShotMetadataSolver:
|
|||
tasks = self._generate_tasks_from_settings(
|
||||
project_doc)
|
||||
|
||||
# generate hierarchy path from parents
|
||||
hierarchy_path = self._create_hierarchy_path(parents)
|
||||
if hierarchy_path:
|
||||
folder_path = f"/{hierarchy_path}/{shot_name}"
|
||||
else:
|
||||
folder_path = f"/{shot_name}"
|
||||
|
||||
return shot_name, {
|
||||
"hierarchy": self._create_hierarchy_path(parents),
|
||||
"hierarchy": hierarchy_path,
|
||||
"folderPath": folder_path,
|
||||
"parents": parents,
|
||||
"tasks": tasks
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,14 +102,23 @@ class EditorialShotInstanceCreator(EditorialClipInstanceCreatorBase):
|
|||
label = "Editorial Shot"
|
||||
|
||||
def get_instance_attr_defs(self):
|
||||
attr_defs = [
|
||||
TextDef(
|
||||
"asset_name",
|
||||
label="Asset name",
|
||||
instance_attributes = []
|
||||
if AYON_SERVER_ENABLED:
|
||||
instance_attributes.append(
|
||||
TextDef(
|
||||
"folderPath",
|
||||
label="Folder path"
|
||||
)
|
||||
)
|
||||
]
|
||||
attr_defs.extend(CLIP_ATTR_DEFS)
|
||||
return attr_defs
|
||||
else:
|
||||
instance_attributes.append(
|
||||
TextDef(
|
||||
"shotName",
|
||||
label="Shot name"
|
||||
)
|
||||
)
|
||||
instance_attributes.extend(CLIP_ATTR_DEFS)
|
||||
return instance_attributes
|
||||
|
||||
|
||||
class EditorialPlateInstanceCreator(EditorialClipInstanceCreatorBase):
|
||||
|
|
@ -215,11 +224,11 @@ or updating already created. Publishing will create OTIO file.
|
|||
i["family"] for i in self._creator_settings["family_presets"]
|
||||
]
|
||||
}
|
||||
# Create otio editorial instance
|
||||
if AYON_SERVER_ENABLED:
|
||||
asset_name = instance_data["folderPath"]
|
||||
else:
|
||||
asset_name = instance_data["asset"]
|
||||
|
||||
asset_doc = get_asset_by_name(self.project_name, asset_name)
|
||||
|
||||
if pre_create_data["fps"] == "from_selection":
|
||||
|
|
@ -599,19 +608,23 @@ or updating already created. Publishing will create OTIO file.
|
|||
Returns:
|
||||
str: label string
|
||||
"""
|
||||
shot_name = instance_data["shotName"]
|
||||
if AYON_SERVER_ENABLED:
|
||||
asset_name = instance_data["creator_attributes"]["folderPath"]
|
||||
else:
|
||||
asset_name = instance_data["creator_attributes"]["shotName"]
|
||||
|
||||
variant_name = instance_data["variant"]
|
||||
family = preset["family"]
|
||||
|
||||
# get variant name from preset or from inharitance
|
||||
# get variant name from preset or from inheritance
|
||||
_variant_name = preset.get("variant") or variant_name
|
||||
|
||||
# subset name
|
||||
subset_name = "{}{}".format(
|
||||
family, _variant_name.capitalize()
|
||||
)
|
||||
label = "{}_{}".format(
|
||||
shot_name,
|
||||
label = "{} {}".format(
|
||||
asset_name,
|
||||
subset_name
|
||||
)
|
||||
|
||||
|
|
@ -670,7 +683,10 @@ or updating already created. Publishing will create OTIO file.
|
|||
}
|
||||
)
|
||||
|
||||
self._validate_name_uniqueness(shot_name)
|
||||
# It should be validated only in openpype since we are supporting
|
||||
# publishing to AYON with folder path and uniqueness is not an issue
|
||||
if not AYON_SERVER_ENABLED:
|
||||
self._validate_name_uniqueness(shot_name)
|
||||
|
||||
timing_data = self._get_timing_data(
|
||||
otio_clip,
|
||||
|
|
@ -681,28 +697,21 @@ or updating already created. Publishing will create OTIO file.
|
|||
|
||||
# create creator attributes
|
||||
creator_attributes = {
|
||||
"asset_name": shot_name,
|
||||
"Parent hierarchy path": shot_metadata["hierarchy"],
|
||||
|
||||
"workfile_start_frame": workfile_start_frame,
|
||||
"fps": fps,
|
||||
"handle_start": int(handle_start),
|
||||
"handle_end": int(handle_end)
|
||||
}
|
||||
# add timing data
|
||||
creator_attributes.update(timing_data)
|
||||
|
||||
# create shared new instance data
|
||||
# create base instance data
|
||||
base_instance_data = {
|
||||
"shotName": shot_name,
|
||||
"variant": variant_name,
|
||||
|
||||
# HACK: just for temporal bug workaround
|
||||
# TODO: should loockup shot name for update
|
||||
"asset": parent_asset_name,
|
||||
"task": "",
|
||||
|
||||
"newAssetPublishing": True,
|
||||
|
||||
# parent time properties
|
||||
"trackStartFrame": track_start_frame,
|
||||
"timelineOffset": timeline_offset,
|
||||
"isEditorial": True,
|
||||
|
|
@ -710,6 +719,22 @@ or updating already created. Publishing will create OTIO file.
|
|||
# creator_attributes
|
||||
"creator_attributes": creator_attributes
|
||||
}
|
||||
# update base instance data with context data
|
||||
# and also update creator attributes with context data
|
||||
if AYON_SERVER_ENABLED:
|
||||
# TODO: this is here just to be able to publish
|
||||
# to AYON with folder path
|
||||
creator_attributes["folderPath"] = shot_metadata.pop("folderPath")
|
||||
base_instance_data["folderPath"] = parent_asset_name
|
||||
else:
|
||||
creator_attributes.update({
|
||||
"shotName": shot_name,
|
||||
"Parent hierarchy path": shot_metadata["hierarchy"]
|
||||
})
|
||||
|
||||
base_instance_data["asset"] = parent_asset_name
|
||||
# add creator attributes to shared instance data
|
||||
base_instance_data["creator_attributes"] = creator_attributes
|
||||
# add hierarchy shot metadata
|
||||
base_instance_data.update(shot_metadata)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ from pprint import pformat
|
|||
import pyblish.api
|
||||
import opentimelineio as otio
|
||||
|
||||
from openpype import AYON_SERVER_ENABLED
|
||||
|
||||
|
||||
class CollectShotInstance(pyblish.api.InstancePlugin):
|
||||
""" Collect shot instances
|
||||
|
|
@ -119,8 +121,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin):
|
|||
frame_end = _cr_attrs["frameEnd"]
|
||||
frame_dur = frame_end - frame_start
|
||||
|
||||
return {
|
||||
"asset": _cr_attrs["asset_name"],
|
||||
data = {
|
||||
"fps": float(_cr_attrs["fps"]),
|
||||
"handleStart": _cr_attrs["handle_start"],
|
||||
"handleEnd": _cr_attrs["handle_end"],
|
||||
|
|
@ -133,6 +134,12 @@ class CollectShotInstance(pyblish.api.InstancePlugin):
|
|||
"sourceOut": _cr_attrs["sourceOut"],
|
||||
"workfileFrameStart": workfile_start_frame
|
||||
}
|
||||
if AYON_SERVER_ENABLED:
|
||||
data["asset"] = _cr_attrs["folderPath"]
|
||||
else:
|
||||
data["asset"] = _cr_attrs["shotName"]
|
||||
|
||||
return data
|
||||
|
||||
def _solve_hierarchy_context(self, instance):
|
||||
""" Adding hierarchy data to context shared data.
|
||||
|
|
@ -148,7 +155,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin):
|
|||
else {}
|
||||
)
|
||||
|
||||
name = instance.data["asset"]
|
||||
asset_name = instance.data["asset"]
|
||||
|
||||
# get handles
|
||||
handle_start = int(instance.data["handleStart"])
|
||||
|
|
@ -170,7 +177,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin):
|
|||
|
||||
parents = instance.data.get('parents', [])
|
||||
|
||||
actual = {name: in_info}
|
||||
actual = {asset_name: in_info}
|
||||
|
||||
for parent in reversed(parents):
|
||||
parent_name = parent["entity_name"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue