示例#1
0
    def test_certificate_footer_data(self):
        """
        Test that get_certificate_footer_context from certificates api returns
        data customized according to site branding.
        """
        # Generate certificates for the course
        CourseModeFactory.create(course_id=self.COURSE_KEY, mode_slug=CourseMode.HONOR)
        data = certs_api.get_certificate_footer_context()

        # Make sure there are not unexpected keys in dict returned by 'get_certificate_footer_context'
        self.assertItemsEqual(
            data.keys(),
            ['company_about_url', 'company_privacy_url', 'company_tos_url']
        )

        # ABOUT is present in MICROSITE_CONFIGURATION['test_microsite']["urls"] so web certificate will use that url
        self.assertIn(
            settings.MICROSITE_CONFIGURATION['test_microsite']["urls"]['ABOUT'],
            data['company_about_url']
        )

        # PRIVACY is present in MICROSITE_CONFIGURATION['test_microsite']["urls"] so web certificate will use that url
        self.assertIn(
            settings.MICROSITE_CONFIGURATION['test_microsite']["urls"]['PRIVACY'],
            data['company_privacy_url']
        )

        # TOS_AND_HONOR is present in MICROSITE_CONFIGURATION['test_microsite']["urls"],
        # so web certificate will use that url
        self.assertIn(
            settings.MICROSITE_CONFIGURATION['test_microsite']["urls"]['TOS_AND_HONOR'],
            data['company_tos_url']
        )
示例#2
0
    def test_certificate_footer_data(self):
        """
        Test that get_certificate_footer_context from certificates api returns
        data customized according to site branding.
        """
        # Generate certificates for the course
        CourseModeFactory.create(course_id=self.COURSE_KEY,
                                 mode_slug=CourseMode.HONOR)
        data = certs_api.get_certificate_footer_context()

        # Make sure there are not unexpected keys in dict returned by 'get_certificate_footer_context'
        self.assertItemsEqual(
            data.keys(),
            ['company_about_url', 'company_privacy_url', 'company_tos_url'])

        # ABOUT is present in MICROSITE_CONFIGURATION['test_microsite']["urls"] so web certificate will use that url
        self.assertIn(
            settings.MICROSITE_CONFIGURATION['test_microsite']["urls"]
            ['ABOUT'], data['company_about_url'])

        # PRIVACY is present in MICROSITE_CONFIGURATION['test_microsite']["urls"] so web certificate will use that url
        self.assertIn(
            settings.MICROSITE_CONFIGURATION['test_microsite']["urls"]
            ['PRIVACY'], data['company_privacy_url'])

        # TOS_AND_HONOR is present in MICROSITE_CONFIGURATION['test_microsite']["urls"],
        # so web certificate will use that url
        self.assertIn(
            settings.MICROSITE_CONFIGURATION['test_microsite']["urls"]
            ['TOS_AND_HONOR'], data['company_tos_url'])
示例#3
0
def render_html_view(request, user_id, course_id):
    """
    This public view generates an HTML representation of the specified user and course
    If a certificate is not available, we display a "Sorry!" screen instead
    """
    try:
        user_id = int(user_id)
    except ValueError:
        raise Http404

    preview_mode = request.GET.get('preview', None)
    platform_name = microsite.get_value("platform_name",
                                        settings.PLATFORM_NAME)
    configuration = CertificateHtmlViewConfiguration.get_config()
    # Create the initial view context, bootstrapping with Django settings and passed-in values
    context = {}
    _update_context_with_basic_info(context, course_id, platform_name,
                                    configuration)
    invalid_template_path = 'certificates/invalid.html'

    # Kick the user back to the "Invalid" screen if the feature is disabled
    if not has_html_certificates_enabled(course_id):
        log.info(
            "Invalid cert: HTML certificates disabled for %s. User id: %d",
            course_id,
            user_id,
        )
        return render_to_response(invalid_template_path, context)

    # Load the course and user objects
    try:
        course_key = CourseKey.from_string(course_id)
        user = User.objects.get(id=user_id)
        course = modulestore().get_course(course_key)

    # For any other expected exceptions, kick the user back to the "Invalid" screen
    except (InvalidKeyError, ItemNotFoundError,
            User.DoesNotExist) as exception:
        error_str = ("Invalid cert: error finding course %s or user with id "
                     "%d. Specific error: %s")
        log.info(error_str, course_id, user_id, str(exception))
        return render_to_response(invalid_template_path, context)

    # Load user's certificate
    user_certificate = _get_user_certificate(request, user, course_key, course,
                                             preview_mode)
    if not user_certificate:
        log.info(
            "Invalid cert: User %d does not have eligible cert for %s.",
            user_id,
            course_id,
        )
        return render_to_response(invalid_template_path, context)

    # Get the active certificate configuration for this course
    # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen
    # Passing in the 'preview' parameter, if specified, will return a configuration, if defined
    active_configuration = get_active_web_certificate(course, preview_mode)
    if active_configuration is None:
        log.info(
            "Invalid cert: course %s does not have an active configuration. User id: %d",
            course_id,
            user_id,
        )
        return render_to_response(invalid_template_path, context)

    context['certificate_data'] = active_configuration

    # Append/Override the existing view context values with any mode-specific ConfigurationModel values
    context.update(configuration.get(user_certificate.mode, {}))

    # Append organization info
    _update_organization_context(context, course)

    # Append course info
    _update_course_context(request, context, course, platform_name)

    # Append user info
    _update_context_with_user_info(context, user, user_certificate)

    # Append social sharing info
    _update_social_context(request, context, course, user, user_certificate,
                           platform_name)

    # Append/Override the existing view context values with certificate specific values
    _update_certificate_context(context, user_certificate, platform_name)

    # Append badge info
    _update_badge_context(context, course, user)

    # Append microsite overrides
    _update_microsite_context(context, configuration)

    # Add certificate header/footer data to current context
    context.update(
        get_certificate_header_context(is_secure=request.is_secure()))
    context.update(get_certificate_footer_context())

    # Append/Override the existing view context values with any course-specific static values from Advanced Settings
    context.update(course.cert_html_view_overrides)

    # Track certificate view events
    _track_certificate_events(request, context, course, user, user_certificate)

    # FINALLY, render appropriate certificate
    return _render_certificate_template(request, context, course,
                                        user_certificate)
示例#4
0
def render_html_view(request, user_id, course_id):
    """
    This public view generates an HTML representation of the specified user and course
    If a certificate is not available, we display a "Sorry!" screen instead
    """
    preview_mode = request.GET.get('preview', None)
    platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME)
    configuration = CertificateHtmlViewConfiguration.get_config()
    # Create the initial view context, bootstrapping with Django settings and passed-in values
    context = {}
    _update_context_with_basic_info(context, course_id, platform_name, configuration)
    invalid_template_path = 'certificates/invalid.html'

    # Kick the user back to the "Invalid" screen if the feature is disabled
    if not has_html_certificates_enabled(course_id):
        return render_to_response(invalid_template_path, context)

    # Load the course and user objects
    try:
        course_key = CourseKey.from_string(course_id)
        user = User.objects.get(id=user_id)
        course = modulestore().get_course(course_key)

    # For any other expected exceptions, kick the user back to the "Invalid" screen
    except (InvalidKeyError, ItemNotFoundError, User.DoesNotExist):
        return render_to_response(invalid_template_path, context)

    # Load user's certificate
    user_certificate = _get_user_certificate(request, user, course_key, course, preview_mode)
    if not user_certificate:
        return render_to_response(invalid_template_path, context)

    # Get the active certificate configuration for this course
    # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen
    # Passing in the 'preview' parameter, if specified, will return a configuration, if defined
    active_configuration = get_active_web_certificate(course, preview_mode)
    if active_configuration is None:
        return render_to_response(invalid_template_path, context)
    context['certificate_data'] = active_configuration

    # Append/Override the existing view context values with any mode-specific ConfigurationModel values
    context.update(configuration.get(user_certificate.mode, {}))

    # Append organization info
    _update_organization_context(context, course)

    # Append course info
    _update_course_context(request, context, course, platform_name)

    # Append user info
    _update_context_with_user_info(context, user, user_certificate)

    # Append social sharing info
    _update_social_context(request, context, course, user, user_certificate, platform_name)

    # Append/Override the existing view context values with certificate specific values
    _update_certificate_context(context, user_certificate, platform_name)

    # Append badge info
    _update_badge_context(context, course, user)

    # Append microsite overrides
    _update_microsite_context(context, configuration)

    # Add certificate header/footer data to current context
    context.update(get_certificate_header_context(is_secure=request.is_secure()))
    context.update(get_certificate_footer_context())

    # Append/Override the existing view context values with any course-specific static values from Advanced Settings
    context.update(course.cert_html_view_overrides)

    # Track certificate view events
    _track_certificate_events(request, context, course, user, user_certificate)

    # FINALLY, render appropriate certificate
    return _render_certificate_template(request, context, course, user_certificate)
示例#5
0
def render_html_view(request, user_id, course_id):
    """
    This public view generates an HTML representation of the specified user and course
    If a certificate is not available, we display a "Sorry!" screen instead
    """
    try:
        user_id = int(user_id)
    except ValueError:
        raise Http404

    preview_mode = request.GET.get('preview', None)
    platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME)
    configuration = CertificateHtmlViewConfiguration.get_config()
    # Create the initial view context, bootstrapping with Django settings and passed-in values
    context = {}
    _update_context_with_basic_info(context, course_id, platform_name, configuration)
    invalid_template_path = 'certificates/invalid.html'

    # Kick the user back to the "Invalid" screen if the feature is disabled globally
    if not settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False):
        return render_to_response(invalid_template_path, context)

    # Load the course and user objects
    try:
        course_key = CourseKey.from_string(course_id)
        user = User.objects.get(id=user_id)
        course = get_course_by_id(course_key)

    # For any course or user exceptions, kick the user back to the "Invalid" screen
    except (InvalidKeyError, User.DoesNotExist, Http404) as exception:
        error_str = (
            "Invalid cert: error finding course %s or user with id "
            "%d. Specific error: %s"
        )
        log.info(error_str, course_id, user_id, str(exception))
        return render_to_response(invalid_template_path, context)

    # Kick the user back to the "Invalid" screen if the feature is disabled for the course
    if not course.cert_html_view_enabled:
        log.info(
            "Invalid cert: HTML certificates disabled for %s. User id: %d",
            course_id,
            user_id,
        )
        return render_to_response(invalid_template_path, context)

    # Load user's certificate
    user_certificate = _get_user_certificate(request, user, course_key, course, preview_mode)
    if not user_certificate:
        log.info(
            "Invalid cert: User %d does not have eligible cert for %s.",
            user_id,
            course_id,
        )
        return render_to_response(invalid_template_path, context)

    # Get the active certificate configuration for this course
    # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen
    # Passing in the 'preview' parameter, if specified, will return a configuration, if defined
    active_configuration = get_active_web_certificate(course, preview_mode)
    if active_configuration is None:
        log.info(
            "Invalid cert: course %s does not have an active configuration. User id: %d",
            course_id,
            user_id,
        )
        return render_to_response(invalid_template_path, context)

    context['certificate_data'] = active_configuration

    # Append/Override the existing view context values with any mode-specific ConfigurationModel values
    context.update(configuration.get(user_certificate.mode, {}))

    # Append organization info
    _update_organization_context(context, course)

    # Append course info
    _update_course_context(request, context, course, course_key, platform_name)

    # Append course run info from discovery
    _update_context_with_catalog_data(context, course_key)

    # Append user info
    _update_context_with_user_info(context, user, user_certificate)

    # Append social sharing info
    _update_social_context(request, context, course, user, user_certificate, platform_name)

    # Append/Override the existing view context values with certificate specific values
    _update_certificate_context(context, course, user_certificate, platform_name)

    # Append badge info
    _update_badge_context(context, course, user)

    # Append site configuration overrides
    _update_configuration_context(context, configuration)

    # Add certificate header/footer data to current context
    context.update(get_certificate_header_context(is_secure=request.is_secure()))
    context.update(get_certificate_footer_context())

    # Append/Override the existing view context values with any course-specific static values from Advanced Settings
    context.update(course.cert_html_view_overrides)

    # Track certificate view events
    _track_certificate_events(request, context, course, user, user_certificate)

    # FINALLY, render appropriate certificate
    return _render_certificate_template(request, context, course, user_certificate)
示例#6
0
def render_html_view(request, user_id, course_id):
    """
    This public view generates an HTML representation of the specified user and course
    If a certificate is not available, we display a "Sorry!" screen instead
    """
    try:
        user_id = int(user_id)
    except ValueError:
        raise Http404

    preview_mode = request.GET.get('preview', None)
    platform_name = configuration_helpers.get_value("platform_name",
                                                    settings.PLATFORM_NAME)
    configuration = CertificateHtmlViewConfiguration.get_config()

    # Kick the user back to the "Invalid" screen if the feature is disabled globally
    if not settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False):
        return _render_invalid_certificate(course_id, platform_name,
                                           configuration)

    # Load the course and user objects
    try:
        course_key = CourseKey.from_string(course_id)
        user = User.objects.get(id=user_id)
        course = get_course_by_id(course_key)

    # For any course or user exceptions, kick the user back to the "Invalid" screen
    except (InvalidKeyError, User.DoesNotExist, Http404) as exception:
        error_str = ("Invalid cert: error finding course %s or user with id "
                     "%d. Specific error: %s")
        log.info(error_str, course_id, user_id, str(exception))
        return _render_invalid_certificate(course_id, platform_name,
                                           configuration)

    # Kick the user back to the "Invalid" screen if the feature is disabled for the course
    if not course.cert_html_view_enabled:
        log.info(
            "Invalid cert: HTML certificates disabled for %s. User id: %d",
            course_id,
            user_id,
        )
        return _render_invalid_certificate(course_id, platform_name,
                                           configuration)

    # Load user's certificate
    user_certificate = _get_user_certificate(request, user, course_key, course,
                                             preview_mode)
    if not user_certificate:
        log.info(
            "Invalid cert: User %d does not have eligible cert for %s.",
            user_id,
            course_id,
        )
        return _render_invalid_certificate(course_id, platform_name,
                                           configuration)

    # Get the active certificate configuration for this course
    # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen
    # Passing in the 'preview' parameter, if specified, will return a configuration, if defined
    active_configuration = get_active_web_certificate(course, preview_mode)
    if active_configuration is None:
        log.info(
            "Invalid cert: course %s does not have an active configuration. User id: %d",
            course_id,
            user_id,
        )
        return _render_invalid_certificate(course_id, platform_name,
                                           configuration)

    # Get data from Discovery service that will be necessary for rendering this Certificate.
    catalog_data = _get_catalog_data_for_course(course_key)

    # Determine whether to use the standard or custom template to render the certificate.
    custom_template = None
    custom_template_language = None
    if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False):
        custom_template, custom_template_language = _get_custom_template_and_language(
            course.id, user_certificate.mode,
            catalog_data.pop('content_language', None))

    # Determine the language that should be used to render the certificate.
    # For the standard certificate template, use the user language. For custom templates, use
    # the language associated with the template.
    user_language = translation.get_language()
    certificate_language = custom_template_language if custom_template else user_language

    # Generate the certificate context in the correct language, then render the template.
    with translation.override(certificate_language):
        context = {'user_language': user_language}

        _update_context_with_basic_info(context, course_id, platform_name,
                                        configuration)

        context['certificate_data'] = active_configuration

        # Append/Override the existing view context values with any mode-specific ConfigurationModel values
        context.update(configuration.get(user_certificate.mode, {}))

        # Append organization info
        _update_organization_context(context, course)

        # Append course info
        _update_course_context(request, context, course, course_key,
                               platform_name)

        # Append course run info from discovery
        context.update(catalog_data)

        # Append user info
        _update_context_with_user_info(context, user, user_certificate)

        # Append social sharing info
        _update_social_context(request, context, course, user,
                               user_certificate, platform_name)

        # Append/Override the existing view context values with certificate specific values
        _update_certificate_context(context, course, user_certificate,
                                    platform_name)

        # Append badge info
        _update_badge_context(context, course, user)

        # Append site configuration overrides
        _update_configuration_context(context, configuration)

        # Add certificate header/footer data to current context
        context.update(
            get_certificate_header_context(is_secure=request.is_secure()))
        context.update(get_certificate_footer_context())

        # Append/Override the existing view context values with any course-specific static values from Advanced Settings
        context.update(course.cert_html_view_overrides)

        # Track certificate view events
        _track_certificate_events(request, context, course, user,
                                  user_certificate)

        # Render the certificate
        return _render_valid_certificate(request, context, custom_template)
示例#7
0
def prorgam_user_certificate(request, certificate_uuid):

    platform_name = configuration_helpers.get_value("platform_name",
                                                    settings.PLATFORM_NAME)
    context = {}
    try:
        user_program_certificate = ProgramGeneratedCertificate.objects.get(
            verify_uuid=certificate_uuid, issued=True)
        user = user_program_certificate.user
        program_certificate_signs = ProgramCertificateSignatories.objects.filter(
            program=user_program_certificate.program)
        context['user_program_certificate'] = user_program_certificate
        context['program_certificate_signs'] = program_certificate_signs
        context['platform_name'] = platform_name
        context['course_id'] = user_program_certificate.program.id

        context['full_course_image_url'] = request.build_absolute_uri(
            user_program_certificate.program.banner_image.url)

        # Needed
        # Translators:  'All rights reserved' is a legal term used in copyrighting to protect published content
        reserved = _("All rights reserved")
        context[
            'copyright_text'] = u'© {year} {platform_name}. {reserved}.'.format(
                year=settings.COPYRIGHT_YEAR,
                platform_name=platform_name,
                reserved=reserved)

        # Needed
        # Translators: A 'Privacy Policy' is a legal document/statement describing a website's use of personal information
        context['company_privacy_urltext'] = _("Privacy Policy")

        # Needed
        # Translators: This line appears as a byline to a header image and describes the purpose of the page
        context['logo_subtitle'] = _("Certificate Validation")

        # Needed
        # Translators: Accomplishments describe the awards/certifications obtained by students on this platform
        context['accomplishment_copy_about'] = _(
            'About {platform_name} Accomplishments').format(
                platform_name=platform_name)

        # Needed
        # Translators:  This line appears on the page just before the generation date for the certificate
        context['certificate_date_issued_title'] = _("Issued On:")

        # Needed
        # Translators:  This text describes (at a high level) the mission and charter the edX platform and organization
        context['company_about_description'] = _(
            "{platform_name} offers interactive online classes and MOOCs."
        ).format(platform_name=platform_name)

        # Needed
        context['company_about_title'] = _("About {platform_name}").format(
            platform_name=platform_name)
        # Needed
        context['company_about_urltext'] = _(
            "Learn more about {platform_name}").format(
                platform_name=platform_name)

        # Needed banner docs
        # Translators:  This text appears near the top of the certficate and describes the guarantee provided by edX
        context['document_banner'] = _(
            "{platform_name} acknowledges the following student accomplishment"
        ).format(platform_name=platform_name)

        # Needed
        # Add certificate header/footer data to current context
        context.update(
            get_certificate_header_context(is_secure=request.is_secure()))
        context.update(get_certificate_footer_context())

        # Needed
        context[
            'accomplishment_copy_course_name'] = user_program_certificate.program.name

        # Needed
        # Translators:  This text represents the description of course
        context['accomplishment_copy_course_description'] = _(
            'a course of study offered by '
            '{platform_name}.').format(platform_name=platform_name)

        user_fullname = user.profile.name

        # Needed
        context['accomplishment_user_id'] = user.id
        # Needed
        context['accomplishment_copy_name'] = user_fullname
        # Needed
        context['accomplishment_copy_username'] = user.username

        # Needed banner text
        # Translators: This line is displayed to a user who has completed a course and achieved a certification
        context['accomplishment_banner_opening'] = _(
            "{fullname}, you earned a certificate!").format(
                fullname=user_fullname)
        # Needed banner text
        # Translators: This line congratulates the user and instructs them to share their accomplishment on social networks
        context['accomplishment_banner_congrats'] = _(
            "Congratulations! This page summarizes what "
            "you accomplished. Show it off to family, friends, and colleagues "
            "in your social and professional networks.")

        # Needed
        # Translators: This line leads the reader to understand more about the certificate that a student has been awarded
        context['accomplishment_copy_more_about'] = _(
            "More about {fullname}'s accomplishment").format(
                fullname=user_fullname)

        # Needed for social sharing
        share_settings = configuration_helpers.get_value(
            "SOCIAL_SHARING_SETTINGS", settings.SOCIAL_SHARING_SETTINGS)
        context['facebook_share_enabled'] = share_settings.get(
            'CERTIFICATE_FACEBOOK', False)
        context['facebook_app_id'] = configuration_helpers.get_value(
            "FACEBOOK_APP_ID", settings.FACEBOOK_APP_ID)
        context['facebook_share_text'] = share_settings.get(
            'CERTIFICATE_FACEBOOK_TEXT',
            _("I completed the {course_title} course on {platform_name}.").
            format(course_title=context['accomplishment_copy_course_name'],
                   platform_name=platform_name))
        context['twitter_share_enabled'] = share_settings.get(
            'CERTIFICATE_TWITTER', False)
        context['twitter_share_text'] = share_settings.get(
            'CERTIFICATE_TWITTER_TEXT',
            _("I completed a course at {platform_name}. Take a look at my certificate."
              ).format(platform_name=platform_name))

        # Need to change certificate url
        share_url = request.build_absolute_uri(
            reverse(
                'openedx.core.djangoapps.micro_masters.views.prorgam_user_certificate',
                kwargs={'certificate_uuid': certificate_uuid}))
        context['share_url'] = share_url
        twitter_url = ''
        if context.get('twitter_share_enabled', False):
            twitter_url = 'https://twitter.com/intent/tweet?text={twitter_share_text}&url={share_url}'.format(
                twitter_share_text=smart_str(context['twitter_share_text']),
                share_url=urllib.quote_plus(smart_str(share_url)))
        context['twitter_url'] = twitter_url
        context['linked_in_url'] = None
        # If enabled, show the LinkedIn "add to profile" button
        # Clicking this button sends the user to LinkedIn where they
        # can add the certificate information to their profile.
        linkedin_config = LinkedInAddToProfileConfiguration.current()
        linkedin_share_enabled = share_settings.get('CERTIFICATE_LINKEDIN',
                                                    linkedin_config.enabled)
        if linkedin_share_enabled:
            context['linked_in_url'] = linkedin_config.add_to_profile_url(
                course.id, context['accomplishment_copy_course_name'],
                user_certificate.mode, smart_str(share_url))

        # certificate_type = context.get('certificate_type')

        # Override the defaults with any mode-specific static values
        # Needed
        context['certificate_id_number'] = certificate_uuid

        # Needed
        # Translators:  The format of the date includes the full name of the month
        context['certificate_date_issued'] = _('{month} {day}, {year}').format(
            month=user_program_certificate.modified.strftime("%B"),
            day=user_program_certificate.modified.day,
            year=user_program_certificate.modified.year)

        # Needed
        # Translators:  This text is bound to the HTML 'title' element of the page and appears in the browser title bar
        context['document_title'] = _("Certificate | {platform_name}").format(
            platform_name=platform_name)

        # Needed
        # Translators:  This text fragment appears after the student's name (displayed in a large font) on the certificate
        # screen.  The text describes the accomplishment represented by the certificate information displayed to the user
        context['accomplishment_copy_description_full'] = _(
            "successfully completed, received a passing grade, and was "
            "awarded this {platform_name} "
            "Certificate of Completion in ").format(
                platform_name=platform_name)

        # Needed
        # Translators: This text describes the purpose (and therefore, value) of a course certificate
        context['certificate_info_description'] = _(
            "{platform_name} acknowledges achievements through "
            "certificates, which are awarded for course activities "
            "that {platform_name} students complete.").format(
                platform_name=platform_name,
                tos_url=context.get('company_tos_url'))

        return render_to_response("micro_masters/certificates/valid.html",
                                  context)

    except Exception, e:
        raise Http404
示例#8
0
def render_html_view(request, user_id, course_id):
    """
    This public view generates an HTML representation of the specified user and course
    If a certificate is not available, we display a "Sorry!" screen instead
    """
    try:
        user_id = int(user_id)
    except ValueError:
        raise Http404

    preview_mode = request.GET.get('preview', None)
    platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME)
    configuration = CertificateHtmlViewConfiguration.get_config()

    # Kick the user back to the "Invalid" screen if the feature is disabled globally
    if not settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False):
        return _render_invalid_certificate(course_id, platform_name, configuration)

    # Load the course and user objects
    try:
        course_key = CourseKey.from_string(course_id)
        user = User.objects.get(id=user_id)
        course = get_course_by_id(course_key)

    # For any course or user exceptions, kick the user back to the "Invalid" screen
    except (InvalidKeyError, User.DoesNotExist, Http404) as exception:
        error_str = (
            "Invalid cert: error finding course %s or user with id "
            "%d. Specific error: %s"
        )
        log.info(error_str, course_id, user_id, str(exception))
        return _render_invalid_certificate(course_id, platform_name, configuration)

    # Kick the user back to the "Invalid" screen if the feature is disabled for the course
    if not course.cert_html_view_enabled:
        log.info(
            "Invalid cert: HTML certificates disabled for %s. User id: %d",
            course_id,
            user_id,
        )
        return _render_invalid_certificate(course_id, platform_name, configuration)

    # Load user's certificate
    user_certificate = _get_user_certificate(request, user, course_key, course, preview_mode)
    if not user_certificate:
        log.info(
            "Invalid cert: User %d does not have eligible cert for %s.",
            user_id,
            course_id,
        )
        return _render_invalid_certificate(course_id, platform_name, configuration)

    # Get the active certificate configuration for this course
    # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen
    # Passing in the 'preview' parameter, if specified, will return a configuration, if defined
    active_configuration = get_active_web_certificate(course, preview_mode)
    if active_configuration is None:
        log.info(
            "Invalid cert: course %s does not have an active configuration. User id: %d",
            course_id,
            user_id,
        )
        return _render_invalid_certificate(course_id, platform_name, configuration)

    # Get data from Discovery service that will be necessary for rendering this Certificate.
    catalog_data = _get_catalog_data_for_course(course_key)

    # Determine whether to use the standard or custom template to render the certificate.
    custom_template = None
    custom_template_language = None
    if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False):
        custom_template, custom_template_language = _get_custom_template_and_language(
            course.id,
            user_certificate.mode,
            catalog_data.pop('content_language', None)
        )

    # Determine the language that should be used to render the certificate.
    # For the standard certificate template, use the user language. For custom templates, use
    # the language associated with the template.
    user_language = translation.get_language()
    certificate_language = custom_template_language if custom_template else user_language

    # Generate the certificate context in the correct language, then render the template.
    with translation.override(certificate_language):
        context = {'user_language': user_language}

        _update_context_with_basic_info(context, course_id, platform_name, configuration)

        context['certificate_data'] = active_configuration

        # Append/Override the existing view context values with any mode-specific ConfigurationModel values
        context.update(configuration.get(user_certificate.mode, {}))

        # Append organization info
        _update_organization_context(context, course)

        # Append course info
        _update_course_context(request, context, course, course_key, platform_name)

        # Append course run info from discovery
        context.update(catalog_data)

        # Append user info
        _update_context_with_user_info(context, user, user_certificate)

        # Append social sharing info
        _update_social_context(request, context, course, user, user_certificate, platform_name)

        # Append/Override the existing view context values with certificate specific values
        _update_certificate_context(context, course, user_certificate, platform_name)

        # Append badge info
        _update_badge_context(context, course, user)

        # Append site configuration overrides
        _update_configuration_context(context, configuration)

        # Add certificate header/footer data to current context
        context.update(get_certificate_header_context(is_secure=request.is_secure()))
        context.update(get_certificate_footer_context())

        # Append/Override the existing view context values with any course-specific static values from Advanced Settings
        context.update(course.cert_html_view_overrides)

        # Track certificate view events
        _track_certificate_events(request, context, course, user, user_certificate)

        # Render the certificate
        return _render_valid_certificate(request, context, custom_template)