예제 #1
0
    def _update_last_visited_sequential(self, request, course, chapter_id, sequential_id, modification_date):
        '''
        course -- xmodule
        '''
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)
        try:
            chapter_descriptor = get_item(course.id, 'chapter', chapter_id)
            sequential_descriptor = get_item(course.id, 'sequential', sequential_id)
        except ItemNotFoundError:
            raise error.Error(status=status.HTTP_404_NOT_FOUND)
        course_descriptor = course
        course = get_module_for_descriptor(
                request.user, request, course_descriptor, field_data_cache, course.id)
        chapter = get_module_for_descriptor(
                request.user, request, chapter_descriptor, field_data_cache, course.id)
        sequential = get_module_for_descriptor(
                request.user, request, sequential_descriptor, field_data_cache, course.id)
        if modification_date:
            key = KeyValueStore.Key(
                scope=Scope.user_state,
                user_id=request.user.id,
                block_scope_id=course.location,
                field_name=None
            )
            student_module = field_data_cache.find(key)
            if student_module:
                original_store_date = student_module.modified
                if modification_date < original_store_date:
                    # old modification date so skip update
                    return self._get_course_info(request, course)

        self.save_sequential_position(course, chapter, sequential)
        return self._get_course_info(request, course)
예제 #2
0
 def test_rebinding_same_user(self, block_type):
     request = self.request_factory.get("")
     request.user = self.mock_user
     course = CourseFactory()
     descriptor = ItemFactory(category=block_type, parent=course)
     field_data_cache = FieldDataCache([self.toy_course, descriptor], self.toy_course.id, self.mock_user)
     render.get_module_for_descriptor(self.mock_user, request, descriptor, field_data_cache, self.toy_course.id)
     render.get_module_for_descriptor(self.mock_user, request, descriptor, field_data_cache, self.toy_course.id)
예제 #3
0
 def test_rebinding_same_user(self, block_type):
     request = self.request_factory.get('')
     request.user = self.mock_user
     course = CourseFactory()
     descriptor = ItemFactory(category=block_type, parent=course)
     field_data_cache = FieldDataCache([self.toy_course, descriptor],
                                       self.toy_course.id, self.mock_user)
     render.get_module_for_descriptor(self.mock_user, request, descriptor,
                                      field_data_cache, self.toy_course.id)
     render.get_module_for_descriptor(self.mock_user, request, descriptor,
                                      field_data_cache, self.toy_course.id)
예제 #4
0
 def create_module(descriptor):
     '''creates an XModule instance given a descriptor'''
     # TODO: We need the request to pass into here. If we could forego that, our arguments
     # would be simpler
     return get_module_for_descriptor(
         student, request, descriptor, field_data_cache, course.id, course=course
     )
예제 #5
0
    def _update_last_visited_module_id(self, request, course, module_key, modification_date):
        """
        Saves the module id if the found modification_date is less recent than the passed modification date
        """
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)
        try:
            module_descriptor = modulestore().get_item(module_key)
        except ItemNotFoundError:
            return Response(errors.ERROR_INVALID_MODULE_ID, status=400)
        module = get_module_for_descriptor(request.user, request, module_descriptor, field_data_cache, course.id)

        if modification_date:
            key = KeyValueStore.Key(
                scope=Scope.user_state,
                user_id=request.user.id,
                block_scope_id=course.location,
                field_name=None
            )
            student_module = field_data_cache.find(key)
            if student_module:
                original_store_date = student_module.modified
                if modification_date < original_store_date:
                    # old modification date so skip update
                    return self._get_course_info(request, course)

        save_positions_recursively_up(request.user, request, field_data_cache, module)
        return self._get_course_info(request, course)
예제 #6
0
    def recurse_blocks_nav(self, request_info, result_data, block_info):
        """
        A depth-first recursive function that supports calculation of both the list of blocks in the course
        and the navigation information up to the requested navigation_depth of the course.

        Arguments:
            request_info - Object encapsulating the request information.
            result_data - Running result data that is updated during the recursion.
            block_info - Information about the current block in the recursion.
        """
        # bind user data to the block
        block_info.block = get_module_for_descriptor(
            request_info.request.user,
            request_info.request,
            block_info.block,
            request_info.field_data_cache,
            request_info.course.id,
            course=request_info.course
        )

        # verify the user has access to this block
        if (block_info.block is None or not has_access(
                request_info.request.user,
                'load',
                block_info.block,
                course_key=request_info.course.id
        )):
            return

        # add the block's value to the result
        result_data.blocks[unicode(block_info.block.location)] = block_info.value

        # descendants
        self.update_descendants(request_info, result_data, block_info)

        # children: recursively call the function for each of the children, while supporting dynamic children.
        if block_info.block.has_children:
            block_info.children = get_dynamic_descriptor_children(block_info.block, request_info.request.user.id)
            for child in block_info.children:
                self.recurse_blocks_nav(
                    request_info,
                    result_data,
                    self.BlockInfo(child, request_info, parent_block_info=block_info)
                )

        # block count
        self.update_block_count(request_info, result_data, block_info)

        # block JSON data
        self.add_block_json(request_info, block_info)

        # multi-device support
        if 'multi_device' in request_info.fields:
            block_info.value['multi_device'] = block_info.block.has_support(
                getattr(block_info.block, 'student_view', None),
                'multi_device'
            )

        # additional fields
        self.add_additional_fields(request_info, block_info)
예제 #7
0
def get_module_combinedopenended(request, course, location, isupload):
    location = course.location[0]+'://'+course.location[1]+'/'+course.location[2]+'/chapter/'+location
    section_descriptor = modulestore().get_instance(course.id, location, depth=None)
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, section_descriptor, depth=None)
    descriptor = modulestore().get_instance_items(course.id, location,'combinedopenended',depth=None)
    content = []
    
    for x in range(len(descriptor)):
        module = get_module_for_descriptor(request.user, request, descriptor[x][1], field_data_cache, course.id,
                                         position=None, wrap_xmodule_display=True, grade_bucket_type=None,
                                         static_asset_path='')
        con = module.runtime.render(module, None, 'student_view').content
        confirm = Get_confirm()
        confirm.feed(con)
        if confirm.score_urls[0] == 'correct' and confirm.state_urls[0] == 'done':
            #content.append(add_edit_tool(con,course,descriptor[x]))
            #import logging
            #log = logging.getLogger("tracking")
            #log.debug("descriptor_location===============================\n:"+str(con)+"\n===========================")
            #c_info = Get_combinedopenended_info()
            #c_info.feed(con)
            title, body = Get_combinedopenended_info(con)
            content.append(create_discussion(request, course, descriptor[x][1].location[4], location,{'title':title,'body':body}))

    return content
예제 #8
0
def edxnotes(request, course_id):
    """
    Displays the EdxNotes page.
    """
    course_key = CourseKey.from_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)

    if not is_feature_enabled(course):
        raise Http404

    try:
        notes = get_notes(request.user, course)
    except EdxNotesServiceUnavailable:
        raise Http404

    context = {
        "course": course,
        "search_endpoint": reverse("search_notes", kwargs={"course_id": course_id}),
        "notes": notes,
        "debug": json.dumps(settings.DEBUG),
        'position': None,
    }

    if not notes:
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2
        )
        course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course_key)
        position = get_course_position(course_module)
        if position:
            context.update({
                'position': position,
            })

    return render_to_response("edxnotes/edxnotes.html", context)
예제 #9
0
    def test_repeated_course_module_instantiation(self, loops, default_store, course_depth):

        with modulestore().default_store(default_store):
            course = CourseFactory.create()
            chapter = ItemFactory(parent=course, category='chapter', graded=True)
            section = ItemFactory(parent=chapter, category='sequential')
            __ = ItemFactory(parent=section, category='problem')

        fake_request = self.factory.get(
            reverse('progress', kwargs={'course_id': unicode(course.id)})
        )

        course = modulestore().get_course(course.id, depth=course_depth)

        for _ in xrange(loops):
            field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
                course.id, self.user, course, depth=course_depth
            )
            course_module = get_module_for_descriptor(
                self.user,
                fake_request,
                course,
                field_data_cache,
                course.id,
                course=course
            )
            for chapter in course_module.get_children():
                for section in chapter.get_children():
                    for item in section.get_children():
                        self.assertTrue(item.graded)
예제 #10
0
    def _iter_scorable_xmodules(block_structure):
        """
        Loop through all the blocks locators in the block structure, and retrieve
        the module (XModule or XBlock) associated with that locator.

        For implementation reasons, we need to pull the max_score from the
        XModule, even though the data is not user specific.  Here we bind the
        data to a SystemUser.
        """
        request = RequestFactory().get('/dummy-collect-max-grades')
        user = SystemUser()
        request.user = user
        request.session = {}
        root_block = block_structure.get_xblock(block_structure.root_block_usage_key)
        course_key = block_structure.root_block_usage_key.course_key
        cache = FieldDataCache.cache_for_descriptor_descendents(
            course_id=course_key,
            user=request.user,
            descriptor=root_block,
            descriptor_filter=lambda descriptor: descriptor.has_score,
        )
        for block_locator in block_structure.post_order_traversal():
            block = block_structure.get_xblock(block_locator)
            if getattr(block, 'has_score', False):
                module = get_module_for_descriptor(user, request, block, cache, course_key)
                yield module
예제 #11
0
    def _update_last_visited_module_id(self, request, course, module_key, modification_date):
        """
        Saves the module id if the found modification_date is less recent than the passed modification date
        """
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)
        try:
            module_descriptor = modulestore().get_item(module_key)
        except ItemNotFoundError:
            return Response(errors.ERROR_INVALID_MODULE_ID, status=400)
        module = get_module_for_descriptor(
            request.user, request, module_descriptor, field_data_cache, course.id, course=course
        )

        if modification_date:
            key = KeyValueStore.Key(
                scope=Scope.user_state,
                user_id=request.user.id,
                block_scope_id=course.location,
                field_name='position'
            )
            original_store_date = field_data_cache.last_modified(key)
            if original_store_date is not None and modification_date < original_store_date:
                # old modification date so skip update
                return self._get_course_info(request, course)

        save_positions_recursively_up(request.user, request, field_data_cache, module, course=course)
        return self._get_course_info(request, course)
예제 #12
0
def _fire_score_changed_for_block(course_id, student, block, module_state_key):
    """
    Fires a SCORE_CHANGED event for the given module. The earned points are
    always zero. We must retrieve the possible points from the XModule, as
    noted below.
    """
    if block and block.has_score:
        cache = FieldDataCache.cache_for_descriptor_descendents(
            course_id=course_id, user=student, descriptor=block, depth=0)
        # For implementation reasons, we need to pull the max_score from the XModule,
        # even though the data is not user-specific.  Here we bind the data to the
        # current user.
        request = crum.get_current_request()
        module = get_module_for_descriptor(user=student,
                                           request=request,
                                           descriptor=block,
                                           field_data_cache=cache,
                                           course_key=course_id)
        max_score = module.max_score()
        if max_score is None:
            return
        else:
            points_earned, points_possible = weighted_score(
                0, max_score, getattr(module, 'weight', None))
    else:
        points_earned, points_possible = 0, 0
    SCORE_CHANGED.send(sender=None,
                       points_possible=points_possible,
                       points_earned=points_earned,
                       user=student,
                       course_id=unicode(course_id),
                       usage_id=unicode(module_state_key))
예제 #13
0
def prep_course_for_grading(course, request):
    """Set up course module for overrides to function properly"""
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, course, depth=2)
    course = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id, course=course)

    course._field_data_cache = {}  # pylint: disable=protected-access
    course.set_grading_policy(course.grading_policy)
예제 #14
0
    def _last_visited_module_path(self, request, course):
        """
        Returns the path from the last module visited by the current user in the given course up to
        the course module. If there is no such visit, the first item deep enough down the course
        tree is used.
        """
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)

        course_module = get_module_for_descriptor(request.user,
                                                  request,
                                                  course,
                                                  field_data_cache,
                                                  course.id,
                                                  course=course)

        path = [course_module]
        chapter = get_current_child(course_module, min_depth=2)
        if chapter is not None:
            path.append(chapter)
            section = get_current_child(chapter, min_depth=1)
            if section is not None:
                path.append(section)

        path.reverse()
        return path
예제 #15
0
def save_positions_recursively_up(user,
                                  request,
                                  field_data_cache,
                                  xmodule,
                                  course=None):
    """
    Recurses up the course tree starting from a leaf
    Saving the position property based on the previous node as it goes
    """
    current_module = xmodule

    while current_module:
        parent_location = modulestore().get_parent_location(
            current_module.location)
        parent = None
        if parent_location:
            parent_descriptor = modulestore().get_item(parent_location)
            parent = get_module_for_descriptor(
                user,
                request,
                parent_descriptor,
                field_data_cache,
                current_module.location.course_key,
                course=course)

        if parent and hasattr(parent, 'position'):
            save_child_position(parent, current_module.location.name)

        current_module = parent
예제 #16
0
파일: views.py 프로젝트: 4eek/edx-platform
    def recurse_blocks_nav(self, request_info, result_data, block_info):
        """
        A depth-first recursive function that supports calculation of both the list of blocks in the course
        and the navigation information up to the requested navigation_depth of the course.

        Arguments:
            request_info - Object encapsulating the request information.
            result_data - Running result data that is updated during the recursion.
            block_info - Information about the current block in the recursion.
        """
        # bind user data to the block
        block_info.block = get_module_for_descriptor(
            request_info.request.user,
            request_info.request,
            block_info.block,
            request_info.field_data_cache,
            request_info.course.id,
            course=request_info.course
        )

        # verify the user has access to this block
        if (block_info.block is None or not has_access(
                request_info.request.user,
                'load',
                block_info.block,
                course_key=request_info.course.id
        )):
            return

        # add the block's value to the result
        result_data.blocks[unicode(block_info.block.location)] = block_info.value

        # descendants
        self.update_descendants(request_info, result_data, block_info)

        # children: recursively call the function for each of the children, while supporting dynamic children.
        if block_info.block.has_children:
            block_info.children = get_dynamic_descriptor_children(block_info.block, request_info.request.user.id)
            for child in block_info.children:
                self.recurse_blocks_nav(
                    request_info,
                    result_data,
                    self.BlockInfo(child, request_info, parent_block_info=block_info)
                )

        # block count
        self.update_block_count(request_info, result_data, block_info)

        # block JSON data
        self.add_block_json(request_info, block_info)

        # multi-device support
        if 'multi_device' in request_info.fields:
            block_info.value['multi_device'] = block_info.block.has_support(
                getattr(block_info.block, 'student_view', None),
                'multi_device'
            )

        # additional fields
        self.add_additional_fields(request_info, block_info)
예제 #17
0
def get_last_accessed_courseware(course, request, user):
    """
    Returns a tuple containing the courseware module (URL, id) that the user last accessed,
    or (None, None) if it cannot be found.
    """
    # TODO: convert this method to use the Course Blocks API
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course.id, request.user, course, depth=2)
    course_module = get_module_for_descriptor(user,
                                              request,
                                              course,
                                              field_data_cache,
                                              course.id,
                                              course=course)
    chapter_module = get_current_child(course_module)
    if chapter_module is not None:
        section_module = get_current_child(chapter_module)
        if section_module is not None:
            url = reverse('courseware_section',
                          kwargs={
                              'course_id': unicode(course.id),
                              'chapter': chapter_module.url_name,
                              'section': section_module.url_name
                          })
            return (url, section_module.url_name)
    return (None, None)
예제 #18
0
    def test_repeated_course_module_instantiation(self, loops, default_store,
                                                  course_depth):

        with modulestore().default_store(default_store):
            course = CourseFactory.create()
            chapter = ItemFactory(parent=course,
                                  category='chapter',
                                  graded=True)
            section = ItemFactory(parent=chapter, category='sequential')
            __ = ItemFactory(parent=section, category='problem')

        fake_request = self.factory.get(
            reverse('progress', kwargs={'course_id':
                                        six.text_type(course.id)}))

        course = modulestore().get_course(course.id, depth=course_depth)

        for _ in range(loops):
            field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
                course.id, self.user, course, depth=course_depth)
            course_module = get_module_for_descriptor(self.user,
                                                      fake_request,
                                                      course,
                                                      field_data_cache,
                                                      course.id,
                                                      course=course)
            for chapter in course_module.get_children():
                for section in chapter.get_children():
                    for item in section.get_children():
                        self.assertTrue(item.graded)
예제 #19
0
    def _iter_scorable_xmodules(block_structure):
        """
        Loop through all the blocks locators in the block structure, and retrieve
        the module (XModule or XBlock) associated with that locator.

        For implementation reasons, we need to pull the max_score from the
        XModule, even though the data is not user specific.  Here we bind the
        data to a SystemUser.
        """
        request = RequestFactory().get('/dummy-collect-max-grades')
        user = SystemUser()
        request.user = user
        request.session = {}
        root_block = block_structure.get_xblock(
            block_structure.root_block_usage_key)
        course_key = block_structure.root_block_usage_key.course_key
        cache = FieldDataCache.cache_for_descriptor_descendents(
            course_id=course_key,
            user=request.user,
            descriptor=root_block,
            descriptor_filter=lambda descriptor: descriptor.has_score,
        )
        for block_locator in block_structure.post_order_traversal():
            block = block_structure.get_xblock(block_locator)
            if getattr(block, 'has_score', False):
                module = get_module_for_descriptor(user, request, block, cache,
                                                   course_key)
                yield module
예제 #20
0
def edxnotes_visibility(request, course_id):
    """
    Handle ajax call from "Show notes" checkbox.
    """
    course_key = CourseKey.from_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)
    field_data_cache = FieldDataCache([course], course_key, request.user)
    course_module = get_module_for_descriptor(request.user,
                                              request,
                                              course,
                                              field_data_cache,
                                              course_key,
                                              course=course)

    if not is_feature_enabled(course, request.user):
        raise Http404

    try:
        visibility = json.loads(request.body)["visibility"]
        course_module.edxnotes_visibility = visibility
        course_module.save()
        return JsonResponse(status=200)
    except (ValueError, KeyError):
        log.warning(
            "Could not decode request body as JSON and find a boolean visibility field: '%s'",
            request.body)
        return JsonResponseBadRequest()
예제 #21
0
    def inner_get_module(descriptor):
        """
        Delegate to get_module_for_descriptor (imported here to avoid circular reference)
        """
        from courseware.module_render import get_module_for_descriptor

        field_data_cache = FieldDataCache([descriptor], course.id, request.user)
        return get_module_for_descriptor(request.user, request, descriptor, field_data_cache, course.id, course=course)
def get_discussion_context(request, course, location, parent_location,portfolio_user):
        section_descriptor = modulestore().get_instance(course.id, parent_location, depth=None)
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, portfolio_user, section_descriptor, depth=None)
        descriptor = modulestore().get_item(location)
        module = get_module_for_descriptor(portfolio_user, request, descriptor, field_data_cache, course.id,
                                     position=None, wrap_xmodule_display=True, grade_bucket_type=None,
                                     static_asset_path='')
        return module.runtime.render(module, None, 'student_view').content
예제 #23
0
 def _get_course_module(self):
     """
     Returns the course module.
     """
     field_data_cache = FieldDataCache([self.course], self.course.id,
                                       self.user)
     return get_module_for_descriptor(self.user, MagicMock(), self.course,
                                      field_data_cache, self.course.id)
예제 #24
0
 def _get_course_module(self):
     """
     Returns the course module.
     """
     field_data_cache = FieldDataCache([self.course], self.course.id, self.user)
     return get_module_for_descriptor(
         self.user, MagicMock(), self.course, field_data_cache, self.course.id, course=self.course
     )
예제 #25
0
def get_course_content(request, user, course_key, course_descriptor):  # pylint: disable=W0613
    """
    Returns course content
    """
    field_data_cache = FieldDataCache([course_descriptor], course_key, user)
    course_content = module_render.get_module_for_descriptor(
        user, request, course_descriptor, field_data_cache, course_key)
    return course_content
예제 #26
0
def get_course_child_content(request, user, course_key, child_descriptor):
    """
    Returns course child content
    """
    field_data_cache = FieldDataCache([child_descriptor], course_key, user)
    child_content = module_render.get_module_for_descriptor(
        user, request, child_descriptor, field_data_cache, course_key)
    return child_content
예제 #27
0
def get_course_child_content(request, user, course_key, child_descriptor):
    field_data_cache = FieldDataCache([child_descriptor], course_key, user)
    child_content = module_render.get_module_for_descriptor(
        user,
        request,
        child_descriptor,
        field_data_cache,
        course_key)
    return child_content
예제 #28
0
 def inner_get_module(descriptor):
     """
     Delegate to get_module_for_descriptor (imported here to avoid circular reference)
     """
     from courseware.module_render import get_module_for_descriptor
     field_data_cache = FieldDataCache([descriptor], course.id,
                                       request.user)
     return get_module_for_descriptor(request.user, request, descriptor,
                                      field_data_cache, course.id)
예제 #29
0
def prep_course_for_grading(course, request):
    """Set up course module for overrides to function properly"""
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course.id, request.user, course, depth=2)
    course = get_module_for_descriptor(
        request.user, request, course, field_data_cache, course.id, course=course
    )

    course._field_data_cache = {}  # pylint: disable=protected-access
    course.set_grading_policy(course.grading_policy)
예제 #30
0
 def create_module(descriptor):
     """
     Factory method for creating and binding a module for the given descriptor.
     """
     field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
         self.course_id, self.request.user, descriptor, depth=0,
     )
     return get_module_for_descriptor(
         self.request.user, self.request, descriptor, field_data_cache, self.course_id
     )
예제 #31
0
 def create_module(descriptor):
     """
     Factory method for creating and binding a module for the given descriptor.
     """
     field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
         self.course_id, self.request.user, descriptor, depth=0,
     )
     return get_module_for_descriptor(
         self.request.user, self.request, descriptor, field_data_cache, self.course_id
     )
