Commit b0c616e2 by Valera Rozuvan

Merge branch 'feature/alex/poll-storage-model' of github.com:MITx/mitx into…

Merge branch 'feature/alex/poll-storage-model' of github.com:MITx/mitx into feature/alex/poll-storage-model
parents 5ef584a3 bbc62e83
# -*- coding: utf-8 -*-
import json import json
import logging import logging
from lxml import etree
from pkg_resources import resource_string
from xmodule.x_module import XModule from xmodule.x_module import XModule
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.seq_module import SequenceDescriptor from xmodule.seq_module import SequenceDescriptor
from xblock.core import List, String, Scope, Integer from xblock.core import String, Scope
from lxml import etree from xmodule.modulestore.exceptions import ItemNotFoundError
from pkg_resources import resource_string
log = logging.getLogger('mitx.' + __name__) log = logging.getLogger('mitx.' + __name__)
class ConditionalModule(XModule): class ConditionalModule(XModule):
''' """
Blocks child module from showing unless certain conditions are met. Blocks child module from showing unless certain conditions are met.
Example: Example:
...@@ -19,7 +24,7 @@ class ConditionalModule(XModule): ...@@ -19,7 +24,7 @@ class ConditionalModule(XModule):
<video url_name="secret_video" /> <video url_name="secret_video" />
</conditional> </conditional>
''' """
js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'), js = {'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee'),
resource_string(__name__, 'js/src/conditional/display.coffee'), resource_string(__name__, 'js/src/conditional/display.coffee'),
...@@ -34,7 +39,7 @@ class ConditionalModule(XModule): ...@@ -34,7 +39,7 @@ class ConditionalModule(XModule):
contents = String(scope=Scope.content) contents = String(scope=Scope.content)
show_modules = String(scope=Scope.content) show_modules = String(scope=Scope.content)
conditions_map = { 'poll_answer': 'poll_answer', conditions_map = {'poll_answer': 'poll_answer',
'compeleted': 'is_competed()'} 'compeleted': 'is_competed()'}
def _get_required_modules(self): def _get_required_modules(self):
...@@ -73,7 +78,7 @@ class ConditionalModule(XModule): ...@@ -73,7 +78,7 @@ class ConditionalModule(XModule):
if not hasattr(module, self.conditions_map.get(self.condition)): if not hasattr(module, self.conditions_map.get(self.condition)):
raise Exception('Error in conditional module: required module %s has no poll_answer field' % module) raise Exception('Error in conditional module: required module %s has no poll_answer field' % module)
module_value = getattr(module, self.conditions_map.get(self.condition)) module_value = getattr(module, self.conditions_map.get(self.condition))
answer = self.descriptor.xml_attributes.get(self.condition) answer = self.descriptor.xml_attributes.get(self.condition)
if answer == 'unanswered' and module_value: if answer == 'unanswered' and module_value:
return False return False
if module_value != answer: if module_value != answer:
...@@ -93,7 +98,7 @@ class ConditionalModule(XModule): ...@@ -93,7 +98,7 @@ class ConditionalModule(XModule):
}) })
def _get_modules_to_show(self): def _get_modules_to_show(self):
to_show = [tuple(x.strip().split('/',1)) for x in self.show_modules.split(';')] to_show = [tuple(x.strip().split('/', 1)) for x in self.show_modules.split(';')]
self.modules_to_show = [] self.modules_to_show = []
for (tag, name) in to_show: for (tag, name) in to_show:
loc = self.location.dict() loc = self.location.dict()
...@@ -101,12 +106,10 @@ class ConditionalModule(XModule): ...@@ -101,12 +106,10 @@ class ConditionalModule(XModule):
loc['name'] = name loc['name'] = name
self.modules_to_show.append(Location(loc)) self.modules_to_show.append(Location(loc))
def handle_ajax(self, dispatch, post): def handle_ajax(self, dispatch, post):
''' '''
This is called by courseware.moduleodule_render, to handle an AJAX call. This is called by courseware.moduleodule_render, to handle an AJAX call.
''' '''
# import ipdb; ipdb.set_trace()
#log.debug('conditional_module handle_ajax: dispatch=%s' % dispatch) #log.debug('conditional_module handle_ajax: dispatch=%s' % dispatch)
if not self.is_condition_satisfied(): if not self.is_condition_satisfied():
context = {'module': self} context = {'module': self}
...@@ -114,19 +117,18 @@ class ConditionalModule(XModule): ...@@ -114,19 +117,18 @@ class ConditionalModule(XModule):
return json.dumps({'html': [html]}) return json.dumps({'html': [html]})
if self.contents is None: if self.contents is None:
# import ipdb; ipdb.set_trace()
# self.contents = [child.get_html() for child in self.get_display_items()] # self.contents = [child.get_html() for child in self.get_display_items()]
# self.contents = [self.system.get_module(x).get_html() for x in self.modules_to_show] # self.contents = [self.system.get_module(x).get_html() for x in self.modules_to_show]
self.contents = [self.system.get_module(child_descriptor.location).get_html() self.contents = [self.system.get_module(child_descriptor.location).get_html()
for child_descriptor in self.descriptor.get_children()] for child_descriptor in self.descriptor.get_children()]
html = self.contents html = self.contents
#log.debug('rendered conditional module %s' % str(self.location)) #log.debug('rendered conditional module %s' % str(self.location))
return json.dumps({'html': html}) return json.dumps({'html': html})
class ConditionalDescriptor(SequenceDescriptor): class ConditionalDescriptor(SequenceDescriptor):
''' TODO check exports''' """TODO: add docs."""
module_class = ConditionalModule module_class = ConditionalModule
filename_extension = "xml" filename_extension = "xml"
...@@ -138,15 +140,14 @@ class ConditionalDescriptor(SequenceDescriptor): ...@@ -138,15 +140,14 @@ class ConditionalDescriptor(SequenceDescriptor):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(ConditionalDescriptor, self).__init__(*args, **kwargs) super(ConditionalDescriptor, self).__init__(*args, **kwargs)
# import ipdb; ipdb.set_trace() required_module_list = [(x.strip().split('/', 5)[4:6]) for x in
required_module_list = [(x.strip().split('/',5)[4:6]) for x in self.xml_attributes.get('source','').split(';')] self.xml_attributes.get('source', '').split(';')]
self.required_module_locations = [] self.required_module_locations = []
for (tag, name) in required_module_list: for (tag, name) in required_module_list:
loc = self.location.dict() loc = self.location.dict()
loc['category'] = tag loc['category'] = tag
loc['name'] = name loc['name'] = name
self.required_module_locations.append(Location(loc)) self.required_module_locations.append(Location(loc))
# import ipdb; ipdb.set_trace()
log.debug('ConditionalDescriptor required_module_locations=%s' % self.required_module_locations) log.debug('ConditionalDescriptor required_module_locations=%s' % self.required_module_locations)
def get_required_module_descriptors(self): def get_required_module_descriptors(self):
...@@ -156,19 +157,34 @@ class ConditionalDescriptor(SequenceDescriptor): ...@@ -156,19 +157,34 @@ class ConditionalDescriptor(SequenceDescriptor):
@classmethod @classmethod
def definition_from_xml(cls, xml_object, system): def definition_from_xml(cls, xml_object, system):
def parse_show_tag(child):
"""Return list of valid module urls from <show> tag."""
urls = []
sources = child.get('sources')
if sources:
locations = [location.strip() for location in sources.split(';')]
for location in locations:
# Check valid location url.
if Location.is_valid(location):
try:
system.load_item(location)
urls.append(location)
except ItemNotFoundError:
pass
return urls
children = [] children = []
for child in xml_object: for child in xml_object:
if child.tag != 'show': if child.tag == 'show':
try: children.extend(parse_show_tag(child))
children.append(system.process_xml(etree.tostring(child)).location.url())
except Exception, e:
log.exception("Unable to load child when parsing Conditional. Continuing...")
if system.error_tracker is not None:
system.error_tracker("ERROR: " + str(e))
continue
else: else:
cls.show_modules = child.get('source') try:
return {'show_modules':''}, children descriptor = system.process_xml(etree.tostring(child))
module_url = descriptor.location.url()
children.append(module_url)
except:
log.exception("Unable to load child when parsing Conditional.")
return {}, children
def definition_to_xml(self, resource_fs): def definition_to_xml(self, resource_fs):
xml_object = etree.Element('sequential') xml_object = etree.Element('sequential')
......
...@@ -70,8 +70,13 @@ class PollModule(XModule): ...@@ -70,8 +70,13 @@ class PollModule(XModule):
'total': sum(self.poll_answers.values()), 'total': sum(self.poll_answers.values()),
'callback': {'objectName': 'Conditional'} 'callback': {'objectName': 'Conditional'}
}) })
# return error message elif dispatch == 'get_state':
return json.dumps({'error': 'Unknown Command!'}) return json.dumps({'poll_answer': self.poll_answer,
'poll_answers': self.poll_answers,
'total': sum(self.poll_answers.values())
})
else: # return error message
return json.dumps({'error': 'Unknown Command!'})
def get_html(self): def get_html(self):
"""Renders parameters to template.""" """Renders parameters to template."""
......
...@@ -179,6 +179,12 @@ end ...@@ -179,6 +179,12 @@ end
TEST_TASK_DIRS = [] TEST_TASK_DIRS = []
task :fastlms do
# this is >2 times faster that rake [lms], and does not need web, good for local dev
django_admin = ENV['DJANGO_ADMIN_PATH'] || select_executable('django-admin.py', 'django-admin')
sh("#{django_admin} runserver --traceback --settings=lms.envs.dev --pythonpath=.")
end
[:lms, :cms].each do |system| [:lms, :cms].each do |system|
report_dir = report_dir_path(system) report_dir = report_dir_path(system)
......
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