diff --git a/src/videoag_common/media_process/basic_targets.py b/src/videoag_common/media_process/basic_targets.py index 0d050d56e474ed5c60bd239c599ab508c3f87966..1ff39edd6e8dbcb62800a2b03f8e83008022b356 100644 --- a/src/videoag_common/media_process/basic_targets.py +++ b/src/videoag_common/media_process/basic_targets.py @@ -10,7 +10,7 @@ from .target import TargetProducer, SingleInputTargetProducer, SingleOutputTarge SOURCE_FILE_TAG_PATTERN = re.compile("[a-zA-Z0-9_]*") -class SourceFileTargetProducer(SingleOutputTargetProducer): +class SourceFileTargetProducer(SingleOutputTargetProducer["SourceMedium"]): def __init__(self, tag: str, **kwargs): super().__init__(**kwargs) @@ -36,18 +36,10 @@ class SourceFileTargetProducer(SingleOutputTargetProducer): # Can't import Lecture, TargetMedium due to circular dependency # noinspection PyUnresolvedReferences - def calculate_current_input_hash(self, lecture: "Lecture", input_media_by_id: dict[str, "TargetMedium"]) -> str: - return "0" * 64 - - # Can't import Lecture, TargetMedium due to circular dependency - # noinspection PyUnresolvedReferences - def create_new_target_media_and_job_data( - self, - session: SessionDb, - lecture: "Lecture", - input_media_by_id: dict[str, "TargetMedium"], - common_new_medium_kwargs: dict[str, Any] - ) -> tuple[list["TargetMedium"], tuple[str, JsonTypes] or None] or None: + def calculate_current_input_hash(self, + session: SessionDb, + lecture: "Lecture", + input_media_by_id: dict[str, "TargetMedium"]) -> [str, "SourceMedium"]: from videoag_common.objects import SourceMedium source_medium = session.scalar( SourceMedium.basic_select().where( @@ -58,6 +50,21 @@ class SourceFileTargetProducer(SingleOutputTargetProducer): .order_by(SourceMedium.update_time.desc()) .limit(1) ) + if source_medium is None: + return "0" * 64, None + return source_medium.sha256, source_medium + + # Can't import Lecture, TargetMedium due to circular dependency + # noinspection PyUnresolvedReferences + def create_new_target_media_and_job_data( + self, + session: SessionDb, + lecture: "Lecture", + input_media_by_id: dict[str, "TargetMedium"], + common_new_medium_kwargs: dict[str, Any], + source_medium: "SourceMedium", + ) -> tuple[list["TargetMedium"], tuple[str, JsonTypes] or None] or None: + from videoag_common.objects import SourceMedium, TargetMedium, TargetMediumType if source_medium is None: return None if source_medium.file_metadata is None: @@ -71,9 +78,11 @@ class SourceFileTargetProducer(SingleOutputTargetProducer): "file_path": source_medium.file_path, "is_produced": True, } - medium = TargetMedium(**kwargs) + medium_type = TargetMediumType(kwargs["type"]) + kwargs.pop("type") + target_medium = orm.class_mapper(TargetMedium).polymorphic_map[medium_type].class_(**kwargs) - return medium, None + return [target_medium], None class DownscaleVideoTarget(SingleInputTargetProducer): @@ -105,7 +114,8 @@ class DownscaleVideoTarget(SingleInputTargetProducer): session: SessionDb, lecture: "Lecture", input_media_by_id: dict[str, "TargetMedium"], - common_new_medium_kwargs: dict[str, Any] + common_new_medium_kwargs: dict[str, Any], + intermediate: None, ) -> tuple[list["TargetMedium"], tuple[str, JsonTypes] or None] or None: # TODO pass diff --git a/src/videoag_common/media_process/target.py b/src/videoag_common/media_process/target.py index b5f704920bdd8118f9021069c1cb71d6eb8fe9c4..4b2dc3d70b6950a7efe2ffea70c0907a6057f259 100644 --- a/src/videoag_common/media_process/target.py +++ b/src/videoag_common/media_process/target.py @@ -1,6 +1,6 @@ import re from abc import abstractmethod, ABC -from typing import Any +from typing import Any, TypeVar, Generic from videoag_common.miscellaneous import * from videoag_common.database import * @@ -8,8 +8,10 @@ from videoag_common.database import * TARGET_ID_PATTERN = re.compile("[a-zA-Z0-9_]{1,100}") TARGET_ID_MAX_LENGTH = 100 +_I = TypeVar("_I") -class TargetProducer: + +class TargetProducer(Generic[_I]): def __init__(self, **kwargs): if len(kwargs) > 0: @@ -49,7 +51,10 @@ class TargetProducer: # Can't import Lecture, TargetMedium due to circular dependency # noinspection PyUnresolvedReferences @abstractmethod - def calculate_current_input_hash(self, lecture: "Lecture", input_media_by_id: dict[str, "TargetMedium"]) -> str: + def calculate_current_input_hash(self, + session: SessionDb, + lecture: "Lecture", + input_media_by_id: dict[str, "TargetMedium"]) -> tuple[str, _I]: """ This is intended to be only called from the process scheduler job @@ -64,7 +69,8 @@ class TargetProducer: session: SessionDb, lecture: "Lecture", input_media_by_id: dict[str, "TargetMedium"], - common_new_medium_kwargs: dict[str, Any] + common_new_medium_kwargs: dict[str, Any], + intermediate: _I, ) -> tuple[list["TargetMedium"], tuple[str, JsonTypes] or None] or None: """ This is intended to be only called from the process scheduler job. @@ -85,11 +91,12 @@ class TargetProducer: :param input_media_by_id: Contains all the media this producer depends on :param common_new_medium_kwargs: Contains all the values required by all target media except the process_target_id (e.g. lecture id, process sha, etc.) + :param intermediate: The value returned by calculate_current_input_hash. May be used to prevent duplicate code """ pass -class SingleInputTargetProducer(TargetProducer, ABC): +class SingleInputTargetProducer(TargetProducer[None], ABC): def __init__(self, source_id: str, **kwargs): super().__init__(**kwargs) @@ -112,11 +119,14 @@ class SingleInputTargetProducer(TargetProducer, ABC): # Can't import Lecture, TargetMedium due to circular dependency # noinspection PyUnresolvedReferences - def calculate_current_input_hash(self, lecture: "Lecture", input_media_by_id: dict[str, "TargetMedium"]) -> str: - return input_media_by_id[self.source_id].input_data_sha256 + def calculate_current_input_hash(self, + session: SessionDb, + lecture: "Lecture", + input_media_by_id: dict[str, "TargetMedium"]) -> [str, None]: + return input_media_by_id[self.source_id].input_data_sha256, None -class SingleOutputTargetProducer(TargetProducer, ABC): +class SingleOutputTargetProducer(TargetProducer[_I], Generic[_I], ABC): def __init__(self, output_id: str, **kwargs): super().__init__(**kwargs)