예제 #32
0
    def test_changing_position_works(self):
        # Make a mock FieldDataCache for this course, so we can get the course module
        mock_field_data_cache = FieldDataCache([self.course], self.course.id, self.student)
        course = get_module_for_descriptor(
            self.student, MagicMock(name="request"), self.course, mock_field_data_cache, self.course.id
        )

        # Now that we have the course, change the position and save, nothing should explode!
        course.position = 2
        course.save()
예제 #33
0
 def create_module(descriptor):
     '''creates an XModule instance given a descriptor'''
     # TODO: We need the request to pass into here. If we could forego that, our arguments
     # would be simpler
     return get_module_for_descriptor(student,
                                      request,
                                      descriptor,
                                      field_data_cache,
                                      course.id,
                                      course=course)
예제 #34
0
def ccx_grades_csv(request, course):
    """
    Download grades as CSV.
    """
    # Need course module for overrides to function properly
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course.id, request.user, course, depth=2)
    course = get_module_for_descriptor(request.user, request, course,
                                       field_data_cache, course.id)
    ccx = get_ccx_for_coach(course, request.user)
    with ccx_context(ccx):
        # The grading policy for the MOOC is probably already cached.  We need
        # to make sure we have the CCX grading policy loaded.
        course._field_data_cache = {}  # pylint: disable=protected-access
        course.set_grading_policy(course.grading_policy)

        enrolled_students = User.objects.filter(
            ccxmembership__ccx=ccx, ccxmembership__active=1).order_by(
                'username').select_related("profile")
        grades = iterate_grades_for(course, enrolled_students)

        header = None
        rows = []
        for student, gradeset, __ in grades:
            if gradeset:
                # We were able to successfully grade this student for this
                # course.
                if not header:
                    # Encode the header row in utf-8 encoding in case there are
                    # unicode characters
                    header = [
                        section['label'].encode('utf-8')
                        for section in gradeset[u'section_breakdown']
                    ]
                    rows.append(["id", "email", "username", "grade"] + header)

                percents = {
                    section['label']: section.get('percent', 0.0)
                    for section in gradeset[u'section_breakdown']
                    if 'label' in section
                }

                row_percents = [percents.get(label, 0.0) for label in header]
                rows.append([
                    student.id, student.email, student.username,
                    gradeset['percent']
                ] + row_percents)

        buf = StringIO()
        writer = csv.writer(buf)
        for row in rows:
            writer.writerow(row)

        return HttpResponse(buf.getvalue(), content_type='text/plain')
예제 #35
0
    def test_changing_position_works(self):
        # Make a mock FieldDataCache for this course, so we can get the course module
        mock_field_data_cache = FieldDataCache([self.course], self.course.id,
                                               self.student)
        course = get_module_for_descriptor(self.student,
                                           MagicMock(name='request'),
                                           self.course, mock_field_data_cache,
                                           self.course.id)

        # Now that we have the course, change the position and save, nothing should explode!
        course.position = 2
        course.save()
def _get_course_module(course_descriptor, user):
    # Fake a request to fool parts of the courseware that want to inspect it.
    request = get_request_or_stub()
    request.user = user

    # Now evil modulestore magic to inflate our descriptor with user state and
    # permissions checks.
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course_descriptor.id, user, course_descriptor, depth=1, read_only=True,
    )
    return get_module_for_descriptor(
        user, request, course_descriptor, field_data_cache, course_descriptor.id, course=course_descriptor,
    )
예제 #37
0
 def inner_get_module(descriptor):
     """
     Delegate to get_module_for_descriptor
     """
     field_data_cache = FieldDataCache([descriptor], course.id, user)
     return get_module_for_descriptor(
         user,
         _get_mock_request(user),
         descriptor,
         field_data_cache,
         course.id,
         course=course
     )
예제 #38
0
def _get_course_module(course_descriptor, user):
    # Fake a request to fool parts of the courseware that want to inspect it.
    request = get_request_or_stub()
    request.user = user

    # Now evil modulestore magic to inflate our descriptor with user state and
    # permissions checks.
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course_descriptor.id, user, course_descriptor, depth=1, read_only=True,
    )
    return get_module_for_descriptor(
        user, request, course_descriptor, field_data_cache, course_descriptor.id, course=course_descriptor,
    )
def get_chaper_for_course(request, course, active_chapter):
    model_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)
    course_module = get_module_for_descriptor(request.user, request, course, model_data_cache, course.id)
    if course_module is None:
        return None

    chapters = list()
    for chapter in course_module.get_display_items():
        chapters.append({'display_name': chapter.display_name_with_default,
                         'url_name': chapter.url_name,
                         'active': chapter.url_name == active_chapter})
    return chapters
예제 #40
0
def ccx_grades_csv(request, course):
    """
    Download grades as CSV.
    """
    # Need course module for overrides to function properly
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course.id, request.user, course, depth=2)
    course = get_module_for_descriptor(
        request.user, request, course, field_data_cache, course.id)
    ccx = get_ccx_for_coach(course, request.user)
    with ccx_context(ccx):
        # The grading policy for the MOOC is probably already cached.  We need
        # to make sure we have the CCX grading policy loaded.
        course._field_data_cache = {}  # pylint: disable=protected-access
        course.set_grading_policy(course.grading_policy)

        enrolled_students = User.objects.filter(
            ccxmembership__ccx=ccx,
            ccxmembership__active=1
        ).order_by('username').select_related("profile")
        grades = iterate_grades_for(course, enrolled_students)

        header = None
        rows = []
        for student, gradeset, __ in grades:
            if gradeset:
                # We were able to successfully grade this student for this
                # course.
                if not header:
                    # Encode the header row in utf-8 encoding in case there are
                    # unicode characters
                    header = [section['label'].encode('utf-8')
                              for section in gradeset[u'section_breakdown']]
                    rows.append(["id", "email", "username", "grade"] + header)

                percents = {
                    section['label']: section.get('percent', 0.0)
                    for section in gradeset[u'section_breakdown']
                    if 'label' in section
                }

                row_percents = [percents.get(label, 0.0) for label in header]
                rows.append([student.id, student.email, student.username,
                             gradeset['percent']] + row_percents)

        buf = StringIO()
        writer = csv.writer(buf)
        for row in rows:
            writer.writerow(row)

        return HttpResponse(buf.getvalue(), content_type='text/plain')
예제 #41
0
def ccx_gradebook(request, course):
    """
    Show the gradebook for this CCX.
    """
    # Need course module for overrides to function properly
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course.id, request.user, course, depth=2)
    course = get_module_for_descriptor(request.user, request, course,
                                       field_data_cache, course.id)

    ccx = get_ccx_for_coach(course, request.user)
    with ccx_context(ccx):
        # The grading policy for the MOOC is probably already cached.  We need
        # to make sure we have the CCX grading policy loaded.
        course._field_data_cache = {}  # pylint: disable=protected-access
        course.set_grading_policy(course.grading_policy)

        enrolled_students = User.objects.filter(
            ccxmembership__ccx=ccx, ccxmembership__active=1).order_by(
                'username').select_related("profile")

        student_info = [{
            'username':
            student.username,
            'id':
            student.id,
            'email':
            student.email,
            'grade_summary':
            student_grades(student, request, course),
            'realname':
            student.profile.name,
        } for student in enrolled_students]

        return render_to_response(
            'courseware/gradebook.html', {
                'students':
                student_info,
                'course':
                course,
                'course_id':
                course.id,
                'staff_access':
                request.user.is_staff,
                'ordered_grades':
                sorted(course.grade_cutoffs.items(),
                       key=lambda i: i[1],
                       reverse=True),
            })
예제 #42
0
def edxnotes(request, course_id):
    """
    Displays the EdxNotes page.

    Arguments:
        request: HTTP request object
        course_id: course id

    Returns:
        Rendered HTTP response.
    """
    course_key = CourseKey.from_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)

    if not is_feature_enabled(course, request.user):
        raise Http404

    notes_info = get_notes(request, course)
    has_notes = (len(notes_info.get('results')) > 0)
    context = {
        "course": course,
        "notes_endpoint": reverse("notes", kwargs={"course_id": course_id}),
        "notes": notes_info,
        "page_size": DEFAULT_PAGE_SIZE,
        "debug": settings.DEBUG,
        'position': None,
        'disabled_tabs': settings.NOTES_DISABLED_TABS,
        'has_notes': has_notes,
    }

    if not has_notes:
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)
        course_module = get_module_for_descriptor(request.user,
                                                  request,
                                                  course,
                                                  field_data_cache,
                                                  course_key,
                                                  course=course)
        position = get_course_position(course_module)
        if position:
            context.update({
                'position': position,
            })

    return render_to_response("edxnotes/edxnotes.html", context)
예제 #43
0
def get_section_id(request, course, discussion_id):
    with modulestore().bulk_operations(course.id):
        course_module = get_module_for_descriptor(request.user,
                                                  request,
                                                  course,
                                                  None,
                                                  course.id,
                                                  course=course)

    for chapter in course_module.get_children():
        for section in chapter.get_children():
            for unit in section.get_children():
                for vertical in unit.get_children():
                    if vertical.category == 'discussion':
                        if vertical.discussion_id == discussion_id:
                            section_id = section.url_name
                            return section_id
def get_module_combinedopenended(request, course, location, isupload):
    location = course.location[0]+'://'+course.location[1]+'/'+course.location[2]+'/chapter/'+location
    section_descriptor = modulestore().get_instance(course.id, location, depth=None)
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, section_descriptor, depth=None)
    descriptor = modulestore().get_instance_items(course.id, location,'combinedopenended',depth=None)
    content = []
    
    for x in range(len(descriptor)):
        module = get_module_for_descriptor(request.user, request, descriptor[x], field_data_cache, course.id,
                                         position=None, wrap_xmodule_display=True, grade_bucket_type=None,
                                         static_asset_path='')
        con = module.runtime.render(module, None, 'student_view').content
        confirm = Get_confirm()
        confirm.feed(con)
        if confirm.score_urls[0] == 'correct' and confirm.state_urls[0] == 'done':
            content.append(add_edit_tool(con,course,descriptor[x]))

    return content
예제 #45
0
    def _last_visited_module_id(self, request, course):
        """
        Returns the id of the last module visited by the current user in the given course.
        If there is no such visit returns the default (the first item deep enough down the course tree)
        """
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)

        course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id)
        current = course_module

        child = current
        while child:
            child = get_current_child(current)
            if child:
                current = child

        return current
예제 #46
0
def edxnotes(request, course_id):
    """
    Displays the EdxNotes page.

    Arguments:
        request: HTTP request object
        course_id: course id

    Returns:
        Rendered HTTP response.
    """
    course_key = CourseKey.from_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)

    if not is_feature_enabled(course, request.user):
        raise Http404

    notes_info = get_notes(request, course)
    has_notes = (len(notes_info.get('results')) > 0)
    context = {
        "course": course,
        "notes_endpoint": reverse("notes", kwargs={"course_id": course_id}),
        "notes": notes_info,
        "page_size": DEFAULT_PAGE_SIZE,
        "debug": settings.DEBUG,
        'position': None,
        'disabled_tabs': settings.NOTES_DISABLED_TABS,
        'has_notes': has_notes,
    }

    if not has_notes:
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2
        )
        course_module = get_module_for_descriptor(
            request.user, request, course, field_data_cache, course_key, course=course
        )
        position = get_course_position(course_module)
        if position:
            context.update({
                'position': position,
            })

    return render_to_response("edxnotes/edxnotes.html", context)
