예제 #1
0
    def make_student(self, block, name, **state):
        answer = {}
        for key in ("sha1", "mimetype", "filename"):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop("score", None)

        user = User(username=name)
        user.save()
        profile = UserProfile(user=user, name=name)
        profile.save()
        module = StudentModule(
            module_state_key=block.location, student=user, course_id=self.course_id, state=json.dumps(state)
        )
        module.save()

        anonymous_id = anonymous_id_for_user(user, self.course_id)
        item = StudentItem(student_id=anonymous_id, course_id=self.course_id, item_id=block.block_id, item_type="sga")
        item.save()

        if answer:
            student_id = block.student_submission_id(anonymous_id)
            submission = submissions_api.create_submission(student_id, answer)
            if score is not None:
                submissions_api.set_score(submission["uuid"], score, block.max_score())
        else:
            submission = None

        self.addCleanup(item.delete)
        self.addCleanup(profile.delete)
        self.addCleanup(module.delete)
        self.addCleanup(user.delete)

        return {"module": module, "item": item, "submission": submission}
예제 #2
0
    def setUp(self):
        """
        Fixtures.
        """
        due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc)
        course = CourseFactory.create()
        week1 = ItemFactory.create(due=due, parent=course)
        week2 = ItemFactory.create(due=due, parent=course)

        homework = ItemFactory.create(parent=week1, due=due)

        user = UserFactory.create()
        StudentModule(state='{}',
                      student_id=user.id,
                      course_id=course.id,
                      module_state_key=week1.location).save()
        StudentModule(state='{}',
                      student_id=user.id,
                      course_id=course.id,
                      module_state_key=homework.location).save()

        self.course = course
        self.week1 = week1
        self.homework = homework
        self.week2 = week2
        self.user = user

        self.extended_due = functools.partial(get_extended_due,
                                              course,
                                              student=user)
예제 #3
0
    def make_student(self, block, name, make_state=True, **state):
        """
        Create a student along with submission state.
        """
        answer = {}
        module = None
        for key in ('sha1', 'mimetype', 'filename', 'finalized'):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop('score', None)

        with transaction.atomic():
            user = User(username=name, email='{}@example.com'.format(name))
            user.save()
            profile = UserProfile(user=user, name=name)
            profile.save()
            if make_state:
                module = StudentModule(
                    module_state_key=block.location,
                    student=user,
                    course_id=self.course_id,
                    state=json.dumps(state))
                module.save()

            anonymous_id = anonymous_id_for_user(user, self.course_id)
            item = StudentItem(
                student_id=anonymous_id,
                course_id=self.course_id,
                item_id=block.block_id,
                item_type='sga')
            item.save()

            if answer:
                student_id = block.get_student_item_dict(anonymous_id)
                submission = submissions_api.create_submission(student_id, answer)
                if score is not None:
                    submissions_api.set_score(
                        submission['uuid'], score, block.max_score())
            else:
                submission = None

            self.addCleanup(item.delete)
            self.addCleanup(profile.delete)
            self.addCleanup(user.delete)

            if make_state:
                self.addCleanup(module.delete)
                return {
                    'module': module,
                    'item': item,
                    'submission': submission
                }

            return {
                'item': item,
                'submission': submission
            }
예제 #4
0
    def make_student(self, block, name, make_state=True, **state):
        """
        Create a student along with submission state.
        """
        answer = {}
        module = None
        for key in ('sha1', 'mimetype', 'filename', 'finalized'):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop('score', None)

        with transaction.atomic():
            user = User(username=name)
            user.save()
            profile = UserProfile(user=user, name=name)
            profile.save()
            if make_state:
                module = StudentModule(
                    module_state_key=block.location,
                    student=user,
                    course_id=self.course_id,
                    state=json.dumps(state))
                module.save()

            anonymous_id = anonymous_id_for_user(user, self.course_id)
            item = StudentItem(
                student_id=anonymous_id,
                course_id=self.course_id,
                item_id=block.block_id,
                item_type='sga')
            item.save()

            if answer:
                student_id = block.get_student_item_dict(anonymous_id)
                submission = submissions_api.create_submission(student_id, answer)
                if score is not None:
                    submissions_api.set_score(
                        submission['uuid'], score, block.max_score())
            else:
                submission = None

            self.addCleanup(item.delete)
            self.addCleanup(profile.delete)
            self.addCleanup(user.delete)

            if make_state:
                self.addCleanup(module.delete)
                return {
                    'module': module,
                    'item': item,
                    'submission': submission
                }

            return {
                'item': item,
                'submission': submission
            }
예제 #5
0
    def setUp(self):
        """
        Fixtures.
        """
        super(TestDataDumps, self).setUp()

        due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc)
        course = CourseFactory.create()
        week1 = ItemFactory.create(due=due, parent=course)
        week2 = ItemFactory.create(due=due, parent=course)
        week3 = ItemFactory.create(due=due, parent=course)

        homework = ItemFactory.create(parent=week1, due=due)

        user1 = UserFactory.create()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=week1.location).save()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=week2.location).save()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=week3.location).save()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=homework.location).save()

        user2 = UserFactory.create()
        StudentModule(state='{}',
                      student_id=user2.id,
                      course_id=course.id,
                      module_state_key=week1.location).save()
        StudentModule(state='{}',
                      student_id=user2.id,
                      course_id=course.id,
                      module_state_key=homework.location).save()

        user3 = UserFactory.create()
        StudentModule(state='{}',
                      student_id=user3.id,
                      course_id=course.id,
                      module_state_key=week1.location).save()
        StudentModule(state='{}',
                      student_id=user3.id,
                      course_id=course.id,
                      module_state_key=homework.location).save()

        self.course = course
        self.week1 = week1
        self.homework = homework
        self.week2 = week2
        self.user1 = user1
        self.user2 = user2
    def create_course_reference_data(course_key):
        """
        Populates DB with test data
        """
        user = UserFactory()
        group = GroupFactory()
        CourseGroupRelationship(course_id=course_key, group=group).save()
        StudentGradebook(
            user=user,
            course_id=course_key,
            grade=0.9,
            proforma_grade=0.91,
            progress_summary='test',
            grade_summary='test',
            grading_policy='test',
        ).save()
        StudentProgress(user=user, course_id=course_key, completions=1).save()
        CourseModuleCompletion(user=user, course_id=course_key, content_id='test', stage='test').save()
        CourseEnrollment(user=user, course_id=course_key).save()
        CourseAccessRole(user=user, course_id=course_key, org='test', role='TA').save()
        handouts_usage_key = course_key.make_usage_key('course_info', 'handouts')
        StudentModule(student=user, course_id=course_key, module_state_key=handouts_usage_key).save()
        CourseAggregatedMetaData(id=course_key, total_assessments=10, total_modules=20).save()

        structure_json = '{"test": true}'
        course_structure, created = CourseStructure.objects.get_or_create(
            course_id=course_key,
            defaults={'structure_json': structure_json}
        )
        if not created:
            course_structure.structure_json = structure_json
            course_structure.save()

        CourseOverview.get_from_id(course_key)
예제 #7
0
def _get_modules_to_update(course_id,
                           usage_keys,
                           student_identifier,
                           filter_fcn,
                           override_score_task=False):
    """
    Fetches a StudentModule instances for a given `course_id`, `student` object, and `usage_keys`.

    StudentModule instances are those that match the specified `course_id` and `module_state_key`.
    If `student_identifier` is not None, it is used as an additional filter to limit the modules to those belonging
    to that student. If `student_identifier` is None, performs update on modules for all students on the specified
    problem.
    The matched instances are then applied `filter_fcn` if not None. It filters out the matched instances.
    It takes one argument, which is the query being filtered, and returns the filtered version of the query.
    If `override_score_task` is True and we there were not matching instances of StudentModule, try to create
    those instances. This is only for override scores and the use case is for learners that have missed the deadline.

    Arguments:
        course_id(str): The unique identifier for the course.
        usage_keys(list): List of UsageKey objects
        student_identifier(str): Identifier for a student or None. The identifier can be either username or email
        filter_fcn: If it is not None, it is applied to the query that has been constructed.
        override_score_task (bool): Optional argument which indicates if it is an override score or not.
    """
    def get_student():
        """ Fetches student instance if an identifier is provided, else return None """
        if student_identifier is None:
            return None

        student_identifier_type = 'email' if '@' in student_identifier else 'username'
        student_query_params = {student_identifier_type: student_identifier}
        return User.objects.get(**student_query_params)

    module_query_params = {
        'course_id': course_id,
        'module_state_keys': usage_keys
    }

    # give the option of updating an individual student. If not specified,
    # then updates all students who have responded to a problem so far
    student = get_student()
    if student:
        module_query_params['student_id'] = student.id

    student_modules = StudentModule.get_state_by_params(**module_query_params)
    if filter_fcn is not None:
        student_modules = filter_fcn(student_modules)

    can_create_student_modules = (override_score_task
                                  and (student_modules.count() == 0)
                                  and student is not None)
    if can_create_student_modules:
        student_modules = [
            StudentModule.objects.get_or_create(course_id=course_id,
                                                student=student,
                                                module_state_key=key)[0]
            for key in usage_keys
        ]
    return student_modules
