Ejemplo n.º 1
0
class Post(SearchableMixin, db.Model):
    """docstring forProducts."""
    __tablename__ = 'posts'
    __searchable__ = ['describe', 'title']
    id = db.Column(db.Integer, primary_key=True)
    date_posted = db.Column(db.DateTime,
                            nullable=False,
                            default=datetime.utcnow())
    title = db.Column(db.String(50), nullable=False, index=True)
    describe = db.Column(db.String, nullable=False, index=True)
    picture = db.Column(db.String(20), nullable=False, default='default.png')
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    comments = db.relationship('Comment', backref='post', lazy='dynamic')
    report = db.relationship('Report', backref='report', lazy='dynamic')

    def __repr__(self):
        return f'''{[self.date_posted, self.title]}
                 '''

    def to_json(self):
        json_user = {
            'id': self.id,
            'Author': self.author.fullname,
            'title': self.title,
            'date_posted': self.date_posted,
            'picture': url_for('static', filename='postpics/' + self.picture),
            'describe': self.describe
        }
        return json_user
Ejemplo n.º 2
0
class Search(db.Model):
    __tablename__ = 'search'
    id = db.Column(db.Integer, primary_key=True)
    timestamp = db.Column(db.DateTime,
                          nullable=False,
                          default=datetime.utcnow())
    key_words = db.Column(db.String(50), nullable=False, index=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
Ejemplo n.º 3
0
class Notification(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), index=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    timestamp = db.Column(db.Float, index=True, default=time)
    payload_json = db.Column(db.Text)

    def get_data(self):
        return json.loads(str(self.payload_json))
Ejemplo n.º 4
0
class Message(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    sender_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    recipient_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)

    def __repr__(self):
        return f'Message: {self.body}'
Ejemplo n.º 5
0
class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    default = db.Column(db.Boolean, default=False, index=True)
    permissions = db.Column(db.Integer)
    users = db.relationship('User', backref='role', lazy='dynamic')

    def __init__(self, **kwargs):
        super(Role, self).__init__(**kwargs)
        if self.permissions is None:
            self.permissions = 0

    @staticmethod
    def insert_roles():
        roles = {
            'User': [Permission.FOLLOW, Permission.COMMENT, Permission.WRITE],
            'Moderator': [
                Permission.FOLLOW, Permission.COMMENT, Permission.WRITE,
                Permission.MODERATE
            ],
            'Administrator': [
                Permission.FOLLOW, Permission.COMMENT, Permission.WRITE,
                Permission.MODERATE, Permission.ADMIN
            ],
        }

        default_role = 'User'
        for r in roles:
            role = Role.query.filter_by(name=r).first()
            if role is None:
                role = Role(name=r)
            role.reset_permissions()
            for perm in roles[r]:
                role.add_permission(perm)
            role.default = (role.name == default_role)
            db.session.add(role)
        db.session.commit()

    def add_permission(self, perm):
        if not self.has_permission(perm):
            self.permissions += perm

    def remove_permission(self, perm):
        if self.has_permission(perm):
            self.permissions -= perm

    def reset_permissions(self):
        self.permissions = 0

    def has_permission(self, perm):
        return self.permissions & perm == perm

    def __repr__(self):
        return '<Role %r>' % self.name
Ejemplo n.º 6
0
class Report(db.Model):
    __tablename__ = 'reports'
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(50))
    #body_html = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))

    def __repr__(self):
        return f'''{self.timestamp, self.body}
Ejemplo n.º 7
0
class Comment(db.Model):
    __tablename__ = 'comments'
    #__searchable__ = ["body"]
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(50))
    #body_html = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    disabled = db.Column(db.Boolean)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))

    def __repr__(self):
        return f'''{self.timestamp, self.body}
Ejemplo n.º 8
0
class User(
        db.Model, UserMixin
):  #The users mixing class helps in user management. We inherit the "is_authenticated" method from here
    """docstring for ."""
    __tablename__ = 'users'
    #__searchable__ = ["fullname", "username", "about_me"]
    id = db.Column(db.Integer, primary_key=True)
    fullname = db.Column(db.String(100))
    username = db.Column(db.String(20), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    email = db.Column(db.String(120), unique=True, index=True)
    country = db.Column(db.String(200))
    #name = db.Column(db.String(64))
    about_me = db.Column(db.Text())
    member_since = db.Column(db.DateTime(), default=datetime.utcnow)
    last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
    image_file = db.Column(db.String(20), default='default.png')
    last_message_read_time = db.Column(db.DateTime)
    password = db.Column(db.String(60), nullable=False)
    comments = db.relationship('Comment', backref='author', lazy='dynamic')
    search = db.relationship('Search', backref='searcher', lazy='dynamic')
    Report = db.relationship('Report', backref='author', lazy='dynamic')
    Post = db.relationship('Post', backref='author', lazy='dynamic')
    notifications = db.relationship('Notification',
                                    backref='user',
                                    lazy='dynamic')
    followed = db.relationship(
        'Follow',
        foreign_keys=[
            Follow.follower_id
        ],  #SQLAlchemy cannot use the association table transparently because that will not give
        backref=db.backref(
            'follower', lazy='joined'
        ),  #the application access to the custom fields in it. Instead, the many-to-many relationship
        lazy=
        'dynamic',  #must be decomposed into the two basic one-to-many relationships for the left
        cascade='all, delete-orphan'
    )  #and right sides, and these must be defined as standard relationships.
    followers = db.relationship('Follow',
                                foreign_keys=[Follow.followed_id],
                                backref=db.backref('followed', lazy='joined'),
                                lazy='dynamic',
                                cascade='all, delete-orphan')
    messages_sent = db.relationship('Message',
                                    foreign_keys='Message.sender_id',
                                    backref='sender',
                                    lazy='dynamic')
    messages_received = db.relationship('Message',
                                        foreign_keys='Message.recipient_id',
                                        backref='recipient',
                                        lazy='dynamic')

    @staticmethod
    def add_self_follows():
        """
        Unfortunately, you likely have several users in the database who are already created
        and are not following themselves. If the database is small and easy to regenerate, then
        it can be deleted and re-created, but if that is not an option, then adding an update
        function that fixes existing users is the proper solution.
        """
        for user in User.query.all():
            if not user.is_following(user):
                user.follow(user)
                db.session.add(user)
                db.session.commit()

    def __init__(self, **kwargs):
        """
        When users register an account with the application, the correct role should be
        assigned to them. For most users, the role assigned at registration time will be the
        "User" role, as that is the role that is marked as a default. The only exception is made
        for the administrator, who needs to be assigned the "Administrator" role from the
        start. This user is identified by an email address stored in the FLASKY_ADMIN configuration
        variable, so as soon as that email address appears in a registration request it
        can be given the correct role.

        The User constructor first invokes the constructors of the base classes, and if after
        that the object does not have a role defined, it sets the administrator or default role
        depending on the email address.
        """
        super(User, self).__init__(**kwargs)
        if self.role is None:
            #if self.email == current_app.config['FLASKY_ADMIN']:
            #self.role = Role.query.filter_by(name='Administrator').first()
            if self.role is None:
                self.role = Role.query.filter_by(default=True).first()
        self.follow(
            self
        )  #Even though the queries are working as designed, most users will expect to see their
        #own posts when they are looking at those of their friends. The easiest way to address
        #this issue is to register all users as their own followers at the time they are created.


#To simplify the implementation of roles and permissions, a helper method can be
#added to the User model that checks whether users have a given permission in the
#role they have been assigned. The implementation simply defers to the role methods
#added previously.
#can() and is_administrator()

    def new_messages(self):
        last_read_time = self.last_message_read_time or datetime(1900, 1, 1)
        return Message.query.filter_by(recipient=self).filter(
            Message.timestamp > last_read_time).count()

    def can(self, perm):
        """
        This method added to the User model returns True if the requested permission
        is present in the role, which means that the user should be allowed to perform the
        requested task.
        """
        return self.role is not None and self.role.has_permission(perm)

    def is_administrator(self):
        return self.can(Permission.ADMIN)

    def get_reset_token(self, expires_sec=1800):
        s = Serializer(current_app.config['SECRET_KEY'], expires_sec)
        return s.dumps({'user_id': self.id}).decode('utf-8')

    @staticmethod
    def verify_reset_token(token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            user_id = s.loads(token)['user_id']
        except:
            return None
        return User.query.get(user_id)

    def ping(self):
        """
        The last_seen field is also initialized to the current time upon creation, but it needs
        to be refreshed each time the user accesses the site. A method in the User class can be
        added to perform this update.
        """
        self.last_seen = datetime.utcnow()
        db.session.add(self)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password1):
        return check_password_hash(self.password, password1)

    def get_reset_password_token(self, expires_in=600):
        return jwt.encode(
            {
                'reset_password': self.id,
                'exp': time() + expires_in
            },
            current_app.config['SECRET_KEY'],
            algorithm='HS256').decode('utf-8')

    staticmethod

    def verify_reset_password_token(token):
        try:
            id = jwt.decode(token,
                            current_app.config['SECRET_KEY'],
                            algorithms=['HS256'])['reset_password']
        except:
            return
        return User.query.get(id)

    def follow(self, user):
        if not self.is_following(user):
            f = Follow(follower=self, followed=user)
            db.session.add(f)

    def unfollow(self, user):
        f = self.followed.filter_by(followed_id=user.id).first()
        if f:
            db.session.delete(f)

    def is_following(self, user):
        if user.id is None:
            return False
        return self.followed.filter_by(followed_id=user.id).first() is not None

    def is_followed_by(self, user):
        if user.id is None:
            return False
        return self.followers.filter_by(
            follower_id=user.id).first() is not None

    def add_notification(self, name, data):
        self.notifications.filter_by(name=name).delete()
        n = Notification(name=name, payload_json=json.dumps(data), user=self)
        db.session.add(n)
        return n

    @property
    def followed_posts(self):
        """This will return all posts of followings user"""
        return Post.query.join(Follow, Follow.followed_id == Post.user_id)\
            .filter(Follow.follower_id == self.id)

    def __repr__(self):
        return f'User: {self.username}'