예제 #47
0
파일: views.py 프로젝트: rhndg/openedx
def ccx_gradebook(request, course):
    """
    Show the gradebook for this CCX.
    """
    # Need course module for overrides to function properly
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, course, depth=2)
    course = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id)

    ccx = get_ccx_for_coach(course, request.user)
    with ccx_context(ccx):
        # The grading policy for the MOOC is probably already cached.  We need
        # to make sure we have the CCX grading policy loaded.
        course._field_data_cache = {}  # pylint: disable=protected-access
        course.set_grading_policy(course.grading_policy)

        enrolled_students = (
            User.objects.filter(ccxmembership__ccx=ccx, ccxmembership__active=1)
            .order_by("username")
            .select_related("profile")
        )

        student_info = [
            {
                "username": student.username,
                "id": student.id,
                "email": student.email,
                "grade_summary": student_grades(student, request, course),
                "realname": student.profile.name,
            }
            for student in enrolled_students
        ]

        return render_to_response(
            "courseware/gradebook.html",
            {
                "students": student_info,
                "course": course,
                "course_id": course.id,
                "staff_access": request.user.is_staff,
                "ordered_grades": sorted(course.grade_cutoffs.items(), key=lambda i: i[1], reverse=True),
            },
        )
예제 #48
0
    def _prefetch_and_bind_course(self):
        """
        Prefetches all descendant data for the requested section and
        sets up the runtime, which binds the request user to the section.
        """
        self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            self.course_key,
            self.effective_user,
            self.course,
            depth=CONTENT_DEPTH,
        )

        self.course = get_module_for_descriptor(
            self.effective_user,
            self.request,
            self.course,
            self.field_data_cache,
            self.course_key,
            course=self.course,
        )
예제 #49
0
def get_section_list(request,course_id,student_id):
    section_id_dict = {}
    commentable_id_list = []
    try:
        course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    except Exception as e:
        return Resposne(
            data={
            "Error": e.message
        })

    course = get_course_by_id(course_key)
    with modulestore().bulk_operations(course.id):
        course_module = get_module_for_descriptor(
            request.user, request, course, None, course.id, course=course
        )
        if course_module is None:
            return Response(
                data={
                "Error":"User is not allowed to do the operation"
            })

    student = User.objects.get(id=student_id)
    query_params = {
    "course_id":course_id,
    "user_id": student.id,
    }
    threads = Thread.search(query_params).collection

    for chapter in course_module.get_children():
        for section in chapter.get_children():
            for unit in section.get_children():
                for vertical in unit.get_children():
                    if vertical.category == 'discussion':
                        participated = False
                        for thread in threads:
                            if thread['commentable_id'] == vertical.discussion_id:
                                participated = thread['username'] == student.username
                        section_id_dict.update({chapter.url_name: participated})

    return section_id_dict
예제 #50
0
    def _last_visited_module_path(self, request, course):
        """
        Returns the path from the last module visited by the current user in the given course up to
        the course module. If there is no such visit, the first item deep enough down the course
        tree is used.
        """
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)

        course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id)

        path = [course_module]
        chapter = get_current_child(course_module, min_depth=2)
        if chapter is not None:
            path.append(chapter)
            section = get_current_child(chapter, min_depth=1)
            if section is not None:
                path.append(section)

        path.reverse()
        return path
예제 #51
0
    def _prefetch_and_bind_section(self):
        """
        Prefetches all descendant data for the requested section and
        sets up the runtime, which binds the request user to the section.
        """
        # Pre-fetch all descendant data
        self.section = modulestore().get_item(self.section.location,
                                              depth=None,
                                              lazy=False)
        self.field_data_cache.add_descriptor_descendents(self.section,
                                                         depth=None)

        # Bind section to user
        self.section = get_module_for_descriptor(
            self.effective_user,
            self.request,
            self.section,
            self.field_data_cache,
            self.course_key,
            self.position,
            course=self.course,
        )
예제 #52
0
파일: views.py 프로젝트: jswope00/griffinx
    def _last_visited_module_path(self, request, course):
        """
        Returns the path from the last module visited by the current user in the given course up to
        the course module. If there is no such visit, the first item deep enough down the course
        tree is used.
        """
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, request.user, course, depth=2)

        course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id)
        current = course_module

        path = []
        child = current
        while child:
            path.append(child)
            child = get_current_child(current)
            if child:
                current = child

        path.reverse()
        return path
예제 #53
0
def _fire_score_changed_for_block(course_id, student, block, module_state_key):
    """
    Fires a PROBLEM_SCORE_CHANGED event for the given module. The earned points are
    always zero. We must retrieve the possible points from the XModule, as
    noted below.
    """
    if block and block.has_score:
        cache = FieldDataCache.cache_for_descriptor_descendents(
            course_id=course_id,
            user=student,
            descriptor=block,
            depth=0
        )
        # For implementation reasons, we need to pull the max_score from the XModule,
        # even though the data is not user-specific.  Here we bind the data to the
        # current user.
        request = crum.get_current_request()
        module = get_module_for_descriptor(
            user=student,
            request=request,
            descriptor=block,
            field_data_cache=cache,
            course_key=course_id
        )
        max_score = module.max_score()
        if max_score is None:
            return
        else:
            points_earned, points_possible = weighted_score(0, max_score, getattr(module, 'weight', None))
    else:
        points_earned, points_possible = 0, 0
    PROBLEM_SCORE_CHANGED.send(
        sender=None,
        points_possible=points_possible,
        points_earned=points_earned,
        user_id=student.id,
        course_id=unicode(course_id),
        usage_id=unicode(module_state_key)
    )
