Example #1
0
class UserTag(db.Model):
    """Many to many relation between User and Tag.

    Uses the 'association object pattern' to be able to save extra data
    in the associations.
    """
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    tag_id = db.Column(db.Integer, db.ForeignKey('tag.id'), primary_key=True)

    user = db.relationship('User', back_populates='tags')
    tag = db.relationship('Tag', back_populates='users')

    start = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    end = db.Column(db.DateTime)

    @hybrid_property
    def is_active(self):
        now = datetime.utcnow()

        has_started = (self.start <= now)
        not_ended = self.end.is_(None) | (now < self.end)

        return has_started & not_ended

    def end_association(self):
        self.end = datetime.utcnow()

    def __str__(self):
        return "UserTag({}/{})".format(self.user, self.tag)
Example #2
0
class Tag(db.Model):
    """Representation of a tag."""
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True, nullable=False)

    users = db.relationship('UserTag', back_populates='tag')

    def __str__(self):
        """String representation of the tag."""
        return self.name
Example #3
0
class Score(db.Model):
    """A score/sheet music."""
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    composer = db.Column(db.String(50))
    lyricist = db.Column(db.String(50))
    arrangement = db.Column(db.String(50))
    amount = db.Column(db.Integer)
    place = db.Column(db.String(50))
    comments = db.Column(db.Text())
    collection_id = db.Column(db.Integer, db.ForeignKey('score_collection.id'))
Example #4
0
class User(UserMixin, db.Model):
    """A representation of a user.

    An email address cannot be longer than 254 characters:
    http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690
    """
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(254), unique=True)
    first_name = db.Column(db.String(50), nullable=False)
    last_name = db.Column(db.String(50), nullable=False)
    phone = db.Column(db.String(20))

    # Do not change the following directly, use User.password
    _password = db.Column(db.String(128))
    _password_timestamp = db.Column(db.DateTime)

    tags = db.relationship('UserTag',
                           cascade="all,delete",
                           back_populates='user')

    def __init__(self, *args, **kwargs):
        if 'password' not in kwargs:
            password = ''.join(
                random.choice(string.ascii_letters + string.digits)
                for _ in range(30))
            kwargs['password'] = password

        super().__init__(*args, **kwargs)

    @hybrid_property
    def password(self):
        """Return password hash."""
        return self._password

    @password.setter
    def password(self, plaintext):
        """Generate and save password hash, update password timestamp."""
        self._password = bcrypt.generate_password_hash(plaintext)

        # Save in UTC, password resets compare this to UTC time!
        self._password_timestamp = datetime.utcnow()

    def verify_password(self, plaintext):
        """Return True if plaintext matches password, else return False."""
        return bcrypt.check_password_hash(self._password, plaintext)

    @property
    def active_tags(self):
        return [
            user_tag.tag for user_tag in UserTag.query.filter(
                UserTag.user == self, UserTag.is_active == True)
        ]

    @hybrid_method
    def has_tag(self, *tags, active=True):
        """Return True if User instance has at least one of tags."""
        has_tag = UserTag.query.filter(UserTag.user == self,
                                       UserTag.tag.has(Tag.name.in_(tags)),
                                       UserTag.is_active == active).scalar()

        return has_tag

    @has_tag.expression
    def has_tag(self, *tags, active=True):
        """Return an Exists with all Users that has at least one of tags."""
        return self.tags.any(UserTag.tag.has(Tag.name.in_(tags)),
                             is_active=active)

    @staticmethod
    def authenticate(email, password):
        """Check email and password and return user if matching.

        It might be tempting to return the user that mathes the email
        and a boolean representing if the password was correct, but
        please don't. The email alone does not identify a user, only
        the email toghether with a matching password is enough to
        identify which user we want! No matching email and password ->
        no user.
        """
        user = User.query.filter_by(email=email).first()

        if user and user.verify_password(password):
            return user

        return None

    def __str__(self):
        """String representation of the user."""
        return "{} {}".format(self.first_name, self.last_name)
Example #5
0
class ScoreCollection(db.Model):
    """A collection of scores."""
    id = db.Column(db.Integer, primary_key=True)
    scores = db.relationship('Score', backref='collection')