Exemplo n.º 1
0
def strftime_localized_html(dtime, fmt):
    """
    Returns an html string that can be further localized in browser by JS code

    For example, a user's default timezone preference is "whatever the browser default is" which must be queried via
    Javascript. So we write out a UTC formatted date here, but tag it with enough information that dateutil_factory.js
    can then later update the DOM to use the proper formatting.

    Arguments:
        dtime (datetime): Datetime to format
        fmt (str): One of the special enum values that strftime_localized accepts. Only SHORT_DATE supported now.
    """
    locale_prefs = user_timezone_locale_prefs(crum.get_current_request())
    user_timezone = locale_prefs['user_timezone']
    language = get_language()

    # Here we map the enums for strftime_localized into the enums used by date-utils.js when localizing on JS side.
    format_mapping = {
        'SHORT_DATE': 'shortDate',
    }
    assert fmt in format_mapping.keys(
    ), 'format "%s" not yet supported in strftime_localized_html' % fmt  # pylint: disable=consider-iterating-dictionary

    date_html = '<span class="localized-datetime" data-format="{format}" data-timezone="{user_timezone}" \
                       data-datetime="{formatted_date}" data-language="{language}">{formatted_date_localized}</span>'

    return HTML(date_html).format(
        language=language,
        user_timezone=user_timezone,
        format=format_mapping[fmt],
        formatted_date=dtime.isoformat(),
        formatted_date_localized=strftime_localized(dtime, fmt),
    )
Exemplo n.º 2
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)

        if course_home_legacy_is_active(course_key):
            raise Http404

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_attribute('course_id', course_key_string)
        monitoring_utils.set_custom_attribute('user_id', request.user.id)
        monitoring_utils.set_custom_attribute('is_staff',
                                              request.user.is_staff)

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)
        is_staff = bool(has_access(request.user, 'staff', course_key))

        _, request.user = setup_masquerade(
            request,
            course_key,
            staff_access=is_staff,
            reset_masquerade_data=True,
        )

        if not CourseEnrollment.is_enrolled(request.user,
                                            course_key) and not is_staff:
            return Response('User not enrolled.', status=401)

        blocks = get_course_date_blocks(course,
                                        request.user,
                                        request,
                                        include_access=True,
                                        include_past_dates=True)

        learner_is_full_access = not ContentTypeGatingConfig.enabled_for_enrollment(
            user=request.user,
            course_key=course_key,
        )

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        data = {
            'has_ended':
            course.has_ended(),
            'course_date_blocks':
            [block for block in blocks if not isinstance(block, TodaysDate)],
            'learner_is_full_access':
            learner_is_full_access,
            'user_timezone':
            user_timezone,
        }
        context = self.get_serializer_context()
        context['learner_is_full_access'] = learner_is_full_access
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 3
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        course_usage_key = modulestore().make_course_usage_key(course_key)

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_metric('course_id', course_key_string)
        monitoring_utils.set_custom_metric('user_id', request.user.id)
        monitoring_utils.set_custom_metric('is_staff', request.user.is_staff)

        _, request.user = setup_masquerade(request,
                                           course_key,
                                           staff_access=has_access(
                                               request.user, 'staff',
                                               course_key),
                                           reset_masquerade_data=True)

        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        transformers = BlockStructureTransformers()
        transformers += course_blocks_api.get_course_block_access_transformers(
            request.user)
        transformers += [
            BlocksAPITransformer(None, None, depth=3),
        ]
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)
        course_blocks = get_course_blocks(request.user,
                                          course_usage_key,
                                          transformers,
                                          include_completion=True)

        enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user(
            request.user, course_key)

        course_grade = CourseGradeFactory().read(request.user, course)
        courseware_summary = course_grade.chapter_grades.values()

        data = {
            'course_blocks': course_blocks,
            'courseware_summary': courseware_summary,
            'enrollment_mode': enrollment_mode,
            'user_timezone': user_timezone,
        }
        context = self.get_serializer_context()
        context['staff_access'] = bool(
            has_access(request.user, 'staff', course))
        context['course_key'] = course_key
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 4
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)

        if not course_home_mfe_dates_tab_is_active(course_key):
            return Response(status=status.HTTP_404_NOT_FOUND)

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_metric('course_id', course_key_string)
        monitoring_utils.set_custom_metric('user_id', request.user.id)
        monitoring_utils.set_custom_metric('is_staff', request.user.is_staff)

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)
        blocks = get_course_date_blocks(course,
                                        request.user,
                                        request,
                                        include_access=True,
                                        include_past_dates=True)
        missed_deadlines, missed_gated_content = dates_banner_should_display(
            course_key, request.user)

        learner_is_full_access = not ContentTypeGatingConfig.enabled_for_enrollment(
            user=request.user,
            course_key=course_key,
        )

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        data = {
            'has_ended':
            course.has_ended(),
            'course_date_blocks':
            [block for block in blocks if not isinstance(block, TodaysDate)],
            'missed_deadlines':
            missed_deadlines,
            'missed_gated_content':
            missed_gated_content,
            'learner_is_full_access':
            learner_is_full_access,
            'user_timezone':
            user_timezone,
            'verified_upgrade_link':
            verified_upgrade_deadline_link(request.user, course=course),
        }
        context = self.get_serializer_context()
        context['learner_is_full_access'] = learner_is_full_access
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 5
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_metric('course_id', course_key_string)
        monitoring_utils.set_custom_metric('user_id', request.user.id)
        monitoring_utils.set_custom_metric('is_staff', request.user.is_staff)

        course_key = CourseKey.from_string(course_key_string)
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)
        blocks = get_course_date_blocks(course,
                                        request.user,
                                        request,
                                        include_access=True,
                                        include_past_dates=True)
        display_reset_dates_text, _ = dates_banner_should_display(
            course_key, request)

        learner_is_verified = False
        enrollment = get_enrollment(request.user.username, course_key_string)
        if enrollment:
            learner_is_verified = enrollment.get('mode') == 'verified'

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        data = {
            'course_date_blocks':
            [block for block in blocks if not isinstance(block, TodaysDate)],
            'display_reset_dates_text':
            display_reset_dates_text,
            'learner_is_verified':
            learner_is_verified,
            'user_timezone':
            user_timezone,
            'verified_upgrade_link':
            verified_upgrade_deadline_link(request.user, course=course),
        }
        context = self.get_serializer_context()
        context['learner_is_verified'] = learner_is_verified
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 6
0
 def test_no_language_preference(self):
     set_user_preference(self.user, 'time_zone', 'Asia/Tokyo')
     context = user_timezone_locale_prefs(self.request)
     self.assertIsNone(context['user_language'])
     self.assertIsNotNone(context['user_timezone'])
     self.assertEqual(context['user_timezone'], 'Asia/Tokyo')
Exemplo n.º 7
0
 def test_no_timezone_preference(self):
     set_user_preference(self.user, 'pref-lang', 'en')
     context = user_timezone_locale_prefs(self.request)
     self.assertIsNone(context['user_timezone'])
     self.assertIsNotNone(context['user_language'])
     self.assertEqual(context['user_language'], 'en')
Exemplo n.º 8
0
 def test_anonymous_user(self):
     self.request.user = AnonymousUser()
     context = user_timezone_locale_prefs(self.request)
     self.assertIsNone(context['user_timezone'])
     self.assertIsNone(context['user_language'])
Exemplo n.º 9
0
def generate_course_expired_message(user, course):
    """
    Generate the message for the user course expiration date if it exists.
    """
    expiration_date = get_user_course_expiration_date(user, course)
    if not expiration_date:
        return

    user_timezone_locale = user_timezone_locale_prefs(
        crum.get_current_request())
    user_timezone = user_timezone_locale['user_timezone']

    now = timezone.now()
    if is_masquerading_as_specific_student(
            user, course.id) and now > expiration_date:
        upgrade_message = _(
            'This learner does not have access to this course. '
            u'Their access expired on {expiration_date}.')
        return HTML(upgrade_message).format(expiration_date=strftime_localized(
            expiration_date, EXPIRATION_DATE_FORMAT_STR))
    else:
        enrollment = CourseEnrollment.get_enrollment(user, course.id)
        if enrollment is None:
            return

        upgrade_deadline = enrollment.upgrade_deadline
        if (not upgrade_deadline) or (upgrade_deadline < now):
            upgrade_deadline = enrollment.course_upgrade_deadline

        expiration_message = _(
            u'{strong_open}Audit Access Expires {expiration_date}{strong_close}'
            u'{line_break}You lose all access to this course, including your progress, on '
            u'{expiration_date}.')
        upgrade_deadline_message = _(
            u'{line_break}Upgrade by {upgrade_deadline} to get unlimited access to the course '
            u'as long as it exists on the site. {a_open}Upgrade now{sronly_span_open} to '
            u'retain access past {expiration_date}{span_close}{a_close}')
        full_message = expiration_message
        if upgrade_deadline and now < upgrade_deadline:
            full_message += upgrade_deadline_message
            using_upgrade_messaging = True
        else:
            using_upgrade_messaging = False

        language = get_language()
        date_string = get_date_string()
        formatted_expiration_date = date_string.format(
            language=language,
            user_timezone=user_timezone,
            formatted_date=expiration_date.isoformat(),
            formatted_date_localized=strftime_localized(
                expiration_date, EXPIRATION_DATE_FORMAT_STR))
        if using_upgrade_messaging:
            formatted_upgrade_deadline = date_string.format(
                language=language,
                user_timezone=user_timezone,
                formatted_date=upgrade_deadline.isoformat(),
                formatted_date_localized=strftime_localized(
                    upgrade_deadline, EXPIRATION_DATE_FORMAT_STR))

            return HTML(full_message).format(
                a_open=HTML(u'<a id="FBE_banner" href="{upgrade_link}">').
                format(upgrade_link=verified_upgrade_deadline_link(
                    user=user, course=course)),
                sronly_span_open=HTML('<span class="sr-only">'),
                span_close=HTML('</span>'),
                a_close=HTML('</a>'),
                expiration_date=HTML(formatted_expiration_date),
                strong_open=HTML('<strong>'),
                strong_close=HTML('</strong>'),
                line_break=HTML('<br>'),
                upgrade_deadline=HTML(formatted_upgrade_deadline))

        else:
            return HTML(full_message).format(
                span_close=HTML('</span>'),
                expiration_date=HTML(formatted_expiration_date),
                strong_open=HTML('<strong>'),
                strong_close=HTML('</strong>'),
                line_break=HTML('<br>'),
            )