예제 #8
0
    def make_student_module(self, block, name, **state):
        user = User(username=name)
        user.save()
        profile = UserProfile(user=user, name=name)
        profile.save()
        module = StudentModule(
            module_state_key=block.location,
            student=user,
            course_id=self.course_id,
            state=json.dumps(state))
        module.save()

        self.addCleanup(profile.delete)
        self.addCleanup(module.delete)
        self.addCleanup(user.delete)

        return module
예제 #9
0
    def make_student_module(self, block, name, **state):
        user = User(username=name)
        user.save()
        profile = UserProfile(user=user, name=name)
        profile.save()
        module = StudentModule(
            module_state_key=block.location,
            student=user,
            course_id=self.course_id,
            state=json.dumps(state))
        module.save()

        self.addCleanup(profile.delete)
        self.addCleanup(module.delete)
        self.addCleanup(user.delete)

        return module
예제 #10
0
    def make_student(self, block, name, **state):
        answer = {}
        for key in ('sha1', 'mimetype', 'filename'):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop('score', None)

        user = User(username=name)
        user.save()
        profile = UserProfile(user=user, name=name)
        profile.save()
        module = StudentModule(
            module_state_key=block.location,
            student=user,
            course_id=self.course_id,
            state=json.dumps(state))
        module.save()

        anonymous_id = anonymous_id_for_user(user, self.course_id)
        item = StudentItem(
            student_id=anonymous_id,
            course_id=self.course_id,
            item_id=block.block_id,
            item_type='sga')
        item.save()

        if answer:
            student_id = block.student_submission_id(anonymous_id)
            submission = submissions_api.create_submission(student_id, answer)
            if score is not None:
                submissions_api.set_score(
                    submission['uuid'], score, block.max_score())
        else:
            submission = None

        self.addCleanup(item.delete)
        self.addCleanup(profile.delete)
        self.addCleanup(module.delete)
        self.addCleanup(user.delete)

        return {
            'module': module,
            'item': item,
            'submission': submission,
        }
예제 #11
0
def _get_modules_to_update(course_id, usage_keys, student_identifier, filter_fcn, override_score_task=False):
    """
    Fetches a StudentModule instances for a given `course_id`, `student` object, and `usage_keys`.

    StudentModule instances are those that match the specified `course_id` and `module_state_key`.
    If `student_identifier` is not None, it is used as an additional filter to limit the modules to those belonging
    to that student. If `student_identifier` is None, performs update on modules for all students on the specified
    problem.
    The matched instances are then applied `filter_fcn` if not None. It filters out the matched instances.
    It takes one argument, which is the query being filtered, and returns the filtered version of the query.
    If `override_score_task` is True and we there were not matching instances of StudentModule, try to create
    those instances. This is only for override scores and the use case is for learners that have missed the deadline.

    Arguments:
        course_id(str): The unique identifier for the course.
        usage_keys(list): List of UsageKey objects
        student_identifier(str): Identifier for a student or None. The identifier can be either username or email
        filter_fcn: If it is not None, it is applied to the query that has been constructed.
        override_score_task (bool): Optional argument which indicates if it is an override score or not.
    """
    def get_student():
        """ Fetches student instance if an identifier is provided, else return None """
        if student_identifier is None:
            return None

        student_identifier_type = 'email' if '@' in student_identifier else 'username'
        student_query_params = {student_identifier_type: student_identifier}
        return User.objects.get(**student_query_params)

    module_query_params = {'course_id': course_id, 'module_state_keys': usage_keys}

    # give the option of updating an individual student. If not specified,
    # then updates all students who have responded to a problem so far
    student = get_student()
    if student:
        module_query_params['student_id'] = student.id

    student_modules = StudentModule.get_state_by_params(**module_query_params)
    if filter_fcn is not None:
        student_modules = filter_fcn(student_modules)

    can_create_student_modules = (override_score_task and (student_modules.count() == 0) and student is not None)
    if can_create_student_modules:
        student_modules = [
            StudentModule.objects.get_or_create(course_id=course_id, student=student, module_state_key=key)[0]
            for key in usage_keys
        ]
    return student_modules
