Commit 779480ba by Diana Huang

Merge pull request #3889 from edx/diana/fix-gen-cert

Fix gen_cert_report to use CourseKeys.
parents 797a1643 019374a4
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.
...@@ -36,76 +43,84 @@ class Command(BaseCommand): ...@@ -36,76 +43,84 @@ class Command(BaseCommand):
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 # find students who are active
# enrolled students are always downloable + notpassing # number of enrolled students = downloadable + notpassing
print "Looking up certificate states for {0}".format(course_id) print "Looking up certificate states for {0}".format(options['course'])
enrolled_current = User.objects.filter( enrolled_current = User.objects.filter(
courseenrollment__course_id=course_id, courseenrollment__course_id=course_id,
courseenrollment__is_active=True) 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( honor_enrolled = GeneratedCertificate.objects.filter(
course_id__exact=course_id, mode__exact='honor') course_id__exact=course_id, mode__exact='honor'
)
audit_enrolled = GeneratedCertificate.objects.filter( audit_enrolled = GeneratedCertificate.objects.filter(
course_id__exact=course_id, mode__exact='audit') course_id__exact=course_id, mode__exact='audit'
)
cert_data[course_id] = {'enrolled_current': enrolled_current.count(), cert_data[course_id] = {
'enrolled_current': enrolled_current.count(),
'enrolled_total': enrolled_total.count(), 'enrolled_total': enrolled_total.count(),
'verified_enrolled': verified_enrolled.count(), 'verified_enrolled': verified_enrolled.count(),
'honor_enrolled': honor_enrolled.count(), 'honor_enrolled': honor_enrolled.count(),
'audit_enrolled': audit_enrolled.count()} 'audit_enrolled': audit_enrolled.count()
}
status_tally = GeneratedCertificate.objects.filter( status_tally = GeneratedCertificate.objects.filter(
course_id__exact=course_id).values('status').annotate( course_id__exact=course_id
dcount=Count('status')) ).values('status').annotate(
dcount=Count('status')
)
cert_data[course_id].update( cert_data[course_id].update(
{status['status']: status['dcount'] {status['status']: status['dcount']
for status in status_tally}) for status in status_tally})
mode_tally = GeneratedCertificate.objects.filter( mode_tally = GeneratedCertificate.objects.filter(
course_id__exact=course_id, course_id__exact=course_id,
status__exact='downloadable').values('mode').annotate( status__exact='downloadable'
dcount=Count('mode')) ).values('mode').annotate(
dcount=Count('mode')
)
cert_data[course_id].update( cert_data[course_id].update(
{mode['mode']: mode['dcount'] {mode['mode']: mode['dcount']
for mode in mode_tally}) 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]),
......
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