def create(self, post_data):  # lint-amnesty, pylint: disable=arguments-differ
        """ Create a new goal if one does not exist, otherwise update the existing goal. """
        # Ensure goal_key is valid
        goal_options = get_course_goal_options()
        goal_key = post_data.data.get('goal_key')
        if not goal_key:
            return Response(
                'Please provide a valid goal key from following options. (options= {goal_options}).'
                .format(goal_options=goal_options, ),
                status=status.HTTP_400_BAD_REQUEST,
            )
        elif goal_key not in goal_options:
            return Response(
                'Provided goal key, {goal_key}, is not a valid goal key (options= {goal_options}).'
                .format(
                    goal_key=goal_key,
                    goal_options=goal_options,
                ),
                status=status.HTTP_400_BAD_REQUEST,
            )

        # Ensure course key is valid
        course_key = CourseKey.from_string(post_data.data['course_key'])
        if not course_key:
            return Response(
                'Provided course_key ({course_key}) does not map to a course.'.
                format(course_key=course_key),
                status=status.HTTP_400_BAD_REQUEST,
            )

        user = post_data.user
        goal = CourseGoal.objects.filter(user=user.id,
                                         course_key=course_key).first()
        if goal:
            goal.goal_key = goal_key
            goal.save(update_fields=['goal_key'])
        else:
            CourseGoal.objects.create(
                user=user,
                course_key=course_key,
                goal_key=goal_key,
            )
        data = {
            'goal_key': str(goal_key),
            'goal_text': str(goal_options[goal_key]),
            'is_unsure': goal_key == GOAL_KEY_CHOICES.unsure,
        }
        return JsonResponse(data,
                            content_type="application/json",
                            status=(200 if goal else 201))  # lint-amnesty, pylint: disable=redundant-content-type-for-json-response
Example #2
0
def _register_course_goal_message(request, course):
    """
    Register a message to let a learner specify a course goal.
    """
    course_goal_options = get_course_goal_options()
    goal_choices_html = Text(
        _('To start, set a course goal by selecting the option below that best describes '
          'your learning plan. {goal_options_container}')).format(
              goal_options_container=HTML(
                  '<div class="row goal-options-container">'))

    # Add the dismissible option for users that are unsure of their goal
    goal_choices_html += Text('{initial_tag}{choice}{closing_tag}').format(
        initial_tag=HTML(
            '<div tabindex="0" aria-label="{aria_label_choice}" class="goal-option dismissible" '
            'data-choice="{goal_key}">').format(
                goal_key=GOAL_KEY_CHOICES.unsure,
                aria_label_choice=Text(_("Set goal to: {choice}")).format(
                    choice=course_goal_options[GOAL_KEY_CHOICES.unsure], ),
            ),
        choice=Text(_('{choice}')).format(
            choice=course_goal_options[GOAL_KEY_CHOICES.unsure], ),
        closing_tag=HTML('</div>'),
    )

    # Add the option to set a goal to earn a certificate,
    # complete the course or explore the course
    course_goals_by_commitment_level = valid_course_goals_ordered()
    for goal in course_goals_by_commitment_level:
        goal_key, goal_text = goal
        goal_choices_html += HTML(
            '{initial_tag}{goal_text}{closing_tag}'
        ).format(
            initial_tag=HTML(
                '<button tabindex="0" aria-label="{aria_label_choice}" class="goal-option btn-outline-primary" '
                'data-choice="{goal_key}">').format(
                    goal_key=goal_key,
                    aria_label_choice=Text(
                        _("Set goal to: {goal_text}")).format(
                            goal_text=Text(_(goal_text))  # lint-amnesty, pylint: disable=translation-of-non-string
                        )),
            goal_text=goal_text,
            closing_tag=HTML('</button>'))

    CourseHomeMessages.register_info_message(
        request,
        HTML('{goal_choices_html}{closing_tag}').format(
            goal_choices_html=goal_choices_html, closing_tag=HTML('</div>')),
        title=Text(_('Welcome to {course_display_name}')).format(
            course_display_name=course.display_name))
Example #3
0
def _register_course_goal_message(request, course):
    """
    Register a message to let a learner specify a course goal.
    """
    course_goal_options = get_course_goal_options()
    goal_choices_html = Text(
        _('To start, set a course goal by selecting the option below that best describes '
          'your learning plan. {goal_options_container}')).format(
              goal_options_container=HTML(
                  '<div class="row goal-options-container">'))

    # Add the dismissible option for users that are unsure of their goal
    goal_choices_html += Text('{initial_tag}{choice}{closing_tag}').format(
        initial_tag=HTML(
            '<div tabindex="0" aria-label="{aria_label_choice}" class="goal-option dismissible" '
            'data-choice="{goal_key}">').format(
                goal_key=GOAL_KEY_CHOICES.unsure,
                aria_label_choice=Text(_("Set goal to: {choice}")).format(
                    choice=course_goal_options[GOAL_KEY_CHOICES.unsure], ),
            ),
        choice=Text(_('{choice}')).format(
            choice=course_goal_options[GOAL_KEY_CHOICES.unsure], ),
        closing_tag=HTML('</div>'),
    )

    # Add the option to set a goal to earn a certificate,
    # complete the course or explore the course
    course_goal_keys = course_goal_options.keys()
    course_goal_keys.remove(GOAL_KEY_CHOICES.unsure)
    for goal_key in course_goal_keys:
        goal_text = course_goal_options[goal_key]
        goal_choices_html += HTML(
            '{initial_tag}{goal_text}{closing_tag}'
        ).format(initial_tag=HTML(
            '<button tabindex="0" aria-label="{aria_label_choice}" class="goal-option {col_sel} btn" '
            'data-choice="{goal_key}">').format(
                goal_key=goal_key,
                aria_label_choice=Text(_("Set goal to: {goal_text}")).format(
                    goal_text=Text(_(goal_text))),
                col_sel='col-' +
                str(int(math.floor(12 / len(course_goal_keys))))),
                 goal_text=goal_text,
                 closing_tag=HTML('</button>'))

    CourseHomeMessages.register_info_message(
        request,
        HTML('{goal_choices_html}{closing_tag}').format(
            goal_choices_html=goal_choices_html, closing_tag=HTML('</div>')),
        title=Text(_('Welcome to {course_display_name}')).format(
            course_display_name=course.display_name))
Example #4
0
    def render_to_fragment(self, request, course_id=None, **kwargs):
        """
        Renders the course's home page as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user, 'load', course_key)

        # Render the course dates as a fragment
        dates_fragment = CourseDatesFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)

        # Render the full content to enrolled users, as well as to course and global staff.
        # Unenrolled users who are not course or global staff are given only a subset.
        enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
        user_access = {
            'is_anonymous': request.user.is_anonymous(),
            'is_enrolled': enrollment is not None,
            'is_staff': has_access(request.user, 'staff', course_key),
        }
        if user_access['is_enrolled'] or user_access['is_staff']:
            outline_fragment = CourseOutlineFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)
            if LATEST_UPDATE_FLAG.is_enabled(course_key):
                update_message_fragment = LatestUpdateFragmentView().render_to_fragment(
                    request, course_id=course_id, **kwargs
                )
            else:
                update_message_fragment = WelcomeMessageFragmentView().render_to_fragment(
                    request, course_id=course_id, **kwargs
                )
            course_sock_fragment = CourseSockFragmentView().render_to_fragment(request, course=course, **kwargs)
            has_visited_course, resume_course_url = self._get_resume_course_info(request, course_id)
        else:
            # Redirect the user to the dashboard if they are not enrolled and
            # this is a course that does not support direct enrollment.
            if not can_self_enroll_in_course(course_key):
                raise CourseAccessRedirect(reverse('dashboard'))

            # Set all the fragments
            outline_fragment = None
            update_message_fragment = None
            course_sock_fragment = None
            has_visited_course = None
            resume_course_url = None

        # Get the handouts
        handouts_html = self._get_course_handouts(request, course)

        # Get the course tools enabled for this user and course
        course_tools = CourseToolsPluginManager.get_enabled_course_tools(request, course_key)

        # Check if the user can access the course goal functionality
        has_goal_permission = has_course_goal_permission(request, course_id, user_access)

        # Grab the current course goal and the acceptable course goal keys mapped to translated values
        current_goal = get_course_goal(request.user, course_key)
        goal_options = get_course_goal_options()

        # Get the course goals api endpoint
        goal_api_url = get_goal_api_url(request)

        # Grab the course home messages fragment to render any relevant django messages
        course_home_message_fragment = CourseHomeMessageFragmentView().render_to_fragment(
            request, course_id=course_id, user_access=user_access, **kwargs
        )

        # Get info for upgrade messaging
        upgrade_price = None
        upgrade_url = None

        # TODO Add switch to control deployment
        if SHOW_UPGRADE_MSG_ON_COURSE_HOME.is_enabled(course_key) and enrollment and enrollment.upgrade_deadline:
            upgrade_url = EcommerceService().upgrade_url(request.user, course_key)
            upgrade_price = get_cosmetic_verified_display_price(course)

        # Render the course home fragment
        context = {
            'request': request,
            'csrf': csrf(request)['csrf_token'],
            'course': course,
            'course_key': course_key,
            'outline_fragment': outline_fragment,
            'handouts_html': handouts_html,
            'course_home_message_fragment': course_home_message_fragment,
            'has_visited_course': has_visited_course,
            'resume_course_url': resume_course_url,
            'course_tools': course_tools,
            'dates_fragment': dates_fragment,
            'username': request.user.username,
            'goal_api_url': goal_api_url,
            'has_goal_permission': has_goal_permission,
            'goal_options': goal_options,
            'current_goal': current_goal,
            'update_message_fragment': update_message_fragment,
            'course_sock_fragment': course_sock_fragment,
            'disable_courseware_js': True,
            'uses_pattern_library': True,
            'upgrade_price': upgrade_price,
            'upgrade_url': upgrade_url,
        }
        html = render_to_string('course_experience/course-home-fragment.html', context)
        return Fragment(html)
Example #5
0
    def render_to_fragment(self, request, course_id=None, **kwargs):  # lint-amnesty, pylint: disable=arguments-differ, too-many-statements
        """
        Renders the course's home page as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user, 'load', course_key)

        # Render the course dates as a fragment
        dates_fragment = CourseDatesFragmentView().render_to_fragment(
            request, course_id=course_id, **kwargs)

        # Render the full content to enrolled users, as well as to course and global staff.
        # Unenrolled users who are not course or global staff are given only a subset.
        enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
        user_access = {
            'is_anonymous': request.user.is_anonymous,
            'is_enrolled': enrollment and enrollment.is_active,
            'is_staff': has_access(request.user, 'staff', course_key),
        }

        allow_anonymous = COURSE_ENABLE_UNENROLLED_ACCESS_FLAG.is_enabled(
            course_key)
        allow_public = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC
        allow_public_outline = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC_OUTLINE

        # Set all the fragments
        outline_fragment = None
        update_message_fragment = None
        course_sock_fragment = None
        offer_banner_fragment = None
        course_expiration_fragment = None
        has_visited_course = None
        resume_course_url = None
        handouts_html = None

        course_overview = CourseOverview.get_from_id(course.id)
        if user_access['is_enrolled'] or user_access['is_staff']:
            outline_fragment = CourseOutlineFragmentView().render_to_fragment(
                request, course_id=course_id, **kwargs)
            if LATEST_UPDATE_FLAG.is_enabled(course_key):
                update_message_fragment = LatestUpdateFragmentView(
                ).render_to_fragment(request, course_id=course_id, **kwargs)
            else:
                update_message_fragment = WelcomeMessageFragmentView(
                ).render_to_fragment(request, course_id=course_id, **kwargs)
            course_sock_fragment = CourseSockFragmentView().render_to_fragment(
                request, course=course, **kwargs)
            has_visited_course, resume_course_url = self._get_resume_course_info(
                request, course_id)
            handouts_html = self._get_course_handouts(request, course)
            offer_banner_fragment = get_first_purchase_offer_banner_fragment(
                request.user, course_overview)
            course_expiration_fragment = generate_course_expired_fragment(
                request.user, course_overview)
        elif allow_public_outline or allow_public:
            outline_fragment = CourseOutlineFragmentView().render_to_fragment(
                request, course_id=course_id, user_is_enrolled=False, **kwargs)
            course_sock_fragment = CourseSockFragmentView().render_to_fragment(
                request, course=course, **kwargs)
            if allow_public:
                handouts_html = self._get_course_handouts(request, course)
        else:
            # Redirect the user to the dashboard if they are not enrolled and
            # this is a course that does not support direct enrollment.
            if not can_self_enroll_in_course(course_key):
                raise CourseAccessRedirect(reverse('dashboard'))

        # Get the course tools enabled for this user and course
        course_tools = CourseToolsPluginManager.get_enabled_course_tools(
            request, course_key)

        # Check if the user can access the course goal functionality
        has_goal_permission = has_course_goal_permission(
            request, course_id, user_access)

        # Grab the current course goal and the acceptable course goal keys mapped to translated values
        current_goal = get_course_goal(request.user, course_key)
        goal_options = get_course_goal_options()

        # Get the course goals api endpoint
        goal_api_url = get_goal_api_url(request)

        # Grab the course home messages fragment to render any relevant django messages
        course_home_message_fragment = CourseHomeMessageFragmentView(
        ).render_to_fragment(request,
                             course_id=course_id,
                             user_access=user_access,
                             **kwargs)

        # Get info for upgrade messaging
        upgrade_price = None
        upgrade_url = None
        has_discount = False

        # TODO Add switch to control deployment
        if SHOW_UPGRADE_MSG_ON_COURSE_HOME.is_enabled(
                course_key) and can_show_verified_upgrade(
                    request.user, enrollment, course):
            upgrade_url = verified_upgrade_deadline_link(request.user,
                                                         course_id=course_key)
            upgrade_price, has_discount = format_strikeout_price(
                request.user, course_overview)

        show_search = (
            settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH') or
            (settings.FEATURES.get('ENABLE_COURSEWARE_SEARCH_FOR_COURSE_STAFF')
             and user_access['is_staff']))
        # Render the course home fragment
        context = {
            'request': request,
            'csrf': csrf(request)['csrf_token'],
            'course': course,
            'course_key': course_key,
            'outline_fragment': outline_fragment,
            'handouts_html': handouts_html,
            'course_home_message_fragment': course_home_message_fragment,
            'offer_banner_fragment': offer_banner_fragment,
            'course_expiration_fragment': course_expiration_fragment,
            'has_visited_course': has_visited_course,
            'resume_course_url': resume_course_url,
            'course_tools': course_tools,
            'dates_fragment': dates_fragment,
            'username': request.user.username,
            'goal_api_url': goal_api_url,
            'has_goal_permission': has_goal_permission,
            'goal_options': goal_options,
            'current_goal': current_goal,
            'update_message_fragment': update_message_fragment,
            'course_sock_fragment': course_sock_fragment,
            'disable_courseware_js': True,
            'uses_bootstrap': True,
            'upgrade_price': upgrade_price,
            'upgrade_url': upgrade_url,
            'has_discount': has_discount,
            'show_search': show_search,
        }
        html = render_to_string('course_experience/course-home-fragment.html',
                                context)
        return Fragment(html)
Example #6
0
    def render_to_fragment(self, request, course_id=None, **kwargs):
        """
        Renders the course's home page as a fragment.
        """
        course_key = CourseKey.from_string(course_id)
        course = get_course_with_access(request.user, 'load', course_key)

        # Render the course dates as a fragment
        dates_fragment = CourseDatesFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)

        # Render the full content to enrolled users, as well as to course and global staff.
        # Unenrolled users who are not course or global staff are given only a subset.
        enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
        user_access = {
            'is_anonymous': request.user.is_anonymous(),
            'is_enrolled': enrollment is not None,
            'is_staff': has_access(request.user, 'staff', course_key),
        }
        if user_access['is_enrolled'] or user_access['is_staff']:
            outline_fragment = CourseOutlineFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)
            if LATEST_UPDATE_FLAG.is_enabled(course_key):
                update_message_fragment = LatestUpdateFragmentView().render_to_fragment(
                    request, course_id=course_id, **kwargs
                )
            else:
                update_message_fragment = WelcomeMessageFragmentView().render_to_fragment(
                    request, course_id=course_id, **kwargs
                )
            course_sock_fragment = CourseSockFragmentView().render_to_fragment(request, course=course, **kwargs)
            has_visited_course, resume_course_url = self._get_resume_course_info(request, course_id)
        else:
            # Redirect the user to the dashboard if they are not enrolled and
            # this is a course that does not support direct enrollment.
            if not can_self_enroll_in_course(course_key):
                raise CourseAccessRedirect(reverse('dashboard'))

            # Set all the fragments
            outline_fragment = None
            update_message_fragment = None
            course_sock_fragment = None
            has_visited_course = None
            resume_course_url = None

        # Get the handouts
        handouts_html = self._get_course_handouts(request, course)

        # Get the course tools enabled for this user and course
        course_tools = CourseToolsPluginManager.get_enabled_course_tools(request, course_key)

        # Check if the user can access the course goal functionality
        has_goal_permission = has_course_goal_permission(request, course_id, user_access)

        # Grab the current course goal and the acceptable course goal keys mapped to translated values
        current_goal = get_course_goal(request.user, course_key)
        goal_options = get_course_goal_options()

        # Get the course goals api endpoint
        goal_api_url = get_goal_api_url(request)

        # Grab the course home messages fragment to render any relevant django messages
        course_home_message_fragment = CourseHomeMessageFragmentView().render_to_fragment(
            request, course_id=course_id, user_access=user_access, **kwargs
        )

        # Get info for upgrade messaging
        upgrade_price = None
        upgrade_url = None

        # TODO Add switch to control deployment
        if SHOW_UPGRADE_MSG_ON_COURSE_HOME.is_enabled(course_key) and enrollment and enrollment.upgrade_deadline:
            upgrade_url = EcommerceService().upgrade_url(request.user, course_key)
            upgrade_price = get_cosmetic_verified_display_price(course)

        # Render the course home fragment
        context = {
            'request': request,
            'csrf': csrf(request)['csrf_token'],
            'course': course,
            'course_key': course_key,
            'outline_fragment': outline_fragment,
            'handouts_html': handouts_html,
            'course_home_message_fragment': course_home_message_fragment,
            'has_visited_course': has_visited_course,
            'resume_course_url': resume_course_url,
            'course_tools': course_tools,
            'dates_fragment': dates_fragment,
            'username': request.user.username,
            'goal_api_url': goal_api_url,
            'has_goal_permission': has_goal_permission,
            'goal_options': goal_options,
            'current_goal': current_goal,
            'update_message_fragment': update_message_fragment,
            'course_sock_fragment': course_sock_fragment,
            'disable_courseware_js': True,
            'uses_pattern_library': True,
            'upgrade_price': upgrade_price,
            'upgrade_url': upgrade_url,
        }
        html = render_to_string('course_experience/course-home-fragment.html', context)
        return Fragment(html)
