diff --git a/courseware/capa_module.py b/courseware/capa_module.py
index f841e764e4..c1a19229d1 100644
--- a/courseware/capa_module.py
+++ b/courseware/capa_module.py
@@ -34,8 +34,16 @@ class LoncapaModule(XModule):
html = self.lcp.get_html()
content={'name':self.name,
'html':html}
+ closed = False
+ if self.lcp.done:
+ check_button="Reset"
+ else:
+ check_button="Check"
html=render_to_string('problem.html',
- {'problem':content, 'id':self.filename, 'done':self.lcp.done})
+ {'problem':content,
+ 'id':self.filename,
+ 'check_button':check_button,
+ })
if encapsulate:
html = '
'.format(id=self.item_id)+html+"
"
return html
diff --git a/courseware/models.py b/courseware/models.py
index c3da838f0e..ea40eb42c2 100644
--- a/courseware/models.py
+++ b/courseware/models.py
@@ -44,7 +44,10 @@ class StudentModule(models.Model):
state = models.TextField(null=True, blank=True)
grade = models.FloatField(null=True, blank=True)
student = models.ForeignKey(User)
- MODULE_TYPES = (('problem','problem'),)
+ MODULE_TYPES = (('problem','problem'),
+ ('video','video'),
+ ('html','html'),
+ )
module_type = models.CharField(max_length=32, choices=MODULE_TYPES, default='problem')
module_id = models.CharField(max_length=255) # Filename for homeworks, etc.
created = models.DateTimeField(auto_now_add=True)
diff --git a/courseware/static/js/video_player.js b/courseware/static/js/video_player.js
index 299b18ecd7..7c1da780ce 100644
--- a/courseware/static/js/video_player.js
+++ b/courseware/static/js/video_player.js
@@ -1,4 +1,4 @@
-var load_id;
+var load_id = 0;
function caption_at(index) {
if (captions==0)
@@ -74,15 +74,20 @@ function setytplayerState(newState) {
// updateHTML("playerstate", newState);
}
+// Updates server with location in video so we can resume from the same place
+// IMPORTANT TODO: Load test
+// POSSIBLE FIX: Move to unload() event and similar
+var ajax_video=function(){};
+
function onYouTubePlayerReady(playerId) {
ytplayer = document.getElementById("myytplayer");
setInterval(updateytplayerInfo, 1000);
+ setInterval(ajax_video,1000);
ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
ytplayer.addEventListener("onError", "onPlayerError");
- if((typeof load_id != "undefined") && (load_id != null)) {
+ if((typeof load_id != "undefined") && (load_id != 0)) {
var id=load_id;
- load_id = null;
- loadNewVideo(id);
+ loadNewVideo(id, 0);
}
}
@@ -151,16 +156,20 @@ function updateytplayerInfo() {
// functions for the api calls
function loadNewVideo(id, startSeconds) {
- if (typeof ytplayer != "undefined") {
- ytplayer.loadVideoById(id, parseInt(startSeconds));
- } else {
- load_id = id;
- }
-
$.getJSON("/static/subs/"+id+".srt.sjson", function(data) {
captions=data;
});
-
+ load_id = id;
+ //if ((typeof ytplayer != "undefined") && (ytplayer.type=="application/x-shockwave-flash")) {
+ // Try it every time. If we fail, we want the error message for now.
+ // TODO: Add try/catch
+ try {
+ ytplayer.loadVideoById(id, parseInt(startSeconds));
+ load_id=0;
+ }
+ catch(e) {
+ window['console'].log(JSON.stringify(e));
+ }
}
function cueNewVideo(id, startSeconds) {
diff --git a/courseware/views.py b/courseware/views.py
index 7fbab1cedc..f69fe5bcb7 100644
--- a/courseware/views.py
+++ b/courseware/views.py
@@ -98,6 +98,7 @@ def render_accordion(request,course,chapter,section):
def video_mod(request, module):
''' Shows a video, with subtitles.
+ OBSOLETE. Remove once x_module version confirmed
'''
id=module.getAttribute('youtube')
return {'js':render_to_string('video_init.js',{'id':id}),
@@ -145,14 +146,14 @@ def seq_module(request, module):
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]])
return {'js':js+render_to_string('seq_module.js',{'items':contents}),
'content':render_to_string('seq_module.html',{'items':contents})}
-modx_modules={'problem':capa_module.LoncapaModule}#, 'video1':video_module.VideoModule}
+modx_modules={'problem':capa_module.LoncapaModule, 'video':video_module.VideoModule}
def render_x_module(request, xml_module):
''' Generic module for extensions. This renders to HTML. '''
@@ -160,28 +161,36 @@ def render_x_module(request, xml_module):
module_type=xml_module.nodeName
module_class=modx_modules[module_type]
module_id=xml_module.getAttribute(module_class.id_attribute)
- s = StudentModule.objects.filter(student=request.user, module_id=module_id)
+
+ # Grab state from database
+ s = StudentModule.objects.filter(student=request.user,
+ module_id=module_id,
+ module_type = module_type)
+ if len(s) == 0: # If nothing in the database...
+ state=None
+ else:
+ smod = s[0]
+ state = smod.state
+
+ # Create a new instance
+ instance=module_class(xml_module.toxml(),
+ module_id,
+ state=state)
+
+ # If instance wasn't already in the database, create it
if len(s) == 0:
- # If not, create one, and save it
- instance=module_class(xml_module.toxml(), module_id)
smod=StudentModule(student=request.user,
+ module_type = module_type,
module_id=module_id,
state=instance.get_state(),
xml=instance.xml)
- smod.save()
- elif len(s) == 1:
- # If so, render it
- s=s[0]
- instance=module_class(xml_module.toxml(),
- module_id,
- state=s.state)
- s.state=instance.get_state()
- s.save()
- else:
- raise Exception("Database is inconsistent (1).")
+ # Grab content
+ content = {'content':instance.get_html(),
+ 'js':instance.get_js()}
- return {'content':instance.get_html(),
- 'js':instance.get_js()}
+ smod.save() # This may be optional (at least in the case of no instance in the dB)
+
+ return content
def modx_dispatch(request, module=None, dispatch=None, id=None):
''' Generic module for extensions. This handles AJAX. '''
@@ -199,12 +208,13 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
s.save()
return HttpResponse(html)
-module_types={'video':video_mod,
+module_types={'video':render_x_module,
'html':html_module,
'tab':tab_module,
'vertical':vertical_module,
'sequential':seq_module,
- 'problem':render_x_module}
+ 'problem':render_x_module,
+ }
#'lab':lab_module,
def render_module(request, module):