Select Git revision
Forked from
Video AG Infrastruktur / website
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
site.py 6.67 KiB
from datetime import datetime
from enum import Enum
from typing import Any
from videoag_common.miscellaneous import *
from videoag_common.database import *
from videoag_common.api_object import *
from .course import Course, Lecture
class AnnouncementType(JsonSerializableEnum):
INFO = "info"
WARNING = "warning"
IMPORTANT = "important"
class AnnouncementPageVisibility(JsonSerializableEnum):
ONLY_MAIN_PAGE = "only_main_page"
ALL_PAGES = "all_pages"
ALL_PAGES_AND_EMBED = "all_pages_and_embed"
ANNOUNCEMENT_TYPE_ENUM = create_enum_type(AnnouncementType)
ANNOUNCEMENT_PAGE_VISIBILITY_ENUM = create_enum_type(AnnouncementPageVisibility)
class Announcement(DeletableApiObject, VisibilityApiObject, Base):
type: Mapped[AnnouncementType] = api_mapped(
mapped_column(ANNOUNCEMENT_TYPE_ENUM, nullable=False),
ApiEnumField(
include_in_config=True,
include_in_data=True
)
)
page_visibility: Mapped[AnnouncementPageVisibility] = api_mapped(
mapped_column(ANNOUNCEMENT_PAGE_VISIBILITY_ENUM, nullable=False),
ApiEnumField(
include_in_config=True,
include_in_data=True
)
)
text: Mapped[str] = api_mapped(
mapped_column(Text(collation=STRING_COLLATION), nullable=False, default=""),
ApiStringField(
max_length=8192,
include_in_config=True, config_directly_modifiable=True,
include_in_data=True
)
)
publish_time: Mapped[datetime] = api_mapped(
mapped_column(UTCTimestamp(), nullable=True),
ApiDatetimeField(
include_in_config=True,
include_in_data=True, data_only_mod=True
)
)
expiration_time: Mapped[datetime] = api_mapped(
mapped_column(UTCTimestamp(), nullable=True),
ApiDatetimeField(
include_in_config=True,
include_in_data=True, data_only_mod=True
)
)
@hybrid_method
def has_access(self, context: dict[AccessContextKey, Any]):
cond = super().has_access(context)
if not AC_IS_MOD.get(context):
current_time = get_standard_datetime_now()
cond &= self.hybrid_is_none(self.publish_time) | (self.publish_time <= current_time)
cond &= self.hybrid_is_none(self.expiration_time) | (self.expiration_time > current_time)
return cond
class FeaturedType(Enum):
PLAIN = "plain"
IMAGE = "image"
COURSE = "course"
LECTURE = "lecture"
FEATURED_TYPE_ENUM = create_enum_type(FeaturedType)
class Featured(DeletableApiObject, VisibilityApiObject, Base):
__mapper_args__ = {
"polymorphic_on": "type",
"with_polymorphic": "*", # Always load all attributes for all types,
"polymorphic_identity": FeaturedType.PLAIN
}
__table_args__ = (
CheckConstraint(
f"type NOT IN ('image') OR image_url IS NOT NULL",
name="check_image_set"
),
CheckConstraint(
f"type NOT IN ('course') OR course_id IS NOT NULL",
name="check_course_id_set"
),
CheckConstraint(
f"type NOT IN ('lecture') OR lecture_id IS NOT NULL",
name="check_lecture_id_set"
),
)
title: Mapped[str] = api_mapped(
mapped_column(Text(collation=STRING_COLLATION), nullable=False, default=""),
ApiStringField(
max_length=1024,
include_in_config=True, config_directly_modifiable=True,
include_in_data=True
)
)
text: Mapped[str] = api_mapped(
mapped_column(Text(collation=STRING_COLLATION), nullable=False, default=""),
ApiStringField(
max_length=8192,
include_in_config=True, config_directly_modifiable=True,
include_in_data=True
)
)
type: Mapped[FeaturedType] = api_mapped(
mapped_column(FEATURED_TYPE_ENUM, nullable=False, default=FeaturedType.PLAIN),
ApiEnumField(
include_in_config=True, config_only_at_creation=True,
include_in_data=True, data_notes="Specifies the variant"
)
)
display_priority: Mapped[int] = api_mapped(
mapped_column(nullable=False, default=0),
ApiIntegerField(
unique=True,
include_in_config=True, config_directly_modifiable=True,
include_in_data=True, data_only_mod=True,
data_notes="Smallest value is at top. If the order is the same, the lower id is higher"
)
)
class ImageFeatured(Featured):
__tablename__ = None # Prevent our own base from adding a table name. This should be a single-table inheritance
__mapper_args__ = {
"polymorphic_identity": FeaturedType.IMAGE
}
image_url: Mapped[str] = api_mapped(
mapped_column(Text(collation=STRING_COLLATION), nullable=True, default=""), # Nullable because of single-table inheritance
ApiStringField(
max_length=8192, may_be_none=False,
include_in_config=True,
include_in_data=True
)
)
class CourseFeatured(Featured):
__tablename__ = None # Prevent our own base from adding a table name. This should be a single-table inheritance
__mapper_args__ = {
"polymorphic_identity": FeaturedType.COURSE
}
course_id: Mapped[int] = mapped_column(ForeignKey("course.id"), nullable=True) # Nullable because of single-table inheritance
course: Mapped[Course] = api_mapped(
relationship(
primaryjoin=lambda: Course.id == CourseFeatured.course_id,
lazy="raise_on_sql"
),
Api2OneRelationshipField(
may_be_none=False,
include_in_config=True,
include_in_data=True, data_foreign_in_context=True,
data_notes="May be null (deleted/not visible). Does not include lectures",
)
)
class LectureFeatured(Featured):
__tablename__ = None # Prevent our own base from adding a table name. This should be a single-table inheritance
__mapper_args__ = {
"polymorphic_identity": FeaturedType.LECTURE
}
lecture_id: Mapped[int] = mapped_column(ForeignKey("lecture.id"), nullable=True) # Nullable because of single-table inheritance
lecture: Mapped[Lecture] = api_mapped(
relationship(
# orm.foreign() marks OUR column with the relevant ForeignKey
primaryjoin=lambda: Lecture.id == LectureFeatured.lecture_id,
lazy="raise_on_sql"
),
Api2OneRelationshipField(
may_be_none=False,
include_in_config=True,
include_in_data=True,
data_notes="May be null (deleted/not visible). Does not include chapters and media_sources"
)
)