diff --git a/client/ayon_core/plugins/publish/extract_color_transcode.py b/client/ayon_core/plugins/publish/extract_color_transcode.py index a28a761e7e..3e54d324e3 100644 --- a/client/ayon_core/plugins/publish/extract_color_transcode.py +++ b/client/ayon_core/plugins/publish/extract_color_transcode.py @@ -122,13 +122,22 @@ class ExtractOIIOTranscode(publish.Extractor): transcoding_type = output_def["transcoding_type"] target_colorspace = view = display = None + # NOTE: we use colorspace_data as the fallback values for + # the target colorspace. if transcoding_type == "colorspace": + # TODO: Should we fallback to the colorspace + # (which used as source above) ? + # or should we compute the target colorspace from + # current view and display ? target_colorspace = (output_def["colorspace"] or colorspace_data.get("colorspace")) - else: - view = output_def["view"] or colorspace_data.get("view") - display = (output_def["display"] or - colorspace_data.get("display")) + elif transcoding_type == "display_view": + display_view = output_def["display_view"] + view = display_view["view"] or colorspace_data.get("view") + display = ( + display_view["display"] + or colorspace_data.get("display") + ) # both could be already collected by DCC, # but could be overwritten when transcoding @@ -192,7 +201,7 @@ class ExtractOIIOTranscode(publish.Extractor): new_repre["files"] = new_repre["files"][0] # If the source representation has "review" tag, but its not - # part of the output defintion tags, then both the + # part of the output definition tags, then both the # representations will be transcoded in ExtractReview and # their outputs will clash in integration. if "review" in repre.get("tags", []): diff --git a/server/settings/conversion.py b/server/settings/conversion.py index f513738603..c855863591 100644 --- a/server/settings/conversion.py +++ b/server/settings/conversion.py @@ -71,10 +71,42 @@ def _convert_validate_version_0_3_3(publish_overrides): validate_version["plugin_state_profiles"] = [profile] +def _convert_oiio_transcode_0_4_5(publish_overrides): + """ExtractOIIOTranscode plugin changed in 0.4.5.""" + if "ExtractOIIOTranscode" not in publish_overrides: + return + + transcode_profiles = publish_overrides["ExtractOIIOTranscode"].get("profiles") + if not transcode_profiles: + return + + for profile in transcode_profiles: + outputs = profile.get("outputs") + if outputs is None: + return + + for output in outputs : + # Already new settings + if "display_view" in output: + break + + # Fix 'display' -> 'display_view' in 'transcoding_type' + transcode_type = output.get("transcoding_type") + if transcode_type == "display": + output["transcoding_type"] = "display_view" + + # Convert 'display' and 'view' to new values + output["display_view"] = { + "display": output.pop("display", ""), + "view": output.pop("view", ""), + } + + def _conver_publish_plugins(overrides): if "publish" not in overrides: return _convert_validate_version_0_3_3(overrides["publish"]) + _convert_oiio_transcode_0_4_5(overrides["publish"]) def convert_settings_overrides( diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 61972e64c4..cdcd28a9ce 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -268,13 +268,36 @@ class ExtractThumbnailModel(BaseSettingsModel): def _extract_oiio_transcoding_type(): return [ {"value": "colorspace", "label": "Use Colorspace"}, - {"value": "display", "label": "Use Display&View"} + {"value": "display_view", "label": "Use Display&View"} ] class OIIOToolArgumentsModel(BaseSettingsModel): additional_command_args: list[str] = SettingsField( - default_factory=list, title="Arguments") + default_factory=list, + title="Arguments", + description="Additional command line arguments for *oiiotool*." + ) + + +class UseDisplayViewModel(BaseSettingsModel): + _layout = "expanded" + display: str = SettingsField( + "", + title="Target Display", + description=( + "Display of the target transform. If left empty, the" + " source Display value will be used." + ) + ) + view: str = SettingsField( + "", + title="Target View", + description=( + "View of the target transform. If left empty, the" + " source View value will be used." + ) + ) class ExtractOIIOTranscodeOutputModel(BaseSettingsModel): @@ -285,22 +308,57 @@ class ExtractOIIOTranscodeOutputModel(BaseSettingsModel): description="Output name (no space)", regex=r"[a-zA-Z0-9_]([a-zA-Z0-9_\.\-]*[a-zA-Z0-9_])?$", ) - extension: str = SettingsField("", title="Extension") + extension: str = SettingsField( + "", + title="Extension", + description=( + "Target extension. If left empty, original" + " extension is used." + ), + ) transcoding_type: str = SettingsField( "colorspace", title="Transcoding type", - enum_resolver=_extract_oiio_transcoding_type + enum_resolver=_extract_oiio_transcoding_type, + conditionalEnum=True, + description=( + "Select the transcoding type for your output, choosing either " + "*Colorspace* or *Display&View* transform." + " Only one option can be applied per output definition." + ), ) - colorspace: str = SettingsField("", title="Colorspace") - display: str = SettingsField("", title="Display") - view: str = SettingsField("", title="View") + colorspace: str = SettingsField( + "", + title="Target Colorspace", + description=( + "Choose the desired target colorspace, confirming its availability" + " in the active OCIO config. If left empty, the" + " source colorspace value will be used, resulting in no" + " colorspace conversion." + ) + ) + display_view: UseDisplayViewModel = SettingsField( + title="Use Display&View", + default_factory=UseDisplayViewModel + ) + oiiotool_args: OIIOToolArgumentsModel = SettingsField( default_factory=OIIOToolArgumentsModel, title="OIIOtool arguments") - tags: list[str] = SettingsField(default_factory=list, title="Tags") + tags: list[str] = SettingsField( + default_factory=list, + title="Tags", + description=( + "Additional tags that will be added to the created representation." + "\nAdd *review* tag to create review from the transcoded" + " representation instead of the original." + ) + ) custom_tags: list[str] = SettingsField( - default_factory=list, title="Custom Tags" + default_factory=list, + title="Custom Tags", + description="Additional custom tags that will be added to the created representation." ) @@ -328,7 +386,13 @@ class ExtractOIIOTranscodeProfileModel(BaseSettingsModel): ) delete_original: bool = SettingsField( True, - title="Delete Original Representation" + title="Delete Original Representation", + description=( + "Choose to preserve or remove the original representation.\n" + "Keep in mind that if the transcoded representation includes" + " a `review` tag, it will take precedence over" + " the original for creating reviews." + ), ) outputs: list[ExtractOIIOTranscodeOutputModel] = SettingsField( default_factory=list, @@ -371,7 +435,7 @@ class ExtractReviewFFmpegModel(BaseSettingsModel): def extract_review_filter_enum(): return [ { - "value": "everytime", + "value": "everytime", # codespell:ignore everytime "label": "Always" }, { @@ -393,7 +457,7 @@ class ExtractReviewFilterModel(BaseSettingsModel): default_factory=list, title="Custom Tags" ) single_frame_filter: str = SettingsField( - "everytime", + "everytime", # codespell:ignore everytime description=( "Use output always / only if input is 1 frame" " image / only if has 2+ frames or is video" @@ -791,7 +855,7 @@ class IntegrateHeroVersionModel(BaseSettingsModel): class CleanUpModel(BaseSettingsModel): _isGroup = True - paterns: list[str] = SettingsField( + paterns: list[str] = SettingsField( # codespell:ignore paterns default_factory=list, title="Patterns (regex)" ) @@ -1225,7 +1289,7 @@ DEFAULT_PUBLISH_VALUES = { "use_hardlinks": False }, "CleanUp": { - "paterns": [], + "paterns": [], # codespell:ignore paterns "remove_temp_renders": False }, "CleanUpFarm": {