Example #1
0
    def get_prep(self):
        student = self.personalize_page_and_get_enrolled()
        if not student:
            return
        if not self.assert_participant_or_fail(student):
            return

        # Extract incoming args
        unit_id = self.request.get('name')
        course = self.get_course()
        unit = course.find_unit_by_id(unit_id)
        if not unit:
            self.error(404)
            return

        self.template_value['navbar'] = {'course': True}
        self.template_value['assessment_title'] = unit.title
        self.template_value['assessment_name'] = unit_id

        reason = AssessmentTracker.reason_if_cant_take(student, unit_id)
        if reason:
            self.template_value['error'] = reason
            self.render('assessment_denied.html')
            return

        params = dict(self.request.params)
        params['action'] = 'prep'
        self.template_value['form_action'] = self.request.path_url + "?" + urllib.urlencode(params)
        self.template_value['xsrf_token'] = self.create_xsrf_token('prep')
        self.render('assessment_prep.html')
Example #2
0
    def get_prep(self):
        student = self.personalize_page_and_get_enrolled()
        if not student:
            return
        if not self.assert_participant_or_fail(student):
            return

        # Extract incoming args
        unit_id = self.request.get("name")
        course = self.get_course()
        unit = course.find_unit_by_id(unit_id)
        if not unit:
            self.error(404)
            return

        self.template_value["navbar"] = {"course": True}
        self.template_value["assessment_title"] = unit.title
        self.template_value["assessment_name"] = unit_id

        reason = AssessmentTracker.reason_if_cant_take(student, unit_id)
        if reason:
            self.template_value["error"] = reason
            self.render("assessment_denied.html")
            return

        params = dict(self.request.params)
        params["action"] = "prep"
        self.template_value["form_action"] = self.request.path_url + "?" + urllib.urlencode(params)
        self.template_value["xsrf_token"] = self.create_xsrf_token("prep")
        self.render("assessment_prep.html")
Example #3
0
    def get_start(self):
        """Handles GET requests."""
        student = self.personalize_page_and_get_enrolled()
        if not student:
            return
        if not self.assert_participant_or_fail(student):
            return

        # Extract incoming args
        unit_id = self.request.get('name')
        course = self.get_course()
        unit = course.find_unit_by_id(unit_id)
        if not unit:
            self.error(404)
            return

        self.template_value['navbar'] = {'course': True}

        try:
            AssessmentTracker.try_start_test(student, unit_id)
        except ValueError as e:
            self.template_value['error'] = e.message
            self.render('assessment_denied.html')
            return

        self.template_value['unit_id'] = unit_id
        self.template_value['record_events'] = CAN_PERSIST_ACTIVITY_EVENTS.value
        self.template_value['assessment_xsrf_token'] = (
            XsrfTokenManager.create_xsrf_token('assessment-post'))
        self.template_value['event_xsrf_token'] = (
            XsrfTokenManager.create_xsrf_token('event-post'))

        self.template_value['grader'] = unit.workflow.get_grader()

        readonly_view = False
        due_date_exceeded = False

        submission_due_date = unit.workflow.get_submission_due_date()
        if submission_due_date:
            self.template_value['submission_due_date'] = (
                submission_due_date.strftime(HUMAN_READABLE_DATETIME_FORMAT))

            time_now = datetime.datetime.now()
            if time_now > submission_due_date:
                readonly_view = True
                due_date_exceeded = True
                self.template_value['due_date_exceeded'] = True

        if course.needs_human_grader(unit):
            self.template_value['matcher'] = unit.workflow.get_matcher()

            rp = course.get_reviews_processor()
            review_steps_by = rp.get_review_steps_by(
                unit.unit_id, student.get_key())

            # Determine if the student can see others' reviews of his/her work.
            if (ReviewUtils.has_completed_enough_reviews(
                    review_steps_by, unit.workflow.get_review_min_count())):
                submission_and_review_steps = (
                    rp.get_submission_and_review_steps(
                        unit.unit_id, student.get_key()))

                submission_contents = submission_and_review_steps[0]
                review_steps_for = submission_and_review_steps[1]

                review_keys_for_student = []
                for review_step in review_steps_for:
                    can_show_review = (
                        review_step.state == domain.REVIEW_STATE_COMPLETED
                        and not review_step.removed
                        and review_step.review_key
                    )

                    if can_show_review:
                        review_keys_for_student.append(review_step.review_key)

                reviews_for_student = rp.get_reviews_by_keys(
                    unit.unit_id, review_keys_for_student)

                self.template_value['reviews_received'] = [
                    create_readonly_assessment_params(
                        course.get_review_form_content(unit),
                        StudentWorkUtils.get_answer_list(review)
                    ) for review in reviews_for_student]
            else:
                submission_contents = student_work.Submission.get_contents(
                    unit.unit_id, student.get_key())

            # Determine whether to show the assessment in readonly mode.
            if submission_contents or due_date_exceeded:
                readonly_view = True
                self.template_value['readonly_student_assessment'] = (
                    create_readonly_assessment_params(
                        course.get_assessment_content(unit),
                        StudentWorkUtils.get_answer_list(submission_contents)
                    )
                )

        if not readonly_view:
            self.template_value['assessment_script_src'] = (
                self.get_course().get_assessment_filename(unit_id))

            # If a previous submission exists, reinstate it.
            submission_contents = student_work.Submission.get_contents(
                unit.unit_id, student.get_key())
            saved_answers = (
                StudentWorkUtils.get_answer_list(submission_contents)
                if submission_contents else [])
            self.template_value['saved_answers'] = transforms.dumps(
                saved_answers)

        self.render('assessment.html')
Example #4
0
    def post(self):
        """Handles POST requests."""
        student = self.personalize_page_and_get_enrolled()
        if not student:
            return

        if not self.assert_xsrf_token_or_fail(self.request, 'assessment-post'):
            return

        if not self.assert_participant_or_fail(student):
            return

        course = self.get_course()
        assessment_type = self.request.get('assessment_type')
        if not assessment_type:
            self.error(404)
            logging.error('No assessment type supplied.')
            return

        unit = course.find_unit_by_id(assessment_type)
        if unit is None or unit.type != verify.UNIT_TYPE_ASSESSMENT:
            self.error(404)
            logging.error('No assessment named %s exists.', assessment_type)
            return

        self.template_value['navbar'] = {'course': True}

        try:
            AssessmentTracker.try_submit_test(student, assessment_type)
        except ValueError as e:
            self.template_value['error'] = e.message
            self.render('assessment_denied.html')
            return

        self.template_value['assessment'] = assessment_type
        self.template_value['assessment_name'] = unit.title
        self.template_value['can_take_again'] = AssessmentTracker.can_take_again(student, assessment_type)
        self.template_value['retake_link'] = '/assessment?' + urllib.urlencode({
            'name': assessment_type,
            'action': 'start',
            })
        self.template_value['is_last_assessment'] = (
            course.is_last_assessment(unit))

        # Convert answers from JSON to dict.
        answers = self.request.get('answers')
        answers = transforms.loads(answers) if answers else []

        grader = unit.workflow.get_grader()

        # Scores are not recorded for human-reviewed assignments.
        score = 0
        if grader == courses.AUTO_GRADER:
            score = int(round(float(self.request.get('score'))))

        # Record assessment transaction.
        student = self.update_assessment_transaction(
            student.key().name(), assessment_type, answers, score)

        if grader == courses.HUMAN_GRADER:
            rp = course.get_reviews_processor()

            # Guard against duplicate submissions of a human-graded assessment.
            previously_submitted = rp.does_submission_exist(
                unit.unit_id, student.get_key())

            if not previously_submitted:
                # Check that the submission due date has not passed.
                time_now = datetime.datetime.now()
                submission_due_date = unit.workflow.get_submission_due_date()
                if time_now > submission_due_date:
                    self.template_value['time_now'] = time_now.strftime(
                        HUMAN_READABLE_DATETIME_FORMAT)
                    self.template_value['submission_due_date'] = (
                        submission_due_date.strftime(
                            HUMAN_READABLE_DATETIME_FORMAT))
                    self.template_value['error_code'] = (
                        'assignment_deadline_exceeded')
                    self.render('error.html')
                    return

                submission_key = student_work.Submission.write(
                    unit.unit_id, student.get_key(), answers)
                rp.start_review_process_for(
                    unit.unit_id, submission_key, student.get_key())
                # Record completion event in progress tracker.
                course.get_progress_tracker().put_assessment_completed(
                    student, assessment_type)

            self.template_value['previously_submitted'] = previously_submitted

            matcher = unit.workflow.get_matcher()
            self.template_value['matcher'] = matcher
            if matcher == review.PEER_MATCHER:
                self.template_value['review_dashboard_url'] = (
                    'reviewdashboard?unit=%s' % unit.unit_id
                )

            self.render('reviewed_assessment_confirmation.html')
            return
        else:
            # Record completion event in progress tracker.
            course.get_progress_tracker().put_assessment_completed(
                student, assessment_type)

            # Save the submission in the datastore, overwriting the earlier
            # version if it exists.
            submission_key = student_work.Submission.write(
                unit.unit_id, student.get_key(), answers)

            self.template_value['result'] = course.get_overall_result(student)
            self.template_value['score'] = score
            self.template_value['overall_score'] = course.get_overall_score(
                student)

            self.render('test_confirmation.html')
Example #5
0
    def post(self):
        """Handles POST requests."""
        student = self.personalize_page_and_get_enrolled()
        if not student:
            return

        if not self.assert_xsrf_token_or_fail(self.request, 'assessment-post'):
            return

        if not self.assert_participant_or_fail(student):
            return

        course = self.get_course()
        assessment_type = self.request.get('assessment_type')
        if not assessment_type:
            self.error(404)
            logging.error('No assessment type supplied.')
            return

        unit = course.find_unit_by_id(assessment_type)
        if unit is None or unit.type != verify.UNIT_TYPE_ASSESSMENT:
            self.error(404)
            logging.error('No assessment named %s exists.', assessment_type)
            return

        self.template_value['navbar'] = {'course': True}

        try:
            AssessmentTracker.try_submit_test(student, assessment_type)
        except ValueError as e:
            self.template_value['error'] = e.message
            self.render('assessment_denied.html')
            return

        self.template_value['assessment'] = assessment_type
        self.template_value['assessment_name'] = unit.title
        self.template_value[
            'can_take_again'] = AssessmentTracker.can_take_again(
                student, assessment_type)
        self.template_value['retake_link'] = '/assessment?' + urllib.urlencode(
            {
                'name': assessment_type,
                'action': 'start',
            })
        self.template_value['is_last_assessment'] = (
            course.is_last_assessment(unit))

        # Convert answers from JSON to dict.
        answers = self.request.get('answers')
        answers = transforms.loads(answers) if answers else []

        grader = unit.workflow.get_grader()

        # Scores are not recorded for human-reviewed assignments.
        score = 0
        if grader == courses.AUTO_GRADER:
            score = int(round(float(self.request.get('score'))))

        # Record assessment transaction.
        student = self.update_assessment_transaction(student.key().name(),
                                                     assessment_type, answers,
                                                     score)

        if grader == courses.HUMAN_GRADER:
            rp = course.get_reviews_processor()

            # Guard against duplicate submissions of a human-graded assessment.
            previously_submitted = rp.does_submission_exist(
                unit.unit_id, student.get_key())

            if not previously_submitted:
                # Check that the submission due date has not passed.
                time_now = datetime.datetime.now()
                submission_due_date = unit.workflow.get_submission_due_date()
                if time_now > submission_due_date:
                    self.template_value['time_now'] = time_now.strftime(
                        HUMAN_READABLE_DATETIME_FORMAT)
                    self.template_value['submission_due_date'] = (
                        submission_due_date.strftime(
                            HUMAN_READABLE_DATETIME_FORMAT))
                    self.template_value['error_code'] = (
                        'assignment_deadline_exceeded')
                    self.render('error.html')
                    return

                submission_key = student_work.Submission.write(
                    unit.unit_id, student.get_key(), answers)
                rp.start_review_process_for(unit.unit_id, submission_key,
                                            student.get_key())
                # Record completion event in progress tracker.
                course.get_progress_tracker().put_assessment_completed(
                    student, assessment_type)

            self.template_value['previously_submitted'] = previously_submitted

            matcher = unit.workflow.get_matcher()
            self.template_value['matcher'] = matcher
            if matcher == review.PEER_MATCHER:
                self.template_value['review_dashboard_url'] = (
                    'reviewdashboard?unit=%s' % unit.unit_id)

            self.render('reviewed_assessment_confirmation.html')
            return
        else:
            # Record completion event in progress tracker.
            course.get_progress_tracker().put_assessment_completed(
                student, assessment_type)

            # Save the submission in the datastore, overwriting the earlier
            # version if it exists.
            submission_key = student_work.Submission.write(
                unit.unit_id, student.get_key(), answers)

            self.template_value['result'] = course.get_overall_result(student)
            self.template_value['score'] = score
            self.template_value['overall_score'] = course.get_overall_score(
                student)

            self.render('test_confirmation.html')
