Ejemplo n.º 1
0
def get_course_tab_list(user, course):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    xmodule_tab_list = CourseTabList.iterate_displayable(course, user=user)

    # Now that we've loaded the tabs for this course, perform the Entrance Exam work.
    # If the user has to take an entrance exam, we'll need to hide away all but the
    # "Courseware" tab. The tab is then renamed as "Entrance Exam".
    course_tab_list = []
    must_complete_ee = not user_can_skip_entrance_exam(user, course)
    for tab in xmodule_tab_list:
        if must_complete_ee:
            # Hide all of the tabs except for 'Courseware'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type != 'courseware':
                continue
            tab.name = _("Entrance Exam")
        # TODO: LEARNER-611 - once the course_info tab is removed, remove this code
        if UNIFIED_COURSE_TAB_FLAG.is_enabled(course.id) and tab.type == 'course_info':
            continue
        if tab.type == 'static_tab' and tab.course_staff_only and \
                not bool(user and has_access(user, 'staff', course, course.id)):
            continue
        # We had initially created a CourseTab.load() for dates that ended up
        # persisting the dates tab tomodulestore on Course Run creation, but
        # ignoring any static dates tab here we can fix forward without
        # allowing the bug to continue to surface
        if tab.type == 'dates':
            continue
        course_tab_list.append(tab)

    # Add in any dynamic tabs, i.e. those that are not persisted
    course_tab_list += _get_dynamic_tabs(course, user)
    return course_tab_list
Ejemplo n.º 2
0
def get_course_tab_list(request, course):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    user = request.user
    xmodule_tab_list = CourseTabList.iterate_displayable(course, user=user)

    # Now that we've loaded the tabs for this course, perform the Entrance Exam work.
    # If the user has to take an entrance exam, we'll need to hide away all but the
    # "Courseware" tab. The tab is then renamed as "Entrance Exam".
    course_tab_list = []
    must_complete_ee = user_must_complete_entrance_exam(request, user, course)
    for tab in xmodule_tab_list:
        if must_complete_ee:
            # Hide all of the tabs except for 'Courseware'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type != 'courseware':
                continue
            tab.name = _("Entrance Exam")
        if tab.type == 'static_tab' and tab.course_staff_only and \
                not bool(user and has_access(user, 'staff', course, course.id)):
            continue
        course_tab_list.append(tab)

    # Add in any dynamic tabs, i.e. those that are not persisted
    course_tab_list += _get_dynamic_tabs(course, user)
    return course_tab_list
Ejemplo n.º 3
0
def get_course_tab_list(request, course):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    user = request.user
    is_user_enrolled = user.is_authenticated() and CourseEnrollment.is_enrolled(user, course.id)
    xmodule_tab_list = CourseTabList.iterate_displayable(
        course,
        user=user,
        settings=settings,
        is_user_authenticated=user.is_authenticated(),
        is_user_staff=has_access(user, 'staff', course, course.id),
        is_user_enrolled=is_user_enrolled,
        is_user_sneakpeek=not UserProfile.has_registered(user),
    )

    # Now that we've loaded the tabs for this course, perform the Entrance Exam work.
    # If the user has to take an entrance exam, we'll need to hide away all but the
    # "Courseware" tab. The tab is then renamed as "Entrance Exam".
    course_tab_list = []
    must_complete_ee = user_must_complete_entrance_exam(request, user, course)
    for tab in xmodule_tab_list:
        if must_complete_ee:
            # Hide all of the tabs except for 'Courseware'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type is not 'courseware':
                continue
            tab.name = _("Entrance Exam")
        course_tab_list.append(tab)

    # Add in any dynamic tabs, i.e. those that are not persisted
    course_tab_list += _get_dynamic_tabs(course, user)
    return course_tab_list
