Commit 65212b20 by John Jarvis

Certificate interface to xqueue

Add, remove or update and existing certificate
parent f53b3c09
...@@ -2,87 +2,203 @@ from django.utils.simplejson import dumps ...@@ -2,87 +2,203 @@ from django.utils.simplejson import dumps
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from certificates.models import GeneratedCertificate from certificates.models import GeneratedCertificate
from certificates.models import certificate_status_for_student from certificates.models import certificate_status_for_student
from certificates.models import CertificateStatuses as status
from courseware import grades, courses from courseware import grades, courses
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.test.client import RequestFactory from django.test.client import RequestFactory
from pprint import pprint
from capa.xqueue_interface import XQueueInterface from capa.xqueue_interface import XQueueInterface
from capa.xqueue_interface import make_xheader, make_hashkey from capa.xqueue_interface import make_xheader, make_hashkey
from django.conf import settings from django.conf import settings
from requests.auth import HTTPBasicAuth from requests.auth import HTTPBasicAuth
from student.models import UserProfile from student.models import UserProfile
from django.conf import settings
import json import json
import random import random
import logging import logging
class XQueueCertInterface(object):
def add_cert_to_queue(student, course_id, xqueue_interface, request=None): log = logging.getLogger("mitx.certificates")
"""
Update or create a new GeneratedCertificates:
If certificate generation is in progress this function will
return None.
If certificate generation was completed for the user this def __init__(self, request=None):
will add a request to delete the existing certificate.
A new certificate request will be made if the student's if settings.XQUEUE_INTERFACE.get('basic_auth') is not None:
grade is not None requests_auth = HTTPBasicAuth(
""" *settings.XQUEUE_INTERFACE['basic_auth'])
log = logging.getLogger("mitx.certificates") else:
if request is None: requests_auth = None
factory = RequestFactory()
request = factory.get('/') if request is None:
factory = RequestFactory()
cert_status = certificate_status_for_student(student, course_id) self.request = factory.get('/')
if cert_status['status'] == 'generating': else:
return None self.request = request
if cert_status['status'] == 'downloadable':
generated_certificate = GeneratedCertificate.objects.get( self.xqueue_interface = XQueueInterface(
user=student, course_id=course_id) settings.XQUEUE_INTERFACE['url'],
generated_certificate.status = 'unavailable' settings.XQUEUE_INTERFACE['django_auth'],
key = generated_certificate.key requests_auth,
username = generated_certificate.user.username )
generated_certificate.save()
contents = { def regen_cert(self, student, course_id):
'remove': True, """
'verify_uuid': cert.verify_uuid,
'download_uuid': cert.download_uuid, Arguments:
'key': cert.key, student - User.object
'username': cert.user.username course_id - courseenrollment.course_id (string)
}
xheader = make_xheader('http://sandbox-jrjarvis-001.m.edx.org/certificate', key, 'test-pull') Removes certificate for a student, will change
(error, msg) = xqueue_interface.send_to_queue(header=xheader, the certificate status to 'regenerating'.
body=json.dumps(contents)) Will invalidate the old certificate and generate
a new one.
# grade the student
course = courses.get_course_by_id(course_id) When completed the certificate status will change
grade = grades.grade(student, request, course) to 'downloadable'
if grade['grade'] is not None: Returns the certificate status.
cert, created = GeneratedCertificate.objects.get_or_create(
user=student, course_id=course_id) """
profile = UserProfile.objects.get(user=student)
VALID_STATUSES = [status.downloadable]
key = make_hashkey(random.random())
cert_status = certificate_status_for_student(
cert.status = 'generating' student, course_id)['status']
cert.grade = grade['percent']
cert.user = student if cert_status in VALID_STATUSES:
cert.course_id = course_id
cert.key = key profile = UserProfile.objects.get(user=student)
cert.save()
cert = GeneratedCertificate.objects.get(
contents = { user=student, course_id=course_id)
'username': student.username, cert.status = status.regenerating
'course_id': course_id, cert.save()
'name': profile.name,
} contents = {
xheader = make_xheader('http://sandbox-jrjarvis-001.m.edx.org/update_certificate', key, 'test-pull') 'action': 'regen',
(error, msg) = xqueue_interface.send_to_queue(header=xheader, 'remove_verify_uuid': cert.verify_uuid,
body=json.dumps(contents)) 'remove_download_uuid': cert.download_uuid,
if error: 'username': cert.user.username,
log.critical('Unable to send message') 'course_id': cert.course_id,
'name': profile.name,
}
key = cert.key
xheader = make_xheader('http://sandbox-jrjarvis-001.m.edx.org/certificate', key, 'test-pull')
(error, msg) = self.xqueue_interface.send_to_queue(header=xheader,
body=json.dumps(contents))
return cert_status
def remove_cert(self, student, course_id):
"""
Arguments:
student - User.object
course_id - courseenrollment.course_id (string)
Removes certificate for a student, will change
the certificate status to 'deleting'.
When completed the certificate status will change
to 'deleted'.
Returns the certificate status.
"""
VALID_STATUSES = [status.downloadable]
cert_status = certificate_status_for_student(
student, course_id)['status']
if cert_status in VALID_STATUSES:
cert = GeneratedCertificate.objects.get(
user=student, course_id=course_id)
username = cert.user.username
cert.status = status.deleting
cert.save()
contents = {
'action': 'remove',
'remove_verify_uuid': cert.verify_uuid,
'remove_download_uuid': cert.download_uuid,
'username': cert.user.username,
}
key = cert.key
xheader = make_xheader('http://sandbox-jrjarvis-001.m.edx.org/certificate', key, 'test-pull')
(error, msg) = self.xqueue_interface.send_to_queue(header=xheader,
body=json.dumps(contents))
return cert_status
def add_cert_to_queue(self, student, course_id):
"""
Arguments:
student - User.object
course_id - courseenrollment.course_id (string)
Adds a new certificate request to the queue only if
the current certificate status is 'unavailable' or
'deleted' and the student has a passing grade for
the course.
When completed the certificate status will change
to 'downloadable'.
If the current status is 'generating', 'regenerating'
or 'deleting' this function will return that status
Returns 'unavailable' if the student is eligible for
a certificate but does not have a passing grade.
"""
VALID_STATUSES = [status.unavailable, status.deleted]
cert_status = certificate_status_for_student(
student, course_id)['status']
if cert_status in VALID_STATUSES:
# grade the student
course = courses.get_course_by_id(course_id)
grade = grades.grade(student, self.request, course)
if grade['grade'] is not None:
cert_status = status.generating
cert, created = GeneratedCertificate.objects.get_or_create(
user=student, course_id=course_id)
profile = UserProfile.objects.get(user=student)
key = make_hashkey(random.random())
cert.status = cert_status
cert.grade = grade['percent']
cert.user = student
cert.course_id = course_id
cert.key = key
cert.save()
contents = {
'action': 'create',
'username': student.username,
'course_id': course_id,
'name': profile.name,
}
xheader = make_xheader('http://sandbox-jrjarvis-001.m.edx.org/update_certificate?{0}'.format(key), key, 'test-pull')
(error, msg) = self.xqueue_interface.send_to_queue(
header=xheader, body=json.dumps(contents))
if error:
log.critical('Unable to send message')
return cert_status
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment