mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge branch 'develop' into enhancement/fill_gaps_in_extract_review
This commit is contained in:
commit
7e73b7d1ad
5 changed files with 219 additions and 10 deletions
|
|
@ -52,15 +52,15 @@ def get_product_name_template(
|
||||||
# TODO remove formatting keys replacement
|
# TODO remove formatting keys replacement
|
||||||
template = (
|
template = (
|
||||||
matching_profile["template"]
|
matching_profile["template"]
|
||||||
.replace("{task[name]}", "{task}")
|
.replace("{task}", "{task[name]}")
|
||||||
.replace("{Task[name]}", "{Task}")
|
.replace("{Task}", "{Task[name]}")
|
||||||
.replace("{TASK[NAME]}", "{TASK}")
|
.replace("{TASK}", "{TASK[NAME]}")
|
||||||
.replace("{product[type]}", "{family}")
|
.replace("{family}", "{product[type]}")
|
||||||
.replace("{Product[type]}", "{Family}")
|
.replace("{Family}", "{Product[type]}")
|
||||||
.replace("{PRODUCT[TYPE]}", "{FAMILY}")
|
.replace("{FAMILY}", "{PRODUCT[TYPE]}")
|
||||||
.replace("{folder[name]}", "{asset}")
|
.replace("{asset}", "{folder[name]}")
|
||||||
.replace("{Folder[name]}", "{Asset}")
|
.replace("{Asset}", "{Folder[name]}")
|
||||||
.replace("{FOLDER[NAME]}", "{ASSET}")
|
.replace("{ASSET}", "{FOLDER[NAME]}")
|
||||||
)
|
)
|
||||||
|
|
||||||
# Make sure template is set (matching may have empty string)
|
# Make sure template is set (matching may have empty string)
|
||||||
|
|
|
||||||
106
client/ayon_core/plugins/publish/collect_explicit_resolution.py
Normal file
106
client/ayon_core/plugins/publish/collect_explicit_resolution.py
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
import pyblish.api
|
||||||
|
from ayon_core.lib import EnumDef
|
||||||
|
from ayon_core.pipeline import publish
|
||||||
|
from ayon_core.pipeline.publish import PublishError
|
||||||
|
|
||||||
|
|
||||||
|
class CollectExplicitResolution(
|
||||||
|
pyblish.api.InstancePlugin,
|
||||||
|
publish.AYONPyblishPluginMixin,
|
||||||
|
):
|
||||||
|
"""Collect explicit user defined resolution attributes for instances"""
|
||||||
|
|
||||||
|
label = "Choose Explicit Resolution"
|
||||||
|
order = pyblish.api.CollectorOrder - 0.091
|
||||||
|
settings_category = "core"
|
||||||
|
|
||||||
|
enabled = False
|
||||||
|
|
||||||
|
default_resolution_item = (None, "Don't override")
|
||||||
|
# Settings
|
||||||
|
product_types = []
|
||||||
|
options = []
|
||||||
|
|
||||||
|
# caching resoluton items
|
||||||
|
resolution_items = None
|
||||||
|
|
||||||
|
def process(self, instance):
|
||||||
|
"""Process the instance and collect explicit resolution attributes"""
|
||||||
|
|
||||||
|
# Get the values from the instance data
|
||||||
|
values = self.get_attr_values_from_data(instance.data)
|
||||||
|
resolution_value = values.get("explicit_resolution", None)
|
||||||
|
if resolution_value is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get the width, height and pixel_aspect from the resolution value
|
||||||
|
resolution_data = self._get_resolution_values(resolution_value)
|
||||||
|
|
||||||
|
# Set the values to the instance data
|
||||||
|
instance.data.update(resolution_data)
|
||||||
|
|
||||||
|
def _get_resolution_values(self, resolution_value):
|
||||||
|
"""
|
||||||
|
Returns width, height and pixel_aspect from the resolution value
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
resolution_value (str): resolution value
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: dictionary with width, height and pixel_aspect
|
||||||
|
"""
|
||||||
|
resolution_items = self._get_resolution_items()
|
||||||
|
# ensure resolution_value is part of expected items
|
||||||
|
item_values = resolution_items.get(resolution_value)
|
||||||
|
|
||||||
|
# if the item is in the cache, get the values from it
|
||||||
|
if item_values:
|
||||||
|
return {
|
||||||
|
"resolutionWidth": item_values["width"],
|
||||||
|
"resolutionHeight": item_values["height"],
|
||||||
|
"pixelAspect": item_values["pixel_aspect"],
|
||||||
|
}
|
||||||
|
|
||||||
|
raise PublishError(
|
||||||
|
f"Invalid resolution value: {resolution_value} "
|
||||||
|
f"expected choices: {resolution_items}"
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_resolution_items(cls):
|
||||||
|
if cls.resolution_items is None:
|
||||||
|
resolution_items = {}
|
||||||
|
for item in cls.options:
|
||||||
|
item_text = (
|
||||||
|
f"{item['width']}x{item['height']} "
|
||||||
|
f"({item['pixel_aspect']})"
|
||||||
|
)
|
||||||
|
resolution_items[item_text] = item
|
||||||
|
|
||||||
|
cls.resolution_items = resolution_items
|
||||||
|
|
||||||
|
return cls.resolution_items
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_attr_defs_for_instance(
|
||||||
|
cls, create_context, instance,
|
||||||
|
):
|
||||||
|
if instance.product_type not in cls.product_types:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Get the resolution items
|
||||||
|
resolution_items = cls._get_resolution_items()
|
||||||
|
|
||||||
|
items = [cls.default_resolution_item]
|
||||||
|
# Add all cached resolution items to the dropdown options
|
||||||
|
for item_text in resolution_items:
|
||||||
|
items.append((item_text, item_text))
|
||||||
|
|
||||||
|
return [
|
||||||
|
EnumDef(
|
||||||
|
"explicit_resolution",
|
||||||
|
items,
|
||||||
|
default="Don't override",
|
||||||
|
label="Force product resolution",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -10,6 +10,7 @@ ayon_server_version = ">=1.7.6,<2.0.0"
|
||||||
ayon_launcher_version = ">=1.0.2"
|
ayon_launcher_version = ">=1.0.2"
|
||||||
ayon_required_addons = {}
|
ayon_required_addons = {}
|
||||||
ayon_compatible_addons = {
|
ayon_compatible_addons = {
|
||||||
|
"ayon_ocio": ">=1.2.1",
|
||||||
"harmony": ">0.4.0",
|
"harmony": ">0.4.0",
|
||||||
"fusion": ">=0.3.3",
|
"fusion": ">=0.3.3",
|
||||||
"openrv": ">=1.0.2",
|
"openrv": ">=1.0.2",
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,24 @@ def _fallback_ocio_config_profile_types():
|
||||||
|
|
||||||
def _ocio_built_in_paths():
|
def _ocio_built_in_paths():
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
"value": "{BUILTIN_OCIO_ROOT}/aces_2.0/studio-config-v3.0.0_aces-v2.0_ocio-v2.4.ocio", # noqa: E501
|
||||||
|
"label": "ACES 2.0 Studio (OCIO v2.4)",
|
||||||
|
"description": (
|
||||||
|
"Aces 2.0 Studio OCIO config file. Requires OCIO v2.4.")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "{BUILTIN_OCIO_ROOT}/aces_1.3/studio-config-v1.0.0_aces-v1.3_ocio-v2.1.ocio", # noqa: E501
|
||||||
|
"label": "ACES 1.3 Studio (OCIO v2.1)",
|
||||||
|
"description": (
|
||||||
|
"Aces 1.3 Studio OCIO config file. Requires OCIO v2.1.")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "{BUILTIN_OCIO_ROOT}/aces_1.3/studio-config-v1.0.0_aces-v1.3_ocio-v2.0.ocio", # noqa: E501
|
||||||
|
"label": "ACES 1.3 Studio (OCIO v2)",
|
||||||
|
"description": (
|
||||||
|
"Aces 1.3 Studio OCIO config file. Requires OCIO v2.")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"value": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
"value": "{BUILTIN_OCIO_ROOT}/aces_1.2/config.ocio",
|
||||||
"label": "ACES 1.2",
|
"label": "ACES 1.2",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from pydantic import validator
|
from pydantic import validator
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from ayon_server.settings import (
|
from ayon_server.settings import (
|
||||||
BaseSettingsModel,
|
BaseSettingsModel,
|
||||||
|
|
@ -9,7 +10,7 @@ from ayon_server.settings import (
|
||||||
task_types_enum,
|
task_types_enum,
|
||||||
anatomy_template_items_enum
|
anatomy_template_items_enum
|
||||||
)
|
)
|
||||||
|
from ayon_server.exceptions import BadRequestException
|
||||||
from ayon_server.types import ColorRGBA_uint8
|
from ayon_server.types import ColorRGBA_uint8
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -167,6 +168,78 @@ class CollectUSDLayerContributionsModel(BaseSettingsModel):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class ResolutionOptionsModel(BaseSettingsModel):
|
||||||
|
_layout = "compact"
|
||||||
|
width: int = SettingsField(
|
||||||
|
1920,
|
||||||
|
ge=0,
|
||||||
|
le=100000,
|
||||||
|
title="Width",
|
||||||
|
description=(
|
||||||
|
"Width resolution number value"),
|
||||||
|
placeholder="Width"
|
||||||
|
)
|
||||||
|
height: int = SettingsField(
|
||||||
|
1080,
|
||||||
|
title="Height",
|
||||||
|
ge=0,
|
||||||
|
le=100000,
|
||||||
|
description=(
|
||||||
|
"Height resolution number value"),
|
||||||
|
placeholder="Height"
|
||||||
|
)
|
||||||
|
pixel_aspect: float = SettingsField(
|
||||||
|
1.0,
|
||||||
|
title="Pixel aspect",
|
||||||
|
ge=0.0,
|
||||||
|
le=100000.0,
|
||||||
|
description=(
|
||||||
|
"Pixel Aspect resolution decimal number value"),
|
||||||
|
placeholder="Pixel aspect"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_unique_resolution_option(
|
||||||
|
objects: list[Any], field_name: str | None = None) -> None: # noqa: C901
|
||||||
|
"""Ensure a list of objects have unique option attributes.
|
||||||
|
|
||||||
|
This function checks if the list of objects has unique 'width',
|
||||||
|
'height' and 'pixel_aspect' properties.
|
||||||
|
"""
|
||||||
|
options = set()
|
||||||
|
for obj in objects:
|
||||||
|
item_test_text = f"{obj.width}x{obj.height}x{obj.pixel_aspect}"
|
||||||
|
if item_test_text in options:
|
||||||
|
raise BadRequestException(
|
||||||
|
f"Duplicate option '{item_test_text}'")
|
||||||
|
|
||||||
|
options.add(item_test_text)
|
||||||
|
|
||||||
|
|
||||||
|
class CollectExplicitResolutionModel(BaseSettingsModel):
|
||||||
|
enabled: bool = SettingsField(True, title="Enabled")
|
||||||
|
product_types: list[str] = SettingsField(
|
||||||
|
default_factory=list,
|
||||||
|
title="Product types",
|
||||||
|
description=(
|
||||||
|
"Only activate the attribute for following product types."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
options: list[ResolutionOptionsModel] = SettingsField(
|
||||||
|
default_factory=list,
|
||||||
|
title="Resolution choices",
|
||||||
|
description=(
|
||||||
|
"Available resolution choices to be displayed in "
|
||||||
|
"the publishers attribute."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@validator("options")
|
||||||
|
def validate_unique_resolution_options(cls, value):
|
||||||
|
ensure_unique_resolution_option(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
class AyonEntityURIModel(BaseSettingsModel):
|
class AyonEntityURIModel(BaseSettingsModel):
|
||||||
use_ayon_entity_uri: bool = SettingsField(
|
use_ayon_entity_uri: bool = SettingsField(
|
||||||
title="Use AYON Entity URI",
|
title="Use AYON Entity URI",
|
||||||
|
|
@ -1012,6 +1085,10 @@ class PublishPuginsModel(BaseSettingsModel):
|
||||||
title="Collect USD Layer Contributions",
|
title="Collect USD Layer Contributions",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
CollectExplicitResolution: CollectExplicitResolutionModel = SettingsField(
|
||||||
|
default_factory=CollectExplicitResolutionModel,
|
||||||
|
title="Collect Explicit Resolution"
|
||||||
|
)
|
||||||
ValidateEditorialAssetName: ValidateBaseModel = SettingsField(
|
ValidateEditorialAssetName: ValidateBaseModel = SettingsField(
|
||||||
default_factory=ValidateBaseModel,
|
default_factory=ValidateBaseModel,
|
||||||
title="Validate Editorial Asset Name"
|
title="Validate Editorial Asset Name"
|
||||||
|
|
@ -1186,6 +1263,13 @@ DEFAULT_PUBLISH_VALUES = {
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"CollectExplicitResolution": {
|
||||||
|
"enabled": True,
|
||||||
|
"product_types": [
|
||||||
|
"shot"
|
||||||
|
],
|
||||||
|
"options": []
|
||||||
|
},
|
||||||
"ValidateEditorialAssetName": {
|
"ValidateEditorialAssetName": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"optional": False,
|
"optional": False,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue