Commit 47159799 by Bridger Maxwell

Tweaks to database and code to allow ungraded AND graded certificates. Also…

Tweaks to database and code to allow ungraded AND graded certificates. Also added grade to certificate request model.
parent b853d29c
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'GeneratedCertificate.graded_certificate_id'
db.add_column('certificates_generatedcertificate', 'graded_certificate_id', self.gf('django.db.models.fields.CharField')(max_length=32, null=True), keep_default=False)
# Adding field 'GeneratedCertificate.graded_download_url'
db.add_column('certificates_generatedcertificate', 'graded_download_url', self.gf('django.db.models.fields.CharField')(max_length=128, null=True), keep_default=False)
# Adding field 'GeneratedCertificate.grade'
db.add_column('certificates_generatedcertificate', 'grade', self.gf('django.db.models.fields.CharField')(max_length=5, null=True), keep_default=False)
def backwards(self, orm):
# Deleting field 'GeneratedCertificate.graded_certificate_id'
db.delete_column('certificates_generatedcertificate', 'graded_certificate_id')
# Deleting field 'GeneratedCertificate.graded_download_url'
db.delete_column('certificates_generatedcertificate', 'graded_download_url')
# Deleting field 'GeneratedCertificate.grade'
db.delete_column('certificates_generatedcertificate', 'grade')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
},
'certificates.generatedcertificate': {
'Meta': {'object_name': 'GeneratedCertificate'},
'certificate_id': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'download_url': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'grade': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True'}),
'graded_certificate_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
'graded_download_url': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['certificates']
...@@ -29,8 +29,12 @@ needs to be set to true. ...@@ -29,8 +29,12 @@ needs to be set to true.
class GeneratedCertificate(models.Model): class GeneratedCertificate(models.Model):
user = models.ForeignKey(User, db_index=True) user = models.ForeignKey(User, db_index=True)
certificate_id = models.CharField(max_length=32) certificate_id = models.CharField(max_length=32)
graded_certificate_id = models.CharField(max_length=32, null=True)
download_url = models.CharField(max_length=128, null=True) download_url = models.CharField(max_length=128, null=True)
graded_download_url = models.CharField(max_length=128, null=True)
grade = models.CharField(max_length=5, null=True)
# enabled should only be true if the student has earned a grade in the course # enabled should only be true if the student has earned a grade in the course
# The student must have a grade and request a certificate for enabled to be True # The student must have a grade and request a certificate for enabled to be True
...@@ -39,7 +43,7 @@ class GeneratedCertificate(models.Model): ...@@ -39,7 +43,7 @@ class GeneratedCertificate(models.Model):
def certificate_state_for_student(student, grade): def certificate_state_for_student(student, grade):
''' '''
This returns a tuple of (state, download_url). The state is one of the This returns a dictionary with a key for state, and other information. The state is one of the
following: following:
unavailable - A student is not elligible for a certificate. unavailable - A student is not elligible for a certificate.
...@@ -47,29 +51,31 @@ def certificate_state_for_student(student, grade): ...@@ -47,29 +51,31 @@ def certificate_state_for_student(student, grade):
generating - A student has requested a certificate, but it is not generated yet. generating - A student has requested a certificate, but it is not generated yet.
downloadable - The certificate has been requested and is available for download. downloadable - The certificate has been requested and is available for download.
In all states except "available", download_url is None If the state is "downloadable", the dictionary also contains "download_url" and "graded_download_url".
''' '''
if grade: if grade:
#TODO: Remove the following after debugging #TODO: Remove the following after debugging
if settings.DEBUG_SURVEY: if settings.DEBUG_SURVEY:
return ("requestable", None) return {'state' : 'requestable' }
try: try:
generated_certificate = GeneratedCertificate.objects.get(user = student) generated_certificate = GeneratedCertificate.objects.get(user = student)
if generated_certificate.enabled: if generated_certificate.enabled:
if generated_certificate.download_url: if generated_certificate.download_url:
return ("downloadable", generated_certificate.download_url) return {'state' : 'downloadable',
'download_url' : generated_certificate.download_url,
'graded_download_url' : generated_certificate.graded_download_url}
else: else:
return ("generating", None) return {'state' : 'generating'}
else: else:
# If enabled=False, it may have been pre-generated but not yet requested # If enabled=False, it may have been pre-generated but not yet requested
# Our output will be the same as if the GeneratedCertificate did not exist # Our output will be the same as if the GeneratedCertificate did not exist
pass pass
except GeneratedCertificate.DoesNotExist: except GeneratedCertificate.DoesNotExist:
pass pass
return ("requestable", None) return {'state' : 'requestable'}
else: else:
# No grade, no certificate. No exceptions # No grade, no certificate. No exceptions
return ("unavailable", None) return {'state' : 'unavailable'}
...@@ -64,9 +64,9 @@ def certificate_request(request): ...@@ -64,9 +64,9 @@ def certificate_request(request):
#This is not a POST, we should render the page with the form #This is not a POST, we should render the page with the form
grade_sheet = grades.grade_sheet(request.user) grade_sheet = grades.grade_sheet(request.user)
certificate_state, certificate_download_url = certificate_state_for_student(request.user, grade_sheet['grade']) certificate_state = certificate_state_for_student(request.user, grade_sheet['grade'])
if certificate_state != "requestable": if certificate_state['state'] != "requestable":
return redirect("/profile") return redirect("/profile")
user_info = UserProfile.objects.get(user=request.user) user_info = UserProfile.objects.get(user=request.user)
...@@ -102,6 +102,11 @@ def generate_certificate(user, grade): ...@@ -102,6 +102,11 @@ def generate_certificate(user, grade):
generated_certificate = GeneratedCertificate(user = user, certificate_id = uuid.uuid4().hex) generated_certificate = GeneratedCertificate(user = user, certificate_id = uuid.uuid4().hex)
generated_certificate.enabled = True generated_certificate.enabled = True
if generated_certificate.graded_download_url and (generated_certificate.grade != grade):
log.critical("A graded certificate has been pre-generated with the grade of " + str(generated_certificate.grade) + " but requested with grade " + str(grade) + \
"! The download URL is " + str(generated_certificate.graded_download_url))
generated_certificate.grade = grade
generated_certificate.save() generated_certificate.save()
certificate_id = generated_certificate.certificate_id certificate_id = generated_certificate.certificate_id
......
...@@ -92,10 +92,9 @@ def profile(request, student_id = None): ...@@ -92,10 +92,9 @@ def profile(request, student_id = None):
if settings.DEBUG_SURVEY: if settings.DEBUG_SURVEY:
took_survey = False took_survey = False
certificate_state, certificate_download_url = certificate_state_for_student(student, grade_sheet['grade']) certificate_state = certificate_state_for_student(student, grade_sheet['grade'])
context.update({'certificate_state' : certificate_state, context.update({'certificate_state' : certificate_state,
'certificate_download_url' : certificate_download_url,
'took_survey' : took_survey}) 'took_survey' : took_survey})
return render_to_response('profile.html', context) return render_to_response('profile.html', context)
......
...@@ -142,11 +142,17 @@ $(function() { ...@@ -142,11 +142,17 @@ $(function() {
%if grade_sheet['grade']: %if grade_sheet['grade']:
<p>Final Grade: <strong>${grade_sheet['grade']}</strong></p> <p>Final Grade: <strong>${grade_sheet['grade']}</strong></p>
%if certificate_state == "requestable": %if certificate_state['state'] == "requestable":
<a class="cert_request_link" href="/certificate_request">Request Certificate</a> <a class="cert_request_link" href="/certificate_request">Request Certificate</a>
%elif certificate_state == "downloadable": %elif certificate_state['state'] == "downloadable":
<a href="${certificate_download_url}" target="_blank">Download Certificate</a> %if certificate_state['download_url']:
%elif certificate_state == "generating": <a href="${certificate_state['download_url']}" target="_blank">Download Certificate</a>
%endif
%if certificate_state['graded_download_url']:
<a href="${certificate_state['graded_download_url']}" target="_blank">Download Certificate (with Grade)</a>
%endif
%elif certificate_state['state'] == "generating":
<a href="#">Certificate is being generated...</a> <a href="#">Certificate is being generated...</a>
%else: %else:
<a href="#">No certificate available</a> <a href="#">No certificate available</a>
......
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