Skip to content
Snippets Groups Projects
Select Git revision
  • 84f568a80926fef67d11e7e0fb3e8d193b591799
  • master default protected
  • postgres_integration
  • s3compatible
  • intros
  • bootstrap4
  • modules
7 results

server.py

Blame
  • 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"
            )
        )