Skip to content

Forum Database #456

Open
Open
@wabscale

Description

@wabscale

I feel like we can basically go off this. The one thing im iffy about is if we should have a circular primary key on the Comment table.

class ForumPost(db.Model):
    __tablename__ = "forum_post"
    __table_args__ = {"mysql_charset": DB_CHARSET, "mysql_collate": DB_COLLATION}

    id = default_id()

    owner_id: str = Column(String(length=default_id_length), ForeignKey(User.id), nullable=False)
    course_id: str = Column(String(length=default_id_length), ForeignKey(Course.id))
    visible_to_students: bool = Column(Boolean, default=False)
    pinned: bool = Column(Boolean, default=False)
    anonymous: bool = Column(Boolean, default=False)
    seen_count: int = Column(Integer, default=0)

    # Content
    title = Column(Text(length=1024))
    content = deferred(Column(Text(length=2 ** 14)))

    # Timestamps
    created: datetime = Column(DateTime, default=datetime.now)
    last_updated: datetime = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    comments = relationship("ForumPostComment", cascade="all,delete", backref="post")
    in_categories = relationship("ForumPostInCategory", cascade="all,delete", backref="post")
    views = relationship("ForumPostViewed", cascade="all,delete", backref="post")
    upvotes = relationship("ForumPostUpvote", cascade="all,delete", backref="post")

    @property
    def meta_data(self):
        return {
            "id":                  self.id,
            "title":               self.title,
            "anonymous":           self.anonymous,
            "display_name":        "Anonymous" if self.anonymous else self.owner.name,
            "course_id":           self.course_id,
            "visible_to_students": self.visible_to_students,
            "pinned":              self.pinned,
            "seen_count":          self.seen_count,
            "created":             str(self.created),
            "last_updated":        str(self.last_updated),
        }

    @property
    def data(self):
        from anubis.lms.forum import get_post_comments_data

        data = self.meta_data
        data["title"] = self.title
        data["content"] = self.content
        data["comments"] = get_post_comments_data(self)
        return data

    @property
    def admin_data(self):
        data = self.data
        data["display_name"] = self.owner.name
        return data


class ForumCategory(db.Model):
    __tablename__ = "forum_category"
    __table_args__ = {"mysql_charset": DB_CHARSET, "mysql_collate": DB_COLLATION}

    id = default_id()

    name: str = Column(String(length=128))
    course_id: str = Column(String(length=default_id_length), ForeignKey(Course.id))

    # Timestamps
    created: datetime = Column(DateTime, default=datetime.now)
    last_updated: datetime = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    in_category = relationship("ForumPostInCategory", cascade="all,delete", backref="category")

    @property
    def data(self):
        return {
            "id":           self.id,
            "name":         self.name,
            "course_id":    self.course_id,
            "created":      str(self.created),
            "last_updated": str(self.last_updated),
        }


class ForumPostInCategory(db.Model):
    __tablename__ = "forum_post_in_category"
    __table_args__ = {"mysql_charset": DB_CHARSET, "mysql_collate": DB_COLLATION}

    post_id: str = Column(String(length=default_id_length), ForeignKey(ForumPost.id), primary_key=True)
    category_id: str = Column(String(length=default_id_length), ForeignKey(ForumCategory.id), primary_key=True)

    # Timestamps
    created: datetime = Column(DateTime, default=datetime.now)
    last_updated: datetime = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    @property
    def data(self):
        return {
            "post_id":      self.post_id,
            "category_id":  self.category_id,
            "created":      str(self.created),
            "last_updated": str(self.last_updated),
        }


class ForumPostViewed(db.Model):
    __tablename__ = "forum_post_viewed"
    __table_args__ = {"mysql_charset": DB_CHARSET, "mysql_collate": DB_COLLATION}

    owner_id: str = Column(String(length=default_id_length), ForeignKey(User.id), primary_key=True)
    post_id: str = Column(String(length=default_id_length), ForeignKey(ForumPost.id), primary_key=True)

    # Timestamps
    created: datetime = Column(DateTime, default=datetime.now)
    last_updated: datetime = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    @property
    def data(self):
        return {
            "owner_id":     self.owner_id,
            "post_id":      self.post_id,
            "created":      str(self.created),
            "last_updated": str(self.last_updated),
        }


class ForumPostComment(db.Model):
    __tablename__ = "forum_post_comment"
    __table_args__ = {"mysql_charset": DB_CHARSET, "mysql_collate": DB_COLLATION}

    id = default_id()

    owner_id: str = Column(String(length=default_id_length), ForeignKey(User.id), nullable=False)
    post_id: str = Column(String(length=default_id_length), ForeignKey(ForumPost.id), nullable=False)
    parent_id: str = Column(String(length=default_id_length), nullable=True)
    approved_by_id: str = Column(String(length=default_id_length), ForeignKey(User.id), nullable=True)
    anonymous: bool = Column(Boolean, default=False)
    thread_start: bool = Column(Boolean, default=False)

    content: str = deferred(Column(Text(length=2 ** 12)))

    # Timestamps
    created: datetime = Column(DateTime, default=datetime.now)
    last_updated: datetime = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    @property
    def meta_data(self):
        return {
            "id":           self.id,
            "anonymous":    self.anonymous,
            "display_name": "Anonymous" if self.anonymous else self.owner.name,
            "post_id":      self.post_id,
            "parent_id":    self.parent_id,
            "approved_by":  self.approved_by.name if self.approved_by_id is not None else None,
            "thread_start": self.thread_start,
            "created":      str(self.created),
            "last_updated": str(self.last_updated),
        }

    @property
    def data(self):
        data = self.meta_data
        data["content"] = self.content
        return data

    @property
    def admin_data(self):
        data = self.data
        data["display_name"] = self.owner.name
        return data


class ForumPostUpvote(db.Model):
    __tablename__ = "forum_post_upvote"
    __table_args__ = {"mysql_charset": DB_CHARSET, "mysql_collate": DB_COLLATION}

    id = default_id()

    owner_id: str = Column(String(length=default_id_length), ForeignKey(User.id), primary_key=True)
    post_id: str = Column(String(length=default_id_length), ForeignKey(ForumPost.id), primary_key=True)

    # Timestamps
    created: datetime = Column(DateTime, default=datetime.now)
    last_updated: datetime = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    @property
    def data(self):
        return {
            "owner_id":     self.owner_id,
            "post_id":      self.post_id,
            "created":      str(self.created),
            "last_updated": str(self.last_updated),
        }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    • Status

      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions