From 344f91c983256d5a29641c5e809761ab39b60f64 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 26 Nov 2025 00:38:37 +0100 Subject: [PATCH] Make settings profiles more granular for OIIO post process --- .../publish/extract_oiio_postprocess.py | 46 +++++++++++++------ server/settings/publish_plugins.py | 10 ++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_oiio_postprocess.py b/client/ayon_core/plugins/publish/extract_oiio_postprocess.py index 2e93c68283..610f464989 100644 --- a/client/ayon_core/plugins/publish/extract_oiio_postprocess.py +++ b/client/ayon_core/plugins/publish/extract_oiio_postprocess.py @@ -1,3 +1,5 @@ +from __future__ import annotations +from typing import Any, Optional import os import copy import clique @@ -49,19 +51,21 @@ class ExtractOIIOPostProcess(publish.Extractor): self.log.warning("OIIO not supported, no transcoding possible.") return - profile = self._get_profile( - instance - ) - if not profile: - return - - profile_output_defs = profile["outputs"] new_representations = [] for idx, repre in enumerate(list(instance.data["representations"])): self.log.debug("repre ({}): `{}`".format(idx + 1, repre["name"])) if not self._repre_is_valid(repre): continue + # We check profile per representation name and extension because + # it's included in the profile check. As such, an instance may have + # a different profile applied per representation. + profile = self._get_profile( + instance + ) + if not profile: + continue + # Get representation files to convert if isinstance(repre["files"], list): repre_files_to_convert = copy.deepcopy(repre["files"]) @@ -72,7 +76,7 @@ class ExtractOIIOPostProcess(publish.Extractor): added_review = False # Process each output definition - for output_def in profile_output_defs: + for output_def in profile["outputs"]: # Local copy to avoid accidental mutable changes files_to_convert = list(repre_files_to_convert) @@ -255,7 +259,7 @@ class ExtractOIIOPostProcess(publish.Extractor): output_extension) return os.path.join(output_dir, new_file_name) - def _get_profile(self, instance): + def _get_profile(self, instance: pyblish.api.Instance, repre: dict) -> Optional[dict[str, Any]]: """Returns profile if it should process this instance.""" host_name = instance.context.data["hostName"] product_type = instance.data["productType"] @@ -263,24 +267,30 @@ class ExtractOIIOPostProcess(publish.Extractor): task_data = instance.data["anatomyData"].get("task", {}) task_name = task_data.get("name") task_type = task_data.get("type") + repre_name: str = repre["name"] + repre_ext: str = repre["ext"] filtering_criteria = { "hosts": host_name, "product_types": product_type, "product_names": product_name, "task_names": task_name, "task_types": task_type, + "representation_names": repre_name, + "representation_exts": repre_ext, } profile = filter_profiles(self.profiles, filtering_criteria, logger=self.log) if not profile: - self.log.debug(( + self.log.debug( "Skipped instance. None of profiles in presets are for" - " Host: \"{}\" | Product types: \"{}\" | Product names: \"{}\"" - " | Task name \"{}\" | Task type \"{}\"" - ).format( - host_name, product_type, product_name, task_name, task_type - )) + f" Host: \"{host_name}\" |" + f" Product types: \"{product_type}\" |" + f" Product names: \"{product_name}\" |" + f" Task name \"{task_name}\" |" + f" Task type \"{task_type}\" |" + f" Representation: \"{repre_name}\" (.{repre_ext})" + ) return profile @@ -305,6 +315,12 @@ class ExtractOIIOPostProcess(publish.Extractor): ).format(repre["name"])) return False + if "delete" in repre.get("tags", []): + self.log.debug(( + "Representation '{}' has 'delete' tag. Skipped." + ).format(repre["name"])) + return False + return True def _mark_original_repre_for_deletion(self, repre, profile, added_review): diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 173526e13f..2c133ddbbf 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -621,6 +621,7 @@ class ExtractOIIOPostProcessOutputModel(BaseSettingsModel): class ExtractOIIOPostProcessProfileModel(BaseSettingsModel): product_types: list[str] = SettingsField( + section="Profile", default_factory=list, title="Product types" ) @@ -641,6 +642,14 @@ class ExtractOIIOPostProcessProfileModel(BaseSettingsModel): default_factory=list, title="Product names" ) + representation_names: list[str] = SettingsField( + default_factory=list, + title="Representation names", + ) + representation_exts: list[str] = SettingsField( + default_factory=list, + title="Representation extensions", + ) delete_original: bool = SettingsField( True, title="Delete Original Representation", @@ -650,6 +659,7 @@ class ExtractOIIOPostProcessProfileModel(BaseSettingsModel): " a `review` tag, it will take precedence over" " the original for creating reviews." ), + section="Conversion Outputs", ) outputs: list[ExtractOIIOPostProcessOutputModel] = SettingsField( default_factory=list,