def _post_async_submission(request, exercise, submission, errors=None): """ Creates or grades a submission. Required parameters in the request are points, max_points and feedback. If errors occur or submissions are no longer accepted, a dictionary with "success" is False and "errors" list will be returned. """ if not errors: errors = [] # The feedback field may contain null characters, which would invalidate # the form before its clean method is executed. So replace them beforehand. post_data = request.POST.copy() feedback = post_data.get('feedback') if feedback: post_data['feedback'] = feedback.replace('\x00', '\\x00') # Use form to parse and validate the request. form = SubmissionCallbackForm(post_data) errors.extend(extract_form_errors(form)) if not form.is_valid(): submission.feedback = _( "ERROR_ALERT_EXERCISE_ASSESSMENT_SERVICE_MALFUNCTIONING") submission.set_error() submission.save() if exercise.course_instance.visible_to_students: msg = "Exercise service returned with invalid grade request: {}"\ .format("\n".join(errors)) logger.error(msg, extra={"request": request}) email_course_error(request, exercise, msg, False) return {"success": False, "errors": errors} # Grade the submission. try: submission.set_points(form.cleaned_data["points"], form.cleaned_data["max_points"]) submission.feedback = form.cleaned_data["feedback"] submission.grading_data = post_data if form.cleaned_data["error"]: submission.set_error() else: submission.set_ready() submission.save() if form.cleaned_data["notify"]: Notification.send(None, submission) else: Notification.remove(submission) return {"success": True, "errors": []} # Produce error if something goes wrong during saving the points. except Exception as e: logger.exception("Unexpected error while saving grade" " for {} and submission id {:d}".format( str(exercise), submission.id)) return {"success": False, "errors": [repr(e)]}
def _post_async_submission(request, exercise, submission, errors=None): """ Creates or grades a submission. Required parameters in the request are points, max_points and feedback. If errors occur or submissions are no longer accepted, a dictionary with "success" is False and "errors" list will be returned. """ if not errors: errors = [] # Use form to parse and validate the request. form = SubmissionCallbackForm(request.POST) errors.extend(extract_form_errors(form)) if not form.is_valid(): submission.feedback = _( "<div class=\"alert alert-error\">\n" "<p>The exercise assessment service is malfunctioning. " "Staff has been notified.</p>\n" "<p>This submission is now marked as erroneous.</p>\n" "</div>") submission.set_error() submission.save() if exercise.course_instance.visible_to_students: msg = "Exercise service returned with invalid grade request: {}"\ .format("\n".join(errors)) logger.error(msg, extra={"request": request}) email_course_error(request, exercise, msg, False) return {"success": False, "errors": errors} # Grade the submission. try: submission.set_points(form.cleaned_data["points"], form.cleaned_data["max_points"]) submission.feedback = form.cleaned_data["feedback"] submission.grading_data = request.POST if form.cleaned_data["error"]: submission.set_error() else: submission.set_ready() submission.save() if form.cleaned_data["notify"]: Notification.send(None, submission) else: Notification.remove(submission) return {"success": True, "errors": []} # Produce error if something goes wrong during saving the points. except Exception as e: logger.exception("Unexpected error while saving grade" " for {} and submission id {:d}".format( str(exercise), submission.id)) return {"success": False, "errors": [repr(e)]}
def _post_async_submission(request, exercise, submission, students, errors): """ Creates or grades a submission. Required parameters in the request are points, max_points and feedback. If errors occur or submissions are no longer accepted, a dictionary with "success" is False and "errors" list will be returned. """ # Use form to parse and validate the request. form = SubmissionCallbackForm(request.POST) errors.extend(extract_form_errors(form)) if not form.is_valid(): submission.feedback = _( "<div class=\"alert alert-error\">\n" "<p>The exercise assessment service is malfunctioning. " "Staff has been notified.</p>\n" "<p>This submission is now marked as erroneous.</p>\n" "</div>") submission.set_error() submission.save() if exercise.course_instance.visible_to_students: msg = "Exercise service returned with invalid grade request: {}"\ .format("\n".join(errors)) logger.error(msg, extra={"request": request}) email_course_error(request, exercise, msg, False) return { "success": False, "errors": errors } # Grade the submission. try: submission.set_points(form.cleaned_data["points"], form.cleaned_data["max_points"]) submission.feedback = form.cleaned_data["feedback"] submission.grading_data = request.POST if form.cleaned_data["error"]: submission.set_error() else: submission.set_ready() submission.save() return { "success": True, "errors": [] } # Produce error if something goes wrong during saving the points. except Exception as e: logger.exception("Unexpected error while saving grade" " for {} and submission id {:d}".format(str(exercise), submission.id)); return { "success": False, "errors": [repr(e)] }
def load_exercise_page(request, url, exercise): """ Loads the exercise page from the remote URL. """ page = ExercisePage(exercise) try: parse_page_content(page, RemotePage(url), exercise) except RemotePageException: messages.error(request, _("Connecting to the exercise service failed!")) if exercise.id and exercise.course_instance.visible_to_students: msg = "Failed to request {}".format(url) logger.exception(msg) email_course_error(request, exercise, msg) return page
def load_exercise_page(request, url, last_modified, exercise): """ Loads the exercise page from the remote URL. """ page = ExercisePage(exercise) try: parse_page_content(page, RemotePage(url, stamp=last_modified), exercise) except RemotePageException: messages.error(request, _("Connecting to the exercise service failed!")) if exercise.id: instance = exercise.course_instance msg = "Failed to request {}".format(url) if instance.visible_to_students and not instance.is_past(): logger.exception(msg) email_course_error(request, exercise, msg) else: logger.warning(msg) return page
def load_exercise_page(request, url, last_modified, exercise): """ Loads the exercise page from the remote URL. """ page = ExercisePage(exercise) try: parse_page_content( page, RemotePage(url, instance_id=exercise.course_instance.id, stamp=last_modified), exercise) except RemotePageException: messages.error(request, _('EXERCISE_SERVICE_ERROR_CONNECTION_FAILED')) if exercise.id: instance = exercise.course_instance msg = "Failed to request {}".format(url) if instance.visible_to_students and not instance.is_past(): logger.exception(msg) email_course_error(request, exercise, msg) else: logger.warning(msg) return page
def load_exercise_page(request, url, last_modified, exercise): """ Loads the exercise page from the remote URL. """ page = ExercisePage(exercise) try: parse_page_content( page, RemotePage(url, stamp=last_modified), exercise ) except RemotePageException: messages.error(request, _("Connecting to the exercise service failed!")) if exercise.id: instance = exercise.course_instance msg = "Failed to request {}".format(url) if instance.visible_to_students and not instance.is_past(): logger.exception(msg) email_course_error(request, exercise, msg) else: logger.warning(msg) return page
def load_feedback_page(request, url, exercise, submission, no_penalties=False): """ Loads the feedback or accept page from the remote URL. """ page = ExercisePage(exercise) try: data, files = submission.get_post_parameters(request, url) remote_page = RemotePage(url, post=True, data=data, files=files, instance_id=exercise.course_instance.id) submission.clean_post_parameters() parse_page_content(page, remote_page, exercise) except RemotePageException: page.errors.append(_('ASSESSMENT_SERVICE_ERROR_CONNECTION_FAILED')) if exercise.course_instance.visible_to_students: msg = "Failed to request {}".format(url) logger.exception(msg) email_course_error(request, exercise, msg) if page.is_loaded: submission.feedback = page.clean_content if page.is_accepted: submission.set_waiting() if page.is_graded: if page.is_sane(): submission.set_points(page.points, page.max_points, no_penalties) submission.set_ready() # Hide unnecessary system wide messages when grader works as expected. # msg = _("The exercise was submitted and graded " # "successfully. Points: {points:d}/{max:d}").format( # points=submission.grade, # max=exercise.max_points # ) # if submission.grade < exercise.max_points: # messages.info(request, msg) # else: # messages.success(request, msg) else: submission.set_error() page.errors.append( format_lazy(_( 'ASSESSMENT_SERVICE_ERROR_RESPONDED_INVALID_POINTS -- {points:d}, {max:d}, {exercise_max:d}' ), points=page.points, max=page.max_points, exercise_max=exercise.max_points)) if exercise.course_instance.visible_to_students: msg = "Graded with invalid points {:d}/{:d}"\ " (exercise max {:d}): {}".format( page.points, page.max_points, exercise.max_points, exercise.service_url) logger.error(msg, extra={"request": request}) email_course_error(request, exercise, msg) else: pass # Hide unnecessary system wide messages when grader works as expected. # messages.success(request, # _("The exercise was submitted successfully " # "and is now waiting to be graded.") # ) elif page.is_rejected: submission.set_rejected() else: submission.set_error() logger.info("No accept or points received: %s", exercise.service_url) page.errors.append(_('ASSESSMENT_SERVICE_ERROR_RESPONDED_ERROR')) submission.save() return page
def load_feedback_page(request, url, exercise, submission, no_penalties=False): """ Loads the feedback or accept page from the remote URL. """ page = ExercisePage(exercise) try: data, files = submission.get_post_parameters(request, url) remote_page = RemotePage(url, post=True, data=data, files=files) submission.clean_post_parameters() parse_page_content(page, remote_page, exercise) except RemotePageException: messages.error(request, _("Connecting to the assessment service failed!")) if exercise.course_instance.visible_to_students: msg = "Failed to request {}".format(url) logger.exception(msg) email_course_error(request, exercise, msg) if page.is_loaded: submission.feedback = page.content if page.is_accepted: submission.set_waiting() if page.is_graded: if page.is_sane(): submission.set_points( page.points, page.max_points, no_penalties) submission.set_ready() msg = _("The exercise was submitted and graded " "successfully. Points: {points:d}/{max:d}").format( points=submission.grade, max=exercise.max_points ) if submission.grade < exercise.max_points: messages.info(request, msg) else: messages.success(request, msg) else: submission.set_error() messages.error(request, _("Assessment service responded with invalid points. " "Points: {points:d}/{max:d} " "(exercise max {exercise_max:d})").format( points=page.points, max=page.max_points, exercise_max=exercise.max_points ) ) if exercise.course_instance.visible_to_students: msg = "Graded with invalid points {:d}/{:d}"\ " (exercise max {:d}): {}".format( page.points, page.max_points, exercise.max_points, exercise.service_url) logger.error(msg, extra={"request": request}) email_course_error(request, exercise, msg) else: messages.success(request, _("The exercise was submitted successfully " "and is now waiting to be graded.") ) else: submission.set_error() logger.info("No accept or points received: %s", exercise.service_url) messages.error(request, _("Assessment service responded with error.")) submission.save() return page