From 019374a41ea4226215e4bdba5ff24117d569423d Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Tue, 27 May 2014 11:53:43 -0400 Subject: [PATCH] Fix gen_cert_report to use CourseKeys. --- .../management/commands/gen_cert_report.py | 127 ++++++++++-------- 1 file changed, 71 insertions(+), 56 deletions(-) diff --git a/lms/djangoapps/certificates/management/commands/gen_cert_report.py b/lms/djangoapps/certificates/management/commands/gen_cert_report.py index 018e5e592b..3c37069753 100644 --- a/lms/djangoapps/certificates/management/commands/gen_cert_report.py +++ b/lms/djangoapps/certificates/management/commands/gen_cert_report.py @@ -1,9 +1,16 @@ -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 django.contrib.auth.models import User from optparse import make_option from django.conf import settings +from opaque_keys import InvalidKeyError 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 django.db.models import Count @@ -12,7 +19,7 @@ class Command(BaseCommand): 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 certificate status. @@ -34,81 +41,89 @@ class Command(BaseCommand): dest='course', default=None, 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): # Find all courses that have ended 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: - ended_courses = self._ended_courses() + raise CommandError("You must specify a course") cert_data = {} - for course_id in ended_courses: + # find students who are active + # number of enrolled students = downloadable + notpassing + print "Looking up certificate states for {0}".format(options['course']) + enrolled_current = User.objects.filter( + courseenrollment__course_id=course_id, + courseenrollment__is_active=True + ) + enrolled_total = User.objects.filter( + courseenrollment__course_id=course_id + ) + verified_enrolled = GeneratedCertificate.objects.filter( + course_id__exact=course_id, mode__exact='verified' + ) + honor_enrolled = GeneratedCertificate.objects.filter( + course_id__exact=course_id, mode__exact='honor' + ) + audit_enrolled = GeneratedCertificate.objects.filter( + course_id__exact=course_id, mode__exact='audit' + ) - # find students who are active - # enrolled students are always downloable + notpassing - print "Looking up certificate states for {0}".format(course_id) - enrolled_current = User.objects.filter( - courseenrollment__course_id=course_id, - courseenrollment__is_active=True) - enrolled_total = User.objects.filter( - courseenrollment__course_id=course_id) - verified_enrolled = GeneratedCertificate.objects.filter( - course_id__exact=course_id, mode__exact='verified') - honor_enrolled = GeneratedCertificate.objects.filter( - course_id__exact=course_id, mode__exact='honor') - audit_enrolled = GeneratedCertificate.objects.filter( - course_id__exact=course_id, mode__exact='audit') + cert_data[course_id] = { + 'enrolled_current': enrolled_current.count(), + 'enrolled_total': enrolled_total.count(), + 'verified_enrolled': verified_enrolled.count(), + 'honor_enrolled': honor_enrolled.count(), + 'audit_enrolled': audit_enrolled.count() + } - cert_data[course_id] = {'enrolled_current': enrolled_current.count(), - 'enrolled_total': enrolled_total.count(), - 'verified_enrolled': verified_enrolled.count(), - 'honor_enrolled': honor_enrolled.count(), - 'audit_enrolled': audit_enrolled.count()} + status_tally = GeneratedCertificate.objects.filter( + course_id__exact=course_id + ).values('status').annotate( + dcount=Count('status') + ) - status_tally = GeneratedCertificate.objects.filter( - course_id__exact=course_id).values('status').annotate( - dcount=Count('status')) - cert_data[course_id].update( - {status['status']: status['dcount'] - for status in status_tally}) + cert_data[course_id].update( + {status['status']: status['dcount'] + 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}) + 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 status_headings = sorted(set( [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 "{:>26}".format("course ID"), print ' '.join(["{:>16}".format(heading) - for heading in status_headings]) + for heading in status_headings] + ) # print the report - for course_id in cert_data: - print "{0:>26}".format(course_id[0:24]), - for heading in status_headings: - if heading in cert_data[course_id]: - print "{:>16}".format(cert_data[course_id][heading]), - else: - print " " * 16, - print + print "{0:>26}".format(course_id.to_deprecated_string()), + for heading in status_headings: + if heading in cert_data[course_id]: + print "{:>16}".format(cert_data[course_id][heading]), + else: + print " " * 16, + print