mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 08:24:53 +01:00
Merge pull request #50 from ynput/enhancement/OP-8200_Traypublisher-use-AYON-settings
TrayPublisher: Use AYON settings
This commit is contained in:
commit
4a016e4f99
4 changed files with 76 additions and 127 deletions
|
|
@ -16,25 +16,31 @@ class ShotMetadataSolver:
|
||||||
|
|
||||||
NO_DECOR_PATERN = re.compile(r"\{([a-z]*?)\}")
|
NO_DECOR_PATERN = re.compile(r"\{([a-z]*?)\}")
|
||||||
|
|
||||||
# presets
|
def __init__(self, logger):
|
||||||
clip_name_tokenizer = None
|
self.clip_name_tokenizer = []
|
||||||
shot_rename = True
|
self.shot_rename = {
|
||||||
shot_hierarchy = None
|
"enabled": False,
|
||||||
shot_add_tasks = None
|
"shot_rename_template": "",
|
||||||
|
}
|
||||||
|
self.shot_hierarchy = {
|
||||||
|
"enabled": False,
|
||||||
|
"parents": [],
|
||||||
|
"parents_path": "",
|
||||||
|
}
|
||||||
|
self.shot_add_tasks = []
|
||||||
|
self.log = logger
|
||||||
|
|
||||||
def __init__(
|
def update_data(
|
||||||
self,
|
self,
|
||||||
clip_name_tokenizer,
|
clip_name_tokenizer,
|
||||||
shot_rename,
|
shot_rename,
|
||||||
shot_hierarchy,
|
shot_hierarchy,
|
||||||
shot_add_tasks,
|
shot_add_tasks
|
||||||
logger
|
|
||||||
):
|
):
|
||||||
self.clip_name_tokenizer = clip_name_tokenizer
|
self.clip_name_tokenizer = clip_name_tokenizer
|
||||||
self.shot_rename = shot_rename
|
self.shot_rename = shot_rename
|
||||||
self.shot_hierarchy = shot_hierarchy
|
self.shot_hierarchy = shot_hierarchy
|
||||||
self.shot_add_tasks = shot_add_tasks
|
self.shot_add_tasks = shot_add_tasks
|
||||||
self.log = logger
|
|
||||||
|
|
||||||
def _rename_template(self, data):
|
def _rename_template(self, data):
|
||||||
"""Shot renaming function
|
"""Shot renaming function
|
||||||
|
|
@ -86,7 +92,9 @@ class ShotMetadataSolver:
|
||||||
|
|
||||||
search_text = parent_name + clip_name
|
search_text = parent_name + clip_name
|
||||||
|
|
||||||
for token_key, pattern in self.clip_name_tokenizer.items():
|
for clip_name_item in self.clip_name_tokenizer:
|
||||||
|
token_key = clip_name_item["name"]
|
||||||
|
pattern = clip_name_item["regex"]
|
||||||
p = re.compile(pattern)
|
p = re.compile(pattern)
|
||||||
match = p.findall(search_text)
|
match = p.findall(search_text)
|
||||||
if not match:
|
if not match:
|
||||||
|
|
@ -137,11 +145,11 @@ class ShotMetadataSolver:
|
||||||
))
|
))
|
||||||
|
|
||||||
_parent_tokens_type = {
|
_parent_tokens_type = {
|
||||||
parent_token["name"]: parent_token["type"]
|
parent_token["name"]: parent_token["parent_type"]
|
||||||
for parent_token in hierarchy_parents
|
for parent_token in hierarchy_parents
|
||||||
}
|
}
|
||||||
for _index, _parent in enumerate(
|
for _index, _parent in enumerate(
|
||||||
shot_hierarchy["parents_path"].split("/")
|
shot_hierarchy["parents_path"].split("/")
|
||||||
):
|
):
|
||||||
# format parent token with value which is formatted
|
# format parent token with value which is formatted
|
||||||
try:
|
try:
|
||||||
|
|
@ -262,22 +270,22 @@ class ShotMetadataSolver:
|
||||||
"""
|
"""
|
||||||
tasks_to_add = {}
|
tasks_to_add = {}
|
||||||
|
|
||||||
project_tasks = project_doc["config"]["tasks"]
|
project_task_types = project_doc["config"]["tasks"]
|
||||||
for task_name, task_data in self.shot_add_tasks.items():
|
for task_item in self.shot_add_tasks:
|
||||||
_task_data = deepcopy(task_data)
|
task_name = task_item["name"]
|
||||||
|
task_type = task_item["task_type"]
|
||||||
|
|
||||||
# check if task type in project task types
|
# check if task type in project task types
|
||||||
if _task_data["type"] in project_tasks.keys():
|
if task_type not in project_task_types.keys():
|
||||||
tasks_to_add[task_name] = _task_data
|
|
||||||
else:
|
|
||||||
raise KeyError(
|
raise KeyError(
|
||||||
"Missing task type `{}` for `{}` is not"
|
"Missing task type `{}` for `{}` is not"
|
||||||
" existing in `{}``".format(
|
" existing in `{}``".format(
|
||||||
_task_data["type"],
|
task_type,
|
||||||
task_name,
|
task_name,
|
||||||
list(project_tasks.keys())
|
list(project_task_types.keys())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
tasks_to_add[task_name] = {"type": task_type}
|
||||||
|
|
||||||
return tasks_to_add
|
return tasks_to_add
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,7 @@ class SettingsCreator(TrayPublishCreator):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_settings(cls, item_data):
|
def from_settings(cls, item_data):
|
||||||
identifier = item_data["identifier"]
|
identifier = item_data["identifier"]
|
||||||
family = item_data["family"]
|
family = item_data["product_type"]
|
||||||
if not identifier:
|
if not identifier:
|
||||||
identifier = "settings_{}".format(family)
|
identifier = "settings_{}".format(family)
|
||||||
return type(
|
return type(
|
||||||
|
|
|
||||||
|
|
@ -174,46 +174,42 @@ Supporting publishing new shots to project
|
||||||
or updating already created. Publishing will create OTIO file.
|
or updating already created. Publishing will create OTIO file.
|
||||||
"""
|
"""
|
||||||
icon = "fa.file"
|
icon = "fa.file"
|
||||||
|
product_type_presets = []
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, *args, **kwargs):
|
||||||
self, project_settings, *args, **kwargs
|
self._shot_metadata_solver = ShotMetadataSolver(self.log)
|
||||||
):
|
super(EditorialSimpleCreator, self).__init__(*args, **kwargs)
|
||||||
super(EditorialSimpleCreator, self).__init__(
|
|
||||||
project_settings, *args, **kwargs
|
def apply_settings(self, project_settings):
|
||||||
)
|
|
||||||
editorial_creators = deepcopy(
|
editorial_creators = deepcopy(
|
||||||
project_settings["traypublisher"]["editorial_creators"]
|
project_settings["traypublisher"]["editorial_creators"]
|
||||||
)
|
)
|
||||||
# get this creator settings by identifier
|
creator_settings = editorial_creators.get(self.identifier)
|
||||||
self._creator_settings = editorial_creators.get(self.identifier)
|
|
||||||
|
|
||||||
clip_name_tokenizer = self._creator_settings["clip_name_tokenizer"]
|
self._shot_metadata_solver.update_data(
|
||||||
shot_rename = self._creator_settings["shot_rename"]
|
creator_settings["clip_name_tokenizer"],
|
||||||
shot_hierarchy = self._creator_settings["shot_hierarchy"]
|
creator_settings["shot_rename"],
|
||||||
shot_add_tasks = self._creator_settings["shot_add_tasks"]
|
creator_settings["shot_hierarchy"],
|
||||||
|
creator_settings["shot_add_tasks"]
|
||||||
self._shot_metadata_solver = ShotMetadataSolver(
|
|
||||||
clip_name_tokenizer,
|
|
||||||
shot_rename,
|
|
||||||
shot_hierarchy,
|
|
||||||
shot_add_tasks,
|
|
||||||
self.log
|
|
||||||
)
|
)
|
||||||
|
self.product_type_presets = creator_settings["product_type_presets"]
|
||||||
# try to set main attributes from settings
|
default_variants = creator_settings.get("default_variants")
|
||||||
if self._creator_settings.get("default_variants"):
|
if default_variants:
|
||||||
self.default_variants = self._creator_settings["default_variants"]
|
self.default_variants = default_variants
|
||||||
|
|
||||||
def create(self, subset_name, instance_data, pre_create_data):
|
def create(self, subset_name, instance_data, pre_create_data):
|
||||||
allowed_family_presets = self._get_allowed_family_presets(
|
allowed_product_type_presets = self._get_allowed_product_type_presets(
|
||||||
pre_create_data)
|
pre_create_data)
|
||||||
|
|
||||||
|
product_types = {
|
||||||
|
item["product_type"]
|
||||||
|
for item in self.product_type_presets
|
||||||
|
}
|
||||||
clip_instance_properties = {
|
clip_instance_properties = {
|
||||||
k: v for k, v in pre_create_data.items()
|
k: v
|
||||||
|
for k, v in pre_create_data.items()
|
||||||
if k != "sequence_filepath_data"
|
if k != "sequence_filepath_data"
|
||||||
if k not in [
|
if k not in product_types
|
||||||
i["family"] for i in self._creator_settings["family_presets"]
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asset_name = instance_data["folderPath"]
|
asset_name = instance_data["folderPath"]
|
||||||
|
|
@ -255,7 +251,7 @@ or updating already created. Publishing will create OTIO file.
|
||||||
otio_timeline,
|
otio_timeline,
|
||||||
media_path,
|
media_path,
|
||||||
clip_instance_properties,
|
clip_instance_properties,
|
||||||
allowed_family_presets,
|
allowed_product_type_presets,
|
||||||
os.path.basename(seq_path),
|
os.path.basename(seq_path),
|
||||||
first_otio_timeline
|
first_otio_timeline
|
||||||
)
|
)
|
||||||
|
|
@ -355,7 +351,7 @@ or updating already created. Publishing will create OTIO file.
|
||||||
otio_timeline,
|
otio_timeline,
|
||||||
media_path,
|
media_path,
|
||||||
instance_data,
|
instance_data,
|
||||||
family_presets,
|
product_type_presets,
|
||||||
sequence_file_name,
|
sequence_file_name,
|
||||||
first_otio_timeline=None
|
first_otio_timeline=None
|
||||||
):
|
):
|
||||||
|
|
@ -365,7 +361,7 @@ or updating already created. Publishing will create OTIO file.
|
||||||
otio_timeline (otio.Timeline): otio timeline object
|
otio_timeline (otio.Timeline): otio timeline object
|
||||||
media_path (str): media file path string
|
media_path (str): media file path string
|
||||||
instance_data (dict): clip instance data
|
instance_data (dict): clip instance data
|
||||||
family_presets (list): list of dict settings subset presets
|
product_type_presets (list): list of dict settings subset presets
|
||||||
"""
|
"""
|
||||||
|
|
||||||
tracks = [
|
tracks = [
|
||||||
|
|
@ -411,17 +407,17 @@ or updating already created. Publishing will create OTIO file.
|
||||||
"instance_id": None
|
"instance_id": None
|
||||||
}
|
}
|
||||||
|
|
||||||
for _fpreset in family_presets:
|
for product_type_preset in product_type_presets:
|
||||||
# exclude audio family if no audio stream
|
# exclude audio family if no audio stream
|
||||||
if (
|
if (
|
||||||
_fpreset["family"] == "audio"
|
product_type_preset["product_type"] == "audio"
|
||||||
and not media_data.get("audio")
|
and not media_data.get("audio")
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
instance = self._make_subset_instance(
|
instance = self._make_subset_instance(
|
||||||
otio_clip,
|
otio_clip,
|
||||||
_fpreset,
|
product_type_preset,
|
||||||
deepcopy(base_instance_data),
|
deepcopy(base_instance_data),
|
||||||
parenting_data
|
parenting_data
|
||||||
)
|
)
|
||||||
|
|
@ -533,7 +529,7 @@ or updating already created. Publishing will create OTIO file.
|
||||||
def _make_subset_instance(
|
def _make_subset_instance(
|
||||||
self,
|
self,
|
||||||
otio_clip,
|
otio_clip,
|
||||||
preset,
|
product_type_preset,
|
||||||
instance_data,
|
instance_data,
|
||||||
parenting_data
|
parenting_data
|
||||||
):
|
):
|
||||||
|
|
@ -541,16 +537,16 @@ or updating already created. Publishing will create OTIO file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
otio_clip (otio.Clip): otio clip object
|
otio_clip (otio.Clip): otio clip object
|
||||||
preset (dict): single family preset
|
product_type_preset (dict): single family preset
|
||||||
instance_data (dict): instance data
|
instance_data (dict): instance data
|
||||||
parenting_data (dict): shot instance parent data
|
parenting_data (dict): shot instance parent data
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
CreatedInstance: creator instance object
|
CreatedInstance: creator instance object
|
||||||
"""
|
"""
|
||||||
family = preset["family"]
|
family = product_type_preset["product_type"]
|
||||||
label = self._make_subset_naming(
|
label = self._make_subset_naming(
|
||||||
preset,
|
product_type_preset,
|
||||||
instance_data
|
instance_data
|
||||||
)
|
)
|
||||||
instance_data["label"] = label
|
instance_data["label"] = label
|
||||||
|
|
@ -569,11 +565,11 @@ or updating already created. Publishing will create OTIO file.
|
||||||
else:
|
else:
|
||||||
# add review family if defined
|
# add review family if defined
|
||||||
instance_data.update({
|
instance_data.update({
|
||||||
"outputFileType": preset["output_file_type"],
|
"outputFileType": product_type_preset["output_file_type"],
|
||||||
"parent_instance_id": parenting_data["instance_id"],
|
"parent_instance_id": parenting_data["instance_id"],
|
||||||
"creator_attributes": {
|
"creator_attributes": {
|
||||||
"parent_instance": parenting_data["instance_label"],
|
"parent_instance": parenting_data["instance_label"],
|
||||||
"add_review_family": preset.get("review")
|
"add_review_family": product_type_preset.get("review")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -585,15 +581,11 @@ or updating already created. Publishing will create OTIO file.
|
||||||
|
|
||||||
return c_instance
|
return c_instance
|
||||||
|
|
||||||
def _make_subset_naming(
|
def _make_subset_naming(self, product_type_preset, instance_data):
|
||||||
self,
|
|
||||||
preset,
|
|
||||||
instance_data
|
|
||||||
):
|
|
||||||
""" Subset name maker
|
""" Subset name maker
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
preset (dict): single preset item
|
product_type_preset (dict): single preset item
|
||||||
instance_data (dict): instance data
|
instance_data (dict): instance data
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
@ -602,10 +594,10 @@ or updating already created. Publishing will create OTIO file.
|
||||||
asset_name = instance_data["creator_attributes"]["folderPath"]
|
asset_name = instance_data["creator_attributes"]["folderPath"]
|
||||||
|
|
||||||
variant_name = instance_data["variant"]
|
variant_name = instance_data["variant"]
|
||||||
family = preset["family"]
|
family = product_type_preset["product_type"]
|
||||||
|
|
||||||
# get variant name from preset or from inheritance
|
# get variant name from preset or from inheritance
|
||||||
_variant_name = preset.get("variant") or variant_name
|
_variant_name = product_type_preset.get("variant") or variant_name
|
||||||
|
|
||||||
# subset name
|
# subset name
|
||||||
subset_name = "{}{}".format(
|
subset_name = "{}{}".format(
|
||||||
|
|
@ -763,7 +755,7 @@ or updating already created. Publishing will create OTIO file.
|
||||||
"sourceOut": int(source_out)
|
"sourceOut": int(source_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_allowed_family_presets(self, pre_create_data):
|
def _get_allowed_product_type_presets(self, pre_create_data):
|
||||||
""" Filter out allowed family presets.
|
""" Filter out allowed family presets.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|
@ -773,10 +765,11 @@ or updating already created. Publishing will create OTIO file.
|
||||||
list: lit of dict with preset items
|
list: lit of dict with preset items
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
{"family": "shot"},
|
{"product_type": "shot"},
|
||||||
*[
|
*[
|
||||||
preset for preset in self._creator_settings["family_presets"]
|
preset
|
||||||
if pre_create_data[preset["family"]]
|
for preset in self.product_type_presets
|
||||||
|
if pre_create_data[preset["product_type"]]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -853,8 +846,8 @@ or updating already created. Publishing will create OTIO file.
|
||||||
]
|
]
|
||||||
# add variants swithers
|
# add variants swithers
|
||||||
attr_defs.extend(
|
attr_defs.extend(
|
||||||
BoolDef(_var["family"], label=_var["family"])
|
BoolDef(item["product_type"], label=item["product_type"])
|
||||||
for _var in self._creator_settings["family_presets"]
|
for item in self.product_type_presets
|
||||||
)
|
)
|
||||||
attr_defs.append(UISeparatorDef())
|
attr_defs.append(UISeparatorDef())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -551,58 +551,6 @@ def _convert_traypublisher_project_settings(ayon_settings, output):
|
||||||
|
|
||||||
_convert_host_imageio(ayon_traypublisher)
|
_convert_host_imageio(ayon_traypublisher)
|
||||||
|
|
||||||
ayon_editorial_simple = (
|
|
||||||
ayon_traypublisher["editorial_creators"]["editorial_simple"]
|
|
||||||
)
|
|
||||||
# Subset -> Product type conversion
|
|
||||||
if "product_type_presets" in ayon_editorial_simple:
|
|
||||||
family_presets = ayon_editorial_simple.pop("product_type_presets")
|
|
||||||
for item in family_presets:
|
|
||||||
item["family"] = item.pop("product_type")
|
|
||||||
ayon_editorial_simple["family_presets"] = family_presets
|
|
||||||
|
|
||||||
if "shot_metadata_creator" in ayon_editorial_simple:
|
|
||||||
shot_metadata_creator = ayon_editorial_simple.pop(
|
|
||||||
"shot_metadata_creator"
|
|
||||||
)
|
|
||||||
if isinstance(shot_metadata_creator["clip_name_tokenizer"], dict):
|
|
||||||
shot_metadata_creator["clip_name_tokenizer"] = [
|
|
||||||
{"name": "_sequence_", "regex": "(sc\\d{3})"},
|
|
||||||
{"name": "_shot_", "regex": "(sh\\d{3})"},
|
|
||||||
]
|
|
||||||
ayon_editorial_simple.update(shot_metadata_creator)
|
|
||||||
|
|
||||||
ayon_editorial_simple["clip_name_tokenizer"] = {
|
|
||||||
item["name"]: item["regex"]
|
|
||||||
for item in ayon_editorial_simple["clip_name_tokenizer"]
|
|
||||||
}
|
|
||||||
|
|
||||||
if "shot_subset_creator" in ayon_editorial_simple:
|
|
||||||
ayon_editorial_simple.update(
|
|
||||||
ayon_editorial_simple.pop("shot_subset_creator"))
|
|
||||||
for item in ayon_editorial_simple["shot_hierarchy"]["parents"]:
|
|
||||||
item["type"] = item.pop("parent_type")
|
|
||||||
|
|
||||||
# Simple creators
|
|
||||||
ayon_simple_creators = ayon_traypublisher["simple_creators"]
|
|
||||||
for item in ayon_simple_creators:
|
|
||||||
if "product_type" not in item:
|
|
||||||
break
|
|
||||||
item["family"] = item.pop("product_type")
|
|
||||||
|
|
||||||
shot_add_tasks = ayon_editorial_simple["shot_add_tasks"]
|
|
||||||
|
|
||||||
# TODO: backward compatibility and remove in future
|
|
||||||
if isinstance(shot_add_tasks, dict):
|
|
||||||
shot_add_tasks = []
|
|
||||||
|
|
||||||
# aggregate shot_add_tasks items
|
|
||||||
new_shot_add_tasks = {
|
|
||||||
item["name"]: {"type": item["task_type"]}
|
|
||||||
for item in shot_add_tasks
|
|
||||||
}
|
|
||||||
ayon_editorial_simple["shot_add_tasks"] = new_shot_add_tasks
|
|
||||||
|
|
||||||
output["traypublisher"] = ayon_traypublisher
|
output["traypublisher"] = ayon_traypublisher
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue