def _section_certificates(course): """Section information for the certificates panel. The certificates panel allows global staff to generate example certificates and enable self-generated certificates for a course. Arguments: course (Course) Returns: dict """ example_cert_status = None html_cert_enabled = certs_api.has_html_certificates_enabled(course.id, course) if html_cert_enabled: can_enable_for_course = True else: example_cert_status = certs_api.example_certificates_status(course.id) # Allow the user to enable self-generated certificates for students # *only* once a set of example certificates has been successfully generated. # If certificates have been misconfigured for the course (for example, if # the PDF template hasn't been uploaded yet), then we don't want # to turn on self-generated certificates for students! can_enable_for_course = example_cert_status is not None and all( cert_status["status"] == "success" for cert_status in example_cert_status ) instructor_generation_enabled = settings.FEATURES.get("CERTIFICATES_INSTRUCTOR_GENERATION", False) certificate_statuses_with_count = { certificate["status"]: certificate["count"] for certificate in GeneratedCertificate.get_unique_statuses(course_key=course.id) } return { "section_key": "certificates", "section_display_name": _("Certificates"), "example_certificate_status": example_cert_status, "can_enable_for_course": can_enable_for_course, "enabled_for_course": certs_api.cert_generation_enabled(course.id), "instructor_generation_enabled": instructor_generation_enabled, "html_cert_enabled": html_cert_enabled, "active_certificate": certs_api.get_active_web_certificate(course), "certificate_statuses_with_count": certificate_statuses_with_count, "status": CertificateStatuses, "certificate_generation_history": CertificateGenerationHistory.objects.filter(course_id=course.id).order_by( "-created" ), "urls": { "generate_example_certificates": reverse("generate_example_certificates", kwargs={"course_id": course.id}), "enable_certificate_generation": reverse("enable_certificate_generation", kwargs={"course_id": course.id}), "start_certificate_generation": reverse("start_certificate_generation", kwargs={"course_id": course.id}), "start_certificate_regeneration": reverse( "start_certificate_regeneration", kwargs={"course_id": course.id} ), "list_instructor_tasks_url": reverse("list_instructor_tasks", kwargs={"course_id": course.id}), }, }
def _section_certificates(course): """Section information for the certificates panel. The certificates panel allows global staff to generate example certificates and enable self-generated certificates for a course. Arguments: course (Course) Returns: dict """ example_cert_status = None html_cert_enabled = certs_api.has_html_certificates_enabled( course.id, course) if html_cert_enabled: can_enable_for_course = True else: example_cert_status = certs_api.example_certificates_status(course.id) # Allow the user to enable self-generated certificates for students # *only* once a set of example certificates has been successfully generated. # If certificates have been misconfigured for the course (for example, if # the PDF template hasn't been uploaded yet), then we don't want # to turn on self-generated certificates for students! can_enable_for_course = (example_cert_status is not None and all( cert_status['status'] == 'success' for cert_status in example_cert_status)) instructor_generation_enabled = settings.FEATURES.get( 'CERTIFICATES_INSTRUCTOR_GENERATION', False) return { 'section_key': 'certificates', 'section_display_name': _('Certificates'), 'example_certificate_status': example_cert_status, 'can_enable_for_course': can_enable_for_course, 'enabled_for_course': certs_api.cert_generation_enabled(course.id), 'instructor_generation_enabled': instructor_generation_enabled, 'html_cert_enabled': html_cert_enabled, 'urls': { 'generate_example_certificates': reverse('generate_example_certificates', kwargs={'course_id': course.id}), 'enable_certificate_generation': reverse('enable_certificate_generation', kwargs={'course_id': course.id}), 'start_certificate_generation': reverse('start_certificate_generation', kwargs={'course_id': course.id}), 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': course.id}), } }
def get_cert_status(self): student_id = self.scope_ids.user_id course_id = str(self.xmodule_runtime.course_id) course_key = CourseKey.from_string(course_id) student = User.objects.prefetch_related("groups").get(id=student_id) course = get_course_with_access(student, 'load', course_key, depth=None, check_if_enrolled=True) show_generate_cert_btn = certs_api.cert_generation_enabled(course_key) grade_summary = get_grades(course,student) print "grade_summary====================",grade_summary failed = None if grade_summary["totaled_scores"]: if grade_summary["percent"] < course.grading_policy["GRADE_CUTOFFS"]["Pass"]: failed = True context = { 'passed': grade_summary, 'course':course, 'student':student, 'failed':failed } if grade_summary["percent"] and grade_summary["percent"] >= course.grading_policy["GRADE_CUTOFFS"]["Pass"]: print "in totaled score" context.update({ 'show_generate_cert_btn':True }) cert_status = certs_api.certificate_downloadable_status(student, course_key) context.update(cert_status) # showing the certificate web view button if feature flags are enabled. if certs_api.has_html_certificates_enabled(course_key, course): if certs_api.get_active_web_certificate(course) is not None: context.update({ 'show_cert_web_view': True, 'cert_web_view_url': certs_api.get_certificate_url(course_id=course_key, uuid=cert_status['uuid']), 'show_generate_cert_btn':True }) else: context.update({ 'is_downloadable': False, 'is_generating': True, 'download_url': None }) print "outside totaled score" return context
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)
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)
def _section_certificates(course): """Section information for the certificates panel. The certificates panel allows global staff to generate example certificates and enable self-generated certificates for a course. Arguments: course (Course) Returns: dict """ example_cert_status = None html_cert_enabled = certs_api.has_html_certificates_enabled(course.id, course) if html_cert_enabled: can_enable_for_course = True else: example_cert_status = certs_api.example_certificates_status(course.id) # Allow the user to enable self-generated certificates for students # *only* once a set of example certificates has been successfully generated. # If certificates have been misconfigured for the course (for example, if # the PDF template hasn't been uploaded yet), then we don't want # to turn on self-generated certificates for students! can_enable_for_course = ( example_cert_status is not None and all( cert_status['status'] == 'success' for cert_status in example_cert_status ) ) instructor_generation_enabled = settings.FEATURES.get('CERTIFICATES_INSTRUCTOR_GENERATION', False) certificate_statuses_with_count = { certificate['status']: certificate['count'] for certificate in GeneratedCertificate.get_unique_statuses(course_key=course.id) } return { 'section_key': 'certificates', 'section_display_name': _('Certificates'), 'example_certificate_status': example_cert_status, 'can_enable_for_course': can_enable_for_course, 'enabled_for_course': certs_api.cert_generation_enabled(course.id), 'is_self_paced': course.self_paced, 'instructor_generation_enabled': instructor_generation_enabled, 'html_cert_enabled': html_cert_enabled, 'active_certificate': certs_api.get_active_web_certificate(course), 'certificate_statuses_with_count': certificate_statuses_with_count, 'status': CertificateStatuses, 'certificate_generation_history': CertificateGenerationHistory.objects.filter(course_id=course.id).order_by("-created"), 'urls': { 'generate_example_certificates': reverse( 'generate_example_certificates', kwargs={'course_id': course.id} ), 'enable_certificate_generation': reverse( 'enable_certificate_generation', kwargs={'course_id': course.id} ), 'start_certificate_generation': reverse( 'start_certificate_generation', kwargs={'course_id': course.id} ), 'start_certificate_regeneration': reverse( 'start_certificate_regeneration', kwargs={'course_id': course.id} ), 'list_instructor_tasks_url': reverse( 'list_instructor_tasks', kwargs={'course_id': course.id} ), } }
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)
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)