From ecbf148688fc3d54c9ccf4ea268bbf4216f1fc29 Mon Sep 17 00:00:00 2001 From: Chris Dodge Date: Thu, 20 Jun 2013 11:46:16 -0400 Subject: [PATCH] add a new django-admin command to dump out a course structure document. This is response to an emergency request from Harvard researchers. --- .../commands/dump_course_structure.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 cms/djangoapps/contentstore/management/commands/dump_course_structure.py diff --git a/cms/djangoapps/contentstore/management/commands/dump_course_structure.py b/cms/djangoapps/contentstore/management/commands/dump_course_structure.py new file mode 100644 index 0000000000..d9b7c55cbd --- /dev/null +++ b/cms/djangoapps/contentstore/management/commands/dump_course_structure.py @@ -0,0 +1,55 @@ +from django.core.management.base import BaseCommand, CommandError +from xmodule.course_module import CourseDescriptor +from xmodule.modulestore.django import modulestore +from json import dumps +from xmodule.modulestore.inheritance import own_metadata +from django.conf import settings + +filter_list = ['xml_attributes', 'checklists'] + + +class Command(BaseCommand): + help = '''Write out to stdout a structural and metadata information about a course in a flat dictionary serialized + in a JSON format. This can be used for analytics.''' + + def handle(self, *args, **options): + if len(args) < 2 or len(args) > 3: + raise CommandError("dump_course_structure requires two or more arguments: ||") + + course_id = args[0] + outfile = args[1] + + # use a user-specified database name, if present + # this is useful for doing dumps from databases restored from prod backups + if len(args) == 3: + settings.MODULESTORE['direct']['OPTIONS']['db'] = args[2] + + loc = CourseDescriptor.id_to_location(course_id) + + store = modulestore() + + course = None + try: + course = store.get_item(loc, depth=4) + except: + print 'Could not find course at {0}'.format(course_id) + return + + info = {} + + def dump_into_dict(module, info): + filtered_metadata = dict((key, value) for key, value in own_metadata(module).iteritems() + if key not in filter_list) + info[module.location.url()] = { + 'category': module.location.category, + 'children': module.children if hasattr(module, 'children') else [], + 'metadata': filtered_metadata + } + + for child in module.get_children(): + dump_into_dict(child, info) + + dump_into_dict(course, info) + + with open(outfile, 'w') as f: + f.write(dumps(info))