Esempio n. 1
0
def check_content_start_date_for_masquerade_user(course_key,
                                                 user,
                                                 request,
                                                 course_start,
                                                 chapter_start=None,
                                                 section_start=None):
    """
    Add a warning message if the masquerade user would not have access to this content
    due to the content start date being in the future.
    """
    now = datetime.now(utc)
    most_future_date = course_start
    if chapter_start and section_start:
        most_future_date = max(course_start, chapter_start, section_start)
    _is_masquerading = get_course_masquerade(user, course_key)
    if now < most_future_date and _is_masquerading:
        group_masquerade = is_masquerading_as_student(user, course_key)
        specific_student_masquerade = is_masquerading_as_specific_student(
            user, course_key)
        is_staff = has_staff_roles(user, course_key)
        if group_masquerade or (specific_student_masquerade and not is_staff):
            PageLevelMessages.register_warning_message(
                request,
                HTML(
                    _('This user does not have access to this content because \
                        the content start date is in the future')),
                once_only=True)
Esempio n. 2
0
def learner_profile(request, username):
    """Render the profile page for the specified username.

    Args:
        request (HttpRequest)
        username (str): username of user whose profile is requested.

    Returns:
        HttpResponse: 200 if the page was sent successfully
        HttpResponse: 302 if not logged in (redirect to login page)
        HttpResponse: 405 if using an unsupported HTTP method
    Raises:
        Http404: 404 if the specified user is not authorized or does not exist

    Example usage:
        GET /account/profile
    """
    user = request.user
    usr = request.user.id
    """ User Account update function starts"""
    if request.is_ajax():
        if request.method == 'GET':
            vfields = request.GET
            for key in vfields:
                vfield = key
            columname = vfield
            fieldvalue = vfields[key]
            gmember = extrafields.objects.filter(user_id=usr).update(
                **{columname: fieldvalue})
            msg = ' Updated succesfully'
            return HttpResponse(msg)
    try:
        context = learner_profile_context(request, username,
                                          request.user.is_staff)
        # TODO: LEARNER-2554: 09/2017: Remove message and cookie logic when we no longer want this message
        message_viewed = False
        if (context['own_profile'] and SHOW_PROFILE_MESSAGE.is_enabled() and
                request.COOKIES.get('profile-message-viewed', '') != 'True'):
            message_text = Text(
                _('Welcome to the new learner profile page. Your full profile now displays more '
                  'information to other learners. You can instead choose to display a limited '
                  'profile. {learn_more_link_start}Learn more{learn_more_link_end}'
                  )
            ).format(learn_more_link_start=HTML(
                '<a href="https://edx.readthedocs.io/projects/open-edx-learner-guide/en/'
                'latest/SFD_dashboard_profile_SectionHead.html#adding-profile-information">'
            ),
                     learn_more_link_end=HTML('</a>'))
            PageLevelMessages.register_info_message(request,
                                                    message_text,
                                                    dismissable=True)
            message_viewed = True
        response = render_to_response('learner_profile/learner_profile.html',
                                      context)

        if message_viewed:
            response.set_cookie('profile-message-viewed', 'True')
        return response
    except (UserNotAuthorized, UserNotFound, ObjectDoesNotExist):
        raise Http404
Esempio n. 3
0
 def _decorated(request, *args, **kwargs):  # pylint: disable=missing-docstring
     if waffle().is_enabled(DISPLAY_MAINTENANCE_WARNING):
         if hasattr(settings, 'MAINTENANCE_BANNER_TEXT') and settings.MAINTENANCE_BANNER_TEXT:
             # The waffle switch is enabled and the banner text is defined
             # and non-empty.  We can now register the message:
             PageLevelMessages.register_warning_message(request, settings.MAINTENANCE_BANNER_TEXT)
     return func(request, *args, **kwargs)
Esempio n. 4
0
def register_course_expired_message(request, course):
    """
    Add a banner notifying the user of the user course expiration date if it exists.
    """
    if not CourseDurationLimitConfig.enabled_for_enrollment(user=request.user, course_key=course.id):
        return

    expiration_date = get_user_course_expiration_date(request.user, course)
    if not expiration_date:
        return

    if is_masquerading_as_student(request.user, course.id) and timezone.now() > expiration_date:
        upgrade_message = _('This learner does not have access to this course. '
                            'Their access expired on {expiration_date}.')
        PageLevelMessages.register_warning_message(
            request,
            HTML(upgrade_message).format(
                expiration_date=expiration_date.strftime('%b %-d')
            )
        )
    else:
        enrollment = CourseEnrollment.get_enrollment(request.user, course.id)
        if enrollment is None:
            return

        upgrade_deadline = enrollment.upgrade_deadline
        if upgrade_deadline is None:
            return
        now = timezone.now()
        course_upgrade_deadline = enrollment.course_upgrade_deadline
        if now > upgrade_deadline:
            upgrade_deadline = course_upgrade_deadline

        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 now < course_upgrade_deadline:
            full_message += upgrade_deadline_message

        PageLevelMessages.register_info_message(
            request,
            Text(full_message).format(
                a_open=HTML('<a href="{upgrade_link}">').format(
                    upgrade_link=verified_upgrade_deadline_link(user=request.user, course=course)
                ),
                sronly_span_open=HTML('<span class="sr-only">'),
                sighted_only_span_open=HTML('<span aria-hidden="true">'),
                span_close=HTML('</span>'),
                a_close=HTML('</a>'),
                expiration_date=expiration_date.strftime('%b. %-d, %Y'),
                strong_open=HTML('<strong>'),
                strong_close=HTML('</strong>'),
                line_break=HTML('<br>'),
                upgrade_deadline=upgrade_deadline.strftime('%b. %-d, %Y')
            )
        )
Esempio n. 5
0
def _enforce_password_policy_compliance(request, user):
    try:
        password_policy_compliance.enforce_compliance_on_login(user, request.POST.get('password'))
    except password_policy_compliance.NonCompliantPasswordWarning as e:
        # Allow login, but warn the user that they will be required to reset their password soon.
        PageLevelMessages.register_warning_message(request, e.message)
    except password_policy_compliance.NonCompliantPasswordException as e:
        # Prevent the login attempt.
        raise AuthFailedError(e.message)
