Read week headings from mongodb
This commit is contained in:
committed by
Matthew Mongeau
parent
31871a0548
commit
bb2910fce5
@@ -82,7 +82,7 @@ class Command(BaseCommand):
|
||||
def handle_list(e):
|
||||
if e.attrib.get("class", None) == "tutorials":
|
||||
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}
|
||||
|
||||
def handle_video(e):
|
||||
|
||||
@@ -3,11 +3,10 @@ from keystore.django import keystore
|
||||
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):
|
||||
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):
|
||||
self.update(location.list())
|
||||
|
||||
def url(self):
|
||||
return "i4x://{org}/{course}/{category}/{name}".format(**self.dict())
|
||||
return "{tag}://{org}/{course}/{category}/{name}".format(**self.dict())
|
||||
|
||||
def list(self):
|
||||
return [self.tag, self.org, self.course, self.category, self.name]
|
||||
@@ -54,10 +54,9 @@ class Location(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
|
||||
with the specified location.
|
||||
Returns an XModuleDescriptor instance for the item at location
|
||||
|
||||
If no object is found at that location, raises keystore.exceptions.ItemNotFoundError
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import pymongo
|
||||
from . import KeyStore, Location
|
||||
from .exceptions import ItemNotFoundError, InsufficientSpecificationError
|
||||
from xmodule.x_module import XModuleDescriptor
|
||||
|
||||
|
||||
class MongoKeyStore(KeyStore):
|
||||
@@ -12,11 +13,22 @@ class MongoKeyStore(KeyStore):
|
||||
host=host,
|
||||
port=port
|
||||
)[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_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(
|
||||
('location.{key}'.format(key=key), val)
|
||||
for (key, val)
|
||||
@@ -25,7 +37,6 @@ class MongoKeyStore(KeyStore):
|
||||
)
|
||||
items = self.collection.find(
|
||||
query,
|
||||
fields={'children': True},
|
||||
sort=[('revision', pymongo.ASCENDING)],
|
||||
limit=1,
|
||||
)
|
||||
@@ -35,7 +46,7 @@ class MongoKeyStore(KeyStore):
|
||||
if items.count() == 0:
|
||||
raise ItemNotFoundError(location)
|
||||
|
||||
return items[0]['children']
|
||||
return XModuleDescriptor.load_from_json(items[0], self.get_item)
|
||||
|
||||
def create_item(self, location, editor):
|
||||
"""
|
||||
|
||||
@@ -35,9 +35,10 @@
|
||||
</header>
|
||||
|
||||
<ol>
|
||||
% for week in weeks:
|
||||
<li>
|
||||
<header>
|
||||
<h1><a href="#">Week 1</a></h1>
|
||||
<h1><a href="#">${week.name}</a></h1>
|
||||
<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 two:</strong> This is another goal for this week so that students have two things to learn</li>
|
||||
@@ -64,125 +65,7 @@
|
||||
<%include file="module-dropdown.html"/>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<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>
|
||||
%endfor
|
||||
<li>
|
||||
<header>
|
||||
<h1>Course Scratch Pad</h1>
|
||||
|
||||
@@ -95,3 +95,11 @@ class Module(XModule):
|
||||
self.position = int(system.get('position'))
|
||||
|
||||
self.rendered = False
|
||||
|
||||
|
||||
class CourseModuleDescriptor(XModuleDescriptor):
|
||||
pass
|
||||
|
||||
|
||||
class ChapterModuleDescriptor(XModuleDescriptor):
|
||||
pass
|
||||
|
||||
14
common/lib/xmodule/setup.py
Normal file
14
common/lib/xmodule/setup.py
Normal file
@@ -0,0 +1,14 @@
|
||||
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",
|
||||
]
|
||||
}
|
||||
)
|
||||
@@ -1,8 +1,34 @@
|
||||
from lxml import etree
|
||||
import pkg_resources
|
||||
import logging
|
||||
from keystore import Location
|
||||
|
||||
log = logging.getLogger('mitx.' + __name__)
|
||||
|
||||
def dummy_track(event_type, event):
|
||||
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):
|
||||
''' Implements a generic learning module.
|
||||
Initialized on access with __init__, first time with state=None, and
|
||||
@@ -24,8 +50,8 @@ class XModule(object):
|
||||
or a CAPA input type '''
|
||||
return ['xmodule']
|
||||
|
||||
def get_name():
|
||||
name = self.__xmltree.get(name)
|
||||
def get_name(self):
|
||||
name = self.__xmltree.get('name')
|
||||
if name:
|
||||
return name
|
||||
else:
|
||||
@@ -98,15 +124,42 @@ class XModule(object):
|
||||
return ""
|
||||
|
||||
|
||||
class XModuleDescriptor(object):
|
||||
def __init__(self, xml = None, json = None):
|
||||
if not xml and not json:
|
||||
raise "XModuleDescriptor must be initalized with XML or JSON"
|
||||
if not xml:
|
||||
raise NotImplementedError("Code does not have support for JSON yet")
|
||||
|
||||
self.xml = xml
|
||||
self.json = json
|
||||
class XModuleDescriptor(Plugin):
|
||||
|
||||
entry_point = "xmodule.v1"
|
||||
|
||||
@staticmethod
|
||||
def load_from_json(json_data, load_item):
|
||||
class_ = XModuleDescriptor.load_class(json_data['location']['category'])
|
||||
return class_.from_json(json_data, load_item)
|
||||
|
||||
@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):
|
||||
''' For conversions between JSON and legacy XML representations.
|
||||
|
||||
@@ -27,3 +27,4 @@ pymongo
|
||||
django_nose
|
||||
nosexcover
|
||||
rednose
|
||||
-e common/lib/xmodule
|
||||
|
||||
Reference in New Issue
Block a user