Ejemplo n.º 4
0
def get_course_tab_list(request, course):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    user = request.user
    xmodule_tab_list = CourseTabList.iterate_displayable(course, user=user)

    # Now that we've loaded the tabs for this course, perform the Entrance Exam work.
    # If the user has to take an entrance exam, we'll need to hide away all but the
    # "Courseware" tab. The tab is then renamed as "Entrance Exam".
    course_tab_list = []
    must_complete_ee = user_must_complete_entrance_exam(request, user, course)
    for tab in xmodule_tab_list:
        # Rename 'Home' tab to 'Information'
        if tab.type is 'course_info':
            tab.name = _("Information")
        if must_complete_ee:
            # Hide all of the tabs except for 'Courseware'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type is not 'courseware':
                continue
            tab.name = _("Entrance Exam")
        course_tab_list.append(tab)

    # Add in any dynamic tabs, i.e. those that are not persisted
    course_tab_list += _get_dynamic_tabs(course, user)

    # Add course welcome tab if feature is enabled
    if settings.FEATURES.get('TMA_ENABLE_COURSE_WELCOME_PAGE'
                             ) and CourseWelcomeTab.is_enabled(course, user):
        course_tab_list.insert(0, CourseWelcomeTab({}))

    return course_tab_list
Ejemplo n.º 5
0
def get_course_tab_list(course, user):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    user_is_enrolled = user.is_authenticated(
    ) and CourseEnrollment.is_enrolled(user, course.id)
    xmodule_tab_list = CourseTabList.iterate_displayable(
        course, settings, user.is_authenticated(),
        has_access(user, 'staff', course, course.id), user_is_enrolled)

    # Now that we've loaded the tabs for this course, perform the Entrance Exam work
    # If the user has to take an entrance exam, we'll need to hide away all of the tabs
    # except for the Courseware and Instructor tabs (latter is only viewed if applicable)
    # We don't have access to the true request object in this context, but we can use a mock
    request = RequestFactory().request()
    request.user = user
    course_tab_list = []
    for tab in xmodule_tab_list:
        if user_must_complete_entrance_exam(request, user, course):
            # Hide all of the tabs except for 'Courseware' and 'Instructor'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type not in ['courseware', 'instructor']:
                continue
            if tab.type == 'courseware':
                tab.name = _("Entrance Exam")
        course_tab_list.append(tab)
    return course_tab_list
Ejemplo n.º 6
0
def get_course_tab_list(course, user):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    user_is_enrolled = user.is_authenticated() and CourseEnrollment.is_enrolled(user, course.id)
    xmodule_tab_list = CourseTabList.iterate_displayable(
        course,
        settings,
        user.is_authenticated(),
        has_access(user, 'staff', course, course.id),
        user_is_enrolled
    )

    # Now that we've loaded the tabs for this course, perform the Entrance Exam work
    # If the user has to take an entrance exam, we'll need to hide away all of the tabs
    # except for the Courseware and Instructor tabs (latter is only viewed if applicable)
    # We don't have access to the true request object in this context, but we can use a mock
    request = RequestFactory().request()
    request.user = user
    course_tab_list = []
    for tab in xmodule_tab_list:
        if user_must_complete_entrance_exam(request, user, course):
            # Hide all of the tabs except for 'Courseware' and 'Instructor'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type not in ['courseware', 'instructor']:
                continue
            if tab.type == 'courseware':
                tab.name = _("Entrance Exam")
        course_tab_list.append(tab)
    return course_tab_list
Ejemplo n.º 7
0
def tabs_handler(request, course_key_string):
    """
    The restful handler for static tabs.

    GET
        html: return page for editing static tabs
        json: not supported
    PUT or POST
        json: update the tab order. It is expected that the request body contains a JSON-encoded dict with entry "tabs".
        The value for "tabs" is an array of tab locators, indicating the desired order of the tabs.

    Creating a tab, deleting a tab, or changing its contents is not supported through this method.
    Instead use the general xblock URL (see item.xblock_handler).
    """
    course_key = CourseKey.from_string(course_key_string)
    if not has_course_author_access(request.user, course_key):
        raise PermissionDenied()

    course_item = modulestore().get_course(course_key)

    if 'application/json' in request.META.get('HTTP_ACCEPT',
                                              'application/json'):
        if request.method == 'GET':
            raise NotImplementedError('coming soon')
        else:
            if 'tabs' in request.json:
                return reorder_tabs_handler(course_item, request)
            elif 'tab_id_locator' in request.json:
                return edit_tab_handler(course_item, request)
            else:
                raise NotImplementedError(
                    'Creating or changing tab content is not supported.')

    elif request.method == 'GET':  # assume html
        # get all tabs from the tabs list: static tabs (a.k.a. user-created tabs) and built-in tabs
        # present in the same order they are displayed in LMS

        tabs_to_render = []
        for tab in CourseTabList.iterate_displayable(course_item,
                                                     user=request.user,
                                                     inline_collections=False,
                                                     include_hidden=True):
            if isinstance(tab, StaticTab):
                # static tab needs its locator information to render itself as an xmodule
                static_tab_loc = course_key.make_usage_key(
                    'static_tab', tab.url_slug)
                tab.locator = static_tab_loc
            tabs_to_render.append(tab)

        return render_to_response(
            'edit-tabs.html', {
                'context_course': course_item,
                'tabs_to_render': tabs_to_render,
                'lms_link': get_lms_link_for_item(course_item.location),
            })
    else:
        return HttpResponseNotFound()
Ejemplo n.º 8
0
def tabs_handler(request, course_key_string):
    """
    The restful handler for static tabs.

    GET
        html: return page for editing static tabs
        json: not supported
    PUT or POST
        json: update the tab order. It is expected that the request body contains a JSON-encoded dict with entry "tabs".
        The value for "tabs" is an array of tab locators, indicating the desired order of the tabs.

    Creating a tab, deleting a tab, or changing its contents is not supported through this method.
    Instead use the general xblock URL (see item.xblock_handler).
    """
    course_key = CourseKey.from_string(course_key_string)
    if not has_course_author_access(request.user, course_key):
        raise PermissionDenied()

    course_item = modulestore().get_course(course_key)

    if "application/json" in request.META.get("HTTP_ACCEPT", "application/json"):
        if request.method == "GET":
            raise NotImplementedError("coming soon")
        else:
            if "tabs" in request.json:
                return reorder_tabs_handler(course_item, request)
            elif "tab_id_locator" in request.json:
                return edit_tab_handler(course_item, request)
            else:
                raise NotImplementedError("Creating or changing tab content is not supported.")

    elif request.method == "GET":  # assume html
        # get all tabs from the tabs list: static tabs (a.k.a. user-created tabs) and built-in tabs
        # present in the same order they are displayed in LMS

        tabs_to_render = []
        for tab in CourseTabList.iterate_displayable(course_item, inline_collections=False):
            if isinstance(tab, StaticTab):
                # static tab needs its locator information to render itself as an xmodule
                static_tab_loc = course_key.make_usage_key("static_tab", tab.url_slug)
                tab.locator = static_tab_loc
            tabs_to_render.append(tab)

        return render_to_response(
            "edit-tabs.html",
            {
                "context_course": course_item,
                "tabs_to_render": tabs_to_render,
                "lms_link": get_lms_link_for_item(course_item.location),
            },
        )
    else:
        return HttpResponseNotFound()
Ejemplo n.º 9
0
def redirect_view(request, course_key_string=None):
    course_key = CourseKey.from_string(course_key_string)
    if not has_course_author_access(request.user, course_key):
        raise PermissionDenied()

    course_item = modulestore().get_course(course_key)

    if request.method == 'GET':
        for tab in CourseTabList.iterate_displayable(course_item,
                                                     inline_collections=False):
            if isinstance(tab, ExternalLinkCourseTab):
                data = {'name': tab.name, 'link_value': tab.link_value}
                form = ExternalLinkTabForm(data=data)
                csrf_token = csrf(request)['csrf_token']
                return render_to_response('external_blog.html', {
                    'form': form,
                    'csrf': csrf_token
                })
    elif request.method == 'POST':
        for tab in CourseTabList.iterate_displayable(course_item,
                                                     inline_collections=False):
            if isinstance(tab, ExternalLinkCourseTab):
                data = request.POST
                form = ExternalLinkTabForm(data=data)
                if form.is_valid():
                    tab.link_value = form.cleaned_data.get('link_value')
                    tab.name = form.cleaned_data.get('name')
                    modulestore().update_item(course_item, request.user.id)
                    return HttpResponseRedirect(
                        reverse(
                            'contentstore.views.tabs_handler',
                            kwargs={'course_key_string': course_key_string}))
                csrf_token = csrf(request)['csrf_token']
                return render_to_response('external_blog.html', {
                    'form': form,
                    'csrf': csrf_token
                })