def _register_course_goal_message(request, course):
    """
    Register a message to let a learner specify a course goal.
    """
    course_goal_options = get_course_goal_options()
    goal_choices_html = Text(_(
        'To start, set a course goal by selecting the option below that best describes '
        'your learning plan. {goal_options_container}'
    )).format(
        goal_options_container=HTML('<div class="row goal-options-container">')
    )

    # Add the dismissible option for users that are unsure of their goal
    goal_choices_html += Text(
        '{initial_tag}{choice}{closing_tag}'
    ).format(
        initial_tag=HTML(
            '<div tabindex="0" aria-label="{aria_label_choice}" class="goal-option dismissible" '
            'data-choice="{goal_key}">'
        ).format(
            goal_key=GOAL_KEY_CHOICES.unsure,
            aria_label_choice=Text(_("Set goal to: {choice}")).format(
                choice=course_goal_options[GOAL_KEY_CHOICES.unsure],
            ),
        ),
        choice=Text(_('{choice}')).format(
            choice=course_goal_options[GOAL_KEY_CHOICES.unsure],
        ),
        closing_tag=HTML('</div>'),
    )

    # Add the option to set a goal to earn a certificate,
    # complete the course or explore the course
    course_goals_by_commitment_level = valid_course_goals_ordered()
    for goal in course_goals_by_commitment_level:
        goal_key, goal_text = goal
        goal_choices_html += HTML(
            '{initial_tag}{goal_text}{closing_tag}'
        ).format(
            initial_tag=HTML(
                '<button tabindex="0" aria-label="{aria_label_choice}" class="goal-option btn-outline-primary" '
                'data-choice="{goal_key}">'
            ).format(
                goal_key=goal_key,
                aria_label_choice=Text(_("Set goal to: {goal_text}")).format(
                    goal_text=Text(_(goal_text))
                )
            ),
            goal_text=goal_text,
            closing_tag=HTML('</button>')
        )

    CourseHomeMessages.register_info_message(
        request,
        HTML('{goal_choices_html}{closing_tag}').format(
            goal_choices_html=goal_choices_html,
            closing_tag=HTML('</div>')
        ),
        title=Text(_('Welcome to {course_display_name}')).format(
            course_display_name=course.display_name
        )
    )