block_depth.py 1.97 KB
Newer Older
1 2 3
"""
Block Depth Transformer
"""
4
from openedx.core.djangoapps.content.block_structure.transformer import BlockStructureTransformer
5 6 7 8 9 10 11


class BlockDepthTransformer(BlockStructureTransformer):
    """
    Keep track of the depth of each block within the block structure.  In case
    of multiple paths to a given node (in a DAG), use the shallowest depth.
    """
12 13
    WRITE_VERSION = 1
    READ_VERSION = 1
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
    BLOCK_DEPTH = 'block_depth'

    def __init__(self, requested_depth=None):
        self.requested_depth = requested_depth

    @classmethod
    def name(cls):
        return "blocks_api:block_depth"

    @classmethod
    def get_block_depth(cls, block_structure, block_key):
        """
        Return the precalculated depth of a block within the block_structure:

        Arguments:
            block_structure: a BlockStructure instance
            block_key: the key of the block whose depth we want to know

        Returns:
            int
        """
        return block_structure.get_transformer_block_field(
            block_key,
            cls,
            cls.BLOCK_DEPTH,
        )

41
    def transform(self, usage_info, block_structure):
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
        """
        Mutates block_structure based on the given usage_info.
        """
        for block_key in block_structure.topological_traversal():
            parents = block_structure.get_parents(block_key)
            if parents:
                block_depth = min(
                    self.get_block_depth(block_structure, parent_key)
                    for parent_key in parents
                ) + 1
            else:
                block_depth = 0
            block_structure.set_transformer_block_field(
                block_key,
                self,
                self.BLOCK_DEPTH,
                block_depth
            )

        if self.requested_depth is not None:
62
            block_structure.remove_block_traversal(
63 64
                lambda block_key: self.get_block_depth(block_structure, block_key) > self.requested_depth
            )