Esempio n. 1
0
def library_blocks_view(library, user, response_format):
    """
    The main view of a course's content library.
    Shows all the XBlocks in the library, and allows adding/editing/deleting
    them.
    Can be called with response_format="json" to get a JSON-formatted list of
    the XBlocks in the library along with library metadata.

    Assumes that read permissions have been checked before calling this.
    """
    assert isinstance(library.location.library_key, LibraryLocator)
    assert isinstance(library.location, LibraryUsageLocator)

    children = library.children
    if response_format == "json":
        # The JSON response for this request is short and sweet:
        prev_version = library.runtime.course_entry.structure[
            'previous_version']
        return JsonResponse({
            "display_name":
            library.display_name,
            "library_id":
            unicode(library.location.library_key),
            "version":
            unicode(library.runtime.course_entry.course_key.version),
            "previous_version":
            unicode(prev_version) if prev_version else None,
            "blocks": [unicode(x) for x in children],
        })

    can_edit = has_studio_write_access(user, library.location.library_key)

    xblock_info = create_xblock_info(library,
                                     include_ancestor_info=False,
                                     graders=[])
    component_templates = get_component_templates(
        library, library=True) if can_edit else []

    return render_to_response(
        'library.html', {
            'can_edit':
            can_edit,
            'context_library':
            library,
            'component_templates':
            json.dumps(component_templates),
            'xblock_info':
            xblock_info,
            'templates':
            CONTAINER_TEMPATES,
            'lib_users_url':
            reverse_library_url('manage_library_users',
                                unicode(library.location.library_key)),
        })
Esempio n. 2
0
    def test_course_outline_initial_state(self):
        course_module = modulestore().get_item(self.course.location)
        course_structure = create_xblock_info(
            course_module,
            include_child_info=True,
            include_children_predicate=lambda xblock: not xblock.category == 'vertical'
        )

        # Verify that None is returned for a non-existent locator
        self.assertIsNone(course_outline_initial_state('no-such-locator', course_structure))

        # Verify that the correct initial state is returned for the test chapter
        chapter_locator = six.text_type(self.chapter.location)
        initial_state = course_outline_initial_state(chapter_locator, course_structure)
        self.assertEqual(initial_state['locator_to_show'], chapter_locator)
        expanded_locators = initial_state['expanded_locators']
        self.assertIn(six.text_type(self.sequential.location), expanded_locators)
        self.assertIn(six.text_type(self.vertical.location), expanded_locators)
    def test_course_outline_initial_state(self):
        course_module = modulestore().get_item(self.course.location)
        course_structure = create_xblock_info(
            course_module,
            include_child_info=True,
            include_children_predicate=lambda xblock: not xblock.category == 'vertical'
        )

        # Verify that None is returned for a non-existent locator
        self.assertIsNone(course_outline_initial_state('no-such-locator', course_structure))

        # Verify that the correct initial state is returned for the test chapter
        chapter_locator = unicode(self.chapter.location)
        initial_state = course_outline_initial_state(chapter_locator, course_structure)
        self.assertEqual(initial_state['locator_to_show'], chapter_locator)
        expanded_locators = initial_state['expanded_locators']
        self.assertIn(unicode(self.sequential.location), expanded_locators)
        self.assertIn(unicode(self.vertical.location), expanded_locators)
Esempio n. 4
0
def library_blocks_view(library, user, response_format):
    """
    The main view of a course's content library.
    Shows all the XBlocks in the library, and allows adding/editing/deleting
    them.
    Can be called with response_format="json" to get a JSON-formatted list of
    the XBlocks in the library along with library metadata.

    Assumes that read permissions have been checked before calling this.
    """
    assert isinstance(library.location.library_key, LibraryLocator)
    assert isinstance(library.location, LibraryUsageLocator)

    children = library.children
    if response_format == "json":
        # The JSON response for this request is short and sweet:
        prev_version = library.runtime.course_entry.structure['previous_version']
        return JsonResponse({
            "display_name": library.display_name,
            "library_id": unicode(library.location.library_key),
            "version": unicode(library.runtime.course_entry.course_key.version),
            "previous_version": unicode(prev_version) if prev_version else None,
            "blocks": [unicode(x) for x in children],
        })

    can_edit = has_studio_write_access(user, library.location.library_key)

    xblock_info = create_xblock_info(library, include_ancestor_info=False, graders=[])
    component_templates = get_component_templates(library, library=True) if can_edit else []

    return render_to_response('library.html', {
        'can_edit': can_edit,
        'context_library': library,
        'component_templates': json.dumps(component_templates),
        'xblock_info': xblock_info,
        'templates': CONTAINER_TEMPATES,
        'lib_users_url': reverse_library_url('manage_library_users', unicode(library.location.library_key)),
    })
