Beispiel #1
0
class Comment(db.Model):
    N = 3

    id = db.Column(db.Integer, primary_key=True)
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    content = db.Column(db.String(256))
    timestamp = db.Column(db.DateTime(), default=datetime.utcnow, index=True)
    path = db.Column(db.Text, index=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('comment.id'))
    replies = db.relationship('Comment',
                              backref=db.backref('parent', remote_side=[id]),
                              lazy='dynamic')

    def save(self):
        db.session.add(self)
        db.session.commit()
        prefix = self.parent.path + '.' if self.parent else ''
        self.path = prefix + '{:0{}d}'.format(self.id, self._N)
        db.session.commit()

    def level(self):
        return len(self.path) // self._N - 1

    def __repr__(self):
        return f"Comment('{self.timestamp}')"
Beispiel #2
0
class Download(db.Model):
    __bind_key__ = 'sb_db'

    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.DateTime())
    version = db.Column(db.String(64))
    build = db.Column(db.String(64))
Beispiel #3
0
class Review(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    movie_id = db.Column(db.String(20), nullable=False)
    title = db.Column(db.String(50), nullable=False)
    data = db.Column(db.Text, nullable=False)
    date = db.Column(db.DateTime(timezone=True), default=datetime.now())
    rating = db.Column(db.String(70), nullable=False)
    spoiler_tag = db.Column(db.Boolean)
Beispiel #4
0
class Download(db.Model):
    __bind_key__ = 'sb_db'

    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.DateTime())
    version = db.Column(db.String(64))
    build = db.Column(db.String(64))
    location_info = db.Column(db.String(256))
    user_agent = db.Column(db.String(256))
