def acceptAttachedExercise(request, course, exercise, post_url): ''' Accepts attached exercise rules and user files for queue. ''' _requireActions(exercise) if not_modified_since(request, exercise): return not_modified_response(request, exercise) result = None # Receive post. if request.method == "POST": # Search for file contents. if "file[]" in request.FILES: file_list = request.FILES.getlist("file[]") else: file_list = [] i = 0 while "content_%d" % (i) in request.FILES: file_list.append(request.FILES["content_%d" % (i)]) i += 1 # Store submitted files. if not file_list: result = { "error":True, "missing_files":True } else: sdir = create_submission_dir(course, exercise) i = 0 for content in file_list: if i > 0: key = "file_%d" % (i) if not key in request.POST or not request.POST[key]: result = { "error": True, "missing_file_name": True } clean_submission_dir(sdir) break save_submitted_file(sdir, request.POST[key], content) else: save_submitted_file(sdir, "exercise_attachment", content) i += 1 if result is None: return _acceptSubmission(request, course, exercise, post_url, sdir) # Add the attachment as a hint to the default view form. if result is None: import copy exercise = copy.deepcopy(exercise) exercise["files"] = [ { "field": "content_0", "name": "exercise_attachment" } ] return cache_headers( render_configured_template( request, course, exercise, post_url, "access/accept_files_default.html", result ), request, exercise )
def acceptAttachedExercise(request, course, exercise, post_url): ''' Accepts attached exercise rules and user files for queue. ''' _requireActions(exercise) if not_modified_since(request, exercise): return not_modified_response(request, exercise) result = None # Receive post. if request.method == "POST": # Search for file contents. if "file[]" in request.FILES: file_list = request.FILES.getlist("file[]") else: file_list = [] i = 0 while "content_%d" % (i) in request.FILES: file_list.append(request.FILES["content_%d" % (i)]) i += 1 # Store submitted files. if not file_list: result = {"rejected": True, "missing_files": True} else: sdir = create_submission_dir(course, exercise) i = 0 for content in file_list: if i > 0: key = "file_%d" % (i) if not key in request.POST or not request.POST[key]: result = {"error": True, "missing_file_name": True} clean_submission_dir(sdir) break save_submitted_file(sdir, request.POST[key], content) else: save_submitted_file(sdir, "exercise_attachment", content) i += 1 if result is None: return _acceptSubmission(request, course, exercise, post_url, sdir) # Add the attachment as a hint to the default view form. if result is None: import copy exercise = copy.deepcopy(exercise) exercise["files"] = [{ "field": "content_0", "name": "exercise_attachment" }] return cache_headers( render_configured_template(request, course, exercise, post_url, "access/accept_files_default.html", result), request, exercise)
def container_post(request): ''' Proxies the grading result from inside container to A+ ''' sid = request.POST.get("sid", None) if not sid: return HttpResponseForbidden("Missing sid") meta = read_and_remove_submission_meta(sid) clean_submission_dir(meta["dir"]) data = { "points": int(request.POST.get("points", 0)), "max_points": int(request.POST.get("max_points", 1)), "feedback": request.POST.get("feedback", ""), } for key in ["error", "grading_data"]: if key in request.POST: data[key] = request.POST[key] if "error" in data and data["error"].lower() in ("no", "false"): del data["error"] if not post_data(meta["url"], data): raise IOError("Failed to deliver results") return HttpResponse("Ok")
def runactions(course, exercise, submission_dir): ''' Runs configured grading actions for an exercise submission. @type course: C{dict} @param course: a course configuration @type exercise: C{dict} @param exercise: an exercise configuration @type submission_dir: C{str} @param submission_dir: a submission directory where submitted files are stored @rtype: C{dict} @return: template = template name, result = points, max_points, tests ''' total_points = 0 max_points = 0 total_result = [] error = False has_appendixes = False # Try to run the grading actions. try: for action in exercise["actions"]: exgrader = None try: exgrader = import_named(course, action["type"]) except ImproperlyConfigured as e: raise ConfigError("Invalid action \"type\" in exercise configuration.", e) # Run the exercise grader action LOGGER.debug("Running action \"%s\"", action["type"]) r = exgrader(course, exercise, action, submission_dir) has_appendixes = has_appendixes or \ ("appendix" in r and r["appendix"]) # Configured template values. if "title" in action: r["title"] = action["title"] if "html" in action and action["html"]: r["html"] = True # Override with configured points. if "points" in action: r["max_points"] = action["points"] if r["stop"]: r["points"] = 0 else: r["points"] = action["points"] elif "max_points" in action: r["max_points"] = action["max_points"] if r["points"] > action["max_points"]: r["points"] = action["max_points"] # Sum total numbers. total_result.append(r) total_points += r["points"] if "max_points" in r: max_points += r["max_points"] if r["stop"]: if "expect_success" in action: error = action["expect_success"] break # Override with configured max points. if "max_points" in exercise: max_points = exercise["max_points"] # Check the points are in range. if total_points > max_points: total_points = max_points elif total_points < 0: total_points = 0 # Determine template. template = None if "feedback_template" in exercise: template = exercise["feedback_template"] else: template = "access/task_success.html" return { "template": template, "result": { "points": total_points, "max_points": max_points, "tests": total_result, "error": error, "has_appendixes": has_appendixes, } } finally: clean_submission_dir(submission_dir)
def runactions(course, exercise, submission_dir, user_ids="", submission_number=1): ''' Runs configured grading actions for an exercise submission. @type course: C{dict} @param course: a course configuration @type exercise: C{dict} @param exercise: an exercise configuration @type submission_dir: C{str} @param submission_dir: a submission directory where submitted files are stored @type user_ids: C{str} @param user_ids: user id(s) of the submitter(s) for personalized exercises @type submission_number: C{int} @param submission_number: ordinal number of the submission (parameter in the grader protocol) @rtype: C{dict} @return: template = template name, result = points, max_points, tests ''' total_points = 0 max_points = 0 total_result = [] error = False has_appendixes = False # Try to run the grading actions. try: for action in exercise["actions"]: exgrader = None try: exgrader = import_named(course, action["type"]) except ImproperlyConfigured as e: raise ConfigError( "Invalid action \"type\" in exercise configuration.", e) # Run the exercise grader action LOGGER.debug("Running action \"%s\"", action["type"]) if action["type"] == "grader.actions.prepare" or \ action["type"] == "grader.actions.store_user_files": r = exgrader(course, exercise, action, submission_dir, user_ids, submission_number) else: r = exgrader(course, exercise, action, submission_dir) has_appendixes = has_appendixes or \ ("appendix" in r and r["appendix"]) # Configured template values. if "title" in action: r["title"] = action["title"] if "html" in action and action["html"]: r["html"] = True # Override with configured points. if "points" in action: r["max_points"] = action["points"] if r["stop"]: r["points"] = 0 else: r["points"] = action["points"] elif "max_points" in action: r["max_points"] = action["max_points"] if r["points"] > action["max_points"]: r["points"] = action["max_points"] # Sum total numbers. total_result.append(r) total_points += r["points"] if "max_points" in r: max_points += r["max_points"] if r["stop"]: if "expect_success" in action: error = action["expect_success"] if not ("continue_after_error" in action and action["continue_after_error"]): break # skip the subsequent actions # Override with configured max points. if "max_points" in exercise: max_points = exercise["max_points"] # Check the points are in range. if total_points > max_points: total_points = max_points elif total_points < 0: total_points = 0 # Determine template. template = None if "feedback_template" in exercise: template = exercise["feedback_template"] else: template = "access/task_success.html" return { "template": template, "result": { "points": total_points, "max_points": max_points, "tests": total_result, "error": error, "has_appendixes": has_appendixes, } } finally: clean_submission_dir(submission_dir)