Exemplo n.º 10
0
def generate_course_expired_message(user, course):
    """
    Generate the message for the user course expiration date if it exists.
    """
    expiration_data = get_access_expiration_data(user, course)
    if not expiration_data:
        return

    expiration_date = expiration_data['expiration_date']
    masquerading_expired_course = expiration_data[
        'masquerading_expired_course']
    upgrade_deadline = expiration_data['upgrade_deadline']
    upgrade_url = expiration_data['upgrade_url']

    user_timezone_locale = user_timezone_locale_prefs(
        crum.get_current_request())
    user_timezone = user_timezone_locale['user_timezone']

    if masquerading_expired_course:
        upgrade_message = _(
            'This learner does not have access to this course. '
            'Their access expired on {expiration_date}.')
        return HTML(upgrade_message).format(expiration_date=strftime_localized(
            expiration_date, EXPIRATION_DATE_FORMAT_STR))
    else:
        expiration_message = _(
            '{strong_open}Audit Access Expires {expiration_date}{strong_close}'
            '{line_break}You lose all access to this course, including your progress, on '
            '{expiration_date}.')
        upgrade_deadline_message = _(
            '{line_break}Upgrade by {upgrade_deadline} to get unlimited access to the course '
            'as long as it exists on the site. {a_open}Upgrade now{sronly_span_open} to '
            'retain access past {expiration_date}{span_close}{a_close}')
        full_message = expiration_message
        if upgrade_deadline and upgrade_url:
            full_message += upgrade_deadline_message
            using_upgrade_messaging = True
        else:
            using_upgrade_messaging = False

        language = get_language()
        date_string = get_date_string()
        formatted_expiration_date = date_string.format(
            language=language,
            user_timezone=user_timezone,
            formatted_date=expiration_date.isoformat(),
            formatted_date_localized=strftime_localized(
                expiration_date, EXPIRATION_DATE_FORMAT_STR))
        if using_upgrade_messaging:
            formatted_upgrade_deadline = date_string.format(
                language=language,
                user_timezone=user_timezone,
                formatted_date=upgrade_deadline.isoformat(),
                formatted_date_localized=strftime_localized(
                    upgrade_deadline, EXPIRATION_DATE_FORMAT_STR))

            return HTML(full_message).format(
                a_open=HTML('<a id="FBE_banner" href="{upgrade_link}">'
                            ).format(upgrade_link=upgrade_url),
                sronly_span_open=HTML('<span class="sr-only">'),
                span_close=HTML('</span>'),
                a_close=HTML('</a>'),
                expiration_date=HTML(formatted_expiration_date),
                strong_open=HTML('<strong>'),
                strong_close=HTML('</strong>'),
                line_break=HTML('<br>'),
                upgrade_deadline=HTML(formatted_upgrade_deadline))

        else:
            return HTML(full_message).format(
                span_close=HTML('</span>'),
                expiration_date=HTML(formatted_expiration_date),
                strong_open=HTML('<strong>'),
                strong_close=HTML('</strong>'),
                line_break=HTML('<br>'),
            )
Exemplo n.º 11
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        course_usage_key = modulestore().make_course_usage_key(course_key)

        if not course_home_mfe_outline_tab_is_active(course_key):
            raise Http404

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_metric('course_id', course_key_string)
        monitoring_utils.set_custom_metric('user_id', request.user.id)
        monitoring_utils.set_custom_metric('is_staff', request.user.is_staff)

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)

        _masquerade, request.user = setup_masquerade(
            request,
            course_key,
            staff_access=has_access(request.user, 'staff', course_key),
            reset_masquerade_data=True,
        )

        course_overview = CourseOverview.get_from_id(course_key)
        enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
        allow_anonymous = COURSE_ENABLE_UNENROLLED_ACCESS_FLAG.is_enabled(
            course_key)
        allow_public = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC
        is_enrolled = enrollment and enrollment.is_active
        is_staff = has_access(request.user, 'staff', course_key)
        show_enrolled = is_enrolled or is_staff

        show_handouts = show_enrolled or allow_public
        handouts_html = get_course_info_section(
            request, request.user, course, 'handouts') if show_handouts else ''

        # TODO: TNL-7185 Legacy: Refactor to return the offer & expired data and format the message in the MFE
        offer_html = generate_offer_html(request.user, course_overview)
        course_expired_html = generate_course_expired_message(
            request.user, course_overview)

        welcome_message_html = None
        if get_course_tag(request.user, course_key, PREFERENCE_KEY) != 'False':
            if LATEST_UPDATE_FLAG.is_enabled(course_key):
                welcome_message_html = LatestUpdateFragmentView(
                ).latest_update_html(request, course)
            else:
                welcome_message_html = WelcomeMessageFragmentView(
                ).welcome_message_html(request, course)

        enroll_alert = {
            'can_enroll': True,
            'extra_text': None,
        }
        if not show_enrolled:
            if CourseMode.is_masters_only(course_key):
                enroll_alert['can_enroll'] = False
                enroll_alert['extra_text'] = _(
                    'Please contact your degree administrator or '
                    'edX Support if you have questions.')
            elif course.invitation_only:
                enroll_alert['can_enroll'] = False

        course_tools = CourseToolsPluginManager.get_enabled_course_tools(
            request, course_key)
        date_blocks = get_course_date_blocks(course,
                                             request.user,
                                             request,
                                             num_assignments=1)

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        dates_tab_link = request.build_absolute_uri(
            reverse('dates', args=[course.id]))
        if course_home_mfe_dates_tab_is_active(course.id):
            dates_tab_link = get_microfrontend_url(course_key=course.id,
                                                   view_name='dates')

        transformers = BlockStructureTransformers()
        transformers += get_course_block_access_transformers(request.user)
        transformers += [
            BlocksAPITransformer(None, None, depth=3),
        ]

        course_blocks = get_course_blocks(request.user,
                                          course_usage_key,
                                          transformers,
                                          include_completion=True)

        dates_widget = {
            'course_date_blocks': [
                block for block in date_blocks
                if not isinstance(block, TodaysDate)
            ],
            'dates_tab_link':
            dates_tab_link,
            'user_timezone':
            user_timezone,
        }

        data = {
            'course_blocks': course_blocks,
            'course_expired_html': course_expired_html,
            'course_tools': course_tools,
            'dates_widget': dates_widget,
            'enroll_alert': enroll_alert,
            'handouts_html': handouts_html,
            'offer_html': offer_html,
            'welcome_message_html': welcome_message_html,
        }
        context = self.get_serializer_context()
        context['course_key'] = course_key
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 12
0
 def user_timezone(self):
     """Returns the user's timezone setting (may be None)"""
     user_timezone_locale = user_timezone_locale_prefs(self.request)
     return user_timezone_locale['user_timezone']
Exemplo n.º 13
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        course_usage_key = modulestore().make_course_usage_key(course_key)

        if course_home_legacy_is_active(course_key):
            raise Http404

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_attribute('course_id', course_key_string)
        monitoring_utils.set_custom_attribute('user_id', request.user.id)
        monitoring_utils.set_custom_attribute('is_staff',
                                              request.user.is_staff)

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)

        masquerade_object, request.user = setup_masquerade(
            request,
            course_key,
            staff_access=has_access(request.user, 'staff', course_key),
            reset_masquerade_data=True,
        )

        user_is_masquerading = is_masquerading(
            request.user, course_key, course_masquerade=masquerade_object)

        course_overview = CourseOverview.get_from_id(course_key)
        enrollment = CourseEnrollment.get_enrollment(request.user, 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

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        if course_home_legacy_is_active(course.id):
            dates_tab_link = request.build_absolute_uri(
                reverse('dates', args=[course.id]))
        else:
            dates_tab_link = get_learning_mfe_home_url(course_key=course.id,
                                                       view_name='dates')

        # Set all of the defaults
        access_expiration = None
        cert_data = None
        course_blocks = None
        course_goals = {'goal_options': [], 'selected_goal': None}
        course_tools = CourseToolsPluginManager.get_enabled_course_tools(
            request, course_key)
        dates_widget = {
            'course_date_blocks': [],
            'dates_tab_link': dates_tab_link,
            'user_timezone': user_timezone,
        }
        enroll_alert = {
            'can_enroll': True,
            'extra_text': None,
        }
        handouts_html = None
        offer_data = None
        resume_course = {
            'has_visited_course': False,
            'url': None,
        }
        welcome_message_html = None

        is_enrolled = enrollment and enrollment.is_active
        is_staff = bool(has_access(request.user, 'staff', course_key))
        show_enrolled = is_enrolled or is_staff
        if show_enrolled:
            course_blocks = get_course_outline_block_tree(
                request, course_key_string, request.user)
            date_blocks = get_course_date_blocks(course,
                                                 request.user,
                                                 request,
                                                 num_assignments=1)
            dates_widget['course_date_blocks'] = [
                block for block in date_blocks
                if not isinstance(block, TodaysDate)
            ]

            handouts_html = get_course_info_section(request, request.user,
                                                    course, 'handouts')
            welcome_message_html = get_current_update_for_user(request, course)

            offer_data = generate_offer_data(request.user, course_overview)
            access_expiration = get_access_expiration_data(
                request.user, course_overview)
            cert_data = get_cert_data(request.user, course,
                                      enrollment.mode) if is_enrolled else None

            # Only show the set course goal message for enrolled, unverified
            # users in a course that allows for verified statuses.
            is_already_verified = CourseEnrollment.is_enrolled_as_verified(
                request.user, course_key)
            if not is_already_verified and has_course_goal_permission(
                    request, course_key_string, {'is_enrolled': is_enrolled}):
                course_goals = {
                    'goal_options':
                    valid_course_goals_ordered(include_unsure=True),
                    'selected_goal': None
                }

                selected_goal = get_course_goal(request.user, course_key)
                if selected_goal:
                    course_goals['selected_goal'] = {
                        'key': selected_goal.goal_key,
                        'text': get_course_goal_text(selected_goal.goal_key),
                    }

            try:
                resume_block = get_key_to_last_completed_block(
                    request.user, course.id)
                resume_course['has_visited_course'] = True
                resume_path = reverse('jump_to',
                                      kwargs={
                                          'course_id': course_key_string,
                                          'location': str(resume_block)
                                      })
                resume_course['url'] = request.build_absolute_uri(resume_path)
            except UnavailableCompletionData:
                start_block = get_start_block(course_blocks)
                resume_course['url'] = start_block['lms_web_url']

        elif allow_public_outline or allow_public or user_is_masquerading:
            course_blocks = get_course_outline_block_tree(
                request, course_key_string, None)
            if allow_public or user_is_masquerading:
                handouts_html = get_course_info_section(
                    request, request.user, course, 'handouts')

        if not show_enrolled:
            if CourseMode.is_masters_only(course_key):
                enroll_alert['can_enroll'] = False
                enroll_alert['extra_text'] = _(
                    'Please contact your degree administrator or '
                    'edX Support if you have questions.')
            elif course.invitation_only:
                enroll_alert['can_enroll'] = False

        # Sometimes there are sequences returned by Course Blocks that we
        # don't actually want to show to the user, such as when a sequence is
        # composed entirely of units that the user can't access. The Learning
        # Sequences API knows how to roll this up, so we use it determine which
        # sequences we should remove from course_blocks.
        #
        # The long term goal is to remove the Course Blocks API call entirely,
        # so this is a tiny first step in that migration.
        if course_blocks and learning_sequences_api_available(
                course_key, request.user):
            user_course_outline = get_user_course_outline(
                course_key, request.user, datetime.now(tz=timezone.utc))
            available_seq_ids = {
                str(usage_key)
                for usage_key in user_course_outline.sequences
            }

            # course_blocks is a reference to the root of the course, so we go
            # through the chapters (sections) to look for sequences to remove.
            for chapter_data in course_blocks['children']:
                chapter_data['children'] = [
                    seq_data for seq_data in chapter_data['children'] if
                    (seq_data['id'] in available_seq_ids or
                     # Edge case: Sometimes we have weird course structures.
                     # We expect only sequentials here, but if there is
                     # another type, just skip it (don't filter it out).
                     seq_data['type'] != 'sequential')
                ] if 'children' in chapter_data else []

        data = {
            'access_expiration': access_expiration,
            'cert_data': cert_data,
            'course_blocks': course_blocks,
            'course_goals': course_goals,
            'course_tools': course_tools,
            'dates_widget': dates_widget,
            'enroll_alert': enroll_alert,
            'handouts_html': handouts_html,
            'has_ended': course.has_ended(),
            'offer': offer_data,
            'resume_course': resume_course,
            'welcome_message_html': welcome_message_html,
        }
        context = self.get_serializer_context()
        context['course_overview'] = course_overview
        context['enable_links'] = show_enrolled or allow_public
        context['enrollment'] = enrollment
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 14
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        course_usage_key = modulestore().make_course_usage_key(course_key)

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_metric('course_id', course_key_string)
        monitoring_utils.set_custom_metric('user_id', request.user.id)
        monitoring_utils.set_custom_metric('is_staff', request.user.is_staff)

        course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False)

        _, request.user = setup_masquerade(
            request,
            course_key,
            staff_access=has_access(request.user, 'staff', course_key),
            reset_masquerade_data=True,
        )

        enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
        allow_anonymous = COURSE_ENABLE_UNENROLLED_ACCESS_FLAG.is_enabled(course_key)
        allow_public = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC
        is_enrolled = enrollment and enrollment.is_active
        is_staff = has_access(request.user, 'staff', course_key)

        show_handouts = is_enrolled or is_staff or allow_public
        handouts_html = get_course_info_section(request, request.user, course, 'handouts') if show_handouts else ''

        welcome_message_html = None
        if get_course_tag(request.user, course_key, PREFERENCE_KEY) != 'False':
            if LATEST_UPDATE_FLAG.is_enabled(course_key):
                welcome_message_html = LatestUpdateFragmentView().latest_update_html(request, course)
            else:
                welcome_message_html = WelcomeMessageFragmentView().welcome_message_html(request, course)

        course_tools = CourseToolsPluginManager.get_enabled_course_tools(request, course_key)
        date_blocks = get_course_date_blocks(course, request.user, request, num_assignments=1)

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        dates_tab_link = request.build_absolute_uri(reverse('dates', args=[course.id]))
        if course_home_mfe_dates_tab_is_active(course.id):
            dates_tab_link = get_microfrontend_url(course_key=course.id, view_name='dates')

        transformers = BlockStructureTransformers()
        transformers += get_course_block_access_transformers(request.user)
        transformers += [
            BlocksAPITransformer(None, None, depth=3),
        ]

        course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True)

        dates_widget = {
            'course_date_blocks': [block for block in date_blocks if not isinstance(block, TodaysDate)],
            'dates_tab_link': dates_tab_link,
            'user_timezone': user_timezone,
        }

        data = {
            'course_blocks': course_blocks,
            'course_tools': course_tools,
            'dates_widget': dates_widget,
            'handouts_html': handouts_html,
            'welcome_message_html': welcome_message_html,
        }
        context = self.get_serializer_context()
        context['course_key'] = course_key
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 15
0
 def test_site_wide_language_set(self, mock_get_value):
     mock_get_value.return_value = 'ar'
     set_user_preference(self.user, 'pref-lang', 'en')
     context = user_timezone_locale_prefs(self.request)
     assert context['user_language'] == 'ar'
