Commit 019374a4 by Diana Huang

Fix gen_cert_report to use CourseKeys.

parent ddfffdaf
from django.core.management.base import BaseCommand """
Generate a report of certificate statuses
"""
from django.core.management.base import BaseCommand, CommandError
from certificates.models import GeneratedCertificate from certificates.models import GeneratedCertificate
from django.contrib.auth.models import User from django.contrib.auth.models import User
from optparse import make_option from optparse import make_option
from django.conf import settings from django.conf import settings
from opaque_keys import InvalidKeyError
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.keys import CourseKey
from xmodule.modulestore.locations import SlashSeparatedCourseKey
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from django.db.models import Count from django.db.models import Count
...@@ -12,7 +19,7 @@ class Command(BaseCommand): ...@@ -12,7 +19,7 @@ class Command(BaseCommand):
help = """ help = """
Generate a certificate status report for all courses that have ended. Generate a certificate status report for a given course.
This command does not do anything other than report the current This command does not do anything other than report the current
certificate status. certificate status.
...@@ -34,81 +41,89 @@ class Command(BaseCommand): ...@@ -34,81 +41,89 @@ class Command(BaseCommand):
dest='course', dest='course',
default=None, default=None,
help='Only generate for COURSE_ID'), help='Only generate for COURSE_ID'),
) )
def _ended_courses(self):
for course_id in [course # all courses in COURSE_LISTINGS
for sub in settings.COURSE_LISTINGS
for course in settings.COURSE_LISTINGS[sub]]:
course = modulestore().get_course(course_id)
if course.has_ended():
yield course_id
def handle(self, *args, **options): def handle(self, *args, **options):
# Find all courses that have ended # Find all courses that have ended
if options['course']: if options['course']:
ended_courses = [options['course']] try:
course_id = CourseKey.from_string(options['course'])
except InvalidKeyError:
print("Course id {} could not be parsed as a CourseKey; falling back to SSCK.from_dep_str".format(options['course']))
course_id = SlashSeparatedCourseKey.from_deprecated_string(options['course'])
else: else:
ended_courses = self._ended_courses() raise CommandError("You must specify a course")
cert_data = {} cert_data = {}
for course_id in ended_courses: # find students who are active
# number of enrolled students = downloadable + notpassing
# find students who are active print "Looking up certificate states for {0}".format(options['course'])
# enrolled students are always downloable + notpassing enrolled_current = User.objects.filter(
print "Looking up certificate states for {0}".format(course_id) courseenrollment__course_id=course_id,
enrolled_current = User.objects.filter( courseenrollment__is_active=True
courseenrollment__course_id=course_id, )
courseenrollment__is_active=True) enrolled_total = User.objects.filter(
enrolled_total = User.objects.filter( courseenrollment__course_id=course_id
courseenrollment__course_id=course_id) )
verified_enrolled = GeneratedCertificate.objects.filter( verified_enrolled = GeneratedCertificate.objects.filter(
course_id__exact=course_id, mode__exact='verified') course_id__exact=course_id, mode__exact='verified'
honor_enrolled = GeneratedCertificate.objects.filter( )
course_id__exact=course_id, mode__exact='honor') honor_enrolled = GeneratedCertificate.objects.filter(
audit_enrolled = GeneratedCertificate.objects.filter( course_id__exact=course_id, mode__exact='honor'
course_id__exact=course_id, mode__exact='audit') )
audit_enrolled = GeneratedCertificate.objects.filter(
cert_data[course_id] = {'enrolled_current': enrolled_current.count(), course_id__exact=course_id, mode__exact='audit'
'enrolled_total': enrolled_total.count(), )
'verified_enrolled': verified_enrolled.count(),
'honor_enrolled': honor_enrolled.count(), cert_data[course_id] = {
'audit_enrolled': audit_enrolled.count()} 'enrolled_current': enrolled_current.count(),
'enrolled_total': enrolled_total.count(),
status_tally = GeneratedCertificate.objects.filter( 'verified_enrolled': verified_enrolled.count(),
course_id__exact=course_id).values('status').annotate( 'honor_enrolled': honor_enrolled.count(),
dcount=Count('status')) 'audit_enrolled': audit_enrolled.count()
cert_data[course_id].update( }
{status['status']: status['dcount']
for status in status_tally}) status_tally = GeneratedCertificate.objects.filter(
course_id__exact=course_id
mode_tally = GeneratedCertificate.objects.filter( ).values('status').annotate(
course_id__exact=course_id, dcount=Count('status')
status__exact='downloadable').values('mode').annotate( )
dcount=Count('mode'))
cert_data[course_id].update( cert_data[course_id].update(
{mode['mode']: mode['dcount'] {status['status']: status['dcount']
for mode in mode_tally}) for status in status_tally})
mode_tally = GeneratedCertificate.objects.filter(
course_id__exact=course_id,
status__exact='downloadable'
).values('mode').annotate(
dcount=Count('mode')
)
cert_data[course_id].update(
{mode['mode']: mode['dcount']
for mode in mode_tally}
)
# all states we have seen far all courses # all states we have seen far all courses
status_headings = sorted(set( status_headings = sorted(set(
[status for course in cert_data [status for course in cert_data
for status in cert_data[course]])) for status in cert_data[course]])
)
# print the heading for the report # print the heading for the report
print "{:>26}".format("course ID"), print "{:>26}".format("course ID"),
print ' '.join(["{:>16}".format(heading) print ' '.join(["{:>16}".format(heading)
for heading in status_headings]) for heading in status_headings]
)
# print the report # print the report
for course_id in cert_data: print "{0:>26}".format(course_id.to_deprecated_string()),
print "{0:>26}".format(course_id[0:24]), for heading in status_headings:
for heading in status_headings: if heading in cert_data[course_id]:
if heading in cert_data[course_id]: print "{:>16}".format(cert_data[course_id][heading]),
print "{:>16}".format(cert_data[course_id][heading]), else:
else: print " " * 16,
print " " * 16, print
print
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