예제 #12
0
    def generate_dummy_submission(student, block, course_key):
        """
        Generates a random answers for a specified user and block

        The currently supported blocks are poll and survey
        """
        location = block.location
        answer = {}

        if block.category == 'poll':
            # Possible answers come in this format:
            # ('G', {'img': None, 'img_alt': None, 'label': 'Green'})
            # and we only need the 'G' bit for saving the answer
            possible_answers = [answer for answer, _ in block.answers]
            # Answer format for StudentModule model:
            # {"submissions_count": 1, "choice": "R"}
            choice = random.choice(possible_answers)
            answer = {
                "submissions_count": 1,
                "choice": choice,
            }
        elif block.category == 'survey':
            # Questions come in this format:
            # ('enjoy', {'img': None, 'img_alt': None, 'label': 'Are you enjoying the course?'})
            # and we only need the 'enjoy' part
            questions = [question for question, _ in block.questions]
            # This happens similarly with answers
            possible_answers = [answer for answer, _ in block.answers]
            # Answer format for StudentModule model:
            # {"submissions_count": 1, "choices": {"enjoy": "Y", "learn": "Y", "recommend": "N"}}
            choices = {
                key: random.choice(possible_answers)
                for key in questions
            }
            answer = {
                "submissions_count": 1,
                "choices": choices,
            }

        return StudentModule(
            module_type='problem',
            module_state_key=location,
            student=student,
            course_id=course_key,
            state=json.dumps(answer),
        )
예제 #13
0
    def transform_block_filters(self, usage_info, block_structure):
        all_library_children = set()
        all_selected_children = set()
        for block_key in block_structure:
            if block_key.block_type != 'library_content':
                continue
            library_children = block_structure.get_children(block_key)
            if library_children:
                all_library_children.update(library_children)
                selected = []
                mode = block_structure.get_xblock_field(block_key, 'mode')
                max_count = block_structure.get_xblock_field(
                    block_key, 'max_count')

                # Retrieve "selected" json from LMS MySQL database.
                state_dict = get_student_module_as_dict(
                    usage_info.user, usage_info.course_key, block_key)
                for selected_block in state_dict.get('selected', []):
                    # Add all selected entries for this user for this
                    # library module to the selected list.
                    block_type, block_id = selected_block
                    usage_key = usage_info.course_key.make_usage_key(
                        block_type, block_id)
                    if usage_key in library_children:
                        selected.append(selected_block)

                # Update selected
                previous_count = len(selected)
                block_keys = LibraryContentModule.make_selection(
                    selected, library_children, max_count, mode)
                selected = block_keys['selected']

                # Save back any changes
                if any(block_keys[changed]
                       for changed in ('invalid', 'overlimit', 'added')):
                    state_dict['selected'] = list(selected)
                    StudentModule.save_state(
                        student=usage_info.user,
                        course_id=usage_info.course_key,
                        module_state_key=block_key,
                        defaults={
                            'state': json.dumps(state_dict),
                        },
                    )

                # publish events for analytics
                self._publish_events(
                    block_structure,
                    block_key,
                    previous_count,
                    max_count,
                    block_keys,
                    usage_info.user.id,
                )
                all_selected_children.update(
                    usage_info.course_key.make_usage_key(s[0], s[1])
                    for s in selected)

        def check_child_removal(block_key):
            """
            Return True if selected block should be removed.

            Block is removed if it is part of library_content, but has
            not been selected for current user, with staff as an exemption.
            """
            if usage_info.has_staff_access:
                return False
            if block_key not in all_library_children:
                return False
            if block_key in all_selected_children:
                return False
            return True

        return [block_structure.create_removal_filter(check_child_removal)]