Exemplo n.º 16
0
 def test_anonymous_user(self):
     self.request.user = AnonymousUser()
     context = user_timezone_locale_prefs(self.request)
     assert context['user_timezone'] is None
     assert context['user_language'] == settings.LANGUAGE_CODE
Exemplo n.º 17
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        course_usage_key = modulestore().make_course_usage_key(course_key)

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_metric('course_id', course_key_string)
        monitoring_utils.set_custom_metric('user_id', request.user.id)
        monitoring_utils.set_custom_metric('is_staff', request.user.is_staff)

        course_tools = CourseToolsPluginManager.get_enabled_course_tools(
            request, course_key)

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)
        date_blocks = get_course_date_blocks(course,
                                             request.user,
                                             request,
                                             num_assignments=1)

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        dates_tab_link = request.build_absolute_uri(
            reverse('dates', args=[course.id]))
        if course_home_mfe_dates_tab_is_active(course.id):
            dates_tab_link = get_microfrontend_url(course_key=course.id,
                                                   view_name='dates')

        transformers = BlockStructureTransformers()
        transformers += course_blocks_api.get_course_block_access_transformers(
            request.user)
        transformers += [
            BlocksAPITransformer(None, None, depth=3),
        ]

        course_blocks = get_course_blocks(request.user,
                                          course_usage_key,
                                          transformers,
                                          include_completion=True)

        dates_widget = {
            'course_date_blocks': [
                block for block in date_blocks
                if not isinstance(block, TodaysDate)
            ],
            'dates_tab_link':
            dates_tab_link,
            'user_timezone':
            user_timezone,
        }

        data = {
            'course_tools': course_tools,
            'course_blocks': course_blocks,
            'dates_widget': dates_widget,
        }
        context = self.get_serializer_context()
        context['course_key'] = course_key
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 18
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_attribute('course_id', course_key_string)
        monitoring_utils.set_custom_attribute('user_id', request.user.id)
        monitoring_utils.set_custom_attribute('is_staff',
                                              request.user.is_staff)

        _, request.user = setup_masquerade(request,
                                           course_key,
                                           staff_access=has_access(
                                               request.user, 'staff',
                                               course_key),
                                           reset_masquerade_data=True)

        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        transformers = BlockStructureTransformers()
        transformers += course_blocks_api.get_course_block_access_transformers(
            request.user)
        transformers += [
            BlocksAPITransformer(None, None, depth=3),
        ]
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)

        enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user(
            request.user, course_key)

        course_grade = CourseGradeFactory().read(request.user, course)
        courseware_summary = course_grade.chapter_grades.values()

        verification_status = IDVerificationService.user_status(request.user)
        verification_link = None
        if verification_status['status'] is None or verification_status[
                'status'] == 'expired':
            verification_link = IDVerificationService.get_verify_location(
                course_id=course_key)
        elif verification_status['status'] == 'must_reverify':
            verification_link = IDVerificationService.get_verify_location(
                course_id=course_key)
        verification_data = {
            'link': verification_link,
            'status': verification_status['status'],
            'status_date': verification_status['status_date'],
        }

        data = {
            'certificate_data':
            get_cert_data(request.user, course, enrollment_mode, course_grade),
            'courseware_summary':
            courseware_summary,
            'credit_course_requirements':
            credit_course_requirements(course_key, request.user),
            'credit_support_url':
            CREDIT_SUPPORT_URL,
            'enrollment_mode':
            enrollment_mode,
            'studio_url':
            get_studio_url(course, 'settings/grading'),
            'user_timezone':
            user_timezone,
            'verification_data':
            verification_data,
        }
        context = self.get_serializer_context()
        context['staff_access'] = bool(
            has_access(request.user, 'staff', course))
        context['course_key'] = course_key
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 19
0
 def test_no_timezone_preference(self):
     set_user_preference(self.user, 'pref-lang', 'en')
     context = user_timezone_locale_prefs(self.request)
     assert context['user_timezone'] is None
     assert context['user_language'] is not None
     assert context['user_language'] == 'en'
