Laying ground work for formula support. Adding Anant's content

This commit is contained in:
Piotr Mitros
2011-12-15 07:51:07 -05:00
parent c524e36606
commit a8037f03e5
11 changed files with 123 additions and 25 deletions

View File

@@ -2,3 +2,7 @@ syntax: glob
*.pyc
*~
database.sqlite
courseware/static/js/mathjax/*
syntax: regexp

View File

@@ -3,6 +3,10 @@ from django.contrib.auth.models import User
import uuid
class UserProfile(models.Model):
## CRITICAL TODO/SECURITY
# Sanitize all fields.
# This is not visible to other users, but could introduce holes
# later
user = models.ForeignKey(User, unique=True, db_index=True)
name = models.TextField(blank=True)
language = models.TextField(blank=True)

View File

@@ -46,6 +46,22 @@ def logout_user(request):
logout(request)
return redirect('/')
def change_setting(request):
if not request.user.is_authenticated():
return redirect('/')
up=UserProfile.objects.get(user=request.user)
if 'location' in request.GET:
print "loc"
up.location=request.GET['location']
if 'language' in request.GET:
print "lang"
up.language=request.GET['language']
up.save()
return HttpResponse(json.dumps({'success':True,
'language':up.language,
'location':up.location,}))
def create_account(request):
js={'success':False}
# Confirm we have a properly formed request

View File

@@ -49,7 +49,7 @@ class LoncapaModule(XModule):
html = '<div id="main_{id}">'.format(id=self.item_id)+html+"</div>"
return html
def get_js(self):
def get_init_js(self):
return ""
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None):

View File

@@ -37,7 +37,6 @@ class LoncapaProblem():
seed will provide the random seed. Alternatively, passing
context will bypass all script execution, and use the
given execution context. '''
print "!!",filename, id
if state!=None:
state=json.loads(state)
else:
@@ -65,25 +64,36 @@ class LoncapaProblem():
g={'random':random,'numpy':numpy,'math':math,'scipy':scipy}
# Buffer stores HTML for problem
buf=StringIO.StringIO()
ot=False ## Are we in an outtext context?
# 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
if e.localName=='endouttext':
elif e.localName=='endouttext':
ot=False
if ot:
elif ot:
print e, "::", e.toxml()
e.writexml(buf)
if e.localName=='startouttext':
elif e.localName=='startouttext':
ot=True
if e.localName in self.handlers:
elif e.localName in self.handlers:
problem=self.handlers[e.localName](self,e)
buf.write(problem)
elif e.localName==None:
pass
else:
raise Exception("ERROR: UNRECOGNIZED XML"+e.localName)
self.text=buf.getvalue()
self.text=self.contextualize_text(self.text)
print self.text
self.filename=filename
done=False

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,18 @@
// Things to abstract out to another file
function postJSON(url, data, callback, csrf) {
$.ajax({
url: url,
dataType: 'json',
data: data,
success: callback
});
}
var global=5;
// Video player
var load_id = 0;
function caption_at(index) {
@@ -92,7 +107,16 @@ function onYouTubePlayerReady(playerId) {
}
function videoDestroy() {
load_id = 0;
// TODO/BUG: Figure out why removeEventListener doesn't work
ytplayer.removeEventListener("onStateChange", "onytplayerStateChange");
ytplayer.removeEventListener("onError", "onPlayerError");
ytplayer = false;
}
function log_event(e) {
// CRITICAL TODO: Change to AJAX
//$("#eventlog").append("<br>");
//$("#eventlog").append(JSON.stringify(e));
window['console'].log(JSON.stringify(e));

View File

@@ -95,7 +95,7 @@ def render_accordion(request,course,chapter,section):
['course_name',course],
['format_string',format_string]]+ \
template_imports.items())
return {'js':render_to_string('accordion_init.js',context),
return {'init_js':render_to_string('accordion_init.js',context),
'content':render_to_string('accordion.html',context)}
def video_mod(request, module):
@@ -103,7 +103,7 @@ def video_mod(request, module):
OBSOLETE. Remove once x_module version confirmed
'''
id=module.getAttribute('youtube')
return {'js':render_to_string('video_init.js',{'id':id}),
return {'init_js':render_to_string('video_init.js',{'id':id}),
'content':render_to_string('video.html',{'id':id})}
def html_module(request, module):
@@ -118,9 +118,9 @@ def tab_module(request, module):
contents=[(e.getAttribute("name"),render_module(request, e)) \
for e in module.childNodes \
if e.nodeType==1]
js="".join([e[1]['js'] for e in contents if 'js' in e[1]])
js="".join([e[1]['init_js'] for e in contents if 'init_js' in e[1]])
return {'js':render_to_string('tab_module.js',{'tabs':contents})+js,
return {'init_js':render_to_string('tab_module.js',{'tabs':contents})+js,
'content':render_to_string('tab_module.html',{'tabs':contents})}
def vertical_module(request, module):
@@ -129,9 +129,9 @@ def vertical_module(request, module):
contents=[(e.getAttribute("name"),render_module(request, e)) \
for e in module.childNodes \
if e.nodeType==1]
js="".join([e[1]['js'] for e in contents if 'js' in e[1]])
js="".join([e[1]['init_js'] for e in contents if 'init_js' in e[1]])
return {'js':js,
return {'init_js':js,
'content':render_to_string('vert_module.html',{'items':contents})}
def seq_module(request, module):
@@ -141,22 +141,28 @@ def seq_module(request, module):
# jsonify contents so it can be embedded in a js array
# We also need to split </script> tags so they don't break
# mid-string
if 'js' not in m: m['js']=""
if 'init_js' not in m: m['init_js']=""
content=json.dumps(m['content'])
content=content.replace('</script>', '<"+"/script>')
return {'content':content, 'js':m['js']}
return {'content':content, 'init_js':m['init_js']}
contents=[(e.getAttribute("name"),j(render_module(request, e))) \
for e in module.childNodes \
if e.nodeType==1]
js="".join([e[1]['js'] for e in contents if 'js' in e[1]])
js="".join([e[1]['init_js'] for e in contents if 'init_js' in e[1]])
iid=uuid.uuid1().hex
return {'js':js+render_to_string('seq_module.js',{'items':contents,
'id':"seq"}),
'content':render_to_string('seq_module.html',{'items':contents,
'id':"seq"})}
params={'items':contents,
'id':"seq"}
print module.nodeName
if module.nodeName == 'sequential':
return {'init_js':js+render_to_string('seq_module.js',params),
'content':render_to_string('seq_module.html',params)}
if module.nodeName == 'tab':
return {'init_js':js+render_to_string('tab_module.js',params),
'content':render_to_string('tab_module.html',params)}
modx_modules={'problem':capa_module.LoncapaModule, 'video':video_module.VideoModule}
@@ -194,7 +200,7 @@ def render_x_module(request, xml_module):
xml=instance.xml)
# Grab content
content = {'content':instance.get_html(),
'js':instance.get_js()}
'init_js':instance.get_init_js()}
smod.save() # This may be optional (at least in the case of no instance in the dB)
@@ -221,7 +227,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
module_types={'video':render_x_module,
'html':html_module,
'tab':tab_module,
'tab':seq_module,
'vertical':vertical_module,
'sequential':seq_module,
'problem':render_x_module,
@@ -265,10 +271,10 @@ def index(request, course="6.002 Spring 2012", chapter="Using the System", secti
module=render_module(request, module)
if 'js' not in module:
module['js']=''
if 'init_js' not in module:
module['init_js']=''
context={'init':accordion['js']+module['js'],
context={'init':accordion['init_js']+module['init_js'],
'accordion':accordion['content'],
'content':module['content']}
return render_to_response('courseware.html', context)

View File

@@ -23,13 +23,16 @@ class XModule:
def get_html(self):
return "Unimplemented"
def get_js(self):
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
(e.g. student switching tabs). Common functions should be put
in the main course .js files for now. '''
return ""
def get_destroy_js(self):
return ""
def handle_ajax(self, dispatch, get):
''' dispatch is last part of the URL.
get is a dictionary-like object '''

View File

@@ -13,6 +13,7 @@ urlpatterns = patterns('',
url(r'^modx/(?P<module>[^/]*)/(?P<id>[^/]*)/(?P<dispatch>[^/]*)$', 'courseware.views.modx_dispatch'), #reset_problem'),
url(r'^courseware/$', 'courseware.views.index'),
url(r'^profile$', 'courseware.views.profile'),
url(r'^change_setting$', 'auth.views.change_setting'),
# url(r'^admin/', include('django.contrib.admin.urls')),
# url(r'^accounts/register/$', 'registration.views.register', {'success_url':'/accounts/register/complete'}),
# url(r'^accounts/', include('registration.urls')),