Example #6
0
    def get_start(self):
        """Handles GET requests."""
        student = self.personalize_page_and_get_enrolled()
        if not student:
            return
        if not self.assert_participant_or_fail(student):
            return

        # Extract incoming args
        unit_id = self.request.get("name")
        course = self.get_course()
        unit = course.find_unit_by_id(unit_id)
        if not unit:
            self.error(404)
            return

        self.template_value["navbar"] = {"course": True}

        try:
            AssessmentTracker.try_start_test(student, unit_id)
        except ValueError as e:
            self.template_value["error"] = e.message
            self.render("assessment_denied.html")
            return

        self.template_value["unit_id"] = unit_id
        self.template_value["record_events"] = CAN_PERSIST_ACTIVITY_EVENTS.value
        self.template_value["assessment_xsrf_token"] = XsrfTokenManager.create_xsrf_token("assessment-post")
        self.template_value["event_xsrf_token"] = XsrfTokenManager.create_xsrf_token("event-post")

        self.template_value["grader"] = unit.workflow.get_grader()

        readonly_view = False
        due_date_exceeded = False

        submission_due_date = unit.workflow.get_submission_due_date()
        if submission_due_date:
            self.template_value["submission_due_date"] = submission_due_date.strftime(HUMAN_READABLE_DATETIME_FORMAT)

            time_now = datetime.datetime.now()
            if time_now > submission_due_date:
                readonly_view = True
                due_date_exceeded = True
                self.template_value["due_date_exceeded"] = True

        if course.needs_human_grader(unit):
            self.template_value["matcher"] = unit.workflow.get_matcher()

            rp = course.get_reviews_processor()
            review_steps_by = rp.get_review_steps_by(unit.unit_id, student.get_key())

            # Determine if the student can see others' reviews of his/her work.
            if ReviewUtils.has_completed_enough_reviews(review_steps_by, unit.workflow.get_review_min_count()):
                submission_and_review_steps = rp.get_submission_and_review_steps(unit.unit_id, student.get_key())

                submission_contents = submission_and_review_steps[0]
                review_steps_for = submission_and_review_steps[1]

                review_keys_for_student = []
                for review_step in review_steps_for:
                    can_show_review = (
                        review_step.state == domain.REVIEW_STATE_COMPLETED
                        and not review_step.removed
                        and review_step.review_key
                    )

                    if can_show_review:
                        review_keys_for_student.append(review_step.review_key)

                reviews_for_student = rp.get_reviews_by_keys(unit.unit_id, review_keys_for_student)

                self.template_value["reviews_received"] = [
                    create_readonly_assessment_params(
                        course.get_review_form_content(unit), StudentWorkUtils.get_answer_list(review)
                    )
                    for review in reviews_for_student
                ]
            else:
                submission_contents = student_work.Submission.get_contents(unit.unit_id, student.get_key())

            # Determine whether to show the assessment in readonly mode.
            if submission_contents or due_date_exceeded:
                readonly_view = True
                self.template_value["readonly_student_assessment"] = create_readonly_assessment_params(
                    course.get_assessment_content(unit), StudentWorkUtils.get_answer_list(submission_contents)
                )

        if not readonly_view:
            self.template_value["assessment_script_src"] = self.get_course().get_assessment_filename(unit_id)

            # If a previous submission exists, reinstate it.
            submission_contents = student_work.Submission.get_contents(unit.unit_id, student.get_key())
            saved_answers = StudentWorkUtils.get_answer_list(submission_contents) if submission_contents else []
            self.template_value["saved_answers"] = transforms.dumps(saved_answers)

        self.render("assessment.html")