Commit 9915727c by John Jarvis

Cleanup, docstrings, recording name in certificate table

parent c2f9e2ce
...@@ -14,6 +14,27 @@ certificate is available for download the GeneratedCertificate ...@@ -14,6 +14,27 @@ certificate is available for download the GeneratedCertificate
table is updated with information that will be displayed table is updated with information that will be displayed
on the course overview page. on the course overview page.
State diagram:
[deleted,error,unavailable] [error,downloadable]
+ + +
| | |
| | |
add_cert regen_cert del_cert
| | |
v v v
[generating] [regenerating] [deleting]
+ + +
| | |
certificate certificate certificate
created removed,created deleted
+----------------+-------------+------->[error]
| | |
| | |
v v v
[downloadable] [downloadable] [deleted]
''' '''
...@@ -37,6 +58,7 @@ class GeneratedCertificate(models.Model): ...@@ -37,6 +58,7 @@ class GeneratedCertificate(models.Model):
key = models.CharField(max_length=32, blank=True, default='') key = models.CharField(max_length=32, blank=True, default='')
distinction = models.BooleanField(default=False) distinction = models.BooleanField(default=False)
status = models.CharField(max_length=32, default='unavailable') status = models.CharField(max_length=32, default='unavailable')
name = models.CharField(blank=True, max_length=255)
class Meta: class Meta:
unique_together = (('user', 'course_id'),) unique_together = (('user', 'course_id'),)
......
...@@ -19,6 +19,35 @@ logger = logging.getLogger(__name__) ...@@ -19,6 +19,35 @@ logger = logging.getLogger(__name__)
class XQueueCertInterface(object): class XQueueCertInterface(object):
"""
XQueueCertificateInterface provides an
interface to the xqueue server for
managing student certificates.
Instantiating an object will create a new
connection to the queue server.
See models.py for valid state transitions,
summary of methods:
add_cert: Add a new certificate. Puts a single
request on the queue for the student/course.
Once the certificate is generated a post
will be made to the update_certificate
view which will save the certificate
download URL.
regen_cert: Regenerate an existing certificate.
For a user that already has a certificate
this will delete the existing one and
generate a new cert.
del_cert: Delete an existing certificate
For a user that already has a certificate
this will delete his cert.
"""
def __init__(self, request=None): def __init__(self, request=None):
...@@ -45,7 +74,6 @@ class XQueueCertInterface(object): ...@@ -45,7 +74,6 @@ class XQueueCertInterface(object):
def regen_cert(self, student, course_id): def regen_cert(self, student, course_id):
""" """
Arguments: Arguments:
student - User.object student - User.object
course_id - courseenrollment.course_id (string) course_id - courseenrollment.course_id (string)
...@@ -62,7 +90,7 @@ class XQueueCertInterface(object): ...@@ -62,7 +90,7 @@ class XQueueCertInterface(object):
""" """
VALID_STATUSES = [status.downloadable] VALID_STATUSES = [status.error, status.downloadable]
cert_status = certificate_status_for_student( cert_status = certificate_status_for_student(
student, course_id)['status'] student, course_id)['status']
...@@ -70,11 +98,16 @@ class XQueueCertInterface(object): ...@@ -70,11 +98,16 @@ class XQueueCertInterface(object):
if cert_status in VALID_STATUSES: if cert_status in VALID_STATUSES:
profile = UserProfile.objects.get(user=student) profile = UserProfile.objects.get(user=student)
try:
cert = GeneratedCertificate.objects.get(
user=student, course_id=course_id)
except GeneratedCertificate.DoesNotExist:
logger.warning("Attempting to regenerate a certificate"
"for a user that doesn't have one")
raise
cert = GeneratedCertificate.objects.get(
user=student, course_id=course_id)
cert.status = status.regenerating cert.status = status.regenerating
cert.save() cert.name = profile.name
contents = { contents = {
'action': 'regen', 'action': 'regen',
...@@ -94,10 +127,11 @@ class XQueueCertInterface(object): ...@@ -94,10 +127,11 @@ class XQueueCertInterface(object):
if error: if error:
logger.critical('Unable to add a request to the queue') logger.critical('Unable to add a request to the queue')
raise Exception('Unable to send queue message') raise Exception('Unable to send queue message')
cert.save()
return cert_status return cert_status
def remove_cert(self, student, course_id): def del_cert(self, student, course_id):
""" """
Arguments: Arguments:
...@@ -114,17 +148,22 @@ class XQueueCertInterface(object): ...@@ -114,17 +148,22 @@ class XQueueCertInterface(object):
""" """
VALID_STATUSES = [status.downloadable] VALID_STATUSES = [status.error, status.downloadable]
cert_status = certificate_status_for_student( cert_status = certificate_status_for_student(
student, course_id)['status'] student, course_id)['status']
if cert_status in VALID_STATUSES: if cert_status in VALID_STATUSES:
cert = GeneratedCertificate.objects.get( try:
user=student, course_id=course_id) cert = GeneratedCertificate.objects.get(
user=student, course_id=course_id)
except GeneratedCertificate.DoesNotExist:
logger.warning("Attempting to delete a certificate"
"for a user that doesn't have one")
raise
cert.status = status.deleting cert.status = status.deleting
cert.save()
contents = { contents = {
'action': 'remove', 'action': 'remove',
...@@ -140,9 +179,10 @@ class XQueueCertInterface(object): ...@@ -140,9 +179,10 @@ class XQueueCertInterface(object):
(error, msg) = self.xqueue_interface.send_to_queue(header=xheader, (error, msg) = self.xqueue_interface.send_to_queue(header=xheader,
body=json.dumps(contents)) body=json.dumps(contents))
cert.save()
return cert_status return cert_status
def add_cert_to_queue(self, student, course_id): def add_cert(self, student, course_id):
""" """
Arguments: Arguments:
...@@ -150,8 +190,8 @@ class XQueueCertInterface(object): ...@@ -150,8 +190,8 @@ class XQueueCertInterface(object):
course_id - courseenrollment.course_id (string) course_id - courseenrollment.course_id (string)
Adds a new certificate request to the queue only if Adds a new certificate request to the queue only if
the current certificate status is 'unavailable' or the current certificate status is 'unavailable', 'error'
'deleted' and the student has a passing grade for or 'deleted' and the student has a passing grade for
the course. the course.
When completed the certificate status will change When completed the certificate status will change
...@@ -165,7 +205,7 @@ class XQueueCertInterface(object): ...@@ -165,7 +205,7 @@ class XQueueCertInterface(object):
""" """
VALID_STATUSES = [status.unavailable, status.deleted] VALID_STATUSES = [status.unavailable, status.deleted, status.error]
cert_status = certificate_status_for_student( cert_status = certificate_status_for_student(
student, course_id)['status'] student, course_id)['status']
...@@ -187,7 +227,7 @@ class XQueueCertInterface(object): ...@@ -187,7 +227,7 @@ class XQueueCertInterface(object):
cert.user = student cert.user = student
cert.course_id = course_id cert.course_id = course_id
cert.key = key cert.key = key
cert.save() cert.name = profile.name
contents = { contents = {
'action': 'create', 'action': 'create',
...@@ -204,5 +244,6 @@ class XQueueCertInterface(object): ...@@ -204,5 +244,6 @@ class XQueueCertInterface(object):
if error: if error:
logger.critical('Unable to post results to qserver') logger.critical('Unable to post results to qserver')
raise Exception('Unable to send queue message') raise Exception('Unable to send queue message')
cert.save()
return cert_status 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