Commit 22f5c5c7 by Calen Pennington Committed by Matthew Mongeau

Successfully read course children out of mongodb

parent 432a8e5f
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
#import mitxmako.middleware #import mitxmako.middleware
#from courseware import content_parser #from courseware import content_parser
#from django.contrib.auth.models import User #from django.contrib.auth.models import User
import os.path
from StringIO import StringIO
from mako.template import Template from mako.template import Template
from mako.lookup import TemplateLookup from mako.lookup import TemplateLookup
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from contentstore.models import create_item, update_item, update_children from keystore.django import keystore
from lxml import etree from lxml import etree
...@@ -20,16 +22,15 @@ class Command(BaseCommand): ...@@ -20,16 +22,15 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
print args print args
data_dir = args[0] data_dir = args[0]
course_file = 'course.xml'
parser = etree.XMLParser(remove_comments = True) parser = etree.XMLParser(remove_comments = True)
lookup = TemplateLookup(directories=[data_dir]) lookup = TemplateLookup(directories=[data_dir])
template = lookup.get_template("course.xml") template = lookup.get_template("course.xml")
course_string = template.render(groups=[]) course_string = template.render(groups=[])
course = etree.XML(course_string, parser=parser) course = etree.parse(StringIO(course_string), parser=parser)
elements = course.xpath("//*") elements = list(course.iter())
tag_to_category = {# Inside HTML ==> Skip these tag_to_category = {# Inside HTML ==> Skip these
# Custom tags # Custom tags
...@@ -39,11 +40,11 @@ class Command(BaseCommand): ...@@ -39,11 +40,11 @@ class Command(BaseCommand):
'image': 'Custom', 'image': 'Custom',
'discuss': 'Custom', 'discuss': 'Custom',
# Simple lists # Simple lists
'chapter': 'Sequence', 'chapter': 'Chapter',
'course': 'Sequence', 'course': 'Course',
'sequential': 'Sequence', 'sequential': 'LectureSequence',
'vertical': 'Sequence', 'vertical': 'ProblemSet',
'section': 'Sequence', 'section': 'Section',
# True types # True types
'video': 'VideoSegment', 'video': 'VideoSegment',
'html': 'HTML', 'html': 'HTML',
...@@ -114,7 +115,7 @@ class Command(BaseCommand): ...@@ -114,7 +115,7 @@ class Command(BaseCommand):
results[e.attrib['url']] = {'data':{'text':text}} results[e.attrib['url']] = {'data':{'text':text}}
def handle_problem(e): def handle_problem(e):
data = open(data_dir+'problems/'+e.attrib['filename']+'.xml').read() data = open(os.path.join(data_dir, 'problems', e.attrib['filename']+'.xml')).read()
results[e.attrib['url']] = {'data':{'statement':data}} results[e.attrib['url']] = {'data':{'statement':data}}
element_actions = {# Inside HTML ==> Skip these element_actions = {# Inside HTML ==> Skip these
...@@ -149,10 +150,8 @@ class Command(BaseCommand): ...@@ -149,10 +150,8 @@ class Command(BaseCommand):
for k in results: for k in results:
print k print k
create_item(k, 'Piotr Mitros') keystore.create_item(k, 'Piotr Mitros')
if 'data' in results[k]: if 'data' in results[k]:
update_item(k, results[k]['data']) keystore.update_item(k, results[k]['data'])
if 'children' in results[k]: if 'children' in results[k]:
update_children(k, results[k]['children']) keystore.update_children(k, results[k]['children'])
from mitxmako.shortcuts import render_to_response from mitxmako.shortcuts import render_to_response
from keystore import Location
from keystore.django import keystore from keystore.django import keystore
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@login_required @login_required
def calendar(request, org, course): def calendar(request, org, course):
weeks = keystore.get_children_for_item( weeks = keystore.get_children_for_item(['i4x', org, course, 'Course', None])
Location(['i4x', org, course, 'Course', 'course'])
)
return render_to_response('calendar.html', {'weeks': weeks}) return render_to_response('calendar.html', {'weeks': weeks})
......
...@@ -60,6 +60,40 @@ class KeyStore(object): ...@@ -60,6 +60,40 @@ class KeyStore(object):
with the specified location. with the specified location.
If no object is found at that location, raises keystore.exceptions.ItemNotFoundError If no object is found at that location, raises keystore.exceptions.ItemNotFoundError
Searches for all matches of a partially specifed location, but raises an
keystore.exceptions.InsufficientSpecificationError if more
than a single object matches the query.
location: Something that can be passed to Location
"""
raise NotImplementedError
def create_item(self, location, editor):
"""
Create an empty item at the specified location with the supplied editor
location: Something that can be passed to Location
"""
raise NotImplementedError
def update_item(self, location, data):
"""
Set the data in the item specified by the location to
data
location: Something that can be passed to Location
data: A nested dictionary of problem data
"""
raise NotImplementedError
def update_children(self, location, children):
"""
Set the children for the item specified by the location to
data
location: Something that can be passed to Location
children: A list of child item identifiers
""" """
raise NotImplementedError raise NotImplementedError
......
...@@ -5,3 +5,7 @@ Exceptions thrown by KeyStore objects ...@@ -5,3 +5,7 @@ Exceptions thrown by KeyStore objects
class ItemNotFoundError(Exception): class ItemNotFoundError(Exception):
pass pass
class InsufficientSpecificationError(Exception):
pass
import pymongo import pymongo
from . import KeyStore from . import KeyStore, Location
from .exceptions import ItemNotFoundError from .exceptions import ItemNotFoundError, InsufficientSpecificationError
class MongoKeyStore(KeyStore): class MongoKeyStore(KeyStore):
...@@ -12,15 +12,64 @@ class MongoKeyStore(KeyStore): ...@@ -12,15 +12,64 @@ class MongoKeyStore(KeyStore):
host=host, host=host,
port=port port=port
)[db][collection] )[db][collection]
# Force mongo to report errors, at the expense of performance
self.collection.safe = True
def get_children_for_item(self, location): def get_children_for_item(self, location):
item = self.collection.find_one( query = dict(
{'location': location.dict()}, ('location.{key}'.format(key=key), val)
for (key, val)
in Location(location).dict().items()
if val is not None
)
items = self.collection.find(
query,
fields={'children': True}, fields={'children': True},
sort=[('revision', pymongo.ASCENDING)], sort=[('revision', pymongo.ASCENDING)],
limit=1,
) )
if items.count() > 1:
raise InsufficientSpecificationError(location)
if items.count() == 0:
raise ItemNotFoundError(location)
return items[0]['children']
def create_item(self, location, editor):
"""
Create an empty item at the specified location with the supplied editor
location: Something that can be passed to Location
"""
self.collection.insert({
'location': Location(location).dict(),
'editor': editor
})
if item is None: def update_item(self, location, data):
raise ItemNotFoundError() """
Set the data in the item specified by the location to
data
return item['children'] location: Something that can be passed to Location
data: A nested dictionary of problem data
"""
self.collection.update(
{'location': Location(location).dict()},
{'$set': {'data': data}}
)
def update_children(self, location, children):
"""
Set the children for the item specified by the location to
data
location: Something that can be passed to Location
children: A list of child item identifiers
"""
self.collection.update(
{'location': Location(location).dict()},
{'$set': {'children': children}}
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment