Пример #1
0
def _get_course_module(course_descriptor, user):
    """ Gets course module that takes into account user state and permissions """
    # Adding courseware imports here to insulate other apps (e.g. schedules) to
    # avoid import errors.
    from lms.djangoapps.courseware.model_data import FieldDataCache
    from lms.djangoapps.courseware.module_render import get_module_for_descriptor

    # 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,
    )
    course_module = get_module_for_descriptor(
        user,
        request,
        course_descriptor,
        field_data_cache,
        course_descriptor.id,
        course=course_descriptor,
    )
    if not course_module:
        raise CourseUpdateDoesNotExist('Course module {} not found'.format(
            course_descriptor.id))
    return course_module
Пример #2
0
    def test_repeated_course_module_instantiation(self, loops, course_depth):

        with modulestore().default_store(ModuleStoreEnum.Type.split):
            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': str(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():
                        assert item.graded
Пример #3
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)
Пример #4
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.decode('utf8'))["visibility"]
        course_module.edxnotes_visibility = visibility
        course_module.save()
        return JsonResponse(status=200)
    except (ValueError, KeyError):
        log.warning(
            u"Could not decode request body as JSON and find a boolean visibility field: '%s'",
            request.body)
        return JsonResponseBadRequest()
Пример #5
0
def _get_course_module(course_descriptor, user):
    # Adding courseware imports here to insulate other apps (e.g. schedules) to
    # avoid import errors.
    from lms.djangoapps.courseware.model_data import FieldDataCache
    from lms.djangoapps.courseware.module_render import get_module_for_descriptor

    # 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,
    )
Пример #6
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
Пример #7
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
Пример #8
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
Пример #9
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,
    )
Пример #10
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,
                                           course=self.course)

        # Now that we have the course, change the position and save, nothing should explode!
        course.position = 2
        course.save()
Пример #11
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)
Пример #12
0
def complete_student_attempt_task(user_identifier: str, content_id: str) -> None:
    """
    Marks all completable children of content_id as complete for the user

    Submits all completable xblocks inside of the content_id block to the
    Completion Service to mark them as complete. One use case of this function is
    for special exams (timed/proctored) where regardless of submission status on
    individual problems, we want to mark the entire exam as complete when the exam
    is finished.

    params:
        user_identifier (str): username or email of a user
        content_id (str): the block key for a piece of content
    """
    err_msg_prefix = (
        'Error occurred while attempting to complete student attempt for user '
        f'{user_identifier} for content_id {content_id}. '
    )
    err_msg = None
    try:
        user = get_user_by_username_or_email(user_identifier)
        block_key = UsageKey.from_string(content_id)
        root_descriptor = modulestore().get_item(block_key)
    except ObjectDoesNotExist:
        err_msg = err_msg_prefix + 'User does not exist!'
    except InvalidKeyError:
        err_msg = err_msg_prefix + 'Invalid content_id!'
    except ItemNotFoundError:
        err_msg = err_msg_prefix + 'Block not found in the modulestore!'
    if err_msg:
        log.error(err_msg)
        return

    # This logic has been copied over from openedx/core/djangoapps/schedules/content_highlights.py
    # in the _get_course_module function.
    # I'm not sure if this is an anti-pattern or not, so if you can avoid re-copying this, please do.
    # We are using it here because we ran into issues with the User service being undefined when we
    # encountered a split_test xblock.

    # 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(
        root_descriptor.course_id, user, root_descriptor, read_only=True,
    )
    root_module = get_module_for_descriptor(
        user, request, root_descriptor, field_data_cache, root_descriptor.course_id,
    )
    if not root_module:
        err_msg = err_msg_prefix + 'Module unable to be created from descriptor!'
        log.error(err_msg)
        return

    def _submit_completions(block, user):
        """
        Recursively submits the children for completion to the Completion Service
        """
        mode = XBlockCompletionMode.get_mode(block)
        if mode == XBlockCompletionMode.COMPLETABLE:
            block.runtime.publish(block, 'completion', {'completion': 1.0, 'user_id': user.id})
        elif mode == XBlockCompletionMode.AGGREGATOR:
            # I know this looks weird, but at the time of writing at least, there isn't a good
            # single way to get the children assigned for a partcular user. Some blocks define the
            # child descriptors method, but others don't and with blocks like Randomized Content
            # (Library Content), the get_children method returns all children and not just assigned
            # children. So this is our way around situations like that. See also Split Test Module
            # for another use case where user state has to be taken into account via get_child_descriptors
            block_children = ((hasattr(block, 'get_child_descriptors') and block.get_child_descriptors())
                              or (hasattr(block, 'get_children') and block.get_children())
                              or [])
            for child in block_children:
                _submit_completions(child, user)

    _submit_completions(root_module, user)