def discover_relevant_flowblock_models(flow, pad, record, alt):
    """Returns a dictionary of all relevant flow blocks.  If no list of
    flow block names is provided all flow blocks are returned.  Otherwise
    only flow blocks that are in the list or are children of flowblocks
    in the list are returned.
    """
    flow_blocks = flow.flow_blocks

    all_blocks = pad.db.flowblocks
    if flow_blocks is None:
        return dict((k, v.to_json(pad, record, alt))
                    for k, v in iteritems(all_blocks))

    wanted_blocks = set()
    to_process = flow_blocks[:]

    while to_process:
        block_name = to_process.pop()
        flowblock = all_blocks.get(block_name)
        if block_name in wanted_blocks or flowblock is None:
            continue
        wanted_blocks.add(block_name)
        for field in flowblock.fields:
            if isinstance(field.type, FlowType):
                if field.type.flow_blocks is None:
                    raise RuntimeError('Nested flow-blocks require explicit '
                                       'list of involved blocks.')
                to_process.extend(field.type.flow_blocks)

    rv = {}
    for block_name in wanted_blocks:
        rv[block_name] = all_blocks[block_name].to_json(pad, record, alt)

    return rv
dataset/ETHPy150Open lektor/lektor/lektor/types/flow.py/discover_relevant_flowblock_models/original