Ejemplo n.º 10
0
def get_course_tab_list(course, user):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    user_is_enrolled = user.is_authenticated() and CourseEnrollment.is_enrolled(user, course.id)
    xmodule_tab_list = CourseTabList.iterate_displayable(
        course,
        settings,
        user.is_authenticated(),
        has_access(user, 'staff', course, course.id),
        user_is_enrolled
    )

    # Entrance Exams Feature
    # If the course has an entrance exam, we'll need to see if the user has not passed it
    # If so, we'll need to hide away all of the tabs except for Courseware and Instructor
    entrance_exam_mode = False
    if settings.FEATURES.get('ENTRANCE_EXAMS', False):
        if getattr(course, 'entrance_exam_enabled', False):
            course_milestones_paths = get_course_milestones_fulfillment_paths(
                unicode(course.id),
                serialize_user(user)
            )
            for __, value in course_milestones_paths.iteritems():
                if len(value.get('content', [])):
                    for content in value['content']:
                        if content == course.entrance_exam_id \
                                and not EntranceExamConfiguration.user_can_skip_entrance_exam(user, course.id):
                            entrance_exam_mode = True
                            break

    # Now that we've loaded the tabs for this course, perform the Entrance Exam mode work
    # Majority case is no entrance exam defined
    course_tab_list = []
    for tab in xmodule_tab_list:
        if entrance_exam_mode:
            # Hide all of the tabs except for 'Courseware' and 'Instructor'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type not in ['courseware', 'instructor']:
                continue
            if tab.type == 'courseware':
                tab.name = _("Entrance Exam")
        course_tab_list.append(tab)
    return course_tab_list
Ejemplo n.º 11
0
def get_course_tab_list(user, course):
    """
    Retrieves the course tab list from xmodule.tabs and manipulates the set as necessary
    """
    xmodule_tab_list = CourseTabList.iterate_displayable(course, user=user)

    # Now that we've loaded the tabs for this course, perform the Entrance Exam work.
    # If the user has to take an entrance exam, we'll need to hide away all but the
    # "Courseware" tab. The tab is then renamed as "Entrance Exam".
    course_tab_list = []
    must_complete_ee = not user_can_skip_entrance_exam(user, course)
    for tab in xmodule_tab_list:
        if must_complete_ee:
            # Hide all of the tabs except for 'Courseware'
            # Rename 'Courseware' tab to 'Entrance Exam'
            if tab.type != 'courseware':
                continue
            tab.name = _("Entrance Exam")
            tab.title = _("Entrance Exam")
        # TODO: LEARNER-611 - once the course_info tab is removed, remove this code
        if not DISABLE_UNIFIED_COURSE_TAB_FLAG.is_enabled(
                course.id) and tab.type == 'course_info':
            continue
        if tab.type == 'static_tab' and tab.course_staff_only and \
                not bool(user and has_access(user, 'staff', course, course.id)):
            continue
        # We are phasing this out in https://github.com/openedx/edx-platform/pull/30045/, but need this
        # until the backfill course tabs command is completed
        if tab.type == 'dates':
            continue
        course_tab_list.append(tab)

    # Add in any dynamic tabs, i.e. those that are not persisted
    course_tab_list += _get_dynamic_tabs(course, user)
    # Sorting here because although the CourseTabPluginManager.get_tab_types function
    # does do sorting on priority, we only use it for getting the dynamic tabs.
    # We can't switch this function to just use the CourseTabPluginManager without
    # further investigation since CourseTabList.iterate_displayable returns
    # Static Tabs that are not returned by the CourseTabPluginManager.
    course_tab_list.sort(key=lambda tab: tab.priority or float('inf'))
    return course_tab_list
Ejemplo n.º 12
0
def get_course_tabs(course_item: CourseBlock,
                    user: User) -> Iterable[CourseTab]:
    """
    Yields all the course tabs in a course including hidden tabs.

    Args:
        course_item (CourseBlock): The course object from which to get the tabs
        user (User): The user fetching the course tabs.

    Returns:
        Iterable[CourseTab]: An iterable containing course tab objects from the
        course
    """

    for tab in CourseTabList.iterate_displayable(course_item,
                                                 user=user,
                                                 inline_collections=False,
                                                 include_hidden=True):
        if isinstance(tab, StaticTab):
            # static tab needs its locator information to render itself as an xmodule
            static_tab_loc = course_item.id.make_usage_key(
                "static_tab", tab.url_slug)
            tab.locator = static_tab_loc
        yield tab
Ejemplo n.º 13
0
def tabs_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None):
    """
    The restful handler for static tabs.

    GET
        html: return page for editing static tabs
        json: not supported
    PUT or POST
        json: update the tab order. It is expected that the request body contains a JSON-encoded dict with entry "tabs".
        The value for "tabs" is an array of tab locators, indicating the desired order of the tabs.

    Creating a tab, deleting a tab, or changing its contents is not supported through this method.
    Instead use the general xblock URL (see item.xblock_handler).
    """
    locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block)
    if not has_course_access(request.user, locator):
        raise PermissionDenied()

    old_location = loc_mapper().translate_locator_to_location(locator)
    store = get_modulestore(old_location)
    course_item = store.get_item(old_location)

    if 'application/json' in request.META.get('HTTP_ACCEPT', 'application/json'):
        if request.method == 'GET':
            raise NotImplementedError('coming soon')
        else:
            if 'tabs' in request.json:
                def get_location_for_tab(tab):
                    """  Returns the location (old-style) for a tab. """
                    return loc_mapper().translate_locator_to_location(BlockUsageLocator(tab))

                tabs = request.json['tabs']

                # get list of existing static tabs in course
                # make sure they are the same lengths (i.e. the number of passed in tabs equals the number
                # that we know about) otherwise we will inadvertently drop some!
                existing_static_tabs = [t for t in course_item.tabs if t['type'] == 'static_tab']
                if len(existing_static_tabs) != len(tabs):
                    return JsonResponse(
                        {"error": "number of tabs must be {}".format(len(existing_static_tabs))}, status=400
                    )

                # load all reference tabs, return BadRequest if we can't find any of them
                tab_items = []
                for tab in tabs:
                    item = modulestore('direct').get_item(get_location_for_tab(tab))
                    if item is None:
                        return JsonResponse(
                            {"error": "no tab for found location {}".format(tab)}, status=400
                        )

                    tab_items.append(item)

                # now just go through the existing course_tabs and re-order the static tabs
                reordered_tabs = []
                static_tab_idx = 0
                for tab in course_item.tabs:
                    if isinstance(tab, StaticTab):
                        reordered_tabs.append(
                            StaticTab(
                                name=tab_items[static_tab_idx].display_name,
                                url_slug=tab_items[static_tab_idx].location.name,
                            )
                        )
                        static_tab_idx += 1
                    else:
                        reordered_tabs.append(tab)

                # OK, re-assemble the static tabs in the new order
                course_item.tabs = reordered_tabs
                modulestore('direct').update_item(course_item, request.user.id)
                return JsonResponse()
            else:
                raise NotImplementedError('Creating or changing tab content is not supported.')
    elif request.method == 'GET':  # assume html
        # get all tabs from the tabs list: static tabs (a.k.a. user-created tabs) and built-in tabs
        # we do this because this is also the order in which items are displayed in the LMS

        static_tabs = []
        built_in_tabs = []
        for tab in CourseTabList.iterate_displayable(course_item, settings, include_instructor_tab=False):
            if isinstance(tab, StaticTab):
                static_tab_loc = old_location.replace(category='static_tab', name=tab.url_slug)
                static_tabs.append(modulestore('direct').get_item(static_tab_loc))
            else:
                built_in_tabs.append(tab)

        # create a list of components for each static tab
        components = [
            loc_mapper().translate_location(
                course_item.location.course_id, static_tab.location, False, True
            )
            for static_tab
            in static_tabs
        ]

        return render_to_response('edit-tabs.html', {
            'context_course': course_item,
            'built_in_tabs': built_in_tabs,
            'components': components,
            'course_locator': locator
        })
    else:
        return HttpResponseNotFound()