Commit 9ac4ac8a by Piotr Mitros

Minor layout fixes, basic schematic entry support, XPath for XML

parent 61880f5a
......@@ -76,15 +76,12 @@ class LoncapaProblem():
# Loop through the nodes of the problem, and
for e in dom.childNodes:
# print e, ot
#
if e.localName=='script':
#print e.childNodes[0].data
exec e.childNodes[0].data in g,self.context
elif e.localName=='endouttext':
ot=False
elif ot:
# print e, "::", e.toxml()
e.writexml(buf)
elif e.localName=='startouttext':
ot=True
......@@ -98,7 +95,6 @@ class LoncapaProblem():
self.text=buf.getvalue()
self.text=self.contextualize_text(self.text)
# print self.text
self.filename=filename
done=False
......@@ -134,8 +130,6 @@ class LoncapaProblem():
if id not in answers:
correct_map[id]='incorrect' # Should always be there
else:
#correct_map[id]=self.grade_nr(self.questions[key],
# self.answers[id])
grader=self.graders[self.questions[key]['type']]
print grader
correct_map[id]=grader(self, self.questions[key],
......@@ -143,23 +137,21 @@ class LoncapaProblem():
self.correct_map=correct_map
return correct_map
def handle_schem(self, element):
height = 480
width = 640
self.lid+=1
id=str(self.gid)+'_'+str(self.lid)
html='<input type="hidden" class="schematic" name="{id}" '+ \
'height="{height}" width="{width}" value="{value}">'
return html.format(height=height, width=width, id=id, value="")
def grade_schem(self, element):
return "correct"
## Internal methods
# def number(self,text):
# ''' Convert a number to a float, understanding suffixes '''
# try:
# text.strip()
# suffixes={'%':0.01,'k':1e3,'M':1e6,'G':1e9,'T':1e12,'P':1e15,
# 'E':1e18,'Z':1e21,'Y':1e24,'c':1e-2,'m':1e-3,'u':1e-6,
# 'n':1e-9,'p':1e-12,'f':1e-15,'a':1e-18,'z':1e-21,'y':1e-24}
# if text[-1] in suffixes:
# return float(text[:-1])*suffixes[text[-1]]
# else:
# return float(text)
# except:
# return 0 # TODO: Better error handling?
def grade_nr(self, question, answer):
error = abs(evaluator({},{},answer) - question['answer'])
allowed_error = abs(question['answer']*question['tolerance'])
......@@ -255,9 +247,11 @@ class LoncapaProblem():
return html
graders={'numericalresponse':grade_nr,
'formularesponse':grade_fr}
'formularesponse':grade_fr,
'schematicresponse':grade_schem}
handlers={'numericalresponse':handle_nr,
'formularesponse':handle_fr}
'formularesponse':handle_fr,
'schematicresponse':handle_schem}
def contextualize_text(self, text):
''' Takes a string with variables. E.g. $a+$b.
......
from django.conf import settings
from xml.dom.minidom import parse, parseString
import libxml2
''' This file will eventually form an abstraction layer between the
course XML file and the rest of the system.
TODO: Shift everything from xml.dom.minidom to XPath (or XQuery)
'''
def module_xml(module, id_tag, module_id):
''' Get XML for a module based on module and module_id. Assumes
module occurs once in course.xml. '''
doc = libxml2.parseFile(settings.DATA_DIR+'course.xml')
# Sanitize input
if not module.isalnum():
raise Exception("Module is not alphanumeric")
if not module_id.isalnum():
raise Exception("Module ID is not alphanumeric")
xpath_search='//*/{module}[@{id_tag} = "{id}"]'.format(module=module,
id_tag=id_tag,
id=module_id)
result_set=doc.xpathEval(xpath_search)
if len(result_set)>1:
print "WARNING: Potentially malformed course file", module, module_id
if len(result_set)==0:
return None
return result_set[0].serialize()
def toc_from_xml(active_chapter,active_section):
dom=parse(settings.DATA_DIR+'course.xml')
......
......@@ -18,7 +18,6 @@ class HtmlModule(XModule):
return "html"
def get_html(self):
print "XX",self.item_id
return render_to_string(self.item_id, {'id': self.item_id})
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None):
......
......@@ -52,7 +52,6 @@ class StudentModule(models.Model):
module_id = models.CharField(max_length=255) # Filename for homeworks, etc.
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
xml = models.TextField(blank=True)
class Meta:
unique_together = (('student', 'module_id', 'module_type'),)
......
......@@ -19,6 +19,7 @@ import urllib
import capa_module
import video_module
import html_module
import schematic_module
from models import StudentModule
......@@ -30,12 +31,6 @@ import content_parser
import uuid
#def html_module(request, module):
# ''' Show basic text
# '''
# template_source=module.getAttribute('filename')
# return {'content':render_to_string(template_source, {})}
def vertical_module(request, module):
''' Layout module which lays out content vertically.
'''
......@@ -86,7 +81,8 @@ def seq_module(request, module):
modx_modules={'problem':capa_module.LoncapaModule,
'video':video_module.VideoModule,
'html':html_module.HtmlModule}
'html':html_module.HtmlModule,
'schematic':schematic_module.SchematicModule}
def render_x_module(request, xml_module):
''' Generic module for extensions. This renders to HTML. '''
......@@ -117,8 +113,7 @@ def render_x_module(request, xml_module):
smod=StudentModule(student=request.user,
module_type = module_type,
module_id=module_id,
state=instance.get_state(),
xml=instance.xml)
state=instance.get_state())
# Grab content
content = {'content':instance.get_html(),
"destroy_js":instance.get_destroy_js(),
......@@ -130,8 +125,11 @@ def render_x_module(request, xml_module):
def modx_dispatch(request, module=None, dispatch=None, id=None):
''' Generic module for extensions. '''
s = StudentModule.objects.filter(module_type=module, student=request.user, module_id=id)
s = StudentModule.objects.filter(module_type=module,
student=request.user,
module_id=id)
if len(s) == 0:
print "ls404"
raise Http404
s=s[0]
......@@ -140,7 +138,16 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
ajax_url = '/modx/'+module+'/'+id+'/'
instance=modx_modules[module](s.xml, s.module_id, ajax_url=ajax_url, state=s.state)
id_tag=modx_modules[module].id_attribute
#print "X",s.xml, "Y",content_parser.module_xml(module, id_tag, id)
print
xml = content_parser.module_xml(module, id_tag, id)
instance=modx_modules[module](xml,
s.module_id,
ajax_url=ajax_url,
state=s.state)
html=instance.handle_ajax(dispatch, request.GET)
s.state=instance.get_state()
s.grade=instance.get_score()['score']
......@@ -153,8 +160,8 @@ module_types={'video':render_x_module,
'vertical':vertical_module,
'sequential':seq_module,
'problem':render_x_module,
'schematic':render_x_module
}
#'lab':lab_module,
def render_module(request, module):
''' Generic dispatch for internal modules. '''
......@@ -162,4 +169,5 @@ def render_module(request, module):
return {"content":""}
if str(module.localName) in module_types:
return module_types[module.localName](request, module)
print "rm404"
raise Http404
from x_module import XModule
from xml.dom.minidom import parse, parseString
import json
## TODO: Abstract out from Django
from django.conf import settings
from djangomako.shortcuts import render_to_response, render_to_string
class SchematicModule(XModule):
id_attribute = 'id'
def get_state(self):
return json.dumps({ })
def get_xml_tags():
return "schematic"
def get_html(self):
return '<input type="hidden" class="schematic" name="{item_id}" height="480" width="640">'.format(item_id=self.item_id)
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None):
XModule.__init__(self, xml, item_id, ajax_url, track_url, state)
......@@ -38,15 +38,22 @@
// add ourselves to the tasks that get performed when window is loaded
window.onload = add_schematic_handler(window.onload);
function update_schematics() {
// set up each schematic on the page
var schematics = document.getElementsByClassName('schematic');
for (var i = schematics.length - 1; i >= 0; i--)
if (schematics[i].getAttribute("loaded") != "true") {
new Schematic(schematics[i]);
schematics[i].setAttribute("loaded","true");
}
}
function add_schematic_handler(other_onload) {
return function() {
// execute othe onload functions first
if (other_onload) other_onload();
// set up each schematic on the page
var schematics = document.getElementsByClassName('schematic');
for (var i = schematics.length - 1; i >= 0; i--)
new Schematic(schematics[i]);
update_schematics();
}
}
......
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