Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
A Django command that dumps the structure of a course as a JSON object.
A Django command that dumps the structure of a course as a JSON object or CSV list.

The resulting JSON object has one entry for each module in the course:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be convenient to add an example of the CSV output too.

Expand All @@ -17,6 +17,8 @@
"""

import json
import csv
import StringIO
from optparse import make_option
from textwrap import dedent

Expand All @@ -41,6 +43,16 @@ class Command(BaseCommand):
action='store',
default='default',
help='Name of the modulestore'),
make_option('--flat',
action='store_true',
dest='flat',
default=False,
help='Show "flattened" course content with order and levels'),
make_option('--csv',
action='store_true',
dest='csv',
default=False,
help='output in CSV format (default is JSON)'),
)

def handle(self, *args, **options):
Expand All @@ -64,12 +76,20 @@ def handle(self, *args, **options):

# Convert course data to dictionary and dump it as JSON to stdout

info = dump_module(course)

return json.dumps(info, indent=2, sort_keys=True)


def dump_module(module, destination=None):
if options['flat']:
info = dump_module_by_position(course_id, course)
else:
info = dump_module_by_module(course)

if options['csv']:
csvout = StringIO.StringIO()
writer = csv.writer(csvout, dialect='excel')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment below on using fieldnames. Afterwards, it is possible to do writer.writeheader() before dumping the data.

writer.writerows(info)
return csvout.getvalue()
else:
return json.dumps(info, indent=2, sort_keys=True)

def dump_module_by_module(module, destination=None):
"""
Add the module and all its children to the destination dictionary in
as a flat structure.
Expand All @@ -87,6 +107,51 @@ def dump_module(module, destination=None):
}

for child in module.get_children():
dump_module(child, destination)
dump_module_by_module(child, destination)

return destination

def dump_module_by_position(course_id, module, level=0,
destination=None, prefix=None, parent=None):
"""
Add a module and all of its children to the end of the list.
Keep a running tally of position in the list and indent level.
"""
pos = 0
if destination:
pos = destination[-1][1] + 1 # pos is the 2nd col

if level == 0:
display_name_long = ""
elif level == 1:
display_name_long = module.display_name
else:
display_name_long = prefix + "," + module.display_name

if destination == None:
destination = [ ('course_id',
'position',
'level',
'module_id',
'type',
'displayname',
'path',
'parent') ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll prefer to use the fieldnames parameter of the cvs writer, with the name of the fields in a global. Each entry in destination will then be a dictionary with the fields like so:

destination.append({
  'course_id': course_id,
  'position': pos,
  'level': level,
  ...
})

That way we don't have to keep the to fields and the entries in sync, and the --flat output in json works too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know about that option, indeed that sounds nicer. I'll try that thanks.


destination.append( (course_id,
pos,
level,
module.id,
module.location.category,
module.display_name,
display_name_long,
parent) )
for child in module.get_children():
dump_module_by_position(course_id,
child,
level=level+1,
destination=destination,
prefix=display_name_long,
parent=module.id)
return destination