Skip to content
Snippets Groups Projects
Commit 4c469cc4 authored by John Jarvis's avatar John Jarvis
Browse files

Merge pull request #666 from edx/jarv/add-get-grades

adding django-admin commands to dump grades to a csv file
parents 57a80635 7dc7406d
No related merge requests found
from courseware import grades, courses
from django.test.client import RequestFactory
from django.core.management.base import BaseCommand, CommandError
import os
from django.contrib.auth.models import User
from optparse import make_option
import datetime
from django.core.handlers.base import BaseHandler
import csv
class RequestMock(RequestFactory):
def request(self, **request):
"Construct a generic request object."
request = RequestFactory.request(self, **request)
handler = BaseHandler()
handler.load_middleware()
for middleware_method in handler._request_middleware:
if middleware_method(request):
raise Exception("Couldn't create request mock object - "
"request middleware returned a response")
return request
class Command(BaseCommand):
help = """
Generate a list of grades for all students
that are enrolled in a course.
Outputs grades to a csv file.
Example:
sudo -u www-data SERVICE_VARIANT=lms /opt/edx/bin/django-admin.py get_grades \
-c MITx/Chi6.00intro/A_Taste_of_Python_Programming -o /tmp/20130813-6.00x.csv \
--settings=lms.envs.aws --pythonpath=/opt/wwc/edx-platform
"""
option_list = BaseCommand.option_list + (
make_option('-c', '--course',
metavar='COURSE_ID',
dest='course',
default=False,
help='Course ID for grade distribution'),
make_option('-o', '--output',
metavar='FILE',
dest='output',
default=False,
help='Filename for grade output'))
def handle(self, *args, **options):
if os.path.exists(options['output']):
raise CommandError("File {0} already exists".format(
options['output']))
STATUS_INTERVAL = 100
course_id = options['course']
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')
factory = RequestMock()
request = factory.get('/')
total = enrolled_students.count()
print "Total enrolled: {0}".format(total)
course = courses.get_course_by_id(course_id)
total = enrolled_students.count()
start = datetime.datetime.now()
rows = []
header = None
for count, student in enumerate(enrolled_students):
count += 1
if count % STATUS_INTERVAL == 0:
# Print a status update with an approximation of
# how much time is left based on how long the last
# interval took
diff = datetime.datetime.now() - start
timeleft = diff * (total - count) / STATUS_INTERVAL
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)
start = datetime.datetime.now()
request.user = student
grade = grades.grade(student, request, course)
if not header:
header = [section['label'] for section in grade[u'section_breakdown']]
rows.append(["email", "username"] + header)
percents = {section['label']: section['percent'] for section in grade[u'section_breakdown']}
row_percents = [percents[label] for label in header]
rows.append([student.email, student.username] + row_percents)
with open(options['output'], 'wb') as f:
writer = csv.writer(f)
writer.writerows(rows)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment