From 491027a814df3f8d01c75826b4840aadbb9f6731 Mon Sep 17 00:00:00 2001 From: John Jarvis Date: Wed, 16 Jan 2013 17:34:48 -0500 Subject: [PATCH 1/5] Allow generation of certificates if they are in the generating state --- lms/djangoapps/certificates/queue.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/certificates/queue.py b/lms/djangoapps/certificates/queue.py index 52a8dcae36..b9316220fa 100644 --- a/lms/djangoapps/certificates/queue.py +++ b/lms/djangoapps/certificates/queue.py @@ -192,7 +192,7 @@ class XQueueCertInterface(object): Will change the certificate status to 'deleting'. Certificate must be in the 'unavailable', 'error', - or 'deleted' state. + 'deleted' or 'generating' state. If a student has a passing grade a request will made for a new cert @@ -204,7 +204,8 @@ class XQueueCertInterface(object): """ - VALID_STATUSES = [status.unavailable, status.deleted, status.error, + VALID_STATUSES = [ status.generating, + status.unavailable, status.deleted, status.error, status.notpassing] cert_status = certificate_status_for_student( From 44141b6a5540cf881e8677782020b96a36c397f0 Mon Sep 17 00:00:00 2001 From: John Jarvis Date: Wed, 16 Jan 2013 17:39:26 -0500 Subject: [PATCH 2/5] pep8 cleanup --- .../management/commands/ungenerated_certs.py | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py index 080918c0cc..78cbc28f22 100644 --- a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py +++ b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py @@ -23,26 +23,24 @@ class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('-n', '--noop', - action='store_true', - dest='noop', - default=False, - help="Don't add certificate requests to the queue"), + action='store_true', + dest='noop', + default=False, + help="Don't add certificate requests to the queue"), make_option('-c', '--course', - metavar='COURSE_ID', - dest='course', - default=False, - help='Grade and generate certificates for a specific course'), - - ) + metavar='COURSE_ID', + dest='course', + default=False, + help='Grade and generate certificates ' + 'for a specific course'), + ) def handle(self, *args, **options): # Will only generate a certificate if the current # status is in this state - VALID_STATUSES = [ - CertificateStatuses.unavailable - ] + VALID_STATUSES = [CertificateStatuses.unavailable] # Print update after this many students @@ -54,8 +52,8 @@ class Command(BaseCommand): # Find all courses that have ended ended_courses = [] for course_id in [course # all courses in COURSE_LISTINGS - for sub in settings.COURSE_LISTINGS - for course in settings.COURSE_LISTINGS[sub]]: + for sub in settings.COURSE_LISTINGS + for course in settings.COURSE_LISTINGS[sub]]: course_loc = CourseDescriptor.id_to_location(course_id) course = modulestore().get_instance(course_id, course_loc) if course.has_ended(): @@ -64,8 +62,8 @@ class Command(BaseCommand): for course_id in ended_courses: print "Fetching enrolled students for {0}".format(course_id) enrolled_students = User.objects.filter( - courseenrollment__course_id=course_id).prefetch_related( - "groups").order_by('username') + courseenrollment__course_id=course_id).prefetch_related( + "groups").order_by('username') xq = XQueueCertInterface() total = enrolled_students.count() count = 0 @@ -81,11 +79,11 @@ class Command(BaseCommand): hours, remainder = divmod(timeleft.seconds, 3600) minutes, seconds = divmod(remainder, 60) print "{0}/{1} completed ~{2:02}:{3:02}m remaining".format( - count, total, hours, minutes) + count, total, hours, minutes) start = datetime.datetime.now() if certificate_status_for_student( - student, course_id)['status'] in VALID_STATUSES: + student, course_id)['status'] in VALID_STATUSES: if not options['noop']: # Add the certificate request to the queue ret = xq.add_cert(student, course_id) From 52e387e0294ca227f4ea8503eb3df1094056b701 Mon Sep 17 00:00:00 2001 From: John Jarvis Date: Wed, 16 Jan 2013 17:44:19 -0500 Subject: [PATCH 3/5] Add the force flag This will allow you to force the certificate generation for when certificate requests are lost and stuck in 'generating', this happens when we have xqueue issues. --- .../management/commands/ungenerated_certs.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py index 78cbc28f22..47d64a7685 100644 --- a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py +++ b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py @@ -33,14 +33,25 @@ class Command(BaseCommand): default=False, help='Grade and generate certificates ' 'for a specific course'), + make_option('-f', '--force-gen', + metavar='STATUS', + dest='force', + default=False, + help='Will force generate a search for STATUS ' + '(cannot be downloadable)'), + ) def handle(self, *args, **options): # Will only generate a certificate if the current - # status is in this state + # status is in the unavailable state, can be set + # to something else with the force flag - VALID_STATUSES = [CertificateStatuses.unavailable] + if options['force']: + valid_statuses = getattr(CertificateStatuses, options['force']) + else: + valid_statuses = [CertificateStatuses.unavailable] # Print update after this many students @@ -83,7 +94,7 @@ class Command(BaseCommand): start = datetime.datetime.now() if certificate_status_for_student( - student, course_id)['status'] in VALID_STATUSES: + student, course_id)['status'] in valid_statuses: if not options['noop']: # Add the certificate request to the queue ret = xq.add_cert(student, course_id) From e09728a3b2b5ebe8abf1aa3e6c74908c87ac85d0 Mon Sep 17 00:00:00 2001 From: John Jarvis Date: Wed, 16 Jan 2013 17:48:46 -0500 Subject: [PATCH 4/5] Removing the unavailable tally It doesn't make sense to print out unavailable students since it will go negative as students unenroll --- .../certificates/management/commands/gen_cert_report.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lms/djangoapps/certificates/management/commands/gen_cert_report.py b/lms/djangoapps/certificates/management/commands/gen_cert_report.py index 93ee20b19f..198ed048fd 100644 --- a/lms/djangoapps/certificates/management/commands/gen_cert_report.py +++ b/lms/djangoapps/certificates/management/commands/gen_cert_report.py @@ -16,7 +16,6 @@ class Command(BaseCommand): This command does not do anything other than report the current certificate status. - unavailable - A student is not eligible for a certificate. generating - A request has been made to generate a certificate, but it has not been generated yet. regenerating - A request has been made to regenerate a certificate, @@ -64,11 +63,7 @@ class Command(BaseCommand): enrolled_students = User.objects.filter( courseenrollment__course_id=course_id).prefetch_related( "groups").order_by('username') - unavailable_count = enrolled_students.count() - \ - GeneratedCertificate.objects.filter( - course_id__exact=course_id).count() cert_data[course_id] = {'enrolled': enrolled_students.count()} - cert_data[course_id].update({'unavailable': unavailable_count}) tallies = GeneratedCertificate.objects.filter( course_id__exact=course_id).values('status').annotate( From 08b8a9f674f986b74bfb111200c6068c0aa47a04 Mon Sep 17 00:00:00 2001 From: John Jarvis Date: Thu, 17 Jan 2013 14:36:08 -0500 Subject: [PATCH 5/5] Better help message for the force-gen option --- .../certificates/management/commands/ungenerated_certs.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py index 47d64a7685..071b2c261b 100644 --- a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py +++ b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py @@ -37,8 +37,10 @@ class Command(BaseCommand): metavar='STATUS', dest='force', default=False, - help='Will force generate a search for STATUS ' - '(cannot be downloadable)'), + help='Will generate new certificates for only those users ' + 'whose entry in the certificate table matches STATUS. ' + 'STATUS can be generating, unavailable, deleted, error ' + 'or notpassing.'), )