Beispiel #5
0
class Note(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    data = db.Column(db.String(10000))
    date = db.Column(db.DateTime(timezone=True), default=func.now())
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
Beispiel #6
0
class Comment(db.Model):  # type: ignore
    __tablename__ = "comments"

    id = db.Column(db.Integer(), primary_key=True)
    body = db.Column(db.String(200), nullable=False)
    path = db.Column(db.Text(), index=True)

    created_at = db.Column(
        db.DateTime(timezone=True),
        server_default=sql.func.current_timestamp(),
        nullable=False,
    )
    updated_at = db.Column(
        db.DateTime(timezone=True),
        onupdate=sql.func.current_timestamp(),
    )
    thread_at = db.Column(
        db.DateTime(timezone=True),
        server_default=sql.func.current_timestamp(),
        nullable=False,
    )

    replies = db.relationship(
        "Comment",
        cascade="all, delete",
        backref=db.backref("parent", remote_side=[id]),
        lazy="dynamic",
    )

    author_id = db.Column(db.Integer(), db.ForeignKey("accounts.id"))
    blog_id = db.Column(db.Integer(),
                        db.ForeignKey("blogs.id"),
                        nullable=False)
    parent_id = db.Column(db.Integer(), db.ForeignKey("comments.id"))

    def __repr__(self):
        return f"<Comment {self.id} - {self.body}>"

    # Factories

    @classmethod
    def new(
        cls,
        *,
        body: str,
        author: Any,
        blog: Any,
        parent: Optional[Any] = None,
        thread_at: Optional[datetime.datetime] = None,
    ):
        # TODO: Make this a transaction
        comment = cls(
            body=body,
            author=author,
            blog=blog,
            parent=parent,
            thread_at=thread_at,
        )
        db.session.add(comment)
        db.session.commit()
        comment.updated_at = None
        prefix = f"{comment.parent.path}." if comment.parent else ""
        comment.path = prefix + "{:0{}d}".format(comment.id, NUMBER_OF_DIGITS)
        db.session.commit()
        return comment

    # Mutators

    def update(self, **kwargs):
        """
        Update Comment.
        """
        allowed_attributes = [
            "body",
            "author",
        ]
        for key, value in kwargs.items():
            assert key in allowed_attributes
            setattr(self, key, value)
        db.session.commit()

    def delete(self):
        """
        Delete Comment.
        """
        db.session.delete(self)
        db.session.commit()

    # Properties

    @property
    def level(self):
        return len(self.path) // NUMBER_OF_DIGITS - 1
Beispiel #7
0
class Category(db.Model):  # type: ignore
    __tablename__ = "categories"

    id = db.Column(db.Integer(), primary_key=True)
    title = db.Column(db.String(100), index=True, unique=True, nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False)
    description = db.Column(db.String(150), nullable=False)

    created_at = db.Column(
        db.DateTime(timezone=True),
        server_default=sql.func.current_timestamp(),
        nullable=False,
    )
    updated_at = db.Column(db.DateTime(timezone=True),
                           onupdate=sql.func.current_timestamp())

    blogs = db.relationship("Blog",
                            secondary=association_table,
                            backref="categories")

    def __repr__(self):
        return f"<Category {self.title}>"

    @classmethod
    def new(
        cls,
        title: str,
        slug: str,
        description: str,
    ):
        """
        Create a new Category in the database.

        Returns a Category.
        """
        category = cls(
            title=title,
            slug=slug,
            description=description,
        )

        db.session.add(category)
        db.session.commit()

        return category

    # Mutators

    def update(self, **kwargs):
        """
        Update Category.
        """
        allowed_attributes = ["title", "description"]
        for key, value in kwargs.items():
            assert key in allowed_attributes
            setattr(self, key, value)
        db.session.commit()

    def delete(self):
        """
        Delete Category.
        """
        db.session.delete(self)
        db.session.commit()
Beispiel #8
0
class Blog(db.Model):  # type: ignore
    __tablename__ = "blogs"

    id = db.Column(db.Integer(), primary_key=True)
    title = db.Column(db.String(100), index=True, nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False)
    description = db.Column(db.String(150))
    body = db.Column(db.Text(), nullable=False)

    published = db.Column(db.Boolean(), nullable=False, default=False)
    comment = db.Column(db.Boolean(), nullable=False, default=False)

    created_at = db.Column(
        db.DateTime(timezone=True),
        server_default=sql.func.current_timestamp(),
        nullable=False,
    )
    updated_at = db.Column(db.DateTime(timezone=True),
                           onupdate=sql.func.current_timestamp())

    author_id = db.Column(db.Integer(),
                          db.ForeignKey("accounts.id"),
                          nullable=True)
    comments = db.relationship("Comment",
                               cascade="all, delete",
                               backref="blog",
                               lazy=True)

    def __repr__(self):
        return f"<Blog {self.title}>"

    # TODO: We need to prevent blank values.
    # @orm.validates("title")
    # def validate(self, key, value):
    #     assert value
    #     return value

    # Factories

    @classmethod
    def new(
        cls,
        title: str,
        slug: str,
        body: str,
        author: Any,
        description: Optional[str] = None,
        categories: Optional[List[Any]] = None,
        published: bool = False,
        comment: bool = False,
    ):
        """
        Create a new Blog in the database.

        Returns a Blog.
        """
        blog = cls(
            title=title,
            slug=slug,
            description=description,
            body=body,
            author=author,
            published=published,
            comment=comment,
        )

        if categories:
            blog.categories = categories

        db.session.add(blog)
        db.session.commit()

        return blog

    # Mutators

    def update(self, **kwargs):
        """
        Update Blog.
        """
        allowed_attributes = [
            "title",
            "description",
            "body",
            "author",
            "categories",
            "published",
            "comment",
        ]
        for key, value in kwargs.items():
            assert key in allowed_attributes
            setattr(self, key, value)
        db.session.commit()

    def delete(self):
        """
        Delete Blog.
        """
        db.session.delete(self)
        db.session.commit()

    # Properties

    @property
    def is_published(self) -> bool:
        return self.published
Beispiel #9
0
class Note(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    data = db.Column(db.String(10000))
    date = db.Column(db.DateTime(timezone=True), default=func.now())
    # here database name should be in lowercase
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
Beispiel #10
0
class Account(db.Model, flask_login.UserMixin):  # type: ignore
    __tablename__ = "accounts"

    id = db.Column(db.Integer(), primary_key=True)
    username = db.Column(db.String(64),
                         index=True,
                         unique=True,
                         nullable=False)
    display = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(120), index=True, unique=True, nullable=False)
    password = db.Column(db.String(255), nullable=False)
    about = db.Column(db.String(300))

    # Authorisation statuses.
    admin = db.Column(db.Boolean(),
                      nullable=False,
                      default=False,
                      server_default="0")
    confirmed = db.Column(db.Boolean(), nullable=False, default=False)

    created_at = db.Column(
        db.DateTime(timezone=True),
        server_default=sql.func.current_timestamp(),
        nullable=False,
    )
    updated_at = db.Column(db.DateTime(timezone=True),
                           onupdate=sql.func.current_timestamp())
    seen_at = db.Column(db.DateTime(timezone=True),
                        onupdate=sql.func.current_timestamp())

    blogs = db.relationship("Blog", backref="author", lazy=True)
    comments = db.relationship("Comment", backref="author", lazy=True)

    def __repr__(self):
        return f"<Account {self.username}>"

    @login.user_loader
    def load_account(account_id):
        return Account.query.get(ident=int(account_id))

    @classmethod
    def new(
        cls,
        username: str,
        display: str,
        email: str,
        password: str,
        admin: bool = False,
        confirmed: bool = False,
    ):
        """
        Create a new Account in the database.

        Password is hashed before being saved to the database.

        Returns an Account.
        """
        hashed_password = cls._hash_password(password=password)
        account = cls(
            username=username,
            display=display if display else username,
            email=email,
            password=hashed_password,
            admin=admin,
            confirmed=confirmed,
        )

        db.session.add(account)
        db.session.commit()

        return account

    # Mutators

    def update(self, **kwargs):
        """
        Update Account.
        """
        allowed_attributes = [
            "username",
            "display",
            "email",
            "password",
            "about",
            "admin",
            "confirmed",
            "seen_at",
        ]
        for key, value in kwargs.items():
            assert key in allowed_attributes
            if key == "display":
                if not value:
                    value = self.username
            if key == "password":
                value = Account._hash_password(password=value)
            setattr(self, key, value)
        db.session.commit()

    def delete(self, delete_blogs: bool = False):
        """
        Delete Account.

        Params:
            - `delete_blogs` whether the blogs associated to the Account should
                be deleted. If set to `False`, the blogs will instead be
                transferred to the default Account.
        """
        # TODO: Make this an atomic transaction - i.e. all-or-nothing.
        for blog in self.blogs:
            if delete_blogs:
                blog.delete()
            else:
                blog.update(author=None)
        db.session.delete(self)
        db.session.commit()

    def check_password(self, password: str) -> bool:
        """
        Check the password against saved hashed password.
        """
        return security.check_password_hash(pwhash=self.password,
                                            password=password)

    # Properties

    @property
    def is_admin(self) -> bool:
        return self.admin

    @property
    def is_confirmed(self) -> bool:
        if flask.current_app.config["ACCOUNT_ALWAYS_CONFIRMED"]:
            return True
        return self.confirmed

    # Queries

    # Private

    @classmethod
    def _hash_password(cls, password: str) -> str:
        """
        Return hashed password.
        """
        return security.generate_password_hash(password=password)