Esempio n. 5
0
def container_handler(request, usage_key_string):
    """
    The restful handler for container xblock requests.

    GET
        html: returns the HTML page for editing a container
        json: not currently supported
    """
    if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):

        try:
            usage_key = UsageKey.from_string(usage_key_string)
        except InvalidKeyError:  # Raise Http404 on invalid 'usage_key_string'
            raise Http404
        with modulestore().bulk_operations(usage_key.course_key):
            try:
                course, xblock, lms_link, preview_lms_link = _get_item_in_course(
                    request, usage_key)
            except ItemNotFoundError:
                return HttpResponseBadRequest()

            component_templates = get_component_templates(course)
            ancestor_xblocks = []
            parent = get_parent_xblock(xblock)
            action = request.GET.get('action', 'view')

            is_unit_page = is_unit(xblock)
            unit = xblock if is_unit_page else None

            while parent and parent.category != 'course':
                if unit is None and is_unit(parent):
                    unit = parent
                ancestor_xblocks.append(parent)
                parent = get_parent_xblock(parent)
            ancestor_xblocks.reverse()

            assert unit is not None, "Could not determine unit page"
            subsection = get_parent_xblock(unit)
            assert subsection is not None, "Could not determine parent subsection from unit " + unicode(
                unit.location)
            section = get_parent_xblock(subsection)
            assert section is not None, "Could not determine ancestor section from unit " + unicode(
                unit.location)

            # Fetch the XBlock info for use by the container page. Note that it includes information
            # about the block's ancestors and siblings for use by the Unit Outline.
            xblock_info = create_xblock_info(
                xblock, include_ancestor_info=is_unit_page)

            if is_unit_page:
                add_container_page_publishing_info(xblock, xblock_info)

            # need to figure out where this item is in the list of children as the
            # preview will need this
            index = 1
            for child in subsection.get_children():
                if child.location == unit.location:
                    break
                index += 1

            return render_to_response(
                'container.html',
                {
                    'context_course':
                    course,  # Needed only for display of menus at top of page.
                    'action': action,
                    'xblock': xblock,
                    'xblock_locator': xblock.location,
                    'unit': unit,
                    'is_unit_page': is_unit_page,
                    'subsection': subsection,
                    'section': section,
                    'new_unit_category': 'vertical',
                    'ancestor_xblocks': ancestor_xblocks,
                    'component_templates': component_templates,
                    'xblock_info': xblock_info,
                    'draft_preview_link': preview_lms_link,
                    'published_preview_link': lms_link,
                    'templates': CONTAINER_TEMPLATES
                })
    else:
        return HttpResponseBadRequest("Only supports HTML requests")
Esempio n. 6
0
def container_handler(request, usage_key_string):
    """
    The restful handler for container xblock requests.

    GET
        html: returns the HTML page for editing a container
        json: not currently supported
    """
    if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):

        try:
            usage_key = UsageKey.from_string(usage_key_string)
        except InvalidKeyError:  # Raise Http404 on invalid 'usage_key_string'
            raise Http404
        with modulestore().bulk_operations(usage_key.course_key):
            try:
                course, xblock, lms_link, preview_lms_link = _get_item_in_course(
                    request, usage_key)
            except ItemNotFoundError:
                return HttpResponseBadRequest()

            component_templates = get_component_templates(course)
            ancestor_xblocks = []
            parent = get_parent_xblock(xblock)
            action = request.GET.get('action', 'view')

            is_unit_page = is_unit(xblock)
            unit = xblock if is_unit_page else None

            is_first = True
            while parent:
                if unit is None and is_unit(parent):
                    unit = parent
                elif parent.category != 'sequential':
                    current_block = {
                        'block': parent,
                        'children': parent.get_children(),
                        'is_last': is_first
                    }
                    is_first = False
                    ancestor_xblocks.append(current_block)
                parent = get_parent_xblock(parent)

            ancestor_xblocks.reverse()

            assert unit is not None, "Could not determine unit page"
            subsection = get_parent_xblock(unit)
            assert subsection is not None, "Could not determine parent subsection from unit " + six.text_type(
                unit.location)
            section = get_parent_xblock(subsection)
            assert section is not None, "Could not determine ancestor section from unit " + six.text_type(
                unit.location)

            # for the sequence navigator
            prev_url, next_url = get_sibling_urls(subsection)
            # these are quoted here because they'll end up in a query string on the page,
            # and quoting with mako will trigger the xss linter...
            prev_url = quote_plus(prev_url) if prev_url else None
            next_url = quote_plus(next_url) if next_url else None

            # Fetch the XBlock info for use by the container page. Note that it includes information
            # about the block's ancestors and siblings for use by the Unit Outline.
            xblock_info = create_xblock_info(
                xblock, include_ancestor_info=is_unit_page)

            if is_unit_page:
                add_container_page_publishing_info(xblock, xblock_info)

            # need to figure out where this item is in the list of children as the
            # preview will need this
            index = 1
            for child in subsection.get_children():
                if child.location == unit.location:
                    break
                index += 1

            return render_to_response(
                'container.html',
                {
                    'language_code':
                    request.LANGUAGE_CODE,
                    'context_course':
                    course,  # Needed only for display of menus at top of page.
                    'action':
                    action,
                    'xblock':
                    xblock,
                    'xblock_locator':
                    xblock.location,
                    'unit':
                    unit,
                    'is_unit_page':
                    is_unit_page,
                    'subsection':
                    subsection,
                    'section':
                    section,
                    'position':
                    index,
                    'prev_url':
                    prev_url,
                    'next_url':
                    next_url,
                    'new_unit_category':
                    'vertical',
                    'outline_url':
                    '{url}?format=concise'.format(
                        url=reverse_course_url('course_handler', course.id)),
                    'ancestor_xblocks':
                    ancestor_xblocks,
                    'component_templates':
                    component_templates,
                    'xblock_info':
                    xblock_info,
                    'draft_preview_link':
                    preview_lms_link,
                    'published_preview_link':
                    lms_link,
                    'templates':
                    CONTAINER_TEMPLATES
                })
    else:
        return HttpResponseBadRequest("Only supports HTML requests")
Esempio n. 7
0
def container_handler(request, usage_key_string):
    """
    The restful handler for container xblock requests.

    GET
        html: returns the HTML page for editing a container
        json: not currently supported
    """
    if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):

        usage_key = UsageKey.from_string(usage_key_string)
        try:
            course, xblock, lms_link = _get_item_in_course(request, usage_key)
        except ItemNotFoundError:
            return HttpResponseBadRequest()

        component_templates = get_component_templates(course)
        ancestor_xblocks = []
        parent = get_parent_xblock(xblock)
        action = request.REQUEST.get('action', 'view')

        is_unit_page = is_unit(xblock)
        unit = xblock if is_unit_page else None

        while parent and parent.category != 'course':
            if unit is None and is_unit(parent):
                unit = parent
            ancestor_xblocks.append(parent)
            parent = get_parent_xblock(parent)
        ancestor_xblocks.reverse()

        assert unit is not None, "Could not determine unit page"
        subsection = get_parent_xblock(unit)
        assert subsection is not None, "Could not determine parent subsection from unit " + unicode(unit.location)
        section = get_parent_xblock(subsection)
        assert section is not None, "Could not determine ancestor section from unit " + unicode(unit.location)

        # Fetch the XBlock info for use by the container page. Note that it includes information
        # about the block's ancestors and siblings for use by the Unit Outline.
        xblock_info = create_xblock_info(xblock, include_ancestor_info=is_unit_page)

        # Create the link for preview.
        preview_lms_base = settings.FEATURES.get('PREVIEW_LMS_BASE')
        # need to figure out where this item is in the list of children as the
        # preview will need this
        index = 1
        for child in subsection.get_children():
            if child.location == unit.location:
                break
            index += 1
        preview_lms_link = (
            u'//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}'
        ).format(
            preview_lms_base=preview_lms_base,
            lms_base=settings.LMS_BASE,
            org=course.location.org,
            course=course.location.course,
            course_name=course.location.name,
            section=section.location.name,
            subsection=subsection.location.name,
            index=index
        )

        return render_to_response('container.html', {
            'context_course': course,  # Needed only for display of menus at top of page.
            'action': action,
            'xblock': xblock,
            'xblock_locator': xblock.location,
            'unit': unit,
            'is_unit_page': is_unit_page,
            'subsection': subsection,
            'section': section,
            'new_unit_category': 'vertical',
            'ancestor_xblocks': ancestor_xblocks,
            'component_templates': json.dumps(component_templates),
            'xblock_info': xblock_info,
            'draft_preview_link': preview_lms_link,
            'published_preview_link': lms_link,
        })
    else:
        return HttpResponseBadRequest("Only supports HTML requests")
