Commit 1b704f79 by Calen Pennington

Read week headings from mongodb

parent 6f8d4c37
...@@ -82,7 +82,7 @@ class Command(BaseCommand): ...@@ -82,7 +82,7 @@ class Command(BaseCommand):
def handle_list(e): def handle_list(e):
if e.attrib.get("class", None) == "tutorials": if e.attrib.get("class", None) == "tutorials":
return return
children = [{'url':le.attrib['url']} for le in e.getchildren()] children = [le.attrib['url'] for le in e.getchildren()]
results[e.attrib['url']] = {'children':children} results[e.attrib['url']] = {'children':children}
def handle_video(e): def handle_video(e):
......
...@@ -3,11 +3,10 @@ from keystore.django import keystore ...@@ -3,11 +3,10 @@ from keystore.django import keystore
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@login_required
def calendar(request, org, course):
weeks = keystore.get_children_for_item(['i4x', org, course, 'Course', None])
return render_to_response('calendar.html', {'weeks': weeks})
def index(request): def index(request):
return render_to_response('index.html', {}) # FIXME (cpennington): These need to be read in from the active user
org = 'mit.edu'
course = '6002xs12'
course = keystore.get_item(['i4x', org, course, 'Course', None])
weeks = course.get_children()
return render_to_response('index.html', {'weeks': weeks})
...@@ -37,7 +37,7 @@ class Location(object): ...@@ -37,7 +37,7 @@ class Location(object):
self.update(location.list()) self.update(location.list())
def url(self): def url(self):
return "i4x://{org}/{course}/{category}/{name}".format(**self.dict()) return "{tag}://{org}/{course}/{category}/{name}".format(**self.dict())
def list(self): def list(self):
return [self.tag, self.org, self.course, self.category, self.name] return [self.tag, self.org, self.course, self.category, self.name]
...@@ -54,10 +54,9 @@ class Location(object): ...@@ -54,10 +54,9 @@ class Location(object):
class KeyStore(object): class KeyStore(object):
def get_children_for_item(self, location): def get_item(self, location):
""" """
Returns the children for the most recent revision of the object Returns an XModuleDescriptor instance for the item at 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
......
import pymongo import pymongo
from . import KeyStore, Location from . import KeyStore, Location
from .exceptions import ItemNotFoundError, InsufficientSpecificationError from .exceptions import ItemNotFoundError, InsufficientSpecificationError
from xmodule.x_module import XModuleDescriptor
class MongoKeyStore(KeyStore): class MongoKeyStore(KeyStore):
...@@ -12,11 +13,22 @@ class MongoKeyStore(KeyStore): ...@@ -12,11 +13,22 @@ 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 # Force mongo to report errors, at the expense of performance
self.collection.safe = True self.collection.safe = True
def get_children_for_item(self, location): def get_item(self, location):
"""
Returns an XModuleDescriptor instance for the item at location
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
"""
query = dict( query = dict(
('location.{key}'.format(key=key), val) ('location.{key}'.format(key=key), val)
for (key, val) for (key, val)
...@@ -25,7 +37,6 @@ class MongoKeyStore(KeyStore): ...@@ -25,7 +37,6 @@ class MongoKeyStore(KeyStore):
) )
items = self.collection.find( items = self.collection.find(
query, query,
fields={'children': True},
sort=[('revision', pymongo.ASCENDING)], sort=[('revision', pymongo.ASCENDING)],
limit=1, limit=1,
) )
...@@ -35,7 +46,7 @@ class MongoKeyStore(KeyStore): ...@@ -35,7 +46,7 @@ class MongoKeyStore(KeyStore):
if items.count() == 0: if items.count() == 0:
raise ItemNotFoundError(location) raise ItemNotFoundError(location)
return items[0]['children'] return XModuleDescriptor.load_from_json(items[0], self.get_item)
def create_item(self, location, editor): def create_item(self, location, editor):
""" """
......
...@@ -35,9 +35,10 @@ ...@@ -35,9 +35,10 @@
</header> </header>
<ol> <ol>
% for week in weeks:
<li> <li>
<header> <header>
<h1><a href="#">Week 1</a></h1> <h1><a href="#">${week.name}</a></h1>
<ul> <ul>
<li class="goal editable"><strong>Goal title:</strong> This is a goal that will be in the header of the week</li> <li class="goal editable"><strong>Goal title:</strong> This is a goal that will be in the header of the week</li>
<li class="goal editable"><strong>Goal title two:</strong> This is another goal for this week so that students have two things to learn</li> <li class="goal editable"><strong>Goal title two:</strong> This is another goal for this week so that students have two things to learn</li>
...@@ -64,125 +65,7 @@ ...@@ -64,125 +65,7 @@
<%include file="module-dropdown.html"/> <%include file="module-dropdown.html"/>
</ul> </ul>
</li> </li>
<li> %endfor
<header>
<h1><a href="#">Week 2</a></h1>
<ul>
<li class="goal editable"><strong>Another title</strong> This is the goal for the week</li>
</ul>
</header>
<ul>
<li class="seq">
<a href="#" class="sequence-edit">Lecture Sequence</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="seq">
<a href="#" class="sequence-edit">Lecture Sequence
<a href="#" class="draggable">handle</a>
</a></li>
<li class="lab">
<a href="#" class="lab-edit">Lab</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="hw">
<a href="#">Homework</a>
<a href="#" class="draggable">handle</a>
</li>
<%include file="module-dropdown.html"/>
</ul>
</li>
<li>
<header>
<h1><a href="#">Week 3</a></h1>
<ul>
<li class="goal editable"><strong>Another title</strong> This is the goal for the week</li>
</ul>
</header>
<ul>
<li class="lab">
<a href="#" class="lab-edit">Lab</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="lab">
<a href="#" class="lab-edit">Lab</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="hw">
<a href="#">Homework</a>
<a href="#" class="draggable">handle</a>
</li>
<%include file="module-dropdown.html"/>
</ul>
</li>
<li>
<header>
<h1><a href="#">Week 4</a></h1>
<ul>
<li class="goal editable"><strong>Another title</strong> This is the goal for the week</li>
<li class="goal editable"><strong>Goal title two:</strong> This is another fgoal for this week so that students have two things to learn</li>
</ul>
</header>
<ul>
<li class="seq">
<a href="#" class="sequence-edit">Lecture Sequence</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="lab">
<a href="#" class="lab-edit">Lab</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="hw">
<a href="#">Homework</a>
<a href="#" class="draggable">handle</a>
</li>
<li class="hw">
<a href="#">Homework</a>
<a href="#" class="draggable">handle</a>
</li>
<%include file="module-dropdown.html"/>
</ul>
</li>
<li>
<header>
<h1><a>Week 5</a></h1>
<ul>
<li class="goal editable">Please create a learning goal for this week</li>
</ul>
</header>
<ul>
<%include file="module-dropdown.html"/>
</ul>
</li>
<li>
<header>
<h1><a>Week 6</a></h1>
<ul>
<li class="goal editable">Please create a learning goal for this week</li>
</ul>
</header>
<ul>
<%include file="module-dropdown.html"/>
</ul>
</li>
<li>
<header>
<h1><a>Week 7</a></h1>
<ul>
<li class="goal editable">Please create a learning goal for this week</li>
</ul>
</header>
<ul>
<%include file="module-dropdown.html"/>
</ul>
</li>
<li> <li>
<header> <header>
<h1>Course Scratch Pad</h1> <h1>Course Scratch Pad</h1>
......
...@@ -95,3 +95,11 @@ class Module(XModule): ...@@ -95,3 +95,11 @@ class Module(XModule):
self.position = int(system.get('position')) self.position = int(system.get('position'))
self.rendered = False self.rendered = False
class CourseModuleDescriptor(XModuleDescriptor):
pass
class ChapterModuleDescriptor(XModuleDescriptor):
pass
from setuptools import setup, find_packages
setup(
name="XModule",
version="0.1",
packages=find_packages(),
install_requires=['distribute'],
entry_points={
'xmodule.v1': [
"Course = seq_module:CourseModuleDescriptor",
"Chapter = seq_module:ChapterModuleDescriptor",
]
}
)
from lxml import etree from lxml import etree
import pkg_resources
import logging
from keystore import Location
log = logging.getLogger('mitx.' + __name__)
def dummy_track(event_type, event): def dummy_track(event_type, event):
pass pass
class ModuleMissingError(Exception):
pass
class Plugin(object):
@classmethod
def load_class(cls, identifier):
classes = list(pkg_resources.iter_entry_points(cls.entry_point, name=identifier))
if len(classes) > 1:
log.warning("Found multiple classes for {entry_point} with identifier {id}: {classes}. Returning the first one.".format(
entry_point=cls.entry_point,
id=identifier,
classes=", ".join([class_.module_name for class_ in classes])))
if len(classes) == 0:
raise ModuleMissingError(identifier)
return classes[0].load()
class XModule(object): class XModule(object):
''' Implements a generic learning module. ''' Implements a generic learning module.
Initialized on access with __init__, first time with state=None, and Initialized on access with __init__, first time with state=None, and
...@@ -24,8 +50,8 @@ class XModule(object): ...@@ -24,8 +50,8 @@ class XModule(object):
or a CAPA input type ''' or a CAPA input type '''
return ['xmodule'] return ['xmodule']
def get_name(): def get_name(self):
name = self.__xmltree.get(name) name = self.__xmltree.get('name')
if name: if name:
return name return name
else: else:
...@@ -98,15 +124,42 @@ class XModule(object): ...@@ -98,15 +124,42 @@ class XModule(object):
return "" return ""
class XModuleDescriptor(object): class XModuleDescriptor(Plugin):
def __init__(self, xml = None, json = None):
if not xml and not json: entry_point = "xmodule.v1"
raise "XModuleDescriptor must be initalized with XML or JSON"
if not xml: @staticmethod
raise NotImplementedError("Code does not have support for JSON yet") def load_from_json(json_data, load_item):
class_ = XModuleDescriptor.load_class(json_data['location']['category'])
self.xml = xml return class_.from_json(json_data, load_item)
self.json = json
@classmethod
def from_json(cls, json_data, load_item):
"""
Creates an instance of this descriptor from the supplied json_data.
json_data: Json data specifying the data, children, and metadata for the descriptor
load_item: A function that takes an i4x url and returns a module descriptor
"""
return cls(load_item=load_item, **json_data)
def __init__(self,
load_item,
data=None,
children=None,
**kwargs):
self.load_item = load_item
self.data = data if data is not None else {}
self.children = children if children is not None else []
self.name = Location(kwargs.get('location')).name
self._child_instances = None
def get_children(self):
"""Returns a list of XModuleDescriptor instances for the children of this module"""
if self._child_instances is None:
self._child_instances = [self.load_item(child) for child in self.children]
return self._child_instances
def get_xml(self): def get_xml(self):
''' For conversions between JSON and legacy XML representations. ''' For conversions between JSON and legacy XML representations.
......
...@@ -24,3 +24,4 @@ sympy ...@@ -24,3 +24,4 @@ sympy
newrelic newrelic
glob2 glob2
pymongo pymongo
-e common/lib/xmodule
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