Commit 9fdbdd3b by Calen Pennington

Merge pull request #71 from MITx/pmitros/modular-refactor

Pmitros/modular refactor
parents b3f02811 2c2072da
......@@ -66,10 +66,8 @@ class GenericResponse(object):
#-----------------------------------------------------------------------------
class MultipleChoiceResponse(GenericResponse):
'''
Example:
<multiplechoiceresponse direction="vertical" randomize="yes">
# TODO: handle direction and randomize
snippets = [{'snippet': '''<multiplechoiceresponse direction="vertical" randomize="yes">
<choicegroup type="MultipleChoice">
<choice location="random" correct="false"><span>`a+b`<br/></span></choice>
<choice location="random" correct="true"><span><math>a+b^2</math><br/></span></choice>
......@@ -77,10 +75,7 @@ class MultipleChoiceResponse(GenericResponse):
<choice location="bottom" correct="false"><math>a+b+d</math></choice>
</choicegroup>
</multiplechoiceresponse>
TODO: handle direction and randomize
'''
'''}]
def __init__(self, xml, context, system=None):
self.xml = xml
self.correct_choices = xml.xpath('//*[@id=$id]//choice[@correct="true"]',
......@@ -218,8 +213,9 @@ class NumericalResponse(GenericResponse):
class CustomResponse(GenericResponse):
'''
Custom response. The python code to be run should be in <answer>...</answer>. Example:
'''
<customresponse>
snippets = [{'snippet': '''<customresponse>
<startouttext/>
<br/>
Suppose that \(I(t)\) rises from \(0\) to \(I_S\) at a time \(t_0 \neq 0\)
......@@ -237,9 +233,10 @@ class CustomResponse(GenericResponse):
if not(r=="IS*u(t-t0)"):
correct[0] ='incorrect'
</answer>
</customresponse>
</customresponse>'''}]
Alternatively, the check function can be defined in <script>...</script> Example:
'''Footnote: the check function can also be defined in <script>...</script> Example:
<script type="loncapa/python"><![CDATA[
......
......@@ -218,6 +218,7 @@ def section_file(user, section, coursename=None, dironly=False):
Given a user and the name of a section, return that section.
This is done specific to each course.
If dironly=True then return the sections directory.
TODO: This is a bit weird; dironly should be scrapped.
'''
filename = section+".xml"
......
......@@ -20,7 +20,9 @@ class Module(XModule):
@classmethod
def get_xml_tags(c):
return ["sequential", 'tab']
obsolete_tags = ["sequential", 'tab']
modern_tags = ["videosequence"]
return obsolete_tags + modern_tags
def get_html(self):
self.render()
......@@ -81,7 +83,8 @@ class Module(XModule):
params={'items':self.contents,
'id':self.item_id,
'position': self.position,
'titles':self.titles}
'titles':self.titles,
'tag':self.xmltree.tag}
# TODO/BUG: Destroy JavaScript should only be called for the active view
# This calls it for all the views
......@@ -90,7 +93,7 @@ class Module(XModule):
# IDs to sequences.
destroy_js="".join([e['destroy_js'] for e in self.contents if 'destroy_js' in e])
if self.xmltree.tag == 'sequential':
if self.xmltree.tag in ['sequential', 'videosequence']:
self.init_js=js+render_to_string('seq_module.js',params)
self.destroy_js=destroy_js
self.content=render_to_string('seq_module.html',params)
......
......@@ -13,7 +13,7 @@ class Module(XModule):
@classmethod
def get_xml_tags(c):
return ["vertical"]
return ["vertical", "problemset"]
def get_html(self):
return render_to_string('vert_module.html',{'items':self.contents})
......
......@@ -17,6 +17,39 @@ class XModule(object):
''' Tags in the courseware file guaranteed to correspond to the module '''
return []
@classmethod
def get_usage_tags(c):
''' We should convert to a real module system
For now, this tells us whether we use this as an xmodule, a CAPA response type
or a CAPA input type '''
return ['xmodule']
def __init__(self, system = None, xml = None, item_id = None,
json = None, track_url=None, state=None):
''' In most cases, you must pass state or xml'''
if not item_id:
raise ValueError("Missing Index")
if not xml and not json:
raise ValueError("xml or json required")
if not system:
raise ValueError("System context required")
self.xml = xml
self.json = json
self.item_id = item_id
self.state = state
if system:
## These are temporary; we really should go
## through self.system.
self.ajax_url = system.ajax_url
self.tracker = system.track_function
self.filestore = system.filestore
self.render_function = system.render_function
self.system = system
### Functions used in the LMS
def get_completion(self):
''' This is mostly unimplemented.
It gives a progress indication -- e.g. 30 minutes of 1.5 hours watched. 3 of 5 problems done, etc. '''
......@@ -45,6 +78,12 @@ class XModule(object):
'''
return "Unimplemented"
# TODO:
# def get_header_js(self):
# ''' Filename of common js that needs to be included in the header
# '''
# raise NotImplementedError
def get_init_js(self):
''' JavaScript code to be run when problem is shown. Be aware
that this may happen several times on the same page
......@@ -63,17 +102,30 @@ class XModule(object):
get is a dictionary-like object '''
return ""
def __init__(self, system, xml, item_id, track_url=None, state=None):
''' In most cases, you must pass state or xml'''
self.xml = xml
self.item_id = item_id
self.state = state
### Functions used in the CMS
def get_xml(self):
''' For conversions between JSON and legacy XML representations.
'''
if self.xml:
return self.xml
else:
raise NotImplementedError
if system:
## These are temporary; we really should go
## through self.system.
self.ajax_url = system.ajax_url
self.tracker = system.track_function
self.filestore = system.filestore
self.render_function = system.render_function
self.system = system
def get_json(self):
''' For conversions between JSON and legacy XML representations.
'''
if self.json:
raise NotImplementedError
return self.json # TODO: Return context as well -- files, etc.
else:
raise NotImplementedError
def handle_cms_json(self):
raise NotImplementedError
def render(self, size):
''' Size: [thumbnail, small, full]
Small ==> what we drag around
Full ==> what we edit
'''
raise NotImplementedError
......@@ -60,7 +60,6 @@ def profile(request, student_id = None):
if student_id == None:
student = request.user
else:
print content_parser.user_groups(request.user)
if 'course_admin' not in content_parser.user_groups(request.user):
raise Http404
student = User.objects.get( id = int(student_id))
......@@ -184,16 +183,28 @@ def index(request, course=None, chapter="Using the System", section="Hints"):
log.exception("Unable to parse courseware xml")
return render_to_response('courseware-error.html', {})
dom_module = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]/*[1]",
#dom_module = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]/*[1]",
dom_module = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]",
course=course, chapter=chapter, section=section)
#print "DM", dom_module
if len(dom_module) == 0:
module_wrapper = None
else:
module_wrapper = dom_module[0]
if module_wrapper == None:
module = None
elif module_wrapper.get("src"):
module = content_parser.section_file(user=user, section=module_wrapper.get("src"), coursename=course)
else:
module = dom_module[0]
module = etree.XML(etree.tostring(module_wrapper[0])) # Copy the element out of the tree
module_ids = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]//@id",
course=course, chapter=chapter, section=section)
module_ids = []
if module:
module_ids = module.xpath("//@id",
course=course, chapter=chapter, section=section)
if user.is_authenticated():
module_object_preload = list(StudentModule.objects.filter(student=user,
......@@ -305,7 +316,7 @@ def quickedit(request, id=None):
Maybe this should be moved into capa/views.py
Or this should take a "module" argument, and the quickedit moved into capa_module.
'''
print "WARNING: UNDEPLOYABLE CODE. FOR DEV USE ONLY."
print "WARNING: UNDEPLOYABLE CODE. FOR CONTENT DEV USE ONLY."
print "In deployed use, this will only edit on one server"
print "We need a setting to disable for production where there is"
print "a load balanacer"
......
......@@ -53,7 +53,7 @@ function disablePrev() {
function ${ id }goto(i) {
log_event("seq_goto", {'old':${id}loc, 'new':i,'id':'${id}'});
postJSON('${ MITX_ROOT_URL }/modx/sequential/${ id }/goto_position',
postJSON('${ MITX_ROOT_URL }/modx/${tag}/${ id }/goto_position',
{'position' : i });
if (${ id }loc!=-1)
......
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