Commit eca523e0 by Nimisha Asthagiri

Mobile API MA-7: Support A/B test and cohorted content

parent 091d6aeb
......@@ -9,22 +9,23 @@ def yield_dynamic_descriptor_descendents(descriptor, module_creator): # pylint:
has dynamic children, the module will be created using module_creator
and the children (as descriptors) of that module will be returned.
"""
def get_dynamic_descriptor_children(descriptor):
"""
Internal recursive helper for traversing the child hierarchy
"""
module_children = []
if descriptor.has_dynamic_children():
module = module_creator(descriptor)
if module is not None:
module_children = module.get_child_descriptors()
else:
module_children = descriptor.get_children()
return module_children
stack = [descriptor]
while len(stack) > 0:
next_descriptor = stack.pop()
stack.extend(get_dynamic_descriptor_children(next_descriptor))
stack.extend(get_dynamic_descriptor_children(next_descriptor, module_creator))
yield next_descriptor
def get_dynamic_descriptor_children(descriptor, module_creator, usage_key_filter=None):
"""
Returns the children of the given descriptor, while supporting descriptors with dynamic children.
"""
module_children = []
if descriptor.has_dynamic_children():
module = module_creator(descriptor)
if module is not None:
module_children = module.get_child_descriptors()
else:
module_children = descriptor.get_children(usage_key_filter)
return module_children
......@@ -408,7 +408,7 @@ class XModuleMixin(XBlockMixin):
else:
return [self.display_name_with_default]
def get_children(self, usage_key_filter=lambda location: True):
def get_children(self, usage_key_filter=None):
"""Returns a list of XBlock instances for the children of
this module"""
......@@ -419,7 +419,7 @@ class XModuleMixin(XBlockMixin):
self._child_instances = [] # pylint: disable=attribute-defined-outside-init
for child_loc in self.children:
# Skip if it doesn't satisfy the filter function
if not usage_key_filter(child_loc):
if usage_key_filter and not usage_key_filter(child_loc):
continue
try:
child = self.runtime.get_block(child_loc)
......
......@@ -5,6 +5,9 @@ from rest_framework.reverse import reverse
from xmodule.modulestore.mongo.base import BLOCK_TYPES_WITH_CHILDREN
from courseware.access import has_access
from courseware.model_data import FieldDataCache
from courseware.module_render import get_module_for_descriptor
from util.module_utils import get_dynamic_descriptor_children
from edxval.api import (
get_video_info_for_course_and_profile, ValInternalError
......@@ -39,6 +42,17 @@ class BlockOutline(object):
usage_key.block_type in BLOCK_TYPES_WITH_CHILDREN
)
def create_module(descriptor):
"""
Factory method for creating and binding a module for the given descriptor.
"""
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
self.course_id, self.request.user, descriptor
)
return get_module_for_descriptor(
self.request.user, self.request, descriptor, field_data_cache, self.course_id
)
child_to_parent = {}
stack = [self.start_block]
while stack:
......@@ -49,7 +63,7 @@ class BlockOutline(object):
# the hierarchy. The reason being is that these blocks may not have human-readable names
# to display on the mobile clients.
# Eventually, we'll need to figure out how we want these blocks to be displayed on the
# mobile clients. As, they are still accessible in the browser, just not navigatable
# mobile clients. As they are still accessible in the browser, just not navigatable
# from the table-of-contents.
continue
......@@ -70,7 +84,11 @@ class BlockOutline(object):
}
if curr_block.has_children:
children = curr_block.get_children(usage_key_filter=parent_or_requested_block_type)
children = get_dynamic_descriptor_children(
curr_block,
create_module,
usage_key_filter=parent_or_requested_block_type
)
for block in reversed(children):
stack.append(block)
child_to_parent[block] = curr_block
......
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