Esempio n. 6
0
 def _clear_preview_language(self, request):
     """
     Clears the preview language for the current user.
     """
     delete_user_preference(request.user, DARK_LANGUAGE_KEY)
     if LANGUAGE_SESSION_KEY in request.session:
         del request.session[LANGUAGE_SESSION_KEY]
     PageLevelMessages.register_success_message(
         request, _('Language reset to the default'))
Esempio n. 7
0
def _enforce_password_policy_compliance(request, user):  # lint-amnesty, pylint: disable=missing-function-docstring
    try:
        password_policy_compliance.enforce_compliance_on_login(user, request.POST.get('password'))
    except password_policy_compliance.NonCompliantPasswordWarning as e:
        # Allow login, but warn the user that they will be required to reset their password soon.
        PageLevelMessages.register_warning_message(request, str(e))
    except password_policy_compliance.NonCompliantPasswordException as e:
        AUDIT_LOG.info("Password reset initiated for email %s.", user.email)
        send_password_reset_email_for_user(user, request)
        # Prevent the login attempt.
        raise AuthFailedError(HTML(str(e)), error_code=e.__class__.__name__)  # lint-amnesty, pylint: disable=raise-missing-from
Esempio n. 8
0
def learner_profile(request, username):
    """Render the profile page for the specified username.

    Args:
        request (HttpRequest)
        username (str): username of user whose profile is requested.

    Returns:
        HttpResponse: 200 if the page was sent successfully
        HttpResponse: 302 if not logged in (redirect to login page)
        HttpResponse: 405 if using an unsupported HTTP method
    Raises:
        Http404: 404 if the specified user is not authorized or does not exist

    Example usage:
        GET /account/profile
    """
    is_profile_mfe_enabled_for_site = configuration_helpers.get_value(
        'ENABLE_PROFILE_MICROFRONTEND')
    if is_profile_mfe_enabled_for_site and REDIRECT_TO_PROFILE_MICROFRONTEND.is_enabled(
    ):
        profile_microfrontend_url = "{}{}".format(
            settings.PROFILE_MICROFRONTEND_URL, username)
        return redirect(profile_microfrontend_url)

    try:
        context = learner_profile_context(request, username,
                                          request.user.is_staff)
        # TODO: LEARNER-2554: 09/2017: Remove message and cookie logic when we no longer want this message
        message_viewed = False
        if (context['own_profile'] and SHOW_PROFILE_MESSAGE.is_enabled() and
                request.COOKIES.get('profile-message-viewed', '') != 'True'):
            message_text = Text(
                _(u'Welcome to the new learner profile page. Your full profile now displays more '
                  u'information to other learners. You can instead choose to display a limited '
                  u'profile. {learn_more_link_start}Learn more{learn_more_link_end}'
                  )
            ).format(learn_more_link_start=HTML(
                '<a href="https://edx.readthedocs.io/projects/open-edx-learner-guide/en/'
                'latest/SFD_dashboard_profile_SectionHead.html#adding-profile-information">'
            ),
                     learn_more_link_end=HTML('</a>'))
            PageLevelMessages.register_info_message(request,
                                                    message_text,
                                                    dismissable=True)
            message_viewed = True
        response = render_to_response('learner_profile/learner_profile.html',
                                      context)

        if message_viewed:
            response.set_cookie('profile-message-viewed', 'True')
        return response
    except (UserNotAuthorized, UserNotFound, ObjectDoesNotExist):
        raise Http404
Esempio n. 9
0
 def _clear_preview_language(self, request):
     """
     Clears the preview language for the current user.
     """
     delete_user_preference(request.user, DARK_LANGUAGE_KEY)
     if LANGUAGE_SESSION_KEY in request.session:
         del request.session[LANGUAGE_SESSION_KEY]
     PageLevelMessages.register_success_message(
         request,
         _('Language reset to the default')
     )
Esempio n. 10
0
    def render(self, request):
        """
        Render the index page.
        """
        self._redirect_if_needed_to_pay_for_course()
        self._prefetch_and_bind_course(request)

        if self.course.has_children_at_depth(CONTENT_DEPTH):
            self._reset_section_to_exam_if_required()
            self.chapter = self._find_chapter()
            self.section = self._find_section()

            if self.chapter and self.section:
                self._redirect_if_not_requested_section()
                self._save_positions()
                self._prefetch_and_bind_section()
                self._redirect_to_learning_mfe()

            check_content_start_date_for_masquerade_user(
                self.course_key, self.effective_user, request,
                self.course.start, self.chapter.start, self.section.start)

        if not request.user.is_authenticated:
            qs = six.moves.urllib.parse.urlencode({
                'course_id': self.course_key,
                'enrollment_action': 'enroll',
                'email_opt_in': False,
            })

            allow_anonymous = check_public_access(self.course,
                                                  [COURSE_VISIBILITY_PUBLIC])

            if not allow_anonymous:
                PageLevelMessages.register_warning_message(
                    request,
                    Text(
                        _(u"You are not signed in. To see additional course content, {sign_in_link} or "
                          u"{register_link}, and enroll in this course.")).
                    format(
                        sign_in_link=HTML(
                            u'<a href="{url}">{sign_in_label}</a>').format(
                                sign_in_label=_('sign in'),
                                url='{}?{}'.format(reverse('signin_user'), qs),
                            ),
                        register_link=HTML(
                            u'<a href="/{url}">{register_label}</a>').format(
                                register_label=_('register'),
                                url=u'{}?{}'.format(reverse('register_user'),
                                                    qs),
                            ),
                    ))

        return render_to_response('courseware/courseware.html',
                                  self._create_courseware_context(request))
Esempio n. 11
0
def _enforce_password_policy_compliance(request, user):
    try:
        password_policy_compliance.enforce_compliance_on_login(
            user, request.POST.get('password'))
    except password_policy_compliance.NonCompliantPasswordWarning as e:
        # Allow login, but warn the user that they will be required to reset their password soon.
        PageLevelMessages.register_warning_message(request, six.text_type(e))
    except password_policy_compliance.NonCompliantPasswordException as e:
        send_password_reset_email_for_user(user, request)
        # Prevent the login attempt.
        raise AuthFailedError(HTML(six.text_type(e)),
                              error_code=e.__class__.__name__)
Esempio n. 12
0
def learner_profile(request, username):
    """Render the profile page for the specified username.

    Args:
        request (HttpRequest)
        username (str): username of user whose profile is requested.

    Returns:
        HttpResponse: 200 if the page was sent successfully
        HttpResponse: 302 if not logged in (redirect to login page)
        HttpResponse: 405 if using an unsupported HTTP method
    Raises:
        Http404: 404 if the specified user is not authorized or does not exist

    Example usage:
        GET /account/profile
    """
    is_profile_mfe_enabled_for_site = configuration_helpers.get_value('ENABLE_PROFILE_MICROFRONTEND')
    if is_profile_mfe_enabled_for_site and REDIRECT_TO_PROFILE_MICROFRONTEND.is_enabled():
        profile_microfrontend_url = "{}{}".format(settings.PROFILE_MICROFRONTEND_URL, username)
        return redirect(profile_microfrontend_url)

    try:
        context = learner_profile_context(request, username, request.user.is_staff)
        # TODO: LEARNER-2554: 09/2017: Remove message and cookie logic when we no longer want this message
        message_viewed = False
        if (context['own_profile'] and
                SHOW_PROFILE_MESSAGE.is_enabled() and
                request.COOKIES.get('profile-message-viewed', '') != 'True'):
            message_text = Text(_(
                u'Welcome to the new learner profile page. Your full profile now displays more '
                u'information to other learners. You can instead choose to display a limited '
                u'profile. {learn_more_link_start}Learn more{learn_more_link_end}'
            )).format(
                learn_more_link_start=HTML(
                    '<a href="https://edx.readthedocs.io/projects/open-edx-learner-guide/en/'
                    'latest/SFD_dashboard_profile_SectionHead.html#adding-profile-information">'
                ),
                learn_more_link_end=HTML('</a>')
            )
            PageLevelMessages.register_info_message(request, message_text, dismissable=True)
            message_viewed = True
        response = render_to_response(
            'learner_profile/learner_profile.html',
            context
        )

        if message_viewed:
            response.set_cookie('profile-message-viewed', 'True')
        return response
    except (UserNotAuthorized, UserNotFound, ObjectDoesNotExist):
        raise Http404
Esempio n. 13
0
    def _set_preview_language(self, request):
        """
        Sets the preview language for the current user.
        """
        preview_language = request.POST.get(LANGUAGE_INPUT_FIELD, '')
        if not preview_language.strip():
            PageLevelMessages.register_error_message(
                request, _('Language not provided'))
            return

        set_user_preference(request.user, DARK_LANGUAGE_KEY, preview_language)
        PageLevelMessages.register_success_message(
            request,
            _(u'Language set to {preview_language}').format(
                preview_language=preview_language))
Esempio n. 14
0
    def _set_preview_language(self, request):
        """
        Sets the preview language for the current user.
        """
        preview_language = request.POST.get(LANGUAGE_INPUT_FIELD, '')
        if not preview_language.strip():
            PageLevelMessages.register_error_message(request, _('Language not provided'))
            return

        set_user_preference(request.user, DARK_LANGUAGE_KEY, preview_language)
        PageLevelMessages.register_success_message(
            request,
            _(u'Language set to {preview_language}').format(
                preview_language=preview_language
            )
        )
Esempio n. 15
0
def register_course_expired_message(request, course):
    """
    Add a banner notifying the user of the user course expiration date if it exists.
    """
    if CourseDurationLimitConfig.enabled_for_enrollment(user=request.user, course_key=course.id):
        expiration_date = get_user_course_expiration_date(request.user, course)
        if expiration_date:
            upgrade_message = _('Your access to this course expires on {expiration_date}. \
                    <a href="{upgrade_link}">Upgrade now</a> for unlimited access.')
            PageLevelMessages.register_info_message(
                request,
                HTML(upgrade_message).format(
                    expiration_date=expiration_date.strftime('%b %-d'),
                    upgrade_link=verified_upgrade_deadline_link(user=request.user, course=course)
                )
            )
Esempio n. 16
0
    def render(self, request):
        """
        Render the index page.
        """
        self._redirect_if_needed_to_pay_for_course()
        self._prefetch_and_bind_course(request)

        if self.course.has_children_at_depth(CONTENT_DEPTH):
            self._reset_section_to_exam_if_required()
            self.chapter = self._find_chapter()
            self.section = self._find_section()

            if self.chapter and self.section:
                self._redirect_if_not_requested_section()
                self._save_positions()
                self._prefetch_and_bind_section()

            check_content_start_date_for_masquerade_user(self.course_key, self.effective_user, request,
                                                         self.course.start, self.chapter.start, self.section.start)

        if not request.user.is_authenticated:
            qs = urllib.urlencode({
                'course_id': self.course_key,
                'enrollment_action': 'enroll',
                'email_opt_in': False,
            })

            allow_anonymous = allow_public_access(self.course, [COURSE_VISIBILITY_PUBLIC])

            if not allow_anonymous:
                PageLevelMessages.register_warning_message(
                    request,
                    Text(_(u"You are not signed in. To see additional course content, {sign_in_link} or "
                           u"{register_link}, and enroll in this course.")).format(
                        sign_in_link=HTML(u'<a href="{url}">{sign_in_label}</a>').format(
                            sign_in_label=_('sign in'),
                            url='{}?{}'.format(reverse('signin_user'), qs),
                        ),
                        register_link=HTML(u'<a href="/{url}">{register_label}</a>').format(
                            register_label=_('register'),
                            url=u'{}?{}'.format(reverse('register_user'), qs),
                        ),
                    )
                )

        return render_to_response('courseware/courseware.html', self._create_courseware_context(request))
Esempio n. 17
0
    def render(self, request):
        """
        Render the index page.
        """
        self._redirect_if_needed_to_enter_university_id()
        self._redirect_if_needed_to_pay_for_course()
        self._prefetch_and_bind_course(request)

        if self.course.has_children_at_depth(CONTENT_DEPTH):
            self._reset_section_to_exam_if_required()
            self.chapter = self._find_chapter()
            self.section = self._find_section()

            if self.chapter and self.section:
                self._redirect_if_not_requested_section()
                self._save_positions()
                self._prefetch_and_bind_section()

        if not request.user.is_authenticated:
            qs = urllib.urlencode({
                'course_id': self.course_key,
                'enrollment_action': 'enroll',
                'email_opt_in': False,
            })

            PageLevelMessages.register_warning_message(
                request,
                Text(
                    _("You are not signed in. To see additional course content, {sign_in_link} or "
                      "{register_link}, and enroll in this course.")).format(
                          sign_in_link=HTML(
                              '<a href="{url}">{sign_in_label}</a>').format(
                                  sign_in_label=_('sign in'),
                                  url='{}?{}'.format(reverse('signin_user'),
                                                     qs),
                              ),
                          register_link=HTML(
                              '<a href="/{url}">{register_label}</a>').format(
                                  register_label=_('register'),
                                  url='{}?{}'.format(reverse('register_user'),
                                                     qs),
                              ),
                      ))

        return render_to_response('courseware/courseware.html',
                                  self._create_courseware_context(request))
Esempio n. 18
0
def _enforce_password_policy_compliance(request, user):  # lint-amnesty, pylint: disable=missing-function-docstring
    try:
        password_policy_compliance.enforce_compliance_on_login(
            user, request.POST.get('password'))
    except password_policy_compliance.NonCompliantPasswordWarning as e:
        # Allow login, but warn the user that they will be required to reset their password soon.
        PageLevelMessages.register_warning_message(request, HTML(str(e)))
    except password_policy_compliance.NonCompliantPasswordException as e:
        # Increment the lockout counter to safguard from further brute force requests
        # if user's password has been compromised.
        if LoginFailures.is_feature_enabled():
            LoginFailures.increment_lockout_counter(user)

        AUDIT_LOG.info("Password reset initiated for email %s.", user.email)
        send_password_reset_email_for_user(user, request)

        # Prevent the login attempt.
        raise AuthFailedError(HTML(str(e)), error_code=e.__class__.__name__)  # lint-amnesty, pylint: disable=raise-missing-from
Esempio n. 19
0
def set_user_preview_site_theme(request, preview_site_theme):
    """
    Sets the current user's preferred preview site theme.

    Args:
        request: the current request
        preview_site_theme (str or SiteTheme): the preview site theme or theme name.
          None can be specified to remove the preview site theme.
    """
    if preview_site_theme:
        if isinstance(preview_site_theme, SiteTheme):
            preview_site_theme_name = preview_site_theme.theme_dir_name
        else:
            preview_site_theme_name = preview_site_theme
        if theme_exists(preview_site_theme_name):
            set_user_preference(request.user,
                                PREVIEW_SITE_THEME_PREFERENCE_KEY,
                                preview_site_theme_name)
            PageLevelMessages.register_success_message(
                request,
                _(u'Site theme changed to {site_theme}').format(
                    site_theme=preview_site_theme_name))
        else:
            PageLevelMessages.register_error_message(
                request,
                _(u'Theme {site_theme} does not exist').format(
                    site_theme=preview_site_theme_name))
    else:
        delete_user_preference(request.user, PREVIEW_SITE_THEME_PREFERENCE_KEY)
        PageLevelMessages.register_success_message(
            request, _('Site theme reverted to the default'))
Esempio n. 20
0
def set_user_preview_site_theme(request, preview_site_theme):
    """
    Sets the current user's preferred preview site theme.

    Args:
        request: the current request
        preview_site_theme (str or SiteTheme): the preview site theme or theme name.
          None can be specified to remove the preview site theme.
    """
    if preview_site_theme:
        if isinstance(preview_site_theme, SiteTheme):
            preview_site_theme_name = preview_site_theme.theme_dir_name
        else:
            preview_site_theme_name = preview_site_theme
        if theme_exists(preview_site_theme_name):
            set_user_preference(request.user, PREVIEW_SITE_THEME_PREFERENCE_KEY, preview_site_theme_name)
            PageLevelMessages.register_success_message(
                request,
                _('Site theme changed to {site_theme}'.format(site_theme=preview_site_theme_name))
            )
        else:
            PageLevelMessages.register_error_message(
                request,
                _('Theme {site_theme} does not exist'.format(site_theme=preview_site_theme_name))
            )
    else:
        delete_user_preference(request.user, PREVIEW_SITE_THEME_PREFERENCE_KEY)
        PageLevelMessages.register_success_message(request, _('Site theme reverted to the default'))
def check_start_date(user, days_early_for_beta, start, course_key):
    """
    Verifies whether the given user is allowed access given the
    start date and the Beta offset for the given course.

    Returns:
        AccessResponse: Either ACCESS_GRANTED or StartDateError.
    """
    start_dates_disabled = settings.FEATURES['DISABLE_START_DATES']
    masquerading_as_student = is_masquerading_as_student(user, course_key)
    masquerading_as_specific_student = is_masquerading_as_specific_student(
        user, course_key)

    if start_dates_disabled and not masquerading_as_student:
        return ACCESS_GRANTED
    else:
        now = datetime.now(UTC)
        if start is None or in_preview_mode():
            return ACCESS_GRANTED

        effective_start = adjust_start_date(user, days_early_for_beta, start,
                                            course_key)
        if now > effective_start:
            return ACCESS_GRANTED

        if get_course_masquerade(user, course_key):
            if masquerading_as_student or (
                    masquerading_as_specific_student
                    and not has_staff_roles(user, course_key)):
                request = get_current_request()
                PageLevelMessages.register_warning_message(
                    request,
                    HTML(
                        _('This user does not have access to this content due to the content start date'
                          )),
                    once_only=True)
                return ACCESS_GRANTED

        return StartDateError(start)
