示例#1
0
class Grade(Serializable, db.Model):
    __tablename__ = 'grades'

    course_id = db.Column('course_id', db.Integer, primary_key=True)
    assignment_id = db.Column('assignment_id', db.Integer, primary_key=True)
    grade_component_id = db.Column('grade_component_id',
                                   db.Unicode,
                                   primary_key=True)
    team_id = db.Column('team_id', db.Integer, primary_key=True)

    points = db.Column(db.Float, nullable=False)

    grade_component = db.relationship('GradeComponent')
    team = db.relationship('AssignmentsTeams', backref="grades")

    default_fields = ['points', 'grade_component_id']
    readonly_fields = ['course_id', 'team_id', 'grade_component']

    __table_args__ = (db.ForeignKeyConstraint(
        [team_id, assignment_id, course_id], [
            AssignmentsTeams.team_id, AssignmentsTeams.assignment_id,
            AssignmentsTeams.course_id
        ]),
                      db.ForeignKeyConstraint(
                          [grade_component_id, assignment_id, course_id], [
                              GradeComponent.id, GradeComponent.assignment_id,
                              GradeComponent.course_id
                          ]), {})
示例#2
0
class Course(ExposedModel, Serializable):
    __tablename__ = 'courses'
    id = db.Column(db.Unicode, primary_key=True, unique=True)
    name = db.Column(db.Unicode)
    options = db.Column(JSONEncodedDict, default={})
    graders = association_proxy('courses_graders', 'grader')
    students = association_proxy('courses_students', 'student')
    instructors = association_proxy('courses_instructors', 'instructor')
    assignments = db.relationship("Assignment", backref="course")
    teams = db.relationship("Team", backref="course")
    default_fields = ['name', 'assignments', 'options']
    readonly_fields = ['id', 'options', 'graders', 'students', 'instructors',
                       'assignments', 'teams']
    
    @staticmethod
    def from_id(course_id):
        return Course.query.filter_by(id=course_id).first()
示例#3
0
class CoursesInstructors(Serializable, db.Model):
    __tablename__ = 'courses_instructors'
    repo_info = db.Column(JSONEncodedDict, default={})
    instructor_id = db.Column('instructor_id',
                              db.Unicode,
                              db.ForeignKey('users.id'),
                              primary_key=True)
    course_id = db.Column('course_id',
                          db.Integer,
                          db.ForeignKey('courses.id'),
                          primary_key=True)
    instructor = db.relationship("User")
    default_fields = ['instructor', 'repo_info']
    readonly_fields = ['instructor_id', 'course_id', 'repo_info']    
    course = db.relationship("Course",
                             backref=db.backref("courses_instructors",
                                                cascade="all, delete-orphan"))
示例#4
0
class AssignmentsTeams(Serializable, db.Model):
    __tablename__ = 'assignments_teams'

    assignment_id = db.Column('assignment_id', db.Integer, primary_key=True)
    team_id = db.Column('team_id', db.Unicode, primary_key=True)
    course_id = db.Column('course_id', db.Integer, primary_key=True)

    extensions_used = db.Column(db.Integer, default=0)
    commit_sha = db.Column(db.Unicode)
    submitted_at = db.Column(UTCDateTime)
    grader_id = db.Column('grader_id', db.Integer, db.ForeignKey('users.id'))
    penalties = db.Column(JSONEncodedDict, default={})

    team = db.relationship("Team",
                           backref=db.backref("assignments_teams",
                                              cascade="all, delete-orphan"))
    assignment = db.relationship("Assignment")
    grader = db.relationship("User")

    default_fields = [
        'extensions_used', 'commit_sha', 'submitted_at', 'assignment_id',
        'grades', 'penalties', 'grader'
    ]
    readonly_fields = ['team', 'grader', 'grades']
    __table_args__ = (db.ForeignKeyConstraint([team_id, course_id],
                                              [Team.id, Team.course_id]),
                      db.ForeignKeyConstraint(
                          [assignment_id, course_id],
                          ["assignments.id", "assignments.course_id"]), {})

    @staticmethod
    def from_id(course_id, team_id, assignment_id):
        return AssignmentsTeams.query.filter_by(
            course_id=course_id, team_id=team_id,
            assignment_id=assignment_id).first()

    def get_grade(self, gc_id):
        grades = [g for g in self.grades if g.grade_component_id == gc_id]
        if len(grades) == 0:
            return None
        else:
            return grades[0]

    def is_ready_for_grading(self):
        if self.submitted_at is None:
            return False
        else:
            now = get_datetime_now_utc()
            deadline = self.assignment.deadline + timedelta(
                days=self.extensions_used)

            if now > deadline:
                return True
            else:
                return False
示例#5
0
class StudentsTeams(Serializable, db.Model):
    STATUS_UNCONFIRMED = 0
    STATUS_CONFIRMED = 1

    __tablename__ = 'students_teams'
    status = db.Column(db.Integer, nullable=False, server_default='0')
    student_id = db.Column('student_id',
                           db.Unicode,
                           db.ForeignKey('users.id'),
                           primary_key=True)
    team_id = db.Column('team_id', db.Integer, primary_key=True)
    course_id = db.Column('course_id', db.Integer, primary_key=True)
    student = db.relationship("User")
    default_fields = ['status', 'student']
    readonly_fields = ['student', 'team']
    team = db.relationship("Team",
                           backref=db.backref("students_teams",
                                              cascade="all, delete-orphan"))
    __table_args__ = (db.ForeignKeyConstraint([team_id, course_id],
                                              [Team.id, Team.course_id]), {})
示例#6
0
class Assignment(Serializable):
    __tablename__ = 'assignments'
    id = db.Column(db.Unicode, primary_key=True)
    course_id = db.Column('course_id',
                          db.Integer,
                          db.ForeignKey('courses.id'),
                          primary_key=True)

    name = db.Column(db.Unicode)
    deadline = db.Column(UTCDateTime)
    grade_components = db.relationship("GradeComponent", backref="assignment")

    default_fields = [
        'id', 'name', 'deadline', 'course_id', 'grade_components'
    ]
    readonly_fields = ['id', 'grade_components', 'course_id']

    @staticmethod
    def from_id(course_id, assignment_id):
        return Assignment.query.filter_by(id=assignment_id,
                                          course_id=course_id).first()
示例#7
0
class CoursesStudents(Serializable, db.Model):
    __tablename__ = 'courses_students'
    repo_info = db.Column(JSONEncodedDict, default={})
    dropped = db.Column('dropped', db.Boolean, server_default='0',
                        nullable=False)
    extensions = db.Column(db.Integer, default=0)    

    student_id = db.Column('student_id',
                           db.Unicode,
                           db.ForeignKey('users.id'),
                           primary_key=True)
    course_id = db.Column('course_id',
                          db.Integer,
                          db.ForeignKey('courses.id'),
                          primary_key=True)
    student = db.relationship("User")
    default_fields = ['student', 'dropped', 'repo_info']
    readonly_fields = ['student_id', 'course_id', 'repo_info']    
    course = db.relationship("Course",
                             backref=db.backref("courses_students",
                                                cascade="all, delete-orphan"))

    @staticmethod
    def from_id(course_id, student_id):
        return CoursesStudents.query.filter_by(student_id=student_id, course_id=course_id).first()

    def get_extensions_available(self):
        from chisubmit.backend.webapp.api.teams.models import Team

        extensions_used = 0
        
        student_teams = Team.find_teams_with_students(self.course_id, [self.student])
        for student_team in student_teams:
            for assignment_team in student_team.assignments_teams:
                extensions_used += assignment_team.extensions_used

        return self.extensions - extensions_used
示例#8
0
class Team(Serializable, db.Model):
    __tablename__ = 'teams'
    id = db.Column(db.Unicode, primary_key=True)
    extensions = db.Column(db.Integer, default=0)
    repo_info = db.Column(JSONEncodedDict, default={})
    extras = db.Column(JSONEncodedDict, default={})
    active = db.Column('active',
                       db.Boolean,
                       server_default='1',
                       nullable=False)
    course_id = db.Column('course_id',
                          db.Integer,
                          db.ForeignKey('courses.id'),
                          primary_key=True)
    students = association_proxy('students_teams', 'student')
    assignments = association_proxy('assignments_teams', 'assignment')

    default_fields = [
        'extensions', 'repo_info', 'active', 'course_id', 'extras',
        'students_teams', 'assignments_teams', 'grades'
    ]
    readonly_fields = ['students', 'assignments', 'grades', 'extras']

    @staticmethod
    def from_id(course_id, team_id):
        return Team.query.filter_by(course_id=course_id, id=team_id).first()

    @staticmethod
    def find_teams_with_students(course_id, students):
        q = Team.query.filter(
            Team.course_id == course_id,
            Team.students.any(
                StudentsTeams.student_id.in_([s.id for s in students])))

        return q.all()

    def get_extensions_used(self):
        extensions = 0
        for at in self.assignments_teams:
            extensions += at.extensions_used
        return extensions

    def get_extensions_available(self, extension_policy):
        from chisubmit.backend.webapp.api.courses.models import CoursesStudents

        if extension_policy == "per_team":
            return self.extensions - self.get_extensions_used()
        elif extension_policy == "per_student":
            student_extensions_available = []
            for student in self.students:
                cs = CoursesStudents.from_id(self.course_id, student.id)
                a = cs.get_extensions_available()
                student_extensions_available.append(a)
            return min(student_extensions_available)
        else:
            return 0
示例#9
0
class GradeComponent(Serializable, db.Model):
    __tablename__ = 'grade_components'
    id = db.Column(db.Unicode, primary_key=True)
    course_id = db.Column('course_id', db.Integer, primary_key=True)
    assignment_id = db.Column('assignment_id', db.Integer, primary_key=True)

    order = db.Column(db.Integer)
    description = db.Column(db.Unicode)
    points = db.Column('points', db.Float)

    default_fields = ['id', 'description', 'order', 'points', 'assignment_id']
    readonly_fields = ['id', 'course_id', 'assignment_id']

    __table_args__ = (db.ForeignKeyConstraint(
        [assignment_id, course_id], [Assignment.id, Assignment.course_id]), {})
示例#10
0
class User(UniqueModel, Serializable, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Unicode, primary_key=True)
    first_name = db.Column(db.Unicode)
    last_name = db.Column(db.Unicode)
    email = db.Column(db.Unicode)
    api_key = db.Column(db.Unicode)
    admin = db.Column('admin', db.Boolean, server_default='0', nullable=False)
    default_fields = ['id', 'first_name', 'last_name', 'email']
    readonly_fields = ['id']

    @classmethod
    def unique_hash(cls, **kws):
        return kws['id']

    @classmethod
    def unique_filter(cls, query, **kws):
        return query.filter(User.id == kws['id'])

    @staticmethod
    def from_id(user_id):
        return User.query.filter_by(id=user_id).first()

    def is_instructor_in(self, course):
        return self in course.instructors

    def is_student_in(self, course):
        return self in course.students

    def is_grader_in(self, course):
        return self in course.graders

    def has_instructor_or_grader_permissions(self, course):
        return self.is_instructor_in(course) or self.is_grader_in(
            course) or self.admin

    def is_in_course(self, course):
        return self.is_instructor_in(course) or self.is_student_in(
            course) or self.is_grader_in(course)