Commit fa39e969 by Bridger Maxwell

Merge

parents d47d95ed 9619bf20
......@@ -108,8 +108,8 @@ class LoncapaModule(XModule):
return html
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)
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None, track_function=None):
XModule.__init__(self, xml, item_id, ajax_url, track_url, state, track_function)
self.attempts = 0
self.max_attempts = None
......@@ -222,22 +222,32 @@ class LoncapaModule(XModule):
def check_problem(self, get):
''' Checks whether answers to a problem are correct, and
returns a map of correct/incorrect answers'''
event_info = dict()
event_info['state'] = self.lcp.get_state()
event_info['filename'] = self.filename
answers=dict()
# input_resistor_1 ==> resistor_1
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
event_info['answers']=answers
# Too late. Cannot submit
if self.closed():
event_info['failure']='closed'
self.tracker('save_problem_check_fail', event_info)
print "cp"
raise Http404
# Problem submitted. Student should reset before checking
# again.
if self.lcp.done and self.rerandomize:
event_info['failure']='unreset'
self.tracker('save_problem_check_fail', event_info)
print "cpdr"
raise Http404
answers=dict()
# input_resistor_1 ==> resistor_1
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
try:
old_state = self.lcp.get_state()
lcp_id = self.lcp.problem_id
......@@ -262,35 +272,56 @@ class LoncapaModule(XModule):
js=json.dumps({'correct_map' : correct_map,
'success' : success})
event_info['correct_map']=correct_map
event_info['success']=success
self.tracker('save_problem_check', event_info)
return js
def save_problem(self, get):
event_info = dict()
event_info['state'] = self.lcp.get_state()
event_info['filename'] = self.filename
answers=dict()
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
event_info['answers'] = answers
# Too late. Cannot submit
if self.closed():
print "sp"
event_info['failure']='closed'
self.tracker('save_problem_fail', event_info)
return "Problem is closed"
# Problem submitted. Student should reset before saving
# again.
if self.lcp.done and self.rerandomize:
print "spdr"
event_info['failure']='done'
self.tracker('save_problem_fail', event_info)
return "Problem needs to be reset prior to save."
answers=dict()
for key in get:
answers['_'.join(key.split('_')[1:])]=get[key]
self.lcp.student_answers=answers
self.tracker('save_problem_fail', event_info)
return json.dumps({'success':True})
def reset_problem(self, get):
''' Changes problem state to unfinished -- removes student answers,
and causes problem to rerender itself. '''
event_info = dict()
event_info['old_state']=self.lcp.get_state()
event_info['filename']=self.filename
if self.closed():
event_info['failure']='closed'
self.tracker('reset_problem_fail', event_info)
return "Problem is closed"
if not self.lcp.done:
event_info['failure']='not_done'
self.tracker('reset_problem_fail', event_info)
return "Refresh the page and make an attempt before resetting."
self.lcp.done=False
......@@ -307,8 +338,7 @@ class LoncapaModule(XModule):
filename=settings.DATA_DIR+"problems/"+self.filename+".xml"
self.lcp=LoncapaProblem(filename, self.item_id, self.lcp.get_state())
event_info = self.lcp.get_state()
event_info.update({'filename':filename})
#server_track(request, 'reset_problem', event_info)
event_info['new_state']=self.lcp.get_state()
self.tracker('reset_problem', event_info)
return json.dumps(self.get_problem_html(encapsulate=False))
......@@ -25,8 +25,8 @@ class HtmlModule(XModule):
textlist=[i for i in textlist if type(i)==str]
return "".join(textlist)
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)
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None, track_function=None):
XModule.__init__(self, xml, item_id, ajax_url, track_url, state, track_function)
xmltree=etree.fromstring(xml)
self.filename = None
filename_l=xmltree.xpath("/html/@filename")
......
......@@ -10,6 +10,7 @@ from auth.models import UserProfile
from django.shortcuts import redirect
import StringIO
import track.views
from django.http import Http404
......@@ -35,6 +36,11 @@ modx_modules={'problem':capa_module.LoncapaModule,
'html':html_module.HtmlModule,
'schematic':schematic_module.SchematicModule}
def make_track_function(request):
def f(event_type, event):
return track.views.server_track(request, event_type, event, page='x_module')
return f
def modx_dispatch(request, module=None, dispatch=None, id=None):
''' Generic view for extensions. '''
# Grab the student information for the module from the database
......@@ -60,7 +66,8 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
instance=modx_modules[module](xml,
s.module_id,
ajax_url=ajax_url,
state=s.state)
state=s.state,
track_function = make_track_function(request))
# Let the module handle the AJAX
ajax_return=instance.handle_ajax(dispatch, request.POST)
# Save the state back to the database
......@@ -153,7 +160,8 @@ def render_x_module(request, xml_module):
instance=module_class(xml_module.toxml(),
module_id,
ajax_url=ajax_url,
state=state)
state=state,
track_function = make_track_function(request))
# If instance wasn't already in the database, create it
if len(s) == 0:
......
......@@ -46,8 +46,8 @@ class VideoModule(XModule):
def get_destroy_js(self):
return "videoDestroy();"
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)
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None, track_function=None):
XModule.__init__(self, xml, item_id, ajax_url, track_url, state, track_function)
print state
if state!=None and "time" not in json.loads(state):
self.video_time = 0
def dummy_track(event_type, event):
pass
class XModule(object):
''' Implements a generic learning module.
Initialized on access with __init__, first time with state=None, and
......@@ -36,10 +39,11 @@ class XModule(object):
get is a dictionary-like object '''
return ""
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None):
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None, track_function=None):
''' In most cases, you must pass state or xml'''
self.xml=xml
self.item_id=item_id
self.ajax_url=ajax_url
self.track_url=track_url
self.state=state
self.tracker=track_function
......@@ -12,6 +12,7 @@ urlpatterns = ('',
url(r'^event$', 'track.views.user_track'),
url(r'^t/(?P<template>[^/]*)$', 'static_template_view.views.index'),
url(r'^logout$', 'auth.views.logout_user'),
url(r'^info$', 'util.views.info'),
url(r'^login$', 'auth.views.login_user'),
url(r'^login/(?P<error>[^/]*)$', 'auth.views.login_user'),
url(r'^create_account$', 'auth.views.create_account'),
......
......@@ -48,3 +48,6 @@ def send_feedback(request):
fail_silently = False
)
return HttpResponse(json.dumps({'success':True}))
def info(request):
return render_to_response("info.html", {})
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