From 13e56429bada4ba61003b5ae0b2ef912e5656f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Fri, 22 Nov 2024 17:42:45 +0100 Subject: [PATCH] :art: add get padding from files --- client/ayon_core/pipeline/traits/time.py | 19 +++++++++++++++++ .../ayon_core/pipeline/traits/test_traits.py | 21 +++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/pipeline/traits/time.py b/client/ayon_core/pipeline/traits/time.py index 5ce8d02426..83534aac18 100644 --- a/client/ayon_core/pipeline/traits/time.py +++ b/client/ayon_core/pipeline/traits/time.py @@ -4,11 +4,15 @@ from __future__ import annotations from enum import Enum, auto from typing import TYPE_CHECKING, ClassVar, Optional +import clique from pydantic import Field from .trait import MissingTraitError, TraitBase if TYPE_CHECKING: + from pathlib import Path + + from .content import FileLocations from .representation import Representation @@ -141,6 +145,21 @@ class Sequence(TraitBase): except MissingTraitError: pass + @staticmethod + def get_frame_padding(file_locations: FileLocations) -> int: + """Get frame padding.""" + files: list[Path] = [ + file.file_path.as_posix() + for file in file_locations.file_paths + ] + src_collections, _ = clique.assemble(files) + + src_collection = src_collections[0] + destination_indexes = list(src_collection.indexes) + # Use last frame for minimum padding + # - that should cover both 'udim' and 'frame' minimum padding + return len(str(destination_indexes[-1])) + # Do we need one for drop and non-drop frame? class SMPTETimecode(TraitBase): """SMPTE Timecode trait model.""" diff --git a/tests/client/ayon_core/pipeline/traits/test_traits.py b/tests/client/ayon_core/pipeline/traits/test_traits.py index 42bb523118..514066d4ef 100644 --- a/tests/client/ayon_core/pipeline/traits/test_traits.py +++ b/tests/client/ayon_core/pipeline/traits/test_traits.py @@ -15,6 +15,7 @@ from ayon_core.pipeline.traits import ( PixelBased, Planar, Representation, + Sequence, TraitBase, ) from ayon_core.pipeline.traits.trait import TraitValidationError @@ -358,7 +359,6 @@ def test_file_locations_validation() -> None: sequence_trait = FrameRanged( frame_start=1001, frame_end=1050, - frame_padding=4, frames_per_second="25" ) representation.add_trait(sequence_trait) @@ -382,10 +382,27 @@ def test_file_locations_validation() -> None: invalid_sequence_trait = FrameRanged( frame_start=1001, frame_end=1051, - frame_padding=4, frames_per_second="25" ) representation.add_trait(invalid_sequence_trait) with pytest.raises(TraitValidationError): file_locations_trait.validate(representation) + +def test_sequence_get_frame_padding() -> None: + """Test getting frame padding from FileLocations trait.""" + file_locations_list = [ + FileLocation( + file_path=Path(f"/path/to/file.{frame}.exr"), + file_size=1024, + file_hash=None, + ) + for frame in range(1001, 1051) + ] + + representation = Representation(name="test", traits=[ + FileLocations(file_paths=file_locations_list) + ]) + + assert Sequence.get_frame_padding( + file_locations=representation.get_trait(FileLocations)) == 4