def make_backup(self, grading=None, attempts=None, submit=False, time=None): """ Create a Backup with specific message info. ``grading`` is a string where each character is a grade for a question: 'c' - correct 'p' - passed at least one testcase 'f' - failed ' ' - omitted ``attempts`` is a string where each character is the number of attempts for a question: '#' - number of attempts ' ' - omitted ``submit`` where the Backup is a submission """ grading = grading or '' attempts = attempts or '' custom_time = time or dt.datetime.utcnow() messages = { 'grading': { q: { 'failed': 0 if result == 'c' else 1, 'locked': 0 if result == 'c' else 1, 'passed': 1 if result == 'p' else 0 } for q, result in enumerate(grading) if result != ' ' }, 'analytics': { 'history': { 'questions': { q: { 'solved': result == 'c', 'attempts': int(n) if n != ' ' else 0 } for q, (result, n) in enumerate( zip_longest(grading, attempts, fillvalue=' ')) if not (result == ' ' and n == ' ') } } } } backup = api.make_backup(self.user1, self.assignment.id, messages, submit) backup.created = custom_time db.session.commit() return backup
def submit_assignment(name): assign = get_assignment(name) group = Group.lookup(current_user, assign) user_ids = assign.active_user_ids(current_user.id) fs = assign.final_submission(user_ids) if not assign.uploads_enabled: flash("This assignment cannot be submitted online", 'warning') return redirect(url_for('.assignment', name=assign.name)) if not assign.active: flash("It's too late to submit this assignment", 'warning') return redirect(url_for('.assignment', name=assign.name)) form = UploadSubmissionForm() if form.validate_on_submit(): files = request.files.getlist("upload_files") if files: templates = assign.files messages = {'file_contents': {}} for upload in files: data = upload.read() if len(data) > 2097152: # File is too large (over 2 MB) flash("{} is over the maximum file size limit of 2MB".format(upload.filename), 'danger') return redirect(url_for('.submit_assignment', name=assign.name)) messages['file_contents'][upload.filename] = str(data, 'latin1') if templates: missing = [] for template in templates: if template not in messages['file_contents']: missing.append(template) if missing: flash(("Missing files: {}. The following files are required: {}" .format(', '.join(missing), ', '.join([t for t in templates])) ), 'danger') return redirect(url_for('.submit_assignment', name=assign.name)) backup = make_backup(current_user, assign.id, messages, True) if form.flag_submission.data: assign.flag(backup.id, user_ids) if assign.autograding_key: try: submit_continous(backup) except ValueError as e: logger.warning('Web submission did not autograde', exc_info=True) flash('Did not send to autograder: {}'.format(e), 'warning') flash("Uploaded submission (ID: {})".format(backup.hashid), 'success') return redirect(url_for('.assignment', name=assign.name)) return render_template('student/assignment/submit.html', assignment=assign, group=group, course=assign.course, form=form)
def test_extension_after_backups(self): """ Backups from before the extension was made should use the extension time instead of the submission time. """ now = dt.datetime.utcnow() self.assignment.due_date = now - dt.timedelta(hours=1) # Make a late backup backup = api.make_backup(self.user1, self.assignment.id, messages={}, submit=True) self.assertFalse(backup.submission_time <= self.assignment.due_date) # After an extension, backup should no longer be late early = now - dt.timedelta(days=1) ext = self._make_ext(self.assignment, self.user1, custom_time=early) self.assertTrue(backup.submission_time <= self.assignment.due_date)
def staff_submit_backup(cid, email, aid): assign = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none() if not assign or not Assignment.can(assign, current_user, 'grade'): return abort(404) result_page = url_for('.student_assignment_detail', cid=cid, email=email, aid=aid) student = User.lookup(email) if not student: abort(404) user_ids = assign.active_user_ids(student.id) # TODO: DRY - Unify with student upload code - should just be a function form = forms.UploadSubmissionForm() if form.validate_on_submit(): files = request.files.getlist("upload_files") if files: templates = assign.files messages = {'file_contents': {}} for upload in files: data = upload.read() if len(data) > 2097152: # File is too large (over 2 MB) flash(("{} is over the maximum file size limit of 2MB" .format(upload.filename)), 'danger') return redirect(result_page) messages['file_contents'][upload.filename] = str(data, 'latin1') if templates: missing = [] for template in templates: if template not in messages['file_contents']: missing.append(template) if missing: flash(("Missing files: {}. The following files are required: {}" .format(', '.join(missing), ', '.join([t for t in templates])) ), 'danger') return redirect(result_page) # use student, not current_user backup = ok_api.make_backup(student, assign.id, messages, True) if form.flag_submission.data: assign.flag(backup.id, user_ids) if assign.autograding_key: try: submit_continous(backup) except ValueError as e: flash('Did not send to autograder: {}'.format(e), 'warning') flash("Uploaded submission (ID: {})".format(backup.hashid), 'success') return redirect(result_page)
def make_backup(self, grading=None, attempts=None, submit=False, time=None): """ Create a Backup with specific message info. ``grading`` is a string where each character is a grade for a question: 'c' - correct 'p' - passed at least one testcase 'f' - failed ' ' - omitted ``attempts`` is a string where each character is the number of attempts for a question: '#' - number of attempts ' ' - omitted ``submit`` where the Backup is a submission """ grading = grading or '' attempts = attempts or '' custom_time = time or dt.datetime.utcnow() messages = { 'grading': { q: { 'failed': 0 if result == 'c' else 1, 'locked': 0 if result == 'c' else 1, 'passed': 1 if result == 'p' else 0 } for q, result in enumerate(grading) if result != ' ' }, 'analytics': { 'history': { 'questions': { q: { 'solved': result == 'c', 'attempts': int(n) if n != ' ' else 0 } for q, (result, n) in enumerate(zip_longest(grading, attempts, fillvalue=' ')) if not (result == ' ' and n == ' ') } } } } backup = api.make_backup(self.user1, self.assignment.id, messages, submit) backup.created = custom_time db.session.commit() return backup
def submit_assignment(name): assign = get_assignment(name) group = Group.lookup(current_user, assign) user_ids = assign.active_user_ids(current_user.id) fs = assign.final_submission(user_ids) if not assign.uploads_enabled: flash("This assignment cannot be submitted online", 'warning') return redirect(url_for('.assignment', name=assign.name)) if not assign.active: flash("It's too late to submit this assignment", 'warning') return redirect(url_for('.assignment', name=assign.name)) form = UploadSubmissionForm() if form.validate_on_submit(): files = request.files.getlist("upload_files") if files: templates = assign.files messages = {'file_contents': {}} for upload in files: data = upload.read() if len(data) > 2097152: # File is too large (over 2 MB) flash( "{} is over the maximum file size limit of 2MB".format( upload.filename), 'danger') return redirect( url_for('.submit_assignment', name=assign.name)) messages['file_contents'][upload.filename] = str( data, 'latin1') if templates: missing = [] for template in templates: if template not in messages['file_contents']: missing.append(template) if missing: flash(( "Missing files: {}. The following files are required: {}" .format(', '.join(missing), ', '.join( [t for t in templates]))), 'danger') return redirect( url_for('.submit_assignment', name=assign.name)) backup = make_backup(current_user, assign.id, messages, True) if form.flag_submission.data: assign.flag(backup.id, user_ids) if assign.autograding_key: try: submit_continous(backup) except ValueError as e: logger.warning('Web submission did not autograde', exc_info=True) flash('Did not send to autograder: {}'.format(e), 'warning') flash("Uploaded submission (ID: {})".format(backup.hashid), 'success') return redirect(url_for('.assignment', name=assign.name)) return render_template('student/assignment/submit.html', assignment=assign, group=group, course=assign.course, form=form)