def assignment_queues(cid, aid): courses, current_course = get_courses(cid) assignment = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none() if not Assignment.can(assignment, current_user, 'grade'): flash('Insufficient permissions', 'error') return abort(401) queues = GradingTask.get_staff_tasks(assignment.id) incomplete = [q.grader.email for q in queues if q.completed != q.total] complete = [q.grader.email for q in queues if q.completed == q.total] mailto_link = "mailto://{0}?subject={1}&body={2}&cc={3}".format( current_user.email, "{0} grading queue is not finished".format(assignment.display_name), "Queue Link: {0}".format(url_for('admin.grading_tasks', _external=True)), ','.join(incomplete) ) remaining = len(incomplete) percent_left = (1-(remaining/max(1, len(queues)))) * 100 if current_user.email in incomplete: flash("Hmm... You aren't finished with your queue.", 'info') elif current_user.email in complete: flash("Nice! You are all done with your queue", 'success') else: flash("You don't have a queue for this assignment", 'info') return render_template('staff/grading/overview.html', courses=courses, current_course=current_course, assignment=assignment, queues=queues, incomplete=incomplete, mailto=mailto_link, remaining=remaining, percent_left=percent_left)
def test_queue_generation(self): students, backups, no_submissions = self._course_submissions_ids(self.assignment) tasks = GradingTask.create_staff_tasks(backups, self.active_staff, self.assignment.id, self.assignment.course.id, "Composition") self.assertEquals(len(tasks), 2) self.assertEquals([t.grader.id for t in tasks], [self.staff1.id, self.staff2.id]) # When only_unassigned is true, it should not add any new backups tasks = GradingTask.create_staff_tasks(backups, self.active_staff, self.assignment.id, self.assignment.course.id, "Composition", True) self.assertEquals(len(tasks), 0)
def test_queue_generation(self): students, backups, no_submissions = self._course_submissions_ids(self.assignment) tasks = GradingTask.create_staff_tasks(backups, self.active_staff, self.assignment.id, self.assignment.course.id, "Composition") self.assertEquals(len(tasks), 2) self.assertEquals([t.grader.id for t in tasks], [self.staff1.id, self.staff2.id]) # All backups have been assigned, so should not add any new backups tasks = GradingTask.create_staff_tasks(backups, self.active_staff, self.assignment.id, self.assignment.course.id, "Composition") self.assertEquals(len(tasks), 0)
def test_queue_generation(self): students, backups, no_submissions = self.assignment.course_submissions() tasks = GradingTask.create_staff_tasks(backups, self.active_staff, self.assignment.id, self.assignment.course.id, "Composition") self.assertEquals(len(tasks), 2) self.assertEquals([t.grader.id for t in tasks], [self.staff1.id, self.staff2.id]) # When only_unassigned is true, it should not add any new backups tasks = GradingTask.create_staff_tasks(backups, self.active_staff, self.assignment.id, self.assignment.course.id, "Composition", True) self.assertEquals(len(tasks), 0)
def gen_queue(backup, grader): created = datetime.datetime.now() - datetime.timedelta( minutes=random.randrange(100)) return GradingTask(created=created, backup=backup, assignment=backup.assignment, course=backup.assignment.course, grader=grader)
def assign_grading(cid, aid): courses, current_course = get_courses(cid) assign = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none() if not assign or not Assignment.can(assign, current_user, 'grade'): flash('Cannot access assignment', 'error') return abort(404) form = forms.CreateTaskForm() course_staff = sorted(current_course.get_staff(), key=lambda x: x.role) details = lambda e: "{0} - ({1})".format(e.user.email, e.role) form.staff.choices = [(utils.encode_id(e.user_id), details(e)) for e in course_staff] if not form.staff.data: # Select all by default form.staff.default = [u[0] for u in form.staff.choices] form.process() if form.validate_on_submit(): # TODO: Use worker job for this (this is query intensive) selected_users = [] for hash_id in form.staff.data: user = User.get_by_id(utils.decode_id(hash_id)) if user and user.is_enrolled(cid, roles=STAFF_ROLES): selected_users.append(user) # Available backups data = assign.course_submissions() backups = set(b['backup']['id'] for b in data if b['backup']) students = set(b['user']['id'] for b in data if b['backup']) no_submissions = set(b['user']['id'] for b in data if not b['backup']) tasks = GradingTask.create_staff_tasks(backups, selected_users, aid, cid, form.kind.data, form.only_unassigned.data) num_with_submissions = len(students) - len(no_submissions) flash(("Created {0} tasks ({1} students) for {2} staff.".format( len(tasks), num_with_submissions, len(selected_users))), "success") return redirect(url_for('.assignment', cid=cid, aid=aid)) # Return template with options for who has to grade. return render_template('staff/grading/assign_tasks.html', current_course=current_course, assignment=assign, form=form)
def assign_grading(cid, aid): courses, current_course = get_courses(cid) assign = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none() if not assign or not Assignment.can(assign, current_user, 'grade'): flash('Cannot access assignment', 'error') return abort(404) form = forms.CreateTaskForm() course_staff = sorted(current_course.get_staff(), key=lambda x: x.role) details = lambda e: "{0} - ({1})".format(e.user.email, e.role) form.staff.choices = [(utils.encode_id(e.user_id), details(e)) for e in course_staff] if not form.staff.data: # Select all by default form.staff.default = [u[0] for u in form.staff.choices] form.process() if form.validate_on_submit(): # TODO: Use worker job for this (this is query intensive) selected_users = [] for hash_id in form.staff.data: user = User.get_by_id(utils.decode_id(hash_id)) if user and user.is_enrolled(cid, roles=STAFF_ROLES): selected_users.append(user) # Available backups: students, backups, no_submissions = assign.course_submissions() tasks = GradingTask.create_staff_tasks(backups, selected_users, aid, cid, form.kind.data, form.only_unassigned.data) num_with_submissions = len(students) - len(no_submissions) flash(("Created {0} tasks ({1} students) for {2} staff." .format(len(tasks), num_with_submissions, len(selected_users))), "success") return redirect(url_for('.assignment', cid=cid, aid=aid)) # Return template with options for who has to grade. return render_template('staff/grading/assign_tasks.html', current_course=current_course, assignment=assign, form=form)