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.
class GeneratedCertificate(models.Model):
user = models.ForeignKey(User, db_index=True)
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)
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
# The student must have a grade and request a certificate for enabled to be True
......@@ -39,7 +43,7 @@ class GeneratedCertificate(models.Model):
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:
unavailable - A student is not elligible for a certificate.
......@@ -47,29 +51,31 @@ def certificate_state_for_student(student, grade):
generating - A student has requested a certificate, but it is not generated yet.
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:
#TODO: Remove the following after debugging
if settings.DEBUG_SURVEY:
return ("requestable", None)
return {'state' : 'requestable' }
try:
generated_certificate = GeneratedCertificate.objects.get(user = student)
if generated_certificate.enabled:
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:
return ("generating", None)
return {'state' : 'generating'}
else:
# 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
pass
except GeneratedCertificate.DoesNotExist:
pass
return ("requestable", None)
return {'state' : 'requestable'}
else:
# No grade, no certificate. No exceptions
return ("unavailable", None)
return {'state' : 'unavailable'}
......@@ -64,9 +64,9 @@ def certificate_request(request):
#This is not a POST, we should render the page with the form
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")
user_info = UserProfile.objects.get(user=request.user)
......@@ -102,6 +102,11 @@ def generate_certificate(user, grade):
generated_certificate = GeneratedCertificate(user = user, certificate_id = uuid.uuid4().hex)
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()
certificate_id = generated_certificate.certificate_id
......
......@@ -92,10 +92,9 @@ def profile(request, student_id = None):
if settings.DEBUG_SURVEY:
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,
'certificate_download_url' : certificate_download_url,
'took_survey' : took_survey})
return render_to_response('profile.html', context)
......
......@@ -142,11 +142,17 @@ $(function() {
%if grade_sheet['grade']:
<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>
%elif certificate_state == "downloadable":
<a href="${certificate_download_url}" target="_blank">Download Certificate</a>
%elif certificate_state == "generating":
%elif certificate_state['state'] == "downloadable":
%if certificate_state['download_url']:
<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>
%else:
<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