Exemplo n.º 20
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        course_usage_key = modulestore().make_course_usage_key(course_key)

        if not course_home_mfe_outline_tab_is_active(course_key):
            raise Http404

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_attribute('course_id', course_key_string)
        monitoring_utils.set_custom_attribute('user_id', request.user.id)
        monitoring_utils.set_custom_attribute('is_staff',
                                              request.user.is_staff)

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)

        _masquerade, request.user = setup_masquerade(
            request,
            course_key,
            staff_access=has_access(request.user, 'staff', course_key),
            reset_masquerade_data=True,
        )

        course_overview = CourseOverview.get_from_id(course_key)
        enrollment = CourseEnrollment.get_enrollment(request.user, 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
        is_enrolled = enrollment and enrollment.is_active
        is_staff = bool(has_access(request.user, 'staff', course_key))
        show_enrolled = is_enrolled or is_staff

        show_handouts = show_enrolled or allow_public
        handouts_html = get_course_info_section(
            request, request.user, course, 'handouts') if show_handouts else ''

        # TODO: TNL-7185 Legacy: Refactor to return the offer & expired data and format the message in the MFE
        offer_html = show_enrolled and generate_offer_html(
            request.user, course_overview)
        course_expired_html = show_enrolled and generate_course_expired_message(
            request.user, course_overview)

        welcome_message_html = None
        if show_enrolled:
            if LATEST_UPDATE_FLAG.is_enabled(course_key):
                welcome_message_html = LatestUpdateFragmentView(
                ).latest_update_html(request, course)
            elif get_course_tag(request.user, course_key,
                                PREFERENCE_KEY) != 'False':
                welcome_message_html = WelcomeMessageFragmentView(
                ).welcome_message_html(request, course)

        enroll_alert = {
            'can_enroll': True,
            'extra_text': None,
        }
        if not show_enrolled:
            if CourseMode.is_masters_only(course_key):
                enroll_alert['can_enroll'] = False
                enroll_alert['extra_text'] = _(
                    'Please contact your degree administrator or '
                    'edX Support if you have questions.')
            elif course.invitation_only:
                enroll_alert['can_enroll'] = False

        course_tools = CourseToolsPluginManager.get_enabled_course_tools(
            request, course_key)
        date_blocks = get_course_date_blocks(course,
                                             request.user,
                                             request,
                                             num_assignments=1)

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        dates_tab_link = request.build_absolute_uri(
            reverse('dates', args=[course.id]))
        if course_home_mfe_dates_tab_is_active(course.id):
            dates_tab_link = get_microfrontend_url(course_key=course.id,
                                                   view_name='dates')

        course_blocks = None
        if show_enrolled or allow_public or allow_public_outline:
            outline_user = request.user if show_enrolled else None
            course_blocks = get_course_outline_block_tree(
                request, course_key_string, outline_user)

        resume_course = {
            'has_visited_course': False,
            'url': None,
        }
        if show_enrolled:
            try:
                resume_block = get_key_to_last_completed_block(
                    request.user, course.id)
                resume_course['has_visited_course'] = True
            except UnavailableCompletionData:
                resume_block = course_usage_key
            resume_path = reverse('jump_to',
                                  kwargs={
                                      'course_id': course_key_string,
                                      'location': str(resume_block)
                                  })
            resume_course['url'] = request.build_absolute_uri(resume_path)

        dates_widget = {
            'course_date_blocks': [
                block for block in date_blocks
                if not isinstance(block, TodaysDate)
            ],
            'dates_tab_link':
            dates_tab_link,
            'user_timezone':
            user_timezone,
        }

        # Only show the set course goal message for enrolled, unverified
        # users in a course that allows for verified statuses.
        is_already_verified = CourseEnrollment.is_enrolled_as_verified(
            request.user, course_key)
        if (not is_already_verified and has_course_goal_permission(
                request, course_key_string, {'is_enrolled': is_enrolled})):
            course_goals = {
                'goal_options':
                valid_course_goals_ordered(include_unsure=True),
                'selected_goal': None
            }

            selected_goal = get_course_goal(request.user, course_key)
            if selected_goal:
                course_goals['selected_goal'] = {
                    'key': selected_goal.goal_key,
                    'text': get_course_goal_text(selected_goal.goal_key),
                }
        else:
            course_goals = {'goal_options': [], 'selected_goal': None}

        data = {
            'course_blocks': course_blocks,
            'course_expired_html': course_expired_html or None,
            'course_goals': course_goals,
            'course_tools': course_tools,
            'dates_widget': dates_widget,
            'enroll_alert': enroll_alert,
            'handouts_html': handouts_html or None,
            'has_ended': course.has_ended(),
            'offer_html': offer_html or None,
            'resume_course': resume_course,
            'welcome_message_html': welcome_message_html or None,
        }
        context = self.get_serializer_context()
        context['course_key'] = course_key
        context['enable_links'] = show_enrolled or allow_public
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 21
0
 def test_no_language_preference(self):
     set_user_preference(self.user, 'time_zone', 'Asia/Tokyo')
     context = user_timezone_locale_prefs(self.request)
     assert context['user_language'] is None
     assert context['user_timezone'] is not None
     assert context['user_timezone'] == 'Asia/Tokyo'
Exemplo n.º 22
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        course_usage_key = modulestore().make_course_usage_key(course_key)

        if not course_home_mfe_outline_tab_is_active(course_key):
            raise Http404

        # Enable NR tracing for this view based on course
        monitoring_utils.set_custom_attribute('course_id', course_key_string)
        monitoring_utils.set_custom_attribute('user_id', request.user.id)
        monitoring_utils.set_custom_attribute('is_staff',
                                              request.user.is_staff)

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=False)

        masquerade_object, request.user = setup_masquerade(
            request,
            course_key,
            staff_access=has_access(request.user, 'staff', course_key),
            reset_masquerade_data=True,
        )

        user_is_masquerading = is_masquerading(
            request.user, course_key, course_masquerade=masquerade_object)

        course_overview = CourseOverview.get_from_id(course_key)
        enrollment = CourseEnrollment.get_enrollment(request.user, 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

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        dates_tab_link = request.build_absolute_uri(
            reverse('dates', args=[course.id]))
        if course_home_mfe_dates_tab_is_active(course.id):
            dates_tab_link = get_learning_mfe_home_url(course_key=course.id,
                                                       view_name='dates')

        # Set all of the defaults
        access_expiration = None
        course_blocks = None
        course_goals = {'goal_options': [], 'selected_goal': None}
        course_tools = CourseToolsPluginManager.get_enabled_course_tools(
            request, course_key)
        dates_widget = {
            'course_date_blocks': [],
            'dates_tab_link': dates_tab_link,
            'user_timezone': user_timezone,
        }
        enroll_alert = {
            'can_enroll': True,
            'extra_text': None,
        }
        handouts_html = None
        offer_data = None
        resume_course = {
            'has_visited_course': False,
            'url': None,
        }
        welcome_message_html = None

        is_enrolled = enrollment and enrollment.is_active
        is_staff = bool(has_access(request.user, 'staff', course_key))
        show_enrolled = is_enrolled or is_staff
        if show_enrolled:
            course_blocks = get_course_outline_block_tree(
                request, course_key_string, request.user)
            date_blocks = get_course_date_blocks(course,
                                                 request.user,
                                                 request,
                                                 num_assignments=1)
            dates_widget['course_date_blocks'] = [
                block for block in date_blocks
                if not isinstance(block, TodaysDate)
            ]

            handouts_html = get_course_info_section(request, request.user,
                                                    course, 'handouts')
            welcome_message_html = get_current_update_for_user(request, course)

            offer_data = generate_offer_data(request.user, course_overview)
            access_expiration = get_access_expiration_data(
                request.user, course_overview)

            # Only show the set course goal message for enrolled, unverified
            # users in a course that allows for verified statuses.
            is_already_verified = CourseEnrollment.is_enrolled_as_verified(
                request.user, course_key)
            if not is_already_verified and has_course_goal_permission(
                    request, course_key_string, {'is_enrolled': is_enrolled}):
                course_goals = {
                    'goal_options':
                    valid_course_goals_ordered(include_unsure=True),
                    'selected_goal': None
                }

                selected_goal = get_course_goal(request.user, course_key)
                if selected_goal:
                    course_goals['selected_goal'] = {
                        'key': selected_goal.goal_key,
                        'text': get_course_goal_text(selected_goal.goal_key),
                    }

            try:
                resume_block = get_key_to_last_completed_block(
                    request.user, course.id)
                resume_course['has_visited_course'] = True
                resume_path = reverse('jump_to',
                                      kwargs={
                                          'course_id': course_key_string,
                                          'location': str(resume_block)
                                      })
                resume_course['url'] = request.build_absolute_uri(resume_path)
            except UnavailableCompletionData:
                start_block = get_start_block(course_blocks)
                resume_course['url'] = start_block['lms_web_url']

        elif allow_public_outline or allow_public or user_is_masquerading:
            course_blocks = get_course_outline_block_tree(
                request, course_key_string, None)
            if allow_public or user_is_masquerading:
                handouts_html = get_course_info_section(
                    request, request.user, course, 'handouts')

        if not show_enrolled:
            if CourseMode.is_masters_only(course_key):
                enroll_alert['can_enroll'] = False
                enroll_alert['extra_text'] = _(
                    'Please contact your degree administrator or '
                    'edX Support if you have questions.')
            elif course.invitation_only:
                enroll_alert['can_enroll'] = False

        data = {
            'access_expiration': access_expiration,
            'course_blocks': course_blocks,
            'course_goals': course_goals,
            'course_tools': course_tools,
            'dates_widget': dates_widget,
            'enroll_alert': enroll_alert,
            'handouts_html': handouts_html,
            'has_ended': course.has_ended(),
            'offer': offer_data,
            'resume_course': resume_course,
            'welcome_message_html': welcome_message_html,
        }
        context = self.get_serializer_context()
        context['course_overview'] = course_overview
        context['enable_links'] = show_enrolled or allow_public
        context['enrollment'] = enrollment
        serializer = self.get_serializer_class()(data, context=context)

        return Response(serializer.data)
Exemplo n.º 23
0
    def get(self, request, *args, **kwargs):
        course_key_string = kwargs.get('course_key_string')
        course_key = CourseKey.from_string(course_key_string)
        original_user_is_global_staff = self.request.user.is_staff
        original_user_is_staff = has_access(request.user, 'staff',
                                            course_key).has_access

        course = course_detail(request, request.user.username, course_key)

        # We must compute course load access *before* setting up masquerading,
        # else course staff (who are not enrolled) will not be able view
        # their course from the perspective of a learner.
        load_access = check_course_access(
            course,
            request.user,
            'load',
            check_if_enrolled=True,
            check_if_authenticated=True,
        )

        _, request.user = setup_masquerade(
            request,
            course_key,
            staff_access=original_user_is_staff,
            reset_masquerade_data=True,
        )

        username = request.user.username if request.user.username else None
        enrollment = CourseEnrollment.get_enrollment(request.user,
                                                     course_key_string)
        user_is_enrolled = bool(enrollment and enrollment.is_active)

        can_load_courseware = courseware_mfe_is_visible(
            course_key=course_key,
            is_global_staff=original_user_is_global_staff,
            is_course_staff=original_user_is_staff)

        # User locale settings
        user_timezone_locale = user_timezone_locale_prefs(request)
        user_timezone = user_timezone_locale['user_timezone']

        browser_timezone = self.request.query_params.get(
            'browser_timezone', None)
        celebrations = get_celebrations_dict(
            request.user, enrollment, course,
            user_timezone if not None else browser_timezone)

        # Record course goals user activity for (web) learning mfe course tabs
        UserActivity.record_user_activity(request.user, course_key)

        data = {
            'course_id': course.id,
            'username': username,
            'is_staff': has_access(request.user, 'staff',
                                   course_key).has_access,
            'original_user_is_staff': original_user_is_staff,
            'number': course.display_number_with_default,
            'org': course.display_org_with_default,
            'start': course.start,
            'tabs': get_course_tab_list(request.user, course),
            'title': course.display_name_with_default,
            'is_self_paced': getattr(course, 'self_paced', False),
            'is_enrolled': user_is_enrolled,
            'course_access': load_access.to_json(),
            'can_load_courseware': can_load_courseware,
            'celebrations': celebrations,
            'user_timezone': user_timezone,
        }
        context = self.get_serializer_context()
        context['course'] = course
        context['course_overview'] = course
        context['enrollment'] = enrollment
        serializer = self.get_serializer_class()(data, context=context)
        return Response(serializer.data)