示例#1
0
def generate_course_certificate(user, course_key, generation_mode):
    """
    Generate a course certificate for this user, in this course run. If the certificate has a passing status, also emit
    a certificate event.

    Note that the certificate could be either an allowlist certificate or a "regular" course certificate; the content
    will be the same either way.

    Args:
        user: user for whom to generate a certificate
        course_key: course run key for which to generate a certificate
        generation_mode: Used when emitting an events. Options are "self" (implying the user generated the cert
            themself) and "batch" for everything else.
    """
    cert = _generate_certificate(user, course_key)

    if CertificateStatuses.is_passing_status(cert.status):
        # Emit a certificate event
        event_data = {
            'user_id': user.id,
            'course_id': str(course_key),
            'certificate_id': cert.verify_uuid,
            'enrollment_mode': cert.mode,
            'generation_mode': generation_mode
        }
        emit_certificate_event(event_name='created',
                               user=user,
                               course_id=course_key,
                               event_data=event_data)

    return cert
示例#2
0
def generate_user_certificates(student, course_key, insecure=False, generation_mode='batch', forced_grade=None):
    """
    It will add the add-cert request into the xqueue.

    A new record will be created to track the certificate
    generation task.  If an error occurs while adding the certificate
    to the queue, the task will have status 'error'. It also emits
    `edx.certificate.created` event for analytics.

    This method has not yet been updated (it predates the certificates revamp). If modifying this method,
    see also generate_user_certificates() in generation_handler.py (which is very similar but is not called from a
    celery task). In the future these methods will be unified.

   Args:
        student (User)
        course_key (CourseKey)

    Keyword Arguments:
        insecure - (Boolean)
        generation_mode - who has requested certificate generation. Its value should `batch`
        in case of django command and `self` if student initiated the request.
        forced_grade - a string indicating to replace grade parameter. if present grading
                       will be skipped.
    """
    beta_testers_queryset = list_with_level(course_key, 'beta')
    if beta_testers_queryset.filter(username=student.username):
        log.info(f"Canceling Certificate Generation task for user {student.id} : {course_key}. User is a Beta Tester.")
        return

    xqueue = XQueueCertInterface()
    if insecure:
        xqueue.use_https = False

    course_overview = get_course_overview(course_key)
    generate_pdf = not has_html_certificates_enabled(course_overview)

    cert = xqueue.add_cert(
        student,
        course_key,
        generate_pdf=generate_pdf,
        forced_grade=forced_grade
    )

    log.info(f"Queued Certificate Generation task for {student.id} : {course_key}")

    # If cert_status is not present in certificate valid_statuses (for example unverified) then
    # add_cert returns None and raises AttributeError while accessing cert attributes.
    if cert is None:
        return

    if CertificateStatuses.is_passing_status(cert.status):
        emit_certificate_event('created', student, course_key, course_overview, {
            'user_id': student.id,
            'course_id': str(course_key),
            'certificate_id': cert.verify_uuid,
            'enrollment_mode': cert.mode,
            'generation_mode': generation_mode
        })
    return cert.status
示例#3
0
def _track_certificate_events(request, course, user, user_certificate):
    """
    Tracks web certificate view related events.
    """
    # Badge Request Event Tracking Logic
    course_key = course.location.course_key

    if 'evidence_visit' in request.GET:
        badge_class = get_completion_badge(course_key, user)
        if not badge_class:
            log.warning(
                'Visit to evidence URL for badge, but badges not configured for course "%s"',
                course_key)
            badges = []
        else:
            badges = badge_class.get_for_user(user)
        if badges:
            # There should only ever be one of these.
            badge = badges[0]
            tracker.emit(
                'edx.badge.assertion.evidence_visited', {
                    'badge_name': badge.badge_class.display_name,
                    'badge_slug': badge.badge_class.slug,
                    'badge_generator': badge.backend,
                    'issuing_component': badge.badge_class.issuing_component,
                    'user_id': user.id,
                    'course_id': str(course_key),
                    'enrollment_mode': badge.badge_class.mode,
                    'assertion_id': badge.id,
                    'assertion_image_url': badge.image_url,
                    'assertion_json_url': badge.assertion_url,
                    'issuer': badge.data.get('issuer'),
                })
        else:
            log.warning(
                "Could not find badge for %s on course %s.",
                user.id,
                course_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,
                               str(course.id),
                               event_data={
                                   'certificate_id':
                                   user_certificate.verify_uuid,
                                   'enrollment_mode':
                                   user_certificate.mode,
                                   'social_network':
                                   CertificateSocialNetworks.linkedin
                               })
示例#4
0
    def _revoke_certificate(self, status, grade=None, source=None):
        """
        Revokes a course certificate from a learner, updating the certificate's status as specified by the value of the
        `status` argument. This will prevent the learner from being able to access their certificate in the associated
        course run.

        We remove the `download_uuid` and the `download_url` as well, but this is only important to PDF certificates.

        Invalidating a certificate fires the `COURSE_CERT_REVOKED` signal. This kicks off a task to determine if there
        are any program certificates that also need to be revoked from the learner.

        If the certificate had a status of `downloadable` before being revoked then we will also emit an
        `edx.certificate.revoked` event for tracking purposes.

        Args:
            status (CertificateStatus) - certificate status to set for the `GeneratedCertificate` record
            grade (float) - snapshot of the learner's current grade as a decimal
            source (String) - source requesting invalidation of the certificate for tracking purposes
        """
        previous_certificate_status = self.status

        self.error_reason = ''
        self.download_uuid = ''
        self.download_url = ''
        self.grade = grade or ''
        self.status = status
        self.save()

        COURSE_CERT_REVOKED.send_robust(
            sender=self.__class__,
            user=self.user,
            course_key=self.course_id,
            mode=self.mode,
            status=self.status,
        )

        if previous_certificate_status == CertificateStatuses.downloadable:
            # imported here to avoid a circular import issue
            from lms.djangoapps.certificates.utils import emit_certificate_event

            event_data = {
                'user_id': self.user.id,
                'course_id': str(self.course_id),
                'certificate_id': self.verify_uuid,
                'enrollment_mode': self.mode,
                'source': source or '',
            }
            emit_certificate_event('revoked', self.user, str(self.course_id), event_data=event_data)
示例#5
0
def generate_allowlist_certificate(user, course_key):
    """
    Generate an allowlist certificate for this user, in this course run. This method should be called from a task.
    """
    cert = _generate_certificate(user, course_key)

    if CertificateStatuses.is_passing_status(cert.status):
        # Emit a certificate event. Note that the two options for generation_mode are "self" (implying the user
        # generated the cert themself) and "batch" for everything else.
        event_data = {
            'user_id': user.id,
            'course_id': str(course_key),
            'certificate_id': cert.verify_uuid,
            'enrollment_mode': cert.mode,
            'generation_mode': 'batch'
        }
        emit_certificate_event(event_name='created', user=user, course_id=course_key, event_data=event_data)

    return cert
def generate_user_certificates(student,
                               course_key,
                               course=None,
                               insecure=False,
                               generation_mode='batch',
                               forced_grade=None):
    """
    It will add the add-cert request into the xqueue.

    A new record will be created to track the certificate
    generation task.  If an error occurs while adding the certificate
    to the queue, the task will have status 'error'. It also emits
    `edx.certificate.created` event for analytics.

    This method has not yet been updated (it predates the certificates revamp). If modifying this method,
    see also generate_user_certificates() in generation.py (which is very similar but is called from a celery task).
    In the future these methods will be unified.

    Args:
        student (User)
        course_key (CourseKey)

    Keyword Arguments:
        course (Course): Optionally provide the course object; if not provided
            it will be loaded.
        insecure - (Boolean)
        generation_mode - who has requested certificate generation. Its value should `batch`
        in case of django command and `self` if student initiated the request.
        forced_grade - a string indicating to replace grade parameter. if present grading
                       will be skipped.
    """
    if is_using_certificate_allowlist_and_is_on_allowlist(student, course_key):
        # Note that this will launch an asynchronous task, and so cannot return the certificate status. This is a
        # change from the older certificate code that tries to immediately create a cert.
        log.info(
            f'{course_key} is using allowlist certificates, and the user {student.id} is on its allowlist. '
            f'Attempt will be made to regenerate an allowlist certificate.')
        return generate_allowlist_certificate_task(student, course_key)

    if not course:
        course = modulestore().get_course(course_key, depth=0)

    beta_testers_queryset = list_with_level(course, 'beta')

    if beta_testers_queryset.filter(username=student.username):
        message = 'Cancelling course certificate generation for user [{}] against course [{}], user is a Beta Tester.'
        log.info(message.format(student.username, course_key))
        return

    xqueue = XQueueCertInterface()
    if insecure:
        xqueue.use_https = False

    generate_pdf = not has_html_certificates_enabled(course)

    cert = xqueue.add_cert(student,
                           course_key,
                           course=course,
                           generate_pdf=generate_pdf,
                           forced_grade=forced_grade)

    message = 'Queued Certificate Generation task for {user} : {course}'
    log.info(message.format(user=student.id, course=course_key))

    # If cert_status is not present in certificate valid_statuses (for example unverified) then
    # add_cert returns None and raises AttributeError while accessing cert attributes.
    if cert is None:
        return

    if CertificateStatuses.is_passing_status(cert.status):
        emit_certificate_event(
            'created', student, course_key, course, {
                'user_id': student.id,
                'course_id': str(course_key),
                'certificate_id': cert.verify_uuid,
                'enrollment_mode': cert.mode,
                'generation_mode': generation_mode
            })
    return cert.status