Esempio n. 8
0
def container_handler(request, usage_key_string):
    """
    The restful handler for container xblock requests.

    GET
        html: returns the HTML page for editing a container
        json: not currently supported
    """
    if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):

        try:
            usage_key = UsageKey.from_string(usage_key_string)
        except InvalidKeyError:  # Raise Http404 on invalid 'usage_key_string'
            raise Http404
        with modulestore().bulk_operations(usage_key.course_key):
            try:
                course, xblock, lms_link, preview_lms_link = _get_item_in_course(request, usage_key)
            except ItemNotFoundError:
                return HttpResponseBadRequest()

            component_templates = get_component_templates(course)
            ancestor_xblocks = []
            parent = get_parent_xblock(xblock)
            action = request.REQUEST.get('action', 'view')

            is_unit_page = is_unit(xblock)
            unit = xblock if is_unit_page else None

            while parent and parent.category != 'course':
                if unit is None and is_unit(parent):
                    unit = parent
                ancestor_xblocks.append(parent)
                parent = get_parent_xblock(parent)
            ancestor_xblocks.reverse()

            assert unit is not None, "Could not determine unit page"
            subsection = get_parent_xblock(unit)
            assert subsection is not None, "Could not determine parent subsection from unit " + unicode(unit.location)
            section = get_parent_xblock(subsection)
            assert section is not None, "Could not determine ancestor section from unit " + unicode(unit.location)

            # Fetch the XBlock info for use by the container page. Note that it includes information
            # about the block's ancestors and siblings for use by the Unit Outline.
            xblock_info = create_xblock_info(xblock, include_ancestor_info=is_unit_page)

            if is_unit_page:
                add_container_page_publishing_info(xblock, xblock_info)

            # need to figure out where this item is in the list of children as the
            # preview will need this
            index = 1
            for child in subsection.get_children():
                if child.location == unit.location:
                    break
                index += 1

            return render_to_response('container.html', {
                'context_course': course,  # Needed only for display of menus at top of page.
                'action': action,
                'xblock': xblock,
                'xblock_locator': xblock.location,
                'unit': unit,
                'is_unit_page': is_unit_page,
                'subsection': subsection,
                'section': section,
                'new_unit_category': 'vertical',
                'ancestor_xblocks': ancestor_xblocks,
                'component_templates': json.dumps(component_templates),
                'xblock_info': xblock_info,
                'draft_preview_link': preview_lms_link,
                'published_preview_link': lms_link,
                'keywords_supported': get_keywords_supported(),
                'templates': CONTAINER_TEMPATES
            })
    else:
        return HttpResponseBadRequest("Only supports HTML requests")
Esempio n. 9
0
def container_handler(request, usage_key_string):
    """
    The restful handler for container xblock requests.

    GET
        html: returns the HTML page for editing a container
        json: not currently supported
    """
    if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):

        usage_key = UsageKey.from_string(usage_key_string)
        try:
            course, xblock, lms_link = _get_item_in_course(request, usage_key)
        except ItemNotFoundError:
            return HttpResponseBadRequest()

        component_templates = get_component_templates(course)
        ancestor_xblocks = []
        parent = get_parent_xblock(xblock)
        action = request.REQUEST.get('action', 'view')

        is_unit_page = is_unit(xblock)
        unit = xblock if is_unit_page else None

        while parent and parent.category != 'course':
            if unit is None and is_unit(parent):
                unit = parent
            ancestor_xblocks.append(parent)
            parent = get_parent_xblock(parent)
        ancestor_xblocks.reverse()

        assert unit is not None, "Could not determine unit page"
        subsection = get_parent_xblock(unit)
        assert subsection is not None, "Could not determine parent subsection from unit " + unicode(unit.location)
        section = get_parent_xblock(subsection)
        assert section is not None, "Could not determine ancestor section from unit " + unicode(unit.location)

        # Fetch the XBlock info for use by the container page. Note that it includes information
        # about the block's ancestors and siblings for use by the Unit Outline.
        xblock_info = create_xblock_info(xblock, include_ancestor_info=is_unit_page)

        # Create the link for preview.
        preview_lms_base = settings.FEATURES.get('PREVIEW_LMS_BASE')
        # need to figure out where this item is in the list of children as the
        # preview will need this
        index = 1
        for child in subsection.get_children():
            if child.location == unit.location:
                break
            index += 1
        preview_lms_link = (
            u'//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}'
        ).format(
            preview_lms_base=preview_lms_base,
            lms_base=settings.LMS_BASE,
            org=course.location.org,
            course=course.location.course,
            course_name=course.location.name,
            section=section.location.name,
            subsection=subsection.location.name,
            index=index
        )

        return render_to_response('container.html', {
            'context_course': course,  # Needed only for display of menus at top of page.
            'action': action,
            'xblock': xblock,
            'xblock_locator': xblock.location,
            'unit': unit,
            'is_unit_page': is_unit_page,
            'subsection': subsection,
            'section': section,
            'new_unit_category': 'vertical',
            'ancestor_xblocks': ancestor_xblocks,
            'component_templates': json.dumps(component_templates),
            'xblock_info': xblock_info,
            'draft_preview_link': preview_lms_link,
            'published_preview_link': lms_link,
        })
    else:
        return HttpResponseBadRequest("Only supports HTML requests")