def test_linked_in_url_with_cert_name_override(self, cert_mode, expected_cert_name):
        config = LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True
        )

        expected_url = (
            'http://www.linkedin.com/profile/add'
            '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
            'pfCertificationName={platform_name}+{expected_cert_name}&'
            'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&'
            'source=o'
        ).format(
            expected_cert_name=expected_cert_name,
            platform_name=quote(settings.PLATFORM_NAME.encode('utf-8'))
        )

        with with_site_configuration_context(configuration=self.SITE_CONFIGURATION):
            actual_url = config.add_to_profile_url(
                self.COURSE_KEY,
                self.COURSE_NAME,
                cert_mode,
                self.CERT_URL
            )

            self.assertEqual(actual_url, expected_url)
Esempio n. 2
0
    def test_linked_in_url_tracking_code(self):
        config = LinkedInAddToProfileConfiguration(company_identifier="abcd123", trk_partner_name="edx", enabled=True)

        expected_param = urlencode({"trk": u"edx-{course_key}_honor-dashboard".format(course_key=self.COURSE_KEY)})

        actual_url = config.add_to_profile_url(self.COURSE_KEY, self.COURSE_NAME, "honor", self.CERT_URL)

        self.assertIn(expected_param, actual_url)
    def test_post_to_linkedin_microsite(self):
        """
        Verifies behavior for microsites which disables the post to LinkedIn
        feature (for now)
        """
        self._create_certificate("honor")

        config = LinkedInAddToProfileConfiguration(
            company_identifier="0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9", enabled=True
        )
        config.save()

        # now we should not see it because we are in a microsite
        self._check_linkedin_visibility(False)
    def test_post_to_linkedin_visibility(self):
        """
        Verifies that the post certificate to linked button appears
        as expected
        """
        self._create_certificate("honor")

        config = LinkedInAddToProfileConfiguration(
            company_identifier="0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9", enabled=True
        )
        config.save()

        # now we should see it
        self._check_linkedin_visibility(True)
Esempio n. 5
0
    def test_post_to_linkedin_visibility(self):
        """
        Verifies that the post certificate to linked button appears
        as expected
        """
        self._create_certificate('honor')

        config = LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True)
        config.save()

        # now we should see it
        self._check_linkedin_visibility(True)
Esempio n. 6
0
    def test_post_to_linkedin_site_specific(self):
        """
        Verifies behavior for themed sites which disables the post to LinkedIn
        feature (for now)
        """
        self._create_certificate('honor')

        config = LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True)
        config.save()

        # now we should not see it because we are in a themed site
        self._check_linkedin_visibility(False)
Esempio n. 7
0
    def test_linked_in_url_tracking_code(self):
        config = LinkedInAddToProfileConfiguration(
            company_identifier="abcd123", trk_partner_name="edx", enabled=True)

        expected_param = urlencode({
            'trk':
            u'edx-{course_key}_honor-dashboard'.format(
                course_key=self.COURSE_KEY)
        })

        actual_url = config.add_to_profile_url(self.COURSE_KEY,
                                               self.COURSE_NAME, 'honor',
                                               self.CERT_URL)

        self.assertIn(expected_param, actual_url)
Esempio n. 8
0
    def test_linked_in_url_with_unicode_course_display_name(self):
        """Test with unicode display name values."""

        user = Mock(username="******")
        survey_url = "http://a_survey.com"
        course = Mock(end_of_course_survey_url=survey_url,
                      certificates_display_behavior='end',
                      display_name=u'edx/abc/courseregisters®')
        download_url = 'http://s3.edx/cert'

        cert_status = {
            'status': 'downloadable',
            'grade': '67',
            'download_url': download_url,
            'mode': 'honor'
        }
        LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True).save()

        status_dict = _cert_info(user, course, cert_status, 'honor')
        expected_url = (
            'http://www.linkedin.com/profile/add'
            '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
            'pfCertificationName=edX+Honor+Code+Certificate+for+edx%2Fabc%2Fcourseregisters%C2%AE&'
            'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&'
            'source=o')
        self.assertEqual(expected_url, status_dict['linked_in_url'])
Esempio n. 9
0
    def test_linked_in_url(self, cert_mode, expected_cert_name):
        config = LinkedInAddToProfileConfiguration(
            company_identifier="0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9", enabled=True
        )

        expected_url = (
            "http://www.linkedin.com/profile/add"
            "?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&"
            "pfCertificationName={platform_name}+{expected_cert_name}&"
            "pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&"
            "source=o"
        ).format(expected_cert_name=expected_cert_name, platform_name=quote(settings.PLATFORM_NAME.encode("utf-8")))

        actual_url = config.add_to_profile_url(self.COURSE_KEY, self.COURSE_NAME, cert_mode, self.CERT_URL)

        self.assertEqual(actual_url, expected_url)
Esempio n. 10
0
    def linkedin_add_to_profile_url(self):
        """
        Returns a URL to add a certificate to a LinkedIn profile (will autofill fields).

        Requires LinkedIn sharing to be enabled, either via a site configuration or a
        LinkedInAddToProfileConfiguration object being enabled.
        """
        if self.effective_user.is_anonymous:
            return

        linkedin_config = LinkedInAddToProfileConfiguration.current()
        if linkedin_config.is_enabled():
            try:
                user_certificate = GeneratedCertificate.eligible_certificates.get(
                    user=self.effective_user, course_id=self.course_key)
            except GeneratedCertificate.DoesNotExist:
                return
            cert_url = self.request.build_absolute_uri(
                get_certificate_url(course_id=self.course_key,
                                    uuid=user_certificate.verify_uuid))
            return linkedin_config.add_to_profile_url(
                self.overview.display_name,
                user_certificate.mode,
                cert_url,
                certificate=user_certificate,
            )
Esempio n. 11
0
    def test_linked_in_url(self, cert_mode, expected_cert_name):
        config = LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True)

        expected_url = ('http://www.linkedin.com/profile/add'
                        '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
                        'pfCertificationName={expected_cert_name}&'
                        'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&'
                        'source=o').format(
                            expected_cert_name=expected_cert_name)

        actual_url = config.add_to_profile_url(self.COURSE_KEY,
                                               self.COURSE_NAME, cert_mode,
                                               self.CERT_URL)

        self.assertEqual(actual_url, expected_url)
Esempio n. 12
0
def _update_social_context(request, context, course, user, user_certificate, platform_name):
    """
    Updates context dictionary with info required for social sharing.
    """
    share_settings = getattr(settings, 'SOCIAL_SHARING_SETTINGS', {})
    context['facebook_share_enabled'] = share_settings.get('CERTIFICATE_FACEBOOK', False)
    context['facebook_app_id'] = getattr(settings, "FACEBOOK_APP_ID", None)
    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 on {platform_name}. Take a look at my certificate.").format(
            platform_name=platform_name
        )
    )

    share_url = request.build_absolute_uri(
        reverse(
            'certificates:html_view',
            kwargs=dict(user_id=str(user.id), course_id=unicode(course.id))
        )
    )
    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()

    # posting certificates to LinkedIn is not currently
    # supported in microsites/White Labels
    if linkedin_config.enabled and not microsite.is_request_in_microsite():
        context['linked_in_url'] = linkedin_config.add_to_profile_url(
            course.id,
            course.display_name,
            user_certificate.mode,
            smart_str(request.build_absolute_uri(get_certificate_url(
                user_id=user.id,
                course_id=unicode(course.id)
            )))
        )
Esempio n. 13
0
    def test_linked_in_url_with_cert_name_override(self, cert_mode,
                                                   expected_cert_name):
        config = LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True)

        expected_url = (
            'http://www.linkedin.com/profile/add'
            '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
            'pfCertificationName={platform_name}+{expected_cert_name}&'
            'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&'
            'source=o').format(expected_cert_name=expected_cert_name,
                               platform_name=quote(
                                   settings.PLATFORM_NAME.encode('utf-8')))

        with with_site_configuration_context(
                configuration=self.SITE_CONFIGURATION):
            actual_url = config.add_to_profile_url(self.COURSE_KEY,
                                                   self.COURSE_NAME, cert_mode,
                                                   self.CERT_URL)

            self.assertEqual(actual_url, expected_url)
Esempio n. 14
0
    def test_linked_in_url(self, cert_mode, expected_cert_name):
        config = LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True
        )

        expected_url = (
            'http://www.linkedin.com/profile/add'
            '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
            'pfCertificationName={expected_cert_name}&'
            'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&'
            'source=o'
        ).format(expected_cert_name=expected_cert_name)

        actual_url = config.add_to_profile_url(
            self.COURSE_KEY,
            self.COURSE_NAME,
            cert_mode,
            self.CERT_URL
        )

        self.assertEqual(actual_url, expected_url)
Esempio n. 15
0
def _update_social_context(request, context, course, user, user_certificate,
                           platform_name):
    """
    Updates context dictionary with info required for social sharing.
    """
    share_settings = getattr(settings, 'SOCIAL_SHARING_SETTINGS', {})
    context['facebook_share_enabled'] = share_settings.get(
        'CERTIFICATE_FACEBOOK', False)
    context['facebook_app_id'] = getattr(settings, "FACEBOOK_APP_ID", None)
    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 on {platform_name}. Take a look at my certificate."
          ).format(platform_name=platform_name))

    share_url = request.build_absolute_uri(
        reverse('certificates:html_view',
                kwargs=dict(user_id=str(user.id),
                            course_id=unicode(course.id))))
    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()

    # posting certificates to LinkedIn is not currently
    # supported in microsites/White Labels
    if linkedin_config.enabled and not microsite.is_request_in_microsite():
        context['linked_in_url'] = linkedin_config.add_to_profile_url(
            course.id, course.display_name, user_certificate.mode,
            smart_str(
                request.build_absolute_uri(
                    get_certificate_url(user_id=user.id,
                                        course_id=unicode(course.id)))))
Esempio n. 16
0
    def test_linked_in_add_to_profile_btn_with_certificate(self):
        # If user has a certificate with valid linked-in config then Add Certificate to LinkedIn button
        # should be visible. and it has URL value with valid parameters.
        self.client.login(username="******", password="******")
        LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True
        ).save()

        CourseModeFactory.create(
            course_id=self.course.id,
            mode_slug='verified',
            mode_display_name='verified',
            expiration_datetime=datetime.now(pytz.UTC) - timedelta(days=1)
        )

        CourseEnrollment.enroll(self.user, self.course.id, mode='honor')

        self.course.start = datetime.now(pytz.UTC) - timedelta(days=2)
        self.course.end = datetime.now(pytz.UTC) - timedelta(days=1)
        self.course.display_name = u"Omega"
        self.course = self.update_course(self.course, self.user.id)

        download_url = 'www.edx.org'
        GeneratedCertificateFactory.create(
            user=self.user,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='honor',
            grade='67',
            download_url=download_url
        )
        response = self.client.get(reverse('dashboard'))

        self.assertEquals(response.status_code, 200)
        self.assertIn('Add Certificate to LinkedIn', response.content)

        expected_url = (
            'http://www.linkedin.com/profile/add'
            '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
            'pfCertificationName=edX+Honor+Code+Certificate+for+Omega&'
            'pfCertificationUrl=www.edx.org&'
            'source=o'
        )
        self.assertContains(response, expected_url)
Esempio n. 17
0
    def test_linked_in_url_not_exists_without_config(self):
        user = Mock(username="******")
        survey_url = "http://a_survey.com"
        course = Mock(display_name="Demo Course",
                      end_of_course_survey_url=survey_url,
                      certificates_display_behavior='end')

        download_url = 'http://s3.edx/cert'
        cert_status = {
            'status': 'downloadable',
            'grade': '67',
            'download_url': download_url,
            'mode': 'verified'
        }

        self.assertEqual(
            _cert_info(user, course, cert_status, 'verified'), {
                'status': 'ready',
                'show_disabled_download_button': False,
                'show_download_url': True,
                'download_url': download_url,
                'show_survey_button': True,
                'survey_url': survey_url,
                'grade': '67',
                'mode': 'verified',
                'linked_in_url': None
            })

        # Enabling the configuration will cause the LinkedIn
        # "add to profile" button to appear.
        # We need to clear the cache again to make sure we
        # pick up the modified configuration.
        cache.clear()
        LinkedInAddToProfileConfiguration(
            company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9',
            enabled=True).save()

        status_dict = _cert_info(user, course, cert_status, 'honor')
        expected_url = (
            'http://www.linkedin.com/profile/add'
            '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&'
            'pfCertificationName=edX+Verified+Certificate+for+Demo+Course&'
            'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&'
            'source=o')
        self.assertEqual(expected_url, status_dict['linked_in_url'])
Esempio n. 18
0
    def test_linked_in_url_certificate_types(self, cert_mode, cert_name):
        user = Mock(username="******")
        course = Mock(display_name='DemoX',
                      end_of_course_survey_url='http://example.com',
                      certificates_display_behavior='end')
        cert_status = {
            'status': 'downloadable',
            'grade': '67',
            'download_url': 'http://edx.org',
            'mode': cert_mode
        }

        LinkedInAddToProfileConfiguration(company_identifier="abcd123",
                                          enabled=True).save()

        status_dict = _cert_info(user, course, cert_status, cert_mode)
        self.assertIn(cert_name.replace(' ', '+'),
                      status_dict['linked_in_url'])
Esempio n. 19
0
def _update_social_context(request, context, course, user, user_certificate,
                           platform_name):
    """
    Updates context dictionary with info required for social sharing.
    """
    share_settings = microsite.get_value("SOCIAL_SHARING_SETTINGS",
                                         settings.SOCIAL_SHARING_SETTINGS)
    context['facebook_share_enabled'] = share_settings.get(
        'CERTIFICATE_FACEBOOK', False)
    context['facebook_app_id'] = microsite.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))

    share_url = request.build_absolute_uri(
        get_certificate_url(course_id=course.id,
                            uuid=user_certificate.verify_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, course.display_name, user_certificate.mode,
            smart_str(share_url))
Esempio n. 20
0
def _update_social_context(request, context, course, user, user_certificate, platform_name):
    """
    Updates context dictionary with info required for social sharing.
    """
    share_settings = microsite.get_value("SOCIAL_SHARING_SETTINGS", settings.SOCIAL_SHARING_SETTINGS)
    context['facebook_share_enabled'] = share_settings.get('CERTIFICATE_FACEBOOK', False)
    context['facebook_app_id'] = microsite.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
        )
    )

    share_url = request.build_absolute_uri(get_certificate_url(course_id=course.id, uuid=user_certificate.verify_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,
            course.display_name,
            user_certificate.mode,
            smart_str(share_url)
        )
Esempio n. 21
0
def render_html_view(request, user_id, course_id):
    """
    This public view generates an HTML representation of the specified student's certificate
    If a certificate is not available, we display a "Sorry!" screen instead
    """

    # Create the initial view context, bootstrapping with Django settings and passed-in values
    context = {}
    context['platform_name'] = microsite.get_value("platform_name",
                                                   settings.PLATFORM_NAME)
    context['course_id'] = course_id

    # Update the view context with the default ConfigurationModel settings
    configuration = CertificateHtmlViewConfiguration.get_config()
    # if we are in a microsite, then let's first see if there is an override
    # section in our config
    config_key = microsite.get_value('microsite_config_key', 'default')
    # if there is no special microsite override, then let's use default
    if config_key not in configuration:
        config_key = 'default'
    context.update(configuration.get(config_key, {}))

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

    # Translators:  This text is bound to the HTML 'title' element of the page and appears
    # in the browser title bar when a requested certificate is not found or recognized
    context['document_title'] = _("Invalid Certificate")

    # Translators: The & characters represent an ampersand character and can be ignored
    context['company_tos_urltext'] = _("Terms of Service & Honor Code")

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

    # Translators: This line appears as a byline to a header image and describes the purpose of the page
    context['logo_subtitle'] = _("Certificate Validation")
    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 core building blocks for the view context
    try:
        course_key = CourseKey.from_string(course_id)
        user = User.objects.get(id=user_id)
        course = modulestore().get_course(course_key)

        if not course:
            raise CourseDoesNotExist

        # Attempt to load the user's generated certificate data
        user_certificate = GeneratedCertificate.objects.get(
            user=user, course_id=course_key)

    # If there's no generated certificate data for this user, we need to see if we're in 'preview' mode...
    # If we are, we'll need to create a mock version of the user_certificate container for previewing
    except GeneratedCertificate.DoesNotExist:
        if request.GET.get('preview', None):
            user_certificate = GeneratedCertificate(
                mode=request.GET.get('preview'),
                verify_uuid=unicode(uuid4().hex),
                modified_date=datetime.now().date())
        else:
            return render_to_response(invalid_template_path, context)

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

    # Badge Request Event Tracking Logic
    if 'evidence_visit' in request.GET:
        try:
            badge = BadgeAssertion.objects.get(user=user, course_id=course_key)
            tracker.emit(
                'edx.badge.assertion.evidence_visited', {
                    'user_id': user.id,
                    'course_id': unicode(course_key),
                    'enrollment_mode': badge.mode,
                    'assertion_id': badge.id,
                    'assertion_image_url': badge.data['image'],
                    'assertion_json_url': badge.data['json']['id'],
                    'issuer': badge.data['issuer'],
                })
        except BadgeAssertion.DoesNotExist:
            log.warn(
                "Could not find badge for %s on course %s.",
                user.id,
                course_key,
            )

    # Okay, now we have all of the pieces, time to put everything together

    # 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, request.GET.get('preview'))
    if active_configuration is None:
        return render_to_response(invalid_template_path, context)
    else:
        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/Override the existing view context values with request-time values
    _update_certificate_context(context, course, user, user_certificate)

    # 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()
    if linkedin_config.enabled:
        context['linked_in_url'] = linkedin_config.add_to_profile_url(
            course.id, course.display_name, user_certificate.mode,
            request.build_absolute_uri(
                get_certificate_url(user_id=user.id,
                                    course_id=unicode(course.id))))

    # Microsites will need to be able to override any hard coded
    # content that was put into the context in the
    # _update_certificate_context() call above. For example the
    # 'company_about_description' talks about edX, which we most likely
    # do not want to keep in a microsite
    #
    # So we need to re-apply any configuration/content that
    # we are sourceing from the database. This is somewhat duplicative of
    # the code at the beginning of this method, but we
    # need the configuration at the top as some error code paths
    # require that to be set up early on in the pipeline
    #
    microsite_config_key = microsite.get_value('microsite_config_key')
    if microsite_config_key:
        context.update(configuration.get(microsite_config_key, {}))

    # track certificate evidence_visited event for analytics when certificate_user and accessing_user are different
    if request.user and request.user.id != user.id:
        emit_certificate_event(
            'evidence_visited', user, course_id, course, {
                'certificate_id': user_certificate.verify_uuid,
                'enrollment_mode': user_certificate.mode,
                'social_network': CertificateSocialNetworks.linkedin
            })

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

    # FINALLY, generate and send the output the client
    if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False):
        custom_template = get_certificate_template(course_key,
                                                   user_certificate.mode)
        if custom_template:
            template = Template(custom_template)
            context = RequestContext(request, context)
            return HttpResponse(template.render(context))

    return render_to_response("certificates/valid.html", context)
Esempio n. 22
0
def _cert_info(user, course_overview, cert_status):
    """
    Implements the logic for cert_info -- split out for testing.

    Arguments:
        user (User): A user.
        course_overview (CourseOverview): A course.
    """
    # simplify the status for the template using this lookup table
    template_state = {
        CertificateStatuses.generating: 'generating',
        CertificateStatuses.downloadable: 'downloadable',
        CertificateStatuses.notpassing: 'notpassing',
        CertificateStatuses.restricted: 'restricted',
        CertificateStatuses.auditing: 'auditing',
        CertificateStatuses.audit_passing: 'auditing',
        CertificateStatuses.audit_notpassing: 'auditing',
        CertificateStatuses.unverified: 'unverified',
    }

    certificate_earned_but_not_available_status = 'certificate_earned_but_not_available'
    default_status = 'processing'

    default_info = {
        'status': default_status,
        'show_survey_button': False,
        'can_unenroll': True,
    }

    if cert_status is None:
        return default_info

    status = template_state.get(cert_status['status'], default_status)
    is_hidden_status = status in ('unavailable', 'processing', 'generating', 'notpassing', 'auditing')

    if (
        not certificates_viewable_for_course(course_overview) and
        (status in CertificateStatuses.PASSED_STATUSES) and
        course_overview.certificate_available_date
    ):
        status = certificate_earned_but_not_available_status

    if (
        course_overview.certificates_display_behavior == 'early_no_info' and
        is_hidden_status
    ):
        return default_info

    status_dict = {
        'status': status,
        'mode': cert_status.get('mode', None),
        'linked_in_url': None,
        'can_unenroll': status not in DISABLE_UNENROLL_CERT_STATES,
    }

    if status != default_status and course_overview.end_of_course_survey_url is not None:
        status_dict.update({
            'show_survey_button': True,
            'survey_url': process_survey_link(course_overview.end_of_course_survey_url, user)})
    else:
        status_dict['show_survey_button'] = False

    if status == 'downloadable':
        # showing the certificate web view button if certificate is downloadable state and feature flags are enabled.
        if has_html_certificates_enabled(course_overview):
            if course_overview.has_any_active_web_certificate:
                status_dict.update({
                    'show_cert_web_view': True,
                    'cert_web_view_url': get_certificate_url(course_id=course_overview.id, uuid=cert_status['uuid'])
                })
            else:
                # don't show download certificate button if we don't have an active certificate for course
                status_dict['status'] = 'unavailable'
        elif 'download_url' not in cert_status:
            log.warning(
                u"User %s has a downloadable cert for %s, but no download url",
                user.username,
                course_overview.id
            )
            return default_info
        else:
            status_dict['download_url'] = cert_status['download_url']

            # 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()

            # posting certificates to LinkedIn is not currently
            # supported in White Labels
            if linkedin_config.enabled and not theming_helpers.is_request_in_themed_site():
                status_dict['linked_in_url'] = linkedin_config.add_to_profile_url(
                    course_overview.id,
                    course_overview.display_name,
                    cert_status.get('mode'),
                    cert_status['download_url']
                )

    if status in {'generating', 'downloadable', 'notpassing', 'restricted', 'auditing', 'unverified'}:
        cert_grade_percent = -1
        persisted_grade_percent = -1
        persisted_grade = CourseGradeFactory().read(user, course=course_overview, create_if_needed=False)
        if persisted_grade is not None:
            persisted_grade_percent = persisted_grade.percent

        if 'grade' in cert_status:
            cert_grade_percent = float(cert_status['grade'])

        if cert_grade_percent == -1 and persisted_grade_percent == -1:
            # Note: as of 11/20/2012, we know there are students in this state-- cs169.1x,
            # who need to be regraded (we weren't tracking 'notpassing' at first).
            # We can add a log.warning here once we think it shouldn't happen.
            return default_info
        grades_input = [cert_grade_percent, persisted_grade_percent]
        max_grade = None if all(grade is None for grade in grades_input) else max(filter(lambda x: x is not None, grades_input))
        status_dict['grade'] = text_type(max_grade)

    return status_dict
Esempio n. 23
0
def _update_certificate_context(context, course, user, user_certificate):
    """
    Build up the certificate web view context using the provided values
    (Helper method to keep the view clean)
    """
    # Populate dynamic output values using the course/certificate data loaded above
    user_fullname = user.profile.name
    platform_name = microsite.get_value("platform_name",
                                        settings.PLATFORM_NAME)
    certificate_type = context.get('certificate_type')

    context['username'] = user.username
    context['course_mode'] = user_certificate.mode
    context['accomplishment_user_id'] = user.id
    context['accomplishment_copy_name'] = user_fullname
    context['accomplishment_copy_username'] = user.username
    context['accomplishment_copy_course_org'] = course.org
    context['accomplishment_copy_course_name'] = course.display_name
    context['course_image_url'] = course_image_url(course)
    context['share_settings'] = settings.FEATURES.get(
        'SOCIAL_SHARING_SETTINGS', {})
    try:
        badge = BadgeAssertion.objects.get(
            user=user, course_id=course.location.course_key)
    except BadgeAssertion.DoesNotExist:
        badge = None
    context['badge'] = badge

    # Override the defaults with any mode-specific static values
    context['certificate_id_number'] = user_certificate.verify_uuid
    context['certificate_verify_url'] = "{prefix}{uuid}{suffix}".format(
        prefix=context.get('certificate_verify_url_prefix'),
        uuid=user_certificate.verify_uuid,
        suffix=context.get('certificate_verify_url_suffix'))

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

    accd_course_org_html = '<span class="detail--xuniversity">{partner_name}</span>'.format(
        partner_name=course.org)
    accd_platform_name_html = '<span class="detail--company">{platform_name}</span>'.format(
        platform_name=platform_name)
    # Translators: This line appears on the certificate after the name of a course, and provides more
    # information about the organizations providing the course material to platform users
    context['accomplishment_copy_course_description'] = _(
        'a course of study offered by {partner_name}, '
        'through {platform_name}.').format(
            partner_name=accd_course_org_html,
            platform_name=accd_platform_name_html)

    # 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)

    context['accomplishment_more_title'] = _(
        "More Information About {user_name}'s Certificate:").format(
            user_name=user_fullname)

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

    # Translators:  The Certificate ID Number is an alphanumeric value unique to each individual certificate
    context['certificate_id_number_title'] = _('Certificate ID Number')

    context['certificate_info_title'] = _('About {platform_name} Certificates'
                                          ).format(platform_name=platform_name)

    # Translators: This text describes the purpose (and therefore, value) of a course certificate
    # 'verifying your identity' refers to the process for establishing the authenticity of the student
    context['certificate_info_description'] = _(
        "{platform_name} acknowledges achievements through certificates, which "
        "are awarded for various activities {platform_name} students complete "
        "under the <a href='{tos_url}'>{platform_name} Honor Code</a>.  Some "
        "certificates require completing additional steps, such as "
        "<a href='{verified_cert_url}'> verifying your identity</a>.").format(
            platform_name=platform_name,
            tos_url=context.get('company_tos_url'),
            verified_cert_url=context.get('company_verified_certificate_url'))

    context['certificate_verify_title'] = _(
        "How {platform_name} Validates Student Certificates").format(
            platform_name=platform_name)

    # Translators:  This text describes the validation mechanism for a certificate file (known as GPG security)
    context['certificate_verify_description'] = _(
        'Certificates issued by {platform_name} are signed by a gpg key so '
        'that they can be validated independently by anyone with the '
        '{platform_name} public key. For independent verification, '
        '{platform_name} uses what is called a '
        '"detached signature"&quot;".').format(platform_name=platform_name)

    context['certificate_verify_urltext'] = _(
        "Validate this certificate for yourself")

    # 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 from the "
        "world's best universities, including MIT, Harvard, Berkeley, University "
        "of Texas, and many others.  {platform_name} is a non-profit online "
        "initiative created by founding partners Harvard and MIT.").format(
            platform_name=platform_name)

    context['company_about_title'] = _("About {platform_name}").format(
        platform_name=platform_name)

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

    context['company_courselist_urltext'] = _(
        "Learn with {platform_name}").format(platform_name=platform_name)

    context['company_careers_urltext'] = _("Work at {platform_name}").format(
        platform_name=platform_name)

    context['company_contact_urltext'] = _("Contact {platform_name}").format(
        platform_name=platform_name)

    # 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)

    # Translators:  This text represents the verification of the certificate
    context['document_meta_description'] = _(
        'This is a valid {platform_name} certificate for {user_name}, '
        'who participated in {partner_name} {course_number}').format(
            platform_name=platform_name,
            user_name=user_fullname,
            partner_name=course.org,
            course_number=course.number)

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

    # 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 a {platform_name} {certificate_type} "
        "Certificate of Completion in ").format(
            platform_name=platform_name,
            certificate_type=context.get("certificate_type"))

    certificate_type_description = get_certificate_description(
        user_certificate.mode, certificate_type, platform_name)
    if certificate_type_description:
        context['certificate_type_description'] = certificate_type_description

    # 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()
    if linkedin_config.enabled:
        context['linked_in_url'] = linkedin_config.add_to_profile_url(
            course.id, course.display_name, user_certificate.mode,
            get_certificate_url(user_id=user.id,
                                course_id=unicode(course.id),
                                verify_uuid=user_certificate.verify_uuid))

    # Translators: This line is displayed to a user who has completed a course and achieved a certification
    context['accomplishment_banner_opening'] = _(
        "{fullname}, you've earned a certificate!").format(
            fullname=user_fullname)

    # Translators: This line congratulates the user and instructs them to share their accomplishment on social networks
    context['accomplishment_banner_congrats'] = _(
        "Congratulations! This page summarizes all of the details of what "
        "you've accomplished. Show it off to family, friends, and colleagues "
        "in your social and professional networks.")

    # 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)
Esempio n. 24
0
def render_html_view(request, user_id, course_id):
    """
    This public view generates an HTML representation of the specified student's certificate
    If a certificate is not available, we display a "Sorry!" screen instead
    """

    # Create the initial view context, bootstrapping with Django settings and passed-in values
    context = {}
    context['platform_name'] = microsite.get_value("platform_name", settings.PLATFORM_NAME)
    context['course_id'] = course_id

    # Update the view context with the default ConfigurationModel settings
    configuration = CertificateHtmlViewConfiguration.get_config()
    # if we are in a microsite, then let's first see if there is an override
    # section in our config
    config_key = microsite.get_value('microsite_config_key', 'default')
    # if there is no special microsite override, then let's use default
    if config_key not in configuration:
        config_key = 'default'
    context.update(configuration.get(config_key, {}))

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

    # Translators:  This text is bound to the HTML 'title' element of the page and appears
    # in the browser title bar when a requested certificate is not found or recognized
    context['document_title'] = _("Invalid Certificate")

    # Translators: The &amp; characters represent an ampersand character and can be ignored
    context['company_tos_urltext'] = _("Terms of Service &amp; Honor Code")

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

    # Translators: This line appears as a byline to a header image and describes the purpose of the page
    context['logo_subtitle'] = _("Certificate Validation")
    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 core building blocks for the view context
    try:
        course_key = CourseKey.from_string(course_id)
        user = User.objects.get(id=user_id)
        course = modulestore().get_course(course_key)

        if not course:
            raise CourseDoesNotExist

        # Attempt to load the user's generated certificate data
        user_certificate = GeneratedCertificate.objects.get(
            user=user,
            course_id=course_key
        )

    # If there's no generated certificate data for this user, we need to see if we're in 'preview' mode...
    # If we are, we'll need to create a mock version of the user_certificate container for previewing
    except GeneratedCertificate.DoesNotExist:
        if request.GET.get('preview', None):
            user_certificate = GeneratedCertificate(
                mode=request.GET.get('preview'),
                verify_uuid=unicode(uuid4().hex),
                modified_date=datetime.now().date()
            )
        else:
            return render_to_response(invalid_template_path, context)

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

    # Badge Request Event Tracking Logic
    if 'evidence_visit' in request.GET:
        try:
            badge = BadgeAssertion.objects.get(user=user, course_id=course_key)
            tracker.emit(
                'edx.badge.assertion.evidence_visited',
                {
                    'user_id': user.id,
                    'course_id': unicode(course_key),
                    'enrollment_mode': badge.mode,
                    'assertion_id': badge.id,
                    'assertion_image_url': badge.data['image'],
                    'assertion_json_url': badge.data['json']['id'],
                    'issuer': badge.data['issuer'],
                }
            )
        except BadgeAssertion.DoesNotExist:
            log.warn(
                "Could not find badge for %s on course %s.",
                user.id,
                course_key,
            )

    # Okay, now we have all of the pieces, time to put everything together

    # 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, request.GET.get('preview'))
    if active_configuration is None:
        return render_to_response(invalid_template_path, context)
    else:
        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/Override the existing view context values with request-time values
    _update_certificate_context(context, course, user, user_certificate)

    # 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()
    if linkedin_config.enabled:
        context['linked_in_url'] = linkedin_config.add_to_profile_url(
            course.id,
            course.display_name,
            user_certificate.mode,
            request.build_absolute_uri(get_certificate_url(
                user_id=user.id,
                course_id=unicode(course.id)
            ))
        )

    # Microsites will need to be able to override any hard coded
    # content that was put into the context in the
    # _update_certificate_context() call above. For example the
    # 'company_about_description' talks about edX, which we most likely
    # do not want to keep in a microsite
    #
    # So we need to re-apply any configuration/content that
    # we are sourceing from the database. This is somewhat duplicative of
    # the code at the beginning of this method, but we
    # need the configuration at the top as some error code paths
    # require that to be set up early on in the pipeline
    #
    microsite_config_key = microsite.get_value('microsite_config_key')
    if microsite_config_key:
        context.update(configuration.get(microsite_config_key, {}))

    # track certificate evidence_visited event for analytics when certificate_user and accessing_user are different
    if request.user and request.user.id != user.id:
        emit_certificate_event('evidence_visited', user, course_id, course, {
            'certificate_id': user_certificate.verify_uuid,
            'enrollment_mode': user_certificate.mode,
            'social_network': CertificateSocialNetworks.linkedin
        })

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

    # FINALLY, generate and send the output the client
    if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False):
        custom_template = get_certificate_template(course_key, user_certificate.mode)
        if custom_template:
            template = Template(custom_template)
            context = RequestContext(request, context)
            return HttpResponse(template.render(context))

    return render_to_response("certificates/valid.html", context)
Esempio n. 25
0
def _cert_info(user, course_overview, cert_status):
    """
    Implements the logic for cert_info -- split out for testing.

    Arguments:
        user (User): A user.
        course_overview (CourseOverview): A course.
    """
    # simplify the status for the template using this lookup table
    template_state = {
        CertificateStatuses.generating: 'generating',
        CertificateStatuses.downloadable: 'downloadable',
        CertificateStatuses.notpassing: 'notpassing',
        CertificateStatuses.restricted: 'restricted',
        CertificateStatuses.auditing: 'auditing',
        CertificateStatuses.audit_passing: 'auditing',
        CertificateStatuses.audit_notpassing: 'auditing',
        CertificateStatuses.unverified: 'unverified',
    }

    certificate_earned_but_not_available_status = 'certificate_earned_but_not_available'
    default_status = 'processing'

    default_info = {
        'status': default_status,
        'show_survey_button': False,
        'can_unenroll': True,
    }

    if cert_status is None:
        return default_info

    status = template_state.get(cert_status['status'], default_status)
    is_hidden_status = status in ('unavailable', 'processing', 'generating', 'notpassing', 'auditing')

    if (
        not certificates_viewable_for_course(course_overview) and
        (status in CertificateStatuses.PASSED_STATUSES) and
        course_overview.certificate_available_date
    ):
        status = certificate_earned_but_not_available_status

    if (
        course_overview.certificates_display_behavior == 'early_no_info' and
        is_hidden_status
    ):
        return default_info

    status_dict = {
        'status': status,
        'mode': cert_status.get('mode', None),
        'linked_in_url': None,
        'can_unenroll': status not in DISABLE_UNENROLL_CERT_STATES,
    }

    if status != default_status and course_overview.end_of_course_survey_url is not None:
        status_dict.update({
            'show_survey_button': True,
            'survey_url': process_survey_link(course_overview.end_of_course_survey_url, user)})
    else:
        status_dict['show_survey_button'] = False

    if status == 'downloadable':
        # showing the certificate web view button if certificate is downloadable state and feature flags are enabled.
        if has_html_certificates_enabled(course_overview):
            if course_overview.has_any_active_web_certificate:
                status_dict.update({
                    'show_cert_web_view': True,
                    'cert_web_view_url': get_certificate_url(course_id=course_overview.id, uuid=cert_status['uuid'])
                })
            else:
                # don't show download certificate button if we don't have an active certificate for course
                status_dict['status'] = 'unavailable'
        elif 'download_url' not in cert_status:
            log.warning(
                u"User %s has a downloadable cert for %s, but no download url",
                user.username,
                course_overview.id
            )
            return default_info
        else:
            status_dict['download_url'] = cert_status['download_url']

            # 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()

            # posting certificates to LinkedIn is not currently
            # supported in White Labels
            if linkedin_config.enabled and not theming_helpers.is_request_in_themed_site():
                status_dict['linked_in_url'] = linkedin_config.add_to_profile_url(
                    course_overview.id,
                    course_overview.display_name,
                    cert_status.get('mode'),
                    cert_status['download_url']
                )

    if status in {'generating', 'downloadable', 'notpassing', 'restricted', 'auditing', 'unverified'}:
        cert_grade_percent = -1
        persisted_grade_percent = -1
        persisted_grade = CourseGradeFactory().read(user, course=course_overview, create_if_needed=False)
        if persisted_grade is not None:
            persisted_grade_percent = persisted_grade.percent

        if 'grade' in cert_status:
            cert_grade_percent = float(cert_status['grade'])

        if cert_grade_percent == -1 and persisted_grade_percent == -1:
            # Note: as of 11/20/2012, we know there are students in this state-- cs169.1x,
            # who need to be regraded (we weren't tracking 'notpassing' at first).
            # We can add a log.warning here once we think it shouldn't happen.
            return default_info

        status_dict['grade'] = text_type(max(cert_grade_percent, persisted_grade_percent))

    return status_dict
Esempio n. 26
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'&copy; {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
Esempio n. 27
0
def _update_certificate_context(context, course, user, user_certificate):
    """
    Build up the certificate web view context using the provided values
    (Helper method to keep the view clean)
    """
    # Populate dynamic output values using the course/certificate data loaded above
    user_fullname = user.profile.name
    platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME)
    certificate_type = context.get('certificate_type')

    context['username'] = user.username
    context['course_mode'] = user_certificate.mode
    context['accomplishment_user_id'] = user.id
    context['accomplishment_copy_name'] = user_fullname
    context['accomplishment_copy_username'] = user.username
    context['accomplishment_copy_course_org'] = course.org
    context['accomplishment_copy_course_name'] = course.display_name
    try:
        badge = BadgeAssertion.objects.get(user=user, course_id=course.location.course_key)
    except BadgeAssertion.DoesNotExist:
        badge = None
    context['badge'] = badge

    # Override the defaults with any mode-specific static values
    context['certificate_id_number'] = user_certificate.verify_uuid
    context['certificate_verify_url'] = "{prefix}{uuid}{suffix}".format(
        prefix=context.get('certificate_verify_url_prefix'),
        uuid=user_certificate.verify_uuid,
        suffix=context.get('certificate_verify_url_suffix')
    )

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

    accd_course_org_html = '<span class="detail--xuniversity">{partner_name}</span>'.format(partner_name=course.org)
    accd_platform_name_html = '<span class="detail--company">{platform_name}</span>'.format(platform_name=platform_name)
    # Translators: This line appears on the certificate after the name of a course, and provides more
    # information about the organizations providing the course material to platform users
    context['accomplishment_copy_course_description'] = _('a course of study offered by {partner_name}, '
                                                          'through {platform_name}.').format(
        partner_name=accd_course_org_html,
        platform_name=accd_platform_name_html
    )

    # 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
    )

    context['accomplishment_more_title'] = _("More Information About {user_name}'s Certificate:").format(
        user_name=user_fullname
    )

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

    # Translators:  The Certificate ID Number is an alphanumeric value unique to each individual certificate
    context['certificate_id_number_title'] = _('Certificate ID Number')

    context['certificate_info_title'] = _('About {platform_name} Certificates').format(
        platform_name=platform_name
    )

    # Translators: This text describes the purpose (and therefore, value) of a course certificate
    # 'verifying your identity' refers to the process for establishing the authenticity of the student
    context['certificate_info_description'] = _("{platform_name} acknowledges achievements through certificates, which "
                                                "are awarded for various activities {platform_name} students complete "
                                                "under the <a href='{tos_url}'>{platform_name} Honor Code</a>.  Some "
                                                "certificates require completing additional steps, such as "
                                                "<a href='{verified_cert_url}'> verifying your identity</a>.").format(
        platform_name=platform_name,
        tos_url=context.get('company_tos_url'),
        verified_cert_url=context.get('company_verified_certificate_url')
    )

    context['certificate_verify_title'] = _("How {platform_name} Validates Student Certificates").format(
        platform_name=platform_name
    )

    # Translators:  This text describes the validation mechanism for a certificate file (known as GPG security)
    context['certificate_verify_description'] = _('Certificates issued by {platform_name} are signed by a gpg key so '
                                                  'that they can be validated independently by anyone with the '
                                                  '{platform_name} public key. For independent verification, '
                                                  '{platform_name} uses what is called a '
                                                  '"detached signature"&quot;".').format(platform_name=platform_name)

    context['certificate_verify_urltext'] = _("Validate this certificate for yourself")

    # 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 from the "
                                             "world's best universities, including MIT, Harvard, Berkeley, University "
                                             "of Texas, and many others.  {platform_name} is a non-profit online "
                                             "initiative created by founding partners Harvard and MIT.").format(
        platform_name=platform_name
    )

    context['company_about_title'] = _("About {platform_name}").format(platform_name=platform_name)

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

    context['company_courselist_urltext'] = _("Learn with {platform_name}").format(platform_name=platform_name)

    context['company_careers_urltext'] = _("Work at {platform_name}").format(platform_name=platform_name)

    context['company_contact_urltext'] = _("Contact {platform_name}").format(platform_name=platform_name)

    # 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
    )

    # Translators:  This text represents the verification of the certificate
    context['document_meta_description'] = _('This is a valid {platform_name} certificate for {user_name}, '
                                             'who participated in {partner_name} {course_number}').format(
        platform_name=platform_name,
        user_name=user_fullname,
        partner_name=course.org,
        course_number=course.number
    )

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

    # 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 a {platform_name} {certificate_type} "
                                                        "Certificate of Completion in ").format(
        platform_name=platform_name,
        certificate_type=context.get("certificate_type")
    )

    certificate_type_description = get_certificate_description(user_certificate.mode, certificate_type, platform_name)
    if certificate_type_description:
        context['certificate_type_description'] = certificate_type_description

    # 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()
    if linkedin_config.enabled:
        context['linked_in_url'] = linkedin_config.add_to_profile_url(
            course.id,
            course.display_name,
            user_certificate.mode,
            get_certificate_url(
                user_id=user.id,
                course_id=course.id.to_deprecated_string()
            )
        )

    # Translators: This line is displayed to a user who has completed a course and achieved a certification
    context['accomplishment_banner_opening'] = _("{fullname}, you've earned a certificate!").format(
        fullname=user_fullname
    )

    # Translators: This line congratulates the user and instructs them to share their accomplishment on social networks
    context['accomplishment_banner_congrats'] = _("Congratulations! This page summarizes all of the details of what "
                                                  "you've accomplished. Show it off to family, friends, and colleagues "
                                                  "in your social and professional networks.")

    # 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
    )