Files
edx-platform/lms/djangoapps/course_blocks/transformers/utils.py
2016-07-19 21:13:14 -04:00

113 lines
3.7 KiB
Python

"""
Common Helper utilities for transformers
"""
def get_field_on_block(block, field_name, default_value=None):
"""
Get the field value that is directly set on the xblock.
Do not get the inherited value since field inheritance
returns value from only a single parent chain
(e.g., doesn't take a union in DAGs).
"""
try:
if block.fields[field_name].is_set_on(block):
return getattr(block, field_name)
except KeyError:
pass
return default_value
def collect_merged_boolean_field(
block_structure,
transformer,
xblock_field_name,
merged_field_name,
):
"""
Collects a boolean xBlock field of name xblock_field_name
for the given block_structure and transformer. The boolean
value is percolated down the hierarchy of the block_structure
and stored as a value of merged_field_name in the
block_structure.
Assumes that the boolean field is False, by default. So,
the value is ANDed across all parents for blocks with
multiple parents and ORed across all ancestors down a single
hierarchy chain.
"""
for block_key in block_structure.topological_traversal():
# compute merged value of the boolean field from all parents
parents = block_structure.get_parents(block_key)
all_parents_merged_value = all( # pylint: disable=invalid-name
block_structure.get_transformer_block_field(
parent_key, transformer, merged_field_name, False,
)
for parent_key in parents
) if parents else False
# set the merged value for this block
block_structure.set_transformer_block_field(
block_key,
transformer,
merged_field_name,
(
all_parents_merged_value or
get_field_on_block(
block_structure.get_xblock(block_key), xblock_field_name,
False,
)
)
)
def collect_merged_date_field(
block_structure,
transformer,
xblock_field_name,
merged_field_name,
default_date,
func_merge_parents=min,
func_merge_ancestors=max,
):
"""
Collects a date xBlock field of name xblock_field_name
for the given block_structure and transformer. The date
value is percolated down the hierarchy of the block_structure
and stored as a value of merged_field_name in the
block_structure.
"""
for block_key in block_structure.topological_traversal():
parents = block_structure.get_parents(block_key)
block_date = get_field_on_block(block_structure.get_xblock(block_key), xblock_field_name)
if not parents:
# no parents so just use value on block or default
merged_date_value = block_date or default_date
else:
# compute merged value of date from all parents
merged_all_parents_date = func_merge_parents(
block_structure.get_transformer_block_field(
parent_key, transformer, merged_field_name, default_date,
)
for parent_key in parents
)
if not block_date:
# no value on this block so take value from parents
merged_date_value = merged_all_parents_date
else:
# compute merged date of the block and the parent
merged_date_value = func_merge_ancestors(merged_all_parents_date, block_date)
block_structure.set_transformer_block_field(
block_key,
transformer,
merged_field_name,
merged_date_value
)