Esempio n. 22
0
def register_course_expired_message(request, course):
    """
    Add a banner notifying the user of the user course expiration date if it exists.
    """
    if not CourseDurationLimitConfig.enabled_for_enrollment(
            user=request.user, course_key=course.id):
        return

    expiration_date = get_user_course_expiration_date(request.user, course)
    if not expiration_date:
        return

    if is_masquerading_as_student(
            request.user, course.id) and timezone.now() > expiration_date:
        upgrade_message = _(
            'This learner would not have access to this course. '
            'Their access expired on {expiration_date}.')
        PageLevelMessages.register_warning_message(
            request,
            HTML(upgrade_message).format(
                expiration_date=expiration_date.strftime('%b %-d')))
    else:
        upgrade_message = _(
            'Your access to this course expires on {expiration_date}. \
                    {a_open}Upgrade now {sronly_span_open}to retain access past {expiration_date}.\
                    {span_close}{a_close}{sighted_only_span_open}for unlimited access.{span_close}'
        )
        PageLevelMessages.register_info_message(
            request,
            Text(upgrade_message).format(
                a_open=HTML('<a href="{upgrade_link}">').format(
                    upgrade_link=verified_upgrade_deadline_link(
                        user=request.user, course=course)),
                sronly_span_open=HTML('<span class="sr-only">'),
                sighted_only_span_open=HTML('<span aria-hidden="true">'),
                span_close=HTML('</span>'),
                a_close=HTML('</a>'),
                expiration_date=expiration_date.strftime('%b %-d'),
            ))
Esempio n. 23
0
def check_content_start_date_for_masquerade_user(course_key, user, request, course_start,
                                                 chapter_start=None, section_start=None):
    """
    Add a warning message if the masquerade user would not have access to this content
    due to the content start date being in the future.
    """
    now = datetime.now(utc)
    most_future_date = course_start
    if chapter_start and section_start:
        most_future_date = max(course_start, chapter_start, section_start)
    is_masquerading = get_course_masquerade(user, course_key)
    if now < most_future_date and is_masquerading:
        group_masquerade = is_masquerading_as_student(user, course_key)
        specific_student_masquerade = is_masquerading_as_specific_student(user, course_key)
        is_staff = has_staff_roles(user, course_key)
        if group_masquerade or (specific_student_masquerade and not is_staff):
            PageLevelMessages.register_warning_message(
                request,
                HTML(_('This user does not have access to this content because \
                        the content start date is in the future')),
                once_only=True
            )
Esempio n. 24
0
def register_course_expired_message(request, course):
    """
    Add a banner notifying the user of the user course expiration date if it exists.
    """
    if not CourseDurationLimitConfig.enabled_for_enrollment(user=request.user, course_key=course.id):
        return

    expiration_date = get_user_course_expiration_date(request.user, course)
    if not expiration_date:
        return

    if is_masquerading_as_student(request.user, course.id) and timezone.now() > expiration_date:
        upgrade_message = _('This learner would not have access to this course. '
                            'Their access expired on {expiration_date}.')
        PageLevelMessages.register_warning_message(
            request,
            HTML(upgrade_message).format(
                expiration_date=expiration_date.strftime('%b %-d')
            )
        )
    else:
        upgrade_message = _('Your access to this course expires on {expiration_date}. \
                    {a_open}Upgrade now {sronly_span_open}to retain access past {expiration_date}.\
                    {span_close}{a_close}{sighted_only_span_open}for unlimited access.{span_close}')
        PageLevelMessages.register_info_message(
            request,
            Text(upgrade_message).format(
                a_open=HTML('<a href="{upgrade_link}">').format(
                    upgrade_link=verified_upgrade_deadline_link(user=request.user, course=course)
                ),
                sronly_span_open=HTML('<span class="sr-only">'),
                sighted_only_span_open=HTML('<span aria-hidden="true">'),
                span_close=HTML('</span>'),
                a_close=HTML('</a>'),
                expiration_date=expiration_date.strftime('%b %-d'),
            )
        )
Esempio n. 25
0
def render_body(context,**pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)
        request = context.get('request', UNDEFINED)
        self = context.get('self', UNDEFINED)
        list = context.get('list', UNDEFINED)
        hasattr = context.get('hasattr', UNDEFINED)
        course = context.get('course', UNDEFINED)
        __M_writer = context.writer()
        __M_writer(u'\n')
        __M_writer(u'\n\n')
        __M_writer(u'\n')
        online_help_token = self.online_help_token() if hasattr(self, 'online_help_token') else None 
        
        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(__M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key]) for __M_key in ['online_help_token'] if __M_key in __M_locals_builtin_stored]))
        __M_writer(u'\n')
        __M_writer(u'\n\n')

        banner_messages = list(PageLevelMessages.user_messages(request))
        
        # insert the global status message
        course_id = course.id if course else None
        site_status_message = get_site_status_msg(course_id)
        if site_status_message:
            banner_messages.insert(0, UserMessage(UserMessageType.WARNING, site_status_message))
        
        
        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(__M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key]) for __M_key in ['course_id','site_status_message','banner_messages'] if __M_key in __M_locals_builtin_stored]))
        __M_writer(u'\n\n')
        if banner_messages:
            __M_writer(u'    <div class="page-banner">\n        <div class="user-messages" role="complementary" aria-label="messages">\n            <ul class="user-messages-ul">\n')
            for message in banner_messages:
                __M_writer(u'                    <li>\n                        <div class="alert ')
                __M_writer(filters.html_escape(filters.decode.utf8(message.css_class)))
                __M_writer(u'" role="alert">\n                            <span class="icon icon-alert fa ')
                __M_writer(filters.html_escape(filters.decode.utf8(message.icon_class)))
                __M_writer(u'" aria-hidden="true"></span>\n                            ')
                __M_writer(filters.html_escape(filters.decode.utf8(HTML(message.message_html))))
                __M_writer(u'\n                        </div>\n                    </li>\n')
            __M_writer(u'            </ul>\n        </div>\n    </div>\n')
        return ''
    finally:
        context.caller_stack._pop_frame()
Esempio n. 26
0
def show_reference_template(request, template):
    """
    Shows the specified template as an HTML page. This is used only in
    debug mode to allow the UX team to produce and work with static
    reference templates.

    e.g. http://localhost:8000/template/ux/reference/index.html
    shows the template from ux/reference/index.html

    Note: dynamic parameters can also be passed to the page.
    e.g. /template/ux/reference/index.html?name=Foo
    """
    try:
        is_v1 = u'/v1/' in request.path
        uses_bootstrap = not is_v1
        context = {
            'request': request,
            'uses_bootstrap': uses_bootstrap,
        }
        context.update(request.GET.dict())

        # Support dynamic rendering of messages
        if request.GET.get('alert'):
            PageLevelMessages.register_info_message(request,
                                                    request.GET.get('alert'))
        if request.GET.get('success'):
            PageLevelMessages.register_success_message(
                request, request.GET.get('success'))
        if request.GET.get('warning'):
            PageLevelMessages.register_warning_message(
                request, request.GET.get('warning'))
        if request.GET.get('error'):
            PageLevelMessages.register_error_message(request,
                                                     request.GET.get('error'))

        # Add some messages to the course skeleton pages
        if u'course-skeleton.html' in request.path:
            PageLevelMessages.register_info_message(
                request, _('This is a test message'))
            PageLevelMessages.register_success_message(
                request, _('This is a success message'))
            PageLevelMessages.register_warning_message(
                request, _('This is a test warning'))
            PageLevelMessages.register_error_message(request,
                                                     _('This is a test error'))

        return render_to_response(template, context)
    except TemplateDoesNotExist:
        return HttpResponseNotFound(u'Missing template {template}'.format(
            template=bleach.clean(template, strip=True)))