예제 #14
0
    def transform_block_filters(self, usage_info, block_structure):
        all_library_children = set()
        all_selected_children = set()
        for block_key in block_structure:
            if block_key.block_type != 'library_content':
                continue
            library_children = block_structure.get_children(block_key)
            if library_children:
                all_library_children.update(library_children)
                selected = []
                mode = block_structure.get_xblock_field(block_key, 'mode')
                max_count = block_structure.get_xblock_field(block_key, 'max_count')

                # Retrieve "selected" json from LMS MySQL database.
                state_dict = get_student_module_as_dict(usage_info.user, usage_info.course_key, block_key)
                for selected_block in state_dict.get('selected', []):
                    # Add all selected entries for this user for this
                    # library module to the selected list.
                    block_type, block_id = selected_block
                    usage_key = usage_info.course_key.make_usage_key(block_type, block_id)
                    if usage_key in library_children:
                        selected.append(selected_block)

                # Update selected
                previous_count = len(selected)
                block_keys = LibraryContentModule.make_selection(selected, library_children, max_count, mode)
                selected = block_keys['selected']

                # Save back any changes
                if any(block_keys[changed] for changed in ('invalid', 'overlimit', 'added')):
                    state_dict['selected'] = list(selected)
                    random.shuffle(state_dict['selected'])
                    StudentModule.save_state(
                        student=usage_info.user,
                        course_id=usage_info.course_key,
                        module_state_key=block_key,
                        defaults={
                            'state': json.dumps(state_dict),
                        },
                    )

                # publish events for analytics
                self._publish_events(
                    block_structure,
                    block_key,
                    previous_count,
                    max_count,
                    block_keys,
                    usage_info.user.id,
                )
                all_selected_children.update(usage_info.course_key.make_usage_key(s[0], s[1]) for s in selected)

        def check_child_removal(block_key):
            """
            Return True if selected block should be removed.

            Block is removed if it is part of library_content, but has
            not been selected for current user, with staff as an exemption.
            """
            if usage_info.has_staff_access:
                return False
            if block_key not in all_library_children:
                return False
            if block_key in all_selected_children:
                return False
            return True

        return [block_structure.create_removal_filter(check_child_removal)]
예제 #15
0
    def setUp(self):
        """
        Fixtures.
        """
        due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc)
        course = CourseFactory.create()
        week1 = ItemFactory.create(due=due)
        week2 = ItemFactory.create(due=due)
        week3 = ItemFactory.create(due=due)
        course.children = [
            week1.location.url(),
            week2.location.url(),
            week3.location.url()
        ]

        homework = ItemFactory.create(parent_location=week1.location, due=due)
        week1.children = [homework.location.url()]

        user1 = UserFactory.create()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=week1.location.url()).save()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=week2.location.url()).save()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=week3.location.url()).save()
        StudentModule(state='{}',
                      student_id=user1.id,
                      course_id=course.id,
                      module_state_key=homework.location.url()).save()

        user2 = UserFactory.create()
        StudentModule(state='{}',
                      student_id=user2.id,
                      course_id=course.id,
                      module_state_key=week1.location.url()).save()
        StudentModule(state='{}',
                      student_id=user2.id,
                      course_id=course.id,
                      module_state_key=homework.location.url()).save()

        user3 = UserFactory.create()
        StudentModule(state='{}',
                      student_id=user3.id,
                      course_id=course.id,
                      module_state_key=week1.location.url()).save()
        StudentModule(state='{}',
                      student_id=user3.id,
                      course_id=course.id,
                      module_state_key=homework.location.url()).save()

        self.course = course
        self.week1 = week1
        self.homework = homework
        self.week2 = week2
        self.user1 = user1
        self.user2 = user2