Beispiel #1
0
import datetime as dt
import uuid
from sqlalchemy_utils import UUIDType
from PEC.database import db, CRUDMixin
from .attributes import Status as Status_
from PEC.user.models import Skill
from . import MAX_LENGTH_TITLE, MAX_LENGTH_DESCRIPTION
"""Relation table mapping project preferred skill attributes"""
skills_projects = db.Table(
    'skills_projects',
    db.Column('projects_id', db.Integer(), db.ForeignKey('projects.id')),
    db.Column('skills_id', db.Integer(), db.ForeignKey('skills.id')))
"""Relation table mapping project ownership"""
users_projects = db.Table(
    'users_projects',
    db.Column('projects_id', db.Integer(), db.ForeignKey('projects.id')),
    db.Column('users_id', db.Integer(), db.ForeignKey('users.id')))


class Project(CRUDMixin, db.Model):
    __tablename__ = 'projects'
    id = db.Column(db.Integer(), primary_key=True)
    github_id = db.Column(db.Integer(), unique=True, nullable=True)
    uuid = db.Column(UUIDType(),
                     nullable=False,
                     unique=True,
                     index=True,
                     default=uuid.uuid4)
    title = db.Column(db.String(MAX_LENGTH_TITLE), nullable=False)
    description = db.Column(db.String(MAX_LENGTH_DESCRIPTION), nullable=False)
    created_at = db.Column(db.DateTime,
Beispiel #2
0
class Project(CRUDMixin, db.Model):
    __tablename__ = 'projects'
    id = db.Column(db.Integer(), primary_key=True)
    github_id = db.Column(db.Integer(), unique=True, nullable=True)
    uuid = db.Column(UUIDType(),
                     nullable=False,
                     unique=True,
                     index=True,
                     default=uuid.uuid4)
    title = db.Column(db.String(MAX_LENGTH_TITLE), nullable=False)
    description = db.Column(db.String(MAX_LENGTH_DESCRIPTION), nullable=False)
    created_at = db.Column(db.DateTime,
                           nullable=False,
                           default=dt.datetime.utcnow)
    status = db.Column(db.Enum(Status_), nullable=False)
    contributors = db.relationship('User',
                                   secondary=users_projects,
                                   backref=db.backref('contribution_projects',
                                                      lazy='dynamic'))
    pref_skills = db.relationship('Skill',
                                  secondary=skills_projects,
                                  backref=db.backref('projects',
                                                     lazy='dynamic'))
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)

    @classmethod
    def from_project_form(cls, form, validate=False):
        """ Creates and returns a project object from a NewProjectForm

        :param form: PEC.project.forms.NewProjectForm
        :param validate: Whether the form should be validated before creating object, default False
        :return: Project object or None if validation fails
        """
        if validate:
            if not form.validate():
                return None
        project = cls()
        project.title = form.title.data
        project.description = form.description.data
        return project

    def mark_proposal(self, commit=True):
        """ Changes project status to Proposal #TODO Project status

        :param commit: Change to be committed to database, defaults to True
        :return:
        """
        self.update(status=Status_.proposal, commit=commit)

    def mark_development(self, commit=True):
        """ Changes project status to Development #TODO Project status

        :param commit: Changes to be committed to database, defaults to True
        :return:
        """
        self.update(status=Status_.development, commit=commit)

    def add_pref_skills(self, *args):
        """ Adds given user skill attributes to the list or preferred skills in the project
        Valid skills enumerated in PEC.user.attributes.Skill

        Usage:
            project.add_pref_skills('HTML', 'CSS')

            skills_to_add = ['HTML', 'CSS']
            project.add_pref_skills(*skills_to_add)

        :param args: Skills (as strings)
        :raises KeyError if invalid skill provided
        :return: None
        """
        for skill in args:
            skill_ = Skill.get(name=skill)
            if skill_ not in self.pref_skills:
                self.pref_skills.append(skill_)

    def has_pref_skills(self, *args):
        """ Checks if project contains all given preferred skills
        Valid skills enumerated in PEC.user.attributes.Skill

        Usage:
            if project.has_pref_skills('HTML', 'CSS'):
                print('The project prefers HTML and CSS skills')

            skills_to_check = ['HTML', 'CSS']
            if project.has_pref_skill(*skills_to_check):
                print('The project prefers HTML and CSS skills')

        :param args: PEC.user.attributes.Skill
        :raises KeyError if invalid skill provided
        :return: True if ALL skills are preferred, False otherwise
        """
        for skill in args:
            skill_ = Skill.get(name=skill)
            if skill_ not in self.pref_skills:
                return False
        return True

    def __repr__(self):
        return '<Project {}>'.format(self.uuid)
Beispiel #3
0
class User(UserMixin, CRUDMixin, BaseModel):

    __tablename__ = 'users'
    uuid = db.Column(UUIDType(), nullable=False, unique=True, index=True, default=uuid.uuid4)
    email = db.Column(db.String(80), index=True, unique=True)
    password = db.Column(db.String(128))
    active = db.Column(db.Boolean(), default=False)
    first_name = db.Column(db.String(30), nullable=True)
    last_name = db.Column(db.String(30), nullable=True)
    github_id = db.Column(db.Integer(), unique=True, index=True)
    created_at = db.Column(db.DateTime, nullable=False, default=dt.datetime.utcnow())
    last_login_at = db.Column(db.DateTime)
    projects = db.relationship('Project', backref='user', lazy=True)
    roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic'))
    courses = db.relationship('Course', secondary=courses_users, backref=db.backref('users', lazy='dynamic'))
    skills = db.relationship('Skill', secondary=skills_users, backref=db.backref('users', lazy='dynamic'))

    # Preserve **kwargs for Model constructor
    def __init__(self, email, password=None, **kwargs):
        db.Model.__init__(self, email=email, **kwargs)
        if password:
            self.set_password(password)
        else:
            self.password = None

    @classmethod
    def from_register_form(cls, form, validate=False):
        """ Creates a User object based on a regsitration form

        :param form: PEC.public.forms.RegisterForm
        :param validate: Whether form should be validated before creating object, defaults to False
        :return: User object or None is validation fails
        """
        if validate:
            if not form.validate():
                return None
        user = cls(form.email.data, form.password.data)
        user.first_name = form.first_name.data
        user.last_name = form.last_name.data
        return user

    @classmethod
    def exists(cls, **kwargs):
        """ Checks if user with given values exists in the database

        Usage:
            if User.exists(first_name='Joe', last_name='Smith'):
                print('Account with name Joe Smith exists!')

        :return: True if user exists, False otherwise
        """
        if not kwargs:
            return False
        u = cls.query.filter_by(**kwargs).first()
        if u is None:
            return False
        return True

    def avatar(self, size):
        """ Generates a link to a Gravatar profile image

        :param size: Size of avatar image
        :return: URL to gravatar image
        """
        digest = md5(self.email.lower().encode('utf-8')).hexdigest()
        return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format(digest, size)

    def add_skill(self, *args):
        """ Adds skill attributes to user.
        Valid skills are enumerated in PEC.user.attributes.Skill

        Usage:
            user.add_skill('HTML')
            user.add_skill('REACT', 'PERL', 'PHOTOSHOP')

            skills_to_add = ['HTML', 'FLASK', 'JAVASCRIPT', 'CSS']
            user.add_skill(*skills_to_add)

        :param args: Skills (as strings) to add
        :raises KeyError if invalid skill provided
        :return:
        """
        for skill_name in args:
            skill_ = Skill.get(name=Skill_[skill_name])
            if skill_ not in self.skills:
                self.skills.append(skill_)

    def has_skill(self, *args):
        """ Checks if user has all provided skills.
        Valid skills are enumerated in PEC.user.attributes.Skill

        Usage:
            if user.has_skill('HTML'):
                print('User knows HTML')

            if user.has_skill('REACT', 'PERL', 'PHOTOSHOP'):
                print('User knows React, Perl, and Photoshop')

            skills_to_check = ['HTML', 'FLASK', 'JAVASCRIPT', 'CSS']
            if user.has_skill(*skills_to_check):
                print('User knows HTML, Flask, Javascript, and CSS')


        :param args: Skills (as strings) to check
        :raises KeyError if invalid skill provided
        :return: True if user has all provided skills, False otherwise
        """
        for skill_name in args:
            skill_ = Skill.get(name=Skill_[skill_name])
            if skill_ not in self.skills:
                return False
        return True

    def add_course(self, *args):
        """ Adds course attributes to user.
        Valid courses are enumerated in PEC.user.attributes.Course

        Usage:
            user.add_course('CS111')
            user.add_course('CS141', 'CS151', 'CS211')

            courses_to_add = ['CS251', 'CS261', 'CS301', 'CS341']
            user.add_course(*courses_to_add)

        :param args: Courses (as strings) to add
        :raises KeyError if invalid course provided
        :return:
        """
        for course_name in args:
            course_ = Course.get(name=Course_[course_name])
            if course_ not in self.courses:
                self.courses.append(course_)

    def has_course(self, *args):
        """ Checks if user has all provided courses.
        Valid courses are enumerated in PEC.user.attributes.Course

        Usage:
            if user.has_course('CS111'):
                print('User has taken CS111')
            if user.has_course('CS141', 'CS151', 'CS211'):
                print('User has taken CS141, CS151, and CS211')

            courses_to_check = ['CS251', 'CS261', 'CS301', 'CS341']
            if user.has_course(*courses_to_check):
                print('User has taken CS251, CS261, CS301, and CS341')

        :param args: Skills (as strings) to check
        :raises KeyError if invalid skill provided
        :return: True if user has all provided skills, False otherwise
        """
        for course_name in args:
            course_ = Course.get(name=Course_[course_name])
            if course_ not in self.courses:
                return False
        return True

    def add_role(self, *args):
        """ Adds role attribute to user
        Valid roles are enumerated in PEC.user.attributes.Role

        Usage:
            user.add_role('USER')
            user.add_role('USER', 'MODERATOR')

        :param args: Roles (as strings) to add
        :return:
        """
        for role_name in args:
            role_ = Role.get(name=Role_[role_name])
            self.roles.append(role_)

    def has_role(self, *args):
        """ Checks if user has all provided roles
        Valid roles are enumerated in PEC.user.attributes.Role

        Usage:
            if user.has_role('USER'):
                print('User has User role')
            if user.has_role('USER', 'MODERATOR'):
                print('User has User and Moderator role')

        :param args: Roles (as strings) to check
        :return: True if user has all provided roles, False otherwise
        """
        for role_name in args:
            role_ = Role.get(name=Role_[role_name])
            if role_ not in self.roles:
                return False
        return True

    def set_password(self, password):
        """ Sets the user password

        Usage:
            user.set_password('strongpassword123')

        :param password: String
        :return:
        """
        self.password = generate_password_hash(password)

    def check_password(self, password):
        """ Compares given password against the hashed password

        Usage:
            if user.check_password('strongpassword123'):
                print('Correct password!')

        :param password: String
        :return: True if password is correct, False otherwise
        """
        return check_password_hash(self.password, password)

    def __repr__(self):
        return '<User {}>'.format(self.email)
Beispiel #4
0
class Skill(UserAttributeModel):
    __tablename__ = 'skills'
    name = db.Column(db.Enum(Skill_))
Beispiel #5
0
class Course(UserAttributeModel):
    __tablename__ = 'courses'
    name = db.Column(db.Enum(Course_))
Beispiel #6
0
class Role(UserAttributeModel):
    __tablename__ = 'roles'
    name = db.Column(db.Enum(Role_))
Beispiel #7
0
import datetime as dt
import uuid
from hashlib import md5
from flask_login import UserMixin
from sqlalchemy_utils import UUIDType
from werkzeug.security import generate_password_hash, check_password_hash
from PEC.database import db, CRUDMixin, UserAttributeModel, BaseModel
from PEC.extensions import login_manager
from .attributes import Course as Course_
from .attributes import Skill as Skill_
from .attributes import Role as Role_


"""Relation table mapping users to roles"""
roles_users = db.Table('roles_users',
                       db.Column('users_id', db.Integer(), db.ForeignKey('users.id')),
                       db.Column('roles_id', db.Integer(), db.ForeignKey('roles.id'))
                       )


class Role(UserAttributeModel):
    __tablename__ = 'roles'
    name = db.Column(db.Enum(Role_))


"""Relation table mapping users to their chosen course attributes"""
courses_users = db.Table('courses_users',
                         db.Column('users_id', db.Integer(), db.ForeignKey('users.id')),
                         db.Column('courses_id', db.Integer(), db.ForeignKey('courses.id'))
                         )