Esempio n. 27
0
def register_course_expired_message(request, course):
    """
    Add a banner notifying the user of the user course expiration date if it exists.
    """
    if not CourseDurationLimitConfig.enabled_for_enrollment(
            user=request.user, course_key=course.id):
        return

    expiration_date = get_user_course_expiration_date(request.user, course)
    if not expiration_date:
        return

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

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

        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 now < upgrade_deadline:
            full_message += upgrade_deadline_message
            using_upgrade_messaging = True
        else:
            using_upgrade_messaging = False

        language = get_language()
        language_is_es = language and language.split('-')[0].lower() == 'es'
        if language_is_es:
            formatted_expiration_date = strftime_localized(
                expiration_date, '%-d de %b. de %Y').lower()
        else:
            formatted_expiration_date = strftime_localized(
                expiration_date, '%b. %-d, %Y')

        if using_upgrade_messaging:
            if language_is_es:
                formatted_upgrade_deadline = strftime_localized(
                    upgrade_deadline, '%-d de %b. de %Y').lower()
            else:
                formatted_upgrade_deadline = strftime_localized(
                    upgrade_deadline, '%b. %-d, %Y')

            PageLevelMessages.register_info_message(
                request,
                Text(full_message).format(
                    a_open=HTML('<a href="{upgrade_link}">').format(
                        upgrade_link=verified_upgrade_deadline_link(
                            user=request.user, course=course)),
                    sronly_span_open=HTML('<span class="sr-only">'),
                    span_close=HTML('</span>'),
                    a_close=HTML('</a>'),
                    expiration_date=formatted_expiration_date,
                    strong_open=HTML('<strong>'),
                    strong_close=HTML('</strong>'),
                    line_break=HTML('<br>'),
                    upgrade_deadline=formatted_upgrade_deadline))
        else:
            PageLevelMessages.register_info_message(
                request,
                Text(full_message).format(
                    span_close=HTML('</span>'),
                    expiration_date=formatted_expiration_date,
                    strong_open=HTML('<strong>'),
                    strong_close=HTML('</strong>'),
                    line_break=HTML('<br>'),
                ))
Esempio n. 28
0
def show_reference_template(request, template):
    """
    Shows the specified template as an HTML page. This is used only in
    debug mode to allow the UX team to produce and work with static
    reference templates.

    e.g. http://localhost:8000/template/ux/reference/index.html
    shows the template from ux/reference/index.html

    Note: dynamic parameters can also be passed to the page.
    e.g. /template/ux/reference/index.html?name=Foo
    """
    try:
        uses_pattern_library = u'/pattern-library/' in request.path
        is_v1 = u'/v1/' in request.path
        uses_bootstrap = not uses_pattern_library and not is_v1
        context = {
            'request': request,
            'uses_pattern_library': uses_pattern_library,
            'uses_bootstrap': uses_bootstrap,
        }
        context.update(request.GET.dict())

        # Support dynamic rendering of messages
        if request.GET.get('alert'):
            PageLevelMessages.register_info_message(request, request.GET.get('alert'))
        if request.GET.get('success'):
            PageLevelMessages.register_success_message(request, request.GET.get('success'))
        if request.GET.get('warning'):
            PageLevelMessages.register_warning_message(request, request.GET.get('warning'))
        if request.GET.get('error'):
            PageLevelMessages.register_error_message(request, request.GET.get('error'))

        # Add some messages to the course skeleton pages
        if u'course-skeleton.html' in request.path:
            PageLevelMessages.register_info_message(request, _('This is a test message'))
            PageLevelMessages.register_success_message(request, _('This is a success message'))
            PageLevelMessages.register_warning_message(request, _('This is a test warning'))
            PageLevelMessages.register_error_message(request, _('This is a test error'))

        return render_to_response(template, context)
    except TopLevelLookupException:
        return HttpResponseNotFound('Missing template {template}'.format(template=template))