예제 #54
0
def edxnotes_visibility(request, course_id):
    """
    Handle ajax call from "Show notes" checkbox.
    """
    course_key = CourseKey.from_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)
    field_data_cache = FieldDataCache([course], course_key, request.user)
    course_module = get_module_for_descriptor(
        request.user, request, course, field_data_cache, course_key, course=course
    )

    if not is_feature_enabled(course):
        raise Http404

    try:
        visibility = json.loads(request.body)["visibility"]
        course_module.edxnotes_visibility = visibility
        course_module.save()
        return JsonResponse(status=200)
    except (ValueError, KeyError):
        log.warning("Could not decode request body as JSON and find a boolean visibility field: '%s'", request.body)
        return JsonResponseBadRequest()
예제 #55
0
        def get_units(chapter, section, position = None):
            chapter_descriptor = course.get_child_by(lambda m: m.location.name == chapter)
            section_descriptor = chapter_descriptor.get_child_by(lambda m: m.location.name == section)
            # cdodge: this looks silly, but let's refetch the section_descriptor with depth=None
            # which will prefetch the children more efficiently than doing a recursive load
            section_descriptor = modulestore().get_item(section_descriptor.location, depth = None)
            section_field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_key, user, section_descriptor, depth = None)
            section_module = get_module_for_descriptor(request.user, request, section_descriptor, section_field_data_cache, course_key, position)

            if section_module is not None:
                units = []
                for unit in section_module.get_display_items():
                    verticals = []
                    for vertical in unit.get_display_items():
                        if isinstance(vertical, VideoDescriptor):
                            subtitles = vertical.transcripts.copy()
                            if vertical.sub != "":
                                subtitles.update({ 'en': sub })
                            verticals.append({
                                'name': vertical.display_name,
                                'video_sources': vertical.html5_sources,
                                'subtitles': subtitles,
                                'type': 'video'
                            })
                        else:
                            verticals.append({
                                'name': vertical.display_name,
                                'type': 'other'
                            })
                    units.append({
                        'name': unit.display_name,
                        'verticals': verticals
                    })
                return units
            else:
                return None
예제 #56
0
    def progress_summary(student, request, course, field_data_cache=None, scores_client=None, grading_type='vertical'):
        """
        This pulls a summary of all problems in the course.

        Returns
        - courseware_summary is a summary of all sections with problems in the course.
        It is organized as an array of chapters, each containing an array of sections,
        each containing an array of scores. This contains information for graded and
        ungraded problems, and is good for displaying a course summary with due dates,
        etc.

        Arguments:
            student: A User object for the student to grade
            course: A Descriptor containing the course to grade

        If the student does not have access to load the course module, this function
        will return None.

        """

        with manual_transaction():
            if field_data_cache is None:
                field_data_cache = field_data_cache_for_grading(course, student)
            if scores_client is None:
                scores_client = ScoresClient.from_field_data_cache(field_data_cache)

            course_module = get_module_for_descriptor(
                student, request, course, field_data_cache, course.id, course=course
            )
            if not course_module:
                return None

            course_module = getattr(course_module, '_x_module', course_module)

        submissions_scores = sub_api.get_scores(
            course.id.to_deprecated_string(), anonymous_id_for_user(student, course.id)
        )
        max_scores_cache = MaxScoresCache.create_for_course(course)
        # For the moment, we have to get scorable_locations from field_data_cache
        # and not from scores_client, because scores_client is ignorant of things
        # in the submissions API. As a further refactoring step, submissions should
        # be hidden behind the ScoresClient.
        max_scores_cache.fetch_from_remote(field_data_cache.scorable_locations)

        blocks_stack = [course_module]
        blocks_dict = {}

        while blocks_stack:
            curr_block = blocks_stack.pop()
            with manual_transaction():
                # Skip if the block is hidden
                if curr_block.hide_from_toc:
                    continue

                key = unicode(curr_block.scope_ids.usage_id)
                children = curr_block.get_display_items() if curr_block.category != grading_type else []
                block = {
                    'display_name': curr_block.display_name_with_default,
                    'block_type': curr_block.category,
                    'url_name': curr_block.url_name,
                    'children': [unicode(child.scope_ids.usage_id) for child in children],
                }

                if curr_block.category == grading_type:
                    graded = curr_block.graded
                    scores = []

                    module_creator = curr_block.xmodule_runtime.get_module
                    for module_descriptor in yield_dynamic_descriptor_descendants(
                            curr_block, student.id, module_creator
                    ):
                        (correct, total) = get_score(
                            student,
                            module_descriptor,
                            module_creator,
                            scores_client,
                            submissions_scores,
                            max_scores_cache,
                        )

                        if correct is None and total is None:
                            continue

                        scores.append(
                            Score(
                                correct,
                                total,
                                graded,
                                module_descriptor.display_name_with_default,
                                module_descriptor.location
                            )
                        )

                    scores.reverse()
                    total, _ = aggregate_scores(scores, curr_block.display_name_with_default)

                    module_format = curr_block.format if curr_block.format is not None else ''
                    block.update({
                        'scores': scores,
                        'total': total,
                        'format': module_format,
                        'due': curr_block.due,
                        'graded': graded,
                    })

                blocks_dict[key] = block
                # Add this blocks children to the stack so that we can traverse them as well.
                blocks_stack.extend(children)

        max_scores_cache.push_to_remote()

        return {
            'root': unicode(course.scope_ids.usage_id),
            'blocks': blocks_dict,
        }