def get_page(self, submission_url=None):
     """
     @param submission_url: the submission url where the service may return submissions
     @return: an ExercisePage object created from data retrieved from exercise service 
     """
     page = ExercisePage(self)
     page.content = self.exercise_page_content
     return page
 def get_page(self, submission_url=None):
     """
     @param submission_url: the submission url where the service may return submissions
     @return: an ExercisePage object created from data retrieved from exercise service 
     """
     page            = ExercisePage(self)
     page.content    = self.exercise_page_content
     return page
    def get_page(self, submission_url=None):
        """
        @param submission_url: the submission url where the service may return submissions
        @return: an ExercisePage containing the exercise instructions and possibly a submit form 
        """
        page            = ExercisePage(self)
        page.content    = self.instructions

        # Adds the submission form to the content if there are files to be submitted.
        # A template is used to avoid hard-coded HTML here.
        if self.get_files_to_submit():
            template = loader.get_template('exercise/_file_submit_form.html')
            context = Context({'files' : self.get_files_to_submit()})
            page.content += template.render(context)

        return page
示例#4
0
def view_exercise(request, exercise_id):
    """ 
    Displays a particular exercise. If the exercise is requested with a HTTP POST request, 
    the view will try to submit the exercise to the exercise service. 
    
    @param request: HttpRequest from Django
    @param exercise_id: the id of the exercise model to display 
    """

    # Load the exercise as an instance of its leaf class
    exercise = get_object_or_404(BaseExercise, id=exercise_id).as_leaf_class()
    students = StudentGroup.get_students_from_request(request)
    submissions = exercise.get_submissions_for_student(
        request.user.get_profile())
    is_post = request.method == "POST"

    is_allowed, issues = exercise.is_submission_allowed(students)

    for error in issues:
        messages.warning(request, error)

    # FIXME: remove support for custom forms
    form = None

    if is_post and is_allowed:
        # This is a successful submission, so we handle submitting the form
        return _handle_submission(request, exercise, students, form,
                                  submissions)

    try:
        # Try retrieving the exercise page
        submission_url = exercise.get_submission_url_for_students(students)
        page = exercise.get_page(submission_url)

    except Exception as e:
        # Retrieving page failed, create an empty page and display an error
        # TODO: an error report should be sent or logged
        page = ExercisePage(exercise=exercise)
        messages.error(
            request,
            _('Connecting to the exercise service failed: %s.') % str(e))

    exercise_summary = ExerciseSummary(exercise, request.user)

    return render_to_response(
        "exercise/view_exercise.html",
        CourseContext(request,
                      exercise=exercise,
                      course_instance=exercise.course_module.course_instance,
                      page=page,
                      form=form,
                      submissions=submissions,
                      exercise_summary=exercise_summary))
    def get_page(self, submission_url):
        """ 
        Retrieves the page for this exercise from the exercise service. 
        
        @param submission_url: the submission url where the service may return submissions
        @return: an ExercisePage object created from data retrieved from exercise service 
        """

        # Build the URL with a callback address, max points etc.
        url = self.build_service_url(submission_url)

        opener = urllib2.build_opener()
        page_content = opener.open(url, timeout=20).read()

        return ExercisePage(self, page_content)
    def submit(self, submission):
        """ 
        This method sends the given submission to the exercise service 
        along with the files related to the submission. 
        """

        # Make sure that this is the correct exercise for the submission
        assert self.id == submission.exercise.id

        # Create an empty list for HTTP request parameters
        post_params = []

        # Parameters are appended to the list as key, value tuples.
        # Using tuples makes it possible to add two values for the same key.
        for (key, value) in submission.submission_data:
            post_params.append((key, value))

        # Collect file handles to a list, so that they can be closed after being used
        handles = []

        # Then the files are appended as key, file handle tuples
        for submitted_file in submission.files.all():
            param_name = submitted_file.param_name
            file_handle = open(submitted_file.file_object.path, "rb")
            post_params.append((param_name, file_handle))
            handles.append(file_handle)

        # Build the service URL, which contains maximum points for this exercise
        # and a callback URL to which the service may return the grading
        url = self.build_service_url(submission.get_callback_url())

        opener = urllib2.build_opener(
            MultipartPostHandler.MultipartPostHandler)
        response_body = opener.open(url, post_params, timeout=50).read()

        # Close all opened file handles
        for file_handle in handles:
            file_handle.close()

        return ExercisePage(self, response_body)
示例#7
0
def _handle_submission(request, exercise, students, form, submissions):
    """
    This method takes care of saving a new_submission locally and 
    sending it to an exercise service for assessment. 
    
    @param request: HttpRequest from Django
    @param exercise: an instance of an exercise class this submission is for
    @param students: a QuerySet of UserProfile objects that are submitting the exercise
    @param form: an instance of a Form class or None if there are no questions for the exercise
    @param submissions: previous submissions for the submitting user to the same exercise
    """

    new_submission = Submission.objects.create(exercise=exercise)
    new_submission.submitters = students

    # Save the POST parameters from the new_submission in
    # a list of tuples [(key1, value1), (key2, value2)].
    # By using tuples inside lists we allow two parameters
    # with the same name, which is not possible with dicts.
    new_submission.submission_data = helpers.query_dict_to_list_of_tuples(
        request.POST)

    # Add all submitted files to the new submission as SubmittedFile objects
    new_submission.add_files(request.FILES)

    try:
        # Try submitting the submission to the exercise service. The submission
        # is done with a multipart POST request that contains all the files and
        # POST parameters sent by the user.
        response_page = new_submission.submit_to_service()
    except Exception, e:
        #raise e
        # TODO: Retrieving the grading failed. An error report should be sent
        # to administrators
        messages.error(
            request,
            _('Connecting to the assessment server failed! (%s)') % str(e))
        response_page = ExercisePage(exercise)
 def submit(self, submission):
     page            = ExercisePage(self)
     page.content    = self.submission_page_content
     page.is_accepted= True
     return page
 def submit(self, submission):
     page = ExercisePage(self)
     page.content = self.submission_page_content
     page.is_accepted = True
     return page