Esempio n. 29
0
def render_body(context, **pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)

        def requirejs():
            return render_requirejs(context._locals(__M_locals))

        request = context.get('request', UNDEFINED)
        EDX_ROOT_URL = context.get('EDX_ROOT_URL', UNDEFINED)
        static = _mako_get_namespace(context, 'static')
        LANGUAGE_CODE = context.get('LANGUAGE_CODE', UNDEFINED)

        def bodyclass():
            return render_bodyclass(context._locals(__M_locals))

        def title():
            return render_title(context._locals(__M_locals))

        context_library = context.get('context_library', UNDEFINED)

        def jsextra():
            return render_jsextra(context._locals(__M_locals))

        def content():
            return render_content(context._locals(__M_locals))

        getattr = context.get('getattr', UNDEFINED)
        uses_bootstrap = context.get('uses_bootstrap', UNDEFINED)

        def view_notes():
            return render_view_notes(context._locals(__M_locals))

        user = context.get('user', UNDEFINED)
        hasattr = context.get('hasattr', UNDEFINED)
        context_course = context.get('context_course', UNDEFINED)
        settings = context.get('settings', UNDEFINED)
        list = context.get('list', UNDEFINED)

        def page_bundle():
            return render_page_bundle(context._locals(__M_locals))

        def page_alert():
            return render_page_alert(context._locals(__M_locals))

        def header_extras():
            return render_header_extras(context._locals(__M_locals))

        def modal_placeholder():
            return render_modal_placeholder(context._locals(__M_locals))

        self = context.get('self', UNDEFINED)
        __M_writer = context.writer()
        __M_writer(u'\n')
        __M_writer(u'\n\n')
        __M_writer(u'\n')
        __M_writer(u'\n\n')
        __M_writer(
            u'\n<!doctype html>\n<!--[if lte IE 9]><html class="ie9 lte9" lang="'
        )
        __M_writer(filters.html_escape(filters.decode.utf8(LANGUAGE_CODE)))
        __M_writer(u'"><![endif]-->\n<!--[if !IE]><<!--><html lang="')
        __M_writer(filters.html_escape(filters.decode.utf8(LANGUAGE_CODE)))
        __M_writer(u'"><!--<![endif]-->\n  <head dir="')
        __M_writer(filters.html_escape(filters.decode.utf8(static.dir_rtl())))
        __M_writer(
            u'">\n    <meta charset="utf-8">\n    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">\n    <meta name="openedx-release-line" content="'
        )
        __M_writer(filters.html_escape(filters.decode.utf8(RELEASE_LINE)))
        __M_writer(u'" />\n    <title>\n        ')
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'title'):
            context['self'].title(**pageargs)

        __M_writer(u' |\n')
        if context_course:
            __M_writer(u'        ')
            ctx_loc = context_course.location

            __M_locals_builtin_stored = __M_locals_builtin()
            __M_locals.update(
                __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                                  for __M_key in ['ctx_loc']
                                  if __M_key in __M_locals_builtin_stored]))
            __M_writer(u'\n        ')
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(
                        context_course.display_name_with_default)))
            __M_writer(u' |\n')
        elif context_library:
            __M_writer(u'        ')
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(
                        context_library.display_name_with_default)))
            __M_writer(u' |\n')
        __M_writer(u'        ')
        __M_writer(
            filters.html_escape(filters.decode.utf8(settings.STUDIO_NAME)))
        __M_writer(u'\n    </title>\n\n    ')

        jsi18n_path = "js/i18n/{language}/djangojs.js".format(
            language=LANGUAGE_CODE)

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                              for __M_key in ['jsi18n_path']
                              if __M_key in __M_locals_builtin_stored]))
        __M_writer(u'\n\n')
        if getattr(settings, 'CAPTURE_CONSOLE_LOG', False):
            __M_writer(
                u'        <script type="text/javascript">\n            var oldOnError = window.onerror;\n            window.localStorage.setItem(\'console_log_capture\', JSON.stringify([]));\n\n            window.onerror = function (message, url, lineno, colno, error) {\n                if (oldOnError) {\n                    oldOnError.apply(this, arguments);\n                }\n\n                var messages = JSON.parse(window.localStorage.getItem(\'console_log_capture\'));\n                messages.push([message, url, lineno, colno, (error || {}).stack]);\n                window.localStorage.setItem(\'console_log_capture\', JSON.stringify(messages));\n            }\n        </script>\n'
            )
        __M_writer(u'\n    <script type="text/javascript" src="')
        __M_writer(
            filters.html_escape(filters.decode.utf8(static.url(jsi18n_path))))
        __M_writer(
            u'"></script>\n    <meta name="viewport" content="width=device-width,initial-scale=1">\n    <meta name="path_prefix" content="'
        )
        __M_writer(filters.html_escape(filters.decode.utf8(EDX_ROOT_URL)))
        __M_writer(u'">\n\n    ')

        def ccall(caller):
            def body():
                __M_writer = context.writer()
                return ''

            return [body]

        context.caller_stack.nextcaller = runtime.Namespace(
            'caller', context, callables=ccall(__M_caller))
        try:
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(static.css(group=u'style-vendor'))))
        finally:
            context.caller_stack.nextcaller = None
        __M_writer(u'\n    ')

        def ccall(caller):
            def body():
                __M_writer = context.writer()
                return ''

            return [body]

        context.caller_stack.nextcaller = runtime.Namespace(
            'caller', context, callables=ccall(__M_caller))
        try:
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(
                        static.css(group=u'style-vendor-tinymce-content'))))
        finally:
            context.caller_stack.nextcaller = None
        __M_writer(u'\n    ')

        def ccall(caller):
            def body():
                __M_writer = context.writer()
                return ''

            return [body]

        context.caller_stack.nextcaller = runtime.Namespace(
            'caller', context, callables=ccall(__M_caller))
        try:
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(
                        static.css(group=u'style-vendor-tinymce-skin'))))
        finally:
            context.caller_stack.nextcaller = None
        __M_writer(u'\n\n')
        if uses_bootstrap:
            __M_writer(u'      <link rel="stylesheet" href="')
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(static.url(self.attr.main_css))))
            __M_writer(u'" type="text/css" media="all" />\n')
        else:
            __M_writer(u'      ')

            def ccall(caller):
                def body():
                    __M_writer = context.writer()
                    return ''

                return [body]

            context.caller_stack.nextcaller = runtime.Namespace(
                'caller', context, callables=ccall(__M_caller))
            try:
                __M_writer(
                    filters.html_escape(
                        filters.decode.utf8(
                            static.css(group=(self.attr.main_css)))))
            finally:
                context.caller_stack.nextcaller = None
            __M_writer(u'\n')
        __M_writer(u'\n    ')
        runtime._include_file(context, u'widgets/segment-io.html',
                              _template_uri)
        __M_writer(u'\n\n    ')
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'header_extras'):
            context['self'].header_extras(**pageargs)

        __M_writer(u'\n  </head>\n\n  <body class="')
        __M_writer(filters.html_escape(filters.decode.utf8(static.dir_rtl())))
        __M_writer(u' ')
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'bodyclass'):
            context['self'].bodyclass(**pageargs)

        __M_writer(u' lang_')
        __M_writer(filters.html_escape(filters.decode.utf8(LANGUAGE_CODE)))
        __M_writer(u'">\n    ')
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'view_notes'):
            context['self'].view_notes(**pageargs)

        __M_writer(u'\n\n    <a class="nav-skip" href="#main">')
        __M_writer(
            filters.html_escape(filters.decode.utf8(
                _("Skip to main content"))))
        __M_writer(u'</a>\n\n    ')

        def ccall(caller):
            def body():
                __M_writer = context.writer()
                return ''

            return [body]

        context.caller_stack.nextcaller = runtime.Namespace(
            'caller', context, callables=ccall(__M_caller))
        try:
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(static.js(group=u'base_vendor'))))
        finally:
            context.caller_stack.nextcaller = None
        __M_writer(u'\n\n    ')

        def ccall(caller):
            def body():
                __M_writer = context.writer()
                return ''

            return [body]

        context.caller_stack.nextcaller = runtime.Namespace(
            'caller', context, callables=ccall(__M_caller))
        try:
            __M_writer(
                filters.html_escape(
                    filters.decode.utf8(static.webpack(entry=u'commons'))))
        finally:
            context.caller_stack.nextcaller = None
        __M_writer(
            u'\n\n    <script type="text/javascript">\n      window.baseUrl = "'
        )
        __M_writer(js_escaped_string(settings.STATIC_URL))
        __M_writer(
            u'";\n      require.config({\n          baseUrl: window.baseUrl\n      });\n    </script>\n\n    <script type="text/javascript" src="'
        )
        __M_writer(
            filters.html_escape(
                filters.decode.utf8(static.url("cms/js/require-config.js"))))
        __M_writer(
            u'"></script>\n\n    <!-- view -->\n    <div class="wrapper wrapper-view" dir="'
        )
        __M_writer(filters.html_escape(filters.decode.utf8(static.dir_rtl())))
        __M_writer(u'">\n      ')
        online_help_token = self.online_help_token() if hasattr(
            self, 'online_help_token') else None

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                              for __M_key in ['online_help_token']
                              if __M_key in __M_locals_builtin_stored]))
        __M_writer(u'\n      ')
        runtime._include_file(context,
                              u'widgets/header.html',
                              _template_uri,
                              online_help_token=online_help_token)
        __M_writer(u'\n\n      ')

        banner_messages = list(PageLevelMessages.user_messages(request))

        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(
            __M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key])
                              for __M_key in ['banner_messages']
                              if __M_key in __M_locals_builtin_stored]))
        __M_writer(u'\n\n')
        if banner_messages:
            __M_writer(
                u'        <div class="page-banner">\n          <div class="user-messages">\n'
            )
            for message in banner_messages:
                __M_writer(u'              <div class="alert ')
                __M_writer(
                    filters.html_escape(filters.decode.utf8(
                        message.css_class)))
                __M_writer(
                    u'" role="alert">\n                <span class="icon icon-alert fa '
                )
                __M_writer(
                    filters.html_escape(filters.decode.utf8(
                        message.icon_class)))
                __M_writer(u'" aria-hidden="true"></span>\n                ')
                __M_writer(
                    filters.html_escape(
                        filters.decode.utf8(HTML(message.message_html))))
                __M_writer(u'\n              </div>\n')
            __M_writer(u'          </div>\n        </div>\n')
        __M_writer(u'\n      <div id="page-alert">\n      ')
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'page_alert'):
            context['self'].page_alert(**pageargs)

        __M_writer(
            u'\n      </div>\n\n      <main id="main" aria-label="Content" tabindex="-1">\n        <div id="content">\n        '
        )
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'content'):
            context['self'].content(**pageargs)

        __M_writer(u'\n        </div>\n      </main>\n\n')
        if user.is_authenticated:
            __M_writer(u'        ')
            runtime._include_file(context,
                                  u'widgets/sock.html',
                                  _template_uri,
                                  online_help_token=online_help_token)
            __M_writer(u'\n')
        __M_writer(u'      ')
        runtime._include_file(context, u'widgets/footer.html', _template_uri)
        __M_writer(
            u'\n\n      <div id="page-notification"></div>\n    </div>\n\n    <div id="page-prompt"></div>\n\n    '
        )
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'modal_placeholder'):
            context['self'].modal_placeholder(**pageargs)

        __M_writer(u'\n\n    ')
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'jsextra'):
            context['self'].jsextra(**pageargs)

        __M_writer(u'\n\n')
        if context_course:
            __M_writer(u'      ')

            def ccall(caller):
                def body():
                    __M_writer = context.writer()
                    return ''

                return [body]

            context.caller_stack.nextcaller = runtime.Namespace(
                'caller', context, callables=ccall(__M_caller))
            try:
                __M_writer(
                    filters.html_escape(
                        filters.decode.utf8(
                            static.webpack(
                                entry=u'js/factories/context_course'))))
            finally:
                context.caller_stack.nextcaller = None
            __M_writer(
                u'\n      <script type="text/javascript">\n        window.course = new ContextCourse({\n          id: "'
            )
            __M_writer(js_escaped_string(context_course.id))
            __M_writer(u'",\n          name: "')
            __M_writer(
                js_escaped_string(context_course.display_name_with_default))
            __M_writer(u'",\n          url_name: "')
            __M_writer(js_escaped_string(context_course.location.block_id))
            __M_writer(u'",\n          org: "')
            __M_writer(js_escaped_string(context_course.location.org))
            __M_writer(u'",\n          num: "')
            __M_writer(js_escaped_string(context_course.location.course))
            __M_writer(u'",\n          display_course_number: "')
            __M_writer(js_escaped_string(context_course.display_coursenumber))
            __M_writer(u'",\n          revision: "')
            __M_writer(js_escaped_string(context_course.location.branch))
            __M_writer(u'",\n          self_paced: ')
            __M_writer(dump_js_escaped_json(context_course.self_paced))
            __M_writer(u'\n        });\n      </script>\n')
        if user.is_authenticated:
            __M_writer(u'      ')

            def ccall(caller):
                def body():
                    __M_writer = context.writer()
                    return ''

                return [body]

            context.caller_stack.nextcaller = runtime.Namespace(
                'caller', context, callables=ccall(__M_caller))
            try:
                __M_writer(
                    filters.html_escape(
                        filters.decode.utf8(static.webpack(entry=u'js/sock'))))
            finally:
                context.caller_stack.nextcaller = None
            __M_writer(u'\n')
        __M_writer(u'    ')
        if 'parent' not in context._data or not hasattr(
                context._data['parent'], 'page_bundle'):
            context['self'].page_bundle(**pageargs)

        __M_writer(u'\n    ')
        runtime._include_file(context, u'widgets/segment-io-footer.html',
                              _template_uri)
        __M_writer(
            u'\n    <div class="modal-cover"></div>\n  </body>\n</html>\n')
        return ''
    finally:
        context.caller_stack._pop_frame()