Merge pull request #834 from ynput/enhancement/AY-6198_OCIO-fallback-for-profiles-and-templated-values

Refactor OCIO config handling, introduce fallback mechanism
This commit is contained in:
Jakub Trllo 2024-10-02 10:24:09 +02:00 committed by GitHub
commit ddd18831a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 151 additions and 33 deletions

View file

@ -699,6 +699,34 @@ def get_ocio_config_views(config_path):
)
def _get_config_path_from_profile_data(
profile, profile_type, template_data
):
"""Get config path from profile data.
Args:
profile (dict[str, Any]): Profile data.
profile_type (str): Profile type.
template_data (dict[str, Any]): Template data.
Returns:
dict[str, str]: Config data with path and template.
"""
template = profile[profile_type]
result = StringTemplate.format_strict_template(
template, template_data
)
normalized_path = str(result.normalized())
if not os.path.exists(normalized_path):
log.warning(f"Path was not found '{normalized_path}'.")
return None
return {
"path": normalized_path,
"template": template
}
def _get_global_config_data(
project_name,
host_name,
@ -717,7 +745,7 @@ def _get_global_config_data(
2. Custom path to ocio config.
3. Path to 'ocioconfig' representation on product. Name of product can be
defined in settings. Product name can be regex but exact match is
always preferred.
always preferred. Fallback can be defined in case no product is found.
None is returned when no profile is found, when path
@ -755,30 +783,36 @@ def _get_global_config_data(
profile_type = profile["type"]
if profile_type in ("builtin_path", "custom_path"):
template = profile[profile_type]
result = StringTemplate.format_strict_template(
template, template_data
)
normalized_path = str(result.normalized())
if not os.path.exists(normalized_path):
log.warning(f"Path was not found '{normalized_path}'.")
return None
return {
"path": normalized_path,
"template": template
}
return _get_config_path_from_profile_data(
profile, profile_type, template_data)
# TODO decide if this is the right name for representation
repre_name = "ocioconfig"
published_product_data = profile["published_product"]
product_name = published_product_data["product_name"]
fallback_data = published_product_data["fallback"]
if product_name == "":
log.error(
"Colorspace OCIO config path cannot be set. "
"Profile is set to published product but `Product name` is empty."
)
return None
folder_info = template_data.get("folder")
if not folder_info:
log.warning("Folder info is missing.")
return None
log.info("Using fallback data for ocio config path.")
# in case no product was found we need to use fallback
fallback_type = fallback_data["fallback_type"]
return _get_config_path_from_profile_data(
fallback_data, fallback_type, template_data
)
folder_path = folder_info["path"]
product_name = profile["product_name"]
if folder_id is None:
folder_entity = ayon_api.get_folder_by_path(
project_name, folder_path, fields={"id"}
@ -797,12 +831,13 @@ def _get_global_config_data(
fields={"id", "name"}
)
}
if not product_entities_by_name:
log.debug(
f"No product entities were found for folder '{folder_path}' with"
f" product name filter '{product_name}'."
# in case no product was found we need to use fallback
fallback_type = fallback_data["type"]
return _get_config_path_from_profile_data(
fallback_data, fallback_type, template_data
)
return None
# Try to use exact match first, otherwise use first available product
product_entity = product_entities_by_name.get(product_name)
@ -837,6 +872,7 @@ def _get_global_config_data(
path = get_representation_path_with_anatomy(repre_entity, anatomy)
template = repre_entity["attrib"]["template"]
return {
"path": path,
"template": template,

View file

@ -4,6 +4,29 @@ from typing import Any
from .publish_plugins import DEFAULT_PUBLISH_VALUES
def _convert_imageio_configs_0_4_5(overrides):
"""Imageio config settings did change to profiles since 0.4.5."""
imageio_overrides = overrides.get("imageio") or {}
# make sure settings are already converted to profiles
ocio_config_profiles = imageio_overrides.get("ocio_config_profiles")
if not ocio_config_profiles:
return
for profile in ocio_config_profiles:
if profile.get("type") != "product_name":
continue
profile["type"] = "published_product"
profile["published_product"] = {
"product_name": profile.pop("product_name"),
"fallback": {
"type": "builtin_path",
"builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
},
}
def _convert_imageio_configs_0_3_1(overrides):
"""Imageio config settings did change to profiles since 0.3.1. ."""
imageio_overrides = overrides.get("imageio") or {}
@ -76,7 +99,8 @@ def _convert_oiio_transcode_0_4_5(publish_overrides):
if "ExtractOIIOTranscode" not in publish_overrides:
return
transcode_profiles = publish_overrides["ExtractOIIOTranscode"].get("profiles")
transcode_profiles = publish_overrides["ExtractOIIOTranscode"].get(
"profiles")
if not transcode_profiles:
return
@ -85,7 +109,7 @@ def _convert_oiio_transcode_0_4_5(publish_overrides):
if outputs is None:
return
for output in outputs :
for output in outputs:
# Already new settings
if "display_view" in output:
break
@ -102,7 +126,7 @@ def _convert_oiio_transcode_0_4_5(publish_overrides):
}
def _conver_publish_plugins(overrides):
def _convert_publish_plugins(overrides):
if "publish" not in overrides:
return
_convert_validate_version_0_3_3(overrides["publish"])
@ -114,5 +138,6 @@ def convert_settings_overrides(
overrides: dict[str, Any],
) -> dict[str, Any]:
_convert_imageio_configs_0_3_1(overrides)
_conver_publish_plugins(overrides)
_convert_imageio_configs_0_4_5(overrides)
_convert_publish_plugins(overrides)
return overrides

View file

@ -58,7 +58,14 @@ def _ocio_config_profile_types():
return [
{"value": "builtin_path", "label": "AYON built-in OCIO config"},
{"value": "custom_path", "label": "Path to OCIO config"},
{"value": "product_name", "label": "Published product"},
{"value": "published_product", "label": "Published product"},
]
def _fallback_ocio_config_profile_types():
return [
{"value": "builtin_path", "label": "AYON built-in OCIO config"},
{"value": "custom_path", "label": "Path to OCIO config"},
]
@ -76,6 +83,49 @@ def _ocio_built_in_paths():
]
class FallbackProductModel(BaseSettingsModel):
_layout = "expanded"
fallback_type: str = SettingsField(
title="Fallback config type",
enum_resolver=_fallback_ocio_config_profile_types,
conditionalEnum=True,
default="builtin_path",
description=(
"Type of config which needs to be used in case published "
"product is not found."
),
)
builtin_path: str = SettingsField(
"ACES 1.2",
title="Built-in OCIO config",
enum_resolver=_ocio_built_in_paths,
description=(
"AYON ocio addon distributed OCIO config. "
"Activated addon in bundle is required: 'ayon_ocio' >= 1.1.1"
),
)
custom_path: str = SettingsField(
"",
title="OCIO config path",
description="Path to OCIO config. Anatomy formatting is supported.",
)
class PublishedProductModel(BaseSettingsModel):
_layout = "expanded"
product_name: str = SettingsField(
"",
title="Product name",
description=(
"Context related published product name to get OCIO config from. "
"Partial match is supported via use of regex expression."
),
)
fallback: FallbackProductModel = SettingsField(
default_factory=FallbackProductModel,
)
class CoreImageIOConfigProfilesModel(BaseSettingsModel):
_layout = "expanded"
host_names: list[str] = SettingsField(
@ -102,19 +152,19 @@ class CoreImageIOConfigProfilesModel(BaseSettingsModel):
"ACES 1.2",
title="Built-in OCIO config",
enum_resolver=_ocio_built_in_paths,
description=(
"AYON ocio addon distributed OCIO config. "
"Activated addon in bundle is required: 'ayon_ocio' >= 1.1.1"
),
)
custom_path: str = SettingsField(
"",
title="OCIO config path",
description="Path to OCIO config. Anatomy formatting is supported.",
)
product_name: str = SettingsField(
"",
title="Product name",
description=(
"Published product name to get OCIO config from. "
"Partial match is supported."
),
published_product: PublishedProductModel = SettingsField(
default_factory=PublishedProductModel,
title="Published product",
)
@ -294,7 +344,14 @@ DEFAULT_VALUES = {
"type": "builtin_path",
"builtin_path": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
"custom_path": "",
"product_name": "",
"published_product": {
"product_name": "",
"fallback": {
"fallback_type": "builtin_path",
"builtin_path": "ACES 1.2",
"custom_path": ""
}
}
}
],
"file_rules": {