From fc812c4ec79cf0e57fcba8ec7a478a89e6502fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=BCnzel?= <simonk@fsmpi.rwth-aachen.de> Date: Thu, 10 Oct 2024 23:03:01 +0200 Subject: [PATCH] Add more fields to target media --- src/videoag_common/objects/medium.py | 104 ++++++++++++++++++++------- 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/src/videoag_common/objects/medium.py b/src/videoag_common/objects/medium.py index 1bb0af1..c79916e 100644 --- a/src/videoag_common/objects/medium.py +++ b/src/videoag_common/objects/medium.py @@ -67,6 +67,21 @@ class SourceMedium(DeletableApiObject, Base): data_notes="Only calculated once this is sorted" ) ) + file_size: Mapped[int] = api_mapped( + mapped_column(sql.types.BigInteger, nullable=True), + ApiIntegerField( + include_in_data=True, + data_notes="Only calculated once this is sorted" + ) + ) + metadata: Mapped[JsonTypes] = api_mapped( + mapped_column(sql.JSON, nullable=True), + ApiDataField( + include_in_data=True, + # See source file sorter for contents + data_notes="Only calculated once this is sorted. There are no guarantees regarding the content" + ) + ) tag: Mapped[str] = mapped_column(String(collation=STRING_COLLATION), nullable=True) lecture: Mapped[Lecture] = relationship( @@ -105,7 +120,6 @@ class TargetMedium(DeletableApiObject, Base): producer_job_id: Mapped[int] = mapped_column(ForeignKey("job.id"), nullable=True) is_produced: Mapped[bool] = mapped_column(nullable=False, default=False) to_be_replaced: Mapped[bool] = mapped_column(nullable=False, default=False) - file_path: Mapped[str] = mapped_column(String(collation=STRING_COLLATION), nullable=True, index=True) # TODO move? type: Mapped[TargetMediumType] = api_mapped( mapped_column(_TARGET_MEDIUM_TYPE_ENUM, nullable=False), ApiEnumField( @@ -127,19 +141,6 @@ class TargetMedium(DeletableApiObject, Base): lazy="raise_on_sql" ) - @api_include_in_data( - type_id="string", - data_notes="URL to the mediums's file (Maybe with a redirect)" - ) - def url(self) -> str: - # This is not too nice and only works from the API, but we need to access the API config - import api - return f"{api.config['API_BASE_URL']}/resources/target_medium/{self.id}" - - def get_default_file_path_no_ending(self): - # TODO path - return f"{self.process_target_id}.{self.id}" - @hybrid_method def is_active(self, usable_check: bool = True, from_lecture: bool = False, from_publish_medium: bool = False, **kwargs): cond = super().is_active(**kwargs) @@ -194,32 +195,61 @@ class TargetMedium(DeletableApiObject, Base): return options -# Note that this usually also includes audio -class PlainVideoTargetMedium(TargetMedium): - __tablename__ = None # Prevent our own base from adding a table name. This should be a single-table inheritance - __mapper_args__ = { - "polymorphic_identity": TargetMediumType.PLAIN_VIDEO - } +class FileTargetMedium(TargetMedium): + file_path: Mapped[str] = mapped_column(String(collation=STRING_COLLATION), nullable=True, index=True) # TODO move? + + @api_include_in_data( + type_id="string", + data_notes="URL to the mediums's file (Maybe with a redirect)" + ) + def url(self) -> str: + # This is not too nice and only works from the API, but we need to access the API config + import api + return f"{api.config['API_BASE_URL']}/resources/target_medium/{self.id}" - vertical_resolution: Mapped[int] = api_mapped( + def get_default_file_path_no_ending(self): + # TODO path + return f"{self.process_target_id}.{self.id}" + + +class SingleAudioContainingMedium(TargetMedium): + + audio_sample_rate: Mapped[int] = api_mapped( + mapped_column(nullable=True), + ApiIntegerField( + include_in_data=True, + help="In Hz" + ) + ) + audio_channel_count: Mapped[int] = api_mapped( + mapped_column(nullable=True), + ApiIntegerField( + include_in_data=True + ) + ) + + +class SingleVideoContainingMedium(TargetMedium): + + video_vertical_resolution: Mapped[int] = api_mapped( mapped_column(nullable=True), ApiIntegerField( include_in_data=True ) ) - horizontal_resolution: Mapped[int] = api_mapped( + video_horizontal_resolution: Mapped[int] = api_mapped( mapped_column(nullable=True), ApiIntegerField( include_in_data=True ) ) - frame_rate_numerator: Mapped[int] = api_mapped( + video_frame_rate_numerator: Mapped[int] = api_mapped( mapped_column(nullable=True), ApiIntegerField( include_in_data=True ) ) - frame_rate_denominator: Mapped[int] = api_mapped( + video_frame_rate_denominator: Mapped[int] = api_mapped( mapped_column(nullable=True), ApiIntegerField( include_in_data=True @@ -227,14 +257,36 @@ class PlainVideoTargetMedium(TargetMedium): ) -class PlainAudioTargetMedium(TargetMedium): +class PlainVideoTargetMedium(FileTargetMedium, SingleVideoContainingMedium, SingleAudioContainingMedium): + __tablename__ = None # Prevent our own base from adding a table name. This should be a single-table inheritance + __mapper_args__ = { + "polymorphic_identity": TargetMediumType.PLAIN_VIDEO + } + + duration_sec: Mapped[int] = api_mapped( + mapped_column(nullable=True), + ApiIntegerField( + include_in_data=True + ) + ) + # TODO check vars not null (except audio) + + +class PlainAudioTargetMedium(FileTargetMedium, SingleAudioContainingMedium): __tablename__ = None # Prevent our own base from adding a table name. This should be a single-table inheritance __mapper_args__ = { "polymorphic_identity": TargetMediumType.PLAIN_AUDIO } + + duration_sec: Mapped[int] = api_mapped( + mapped_column(nullable=True), + ApiIntegerField( + include_in_data=True + ) + ) -class ThumbnailTargetMedium(TargetMedium): +class ThumbnailTargetMedium(FileTargetMedium): __tablename__ = None # Prevent our own base from adding a table name. This should be a single-table inheritance __mapper_args__ = { "polymorphic_identity": TargetMediumType.THUMBNAIL -- GitLab