akvo.rsr.usecases.utils module

class akvo.rsr.usecases.utils.DictWithId(*args, **kwargs)[source]

Bases: dict

id: int
class akvo.rsr.usecases.utils.TreeNode(item: akvo.rsr.usecases.utils.DictWithId, children: List[ForwardRef('TreeNode')] = <factory>)[source]

Bases: object

children: List[TreeNode]
item: DictWithId
akvo.rsr.usecases.utils.does_tree_contain(tree: TreeNode, predicate: Callable[[TreeNode], bool]) bool[source]
akvo.rsr.usecases.utils.filter_trees(trees: List[TreeNode], predicate: Callable[[TreeNode], bool]) List[TreeNode][source]
akvo.rsr.usecases.utils.get_direct_lineage_hierarchy_ids(lhs_project: Project | None, rhs_project: Project | None) Set[int][source]

Resolve the direct lineage path from lhs_project node to rhs_project node in a projects hierarchy tree

Given a projects hierarchy

A

/ B C
/ | D E F

/ G H

The lineage path from D to G

C

/ D F

/

G

With C as the common ancestor, the ancestor lineage above C is omitted as it is unnecessary

get_direct_lineage_hierarchy_ids(D, G) -> [D.id, C.id, F.id, G.id]

If any projects of the function arguments are empty, the function will resolve the lineage path of the non-empty project up to the root project

The lineage path from D to None

A

C

/

D

get_direct_lineage_hierarchy_ids(D, None) -> [D.id, C.id, A.id]

If both projects are not in the same hierarchy, the function will return empty set

akvo.rsr.usecases.utils.get_first_common_item(left: List[int], right: List[int]) int | None[source]
akvo.rsr.usecases.utils.get_leaf_item_of_single_lineage_path_tree(node: TreeNode)[source]
akvo.rsr.usecases.utils.get_project_lineage_ids(project: Project) List[int][source]
akvo.rsr.usecases.utils.get_source_to_target_pair(node: TreeNode, project_attr: str, source_project_id: int, target_project_id: int | None) Tuple[int | None, int | None][source]

Resolve node item ids of source and target projects of a direct lineage path tree

Expected node structure is that the root node (as the common ancestor) only have two children (two path) and each of the children only have single lineage path to either the source or the target project

A

/ B C

/ D E

F

Descendants nodes with multiple children will be considered ambiguous and will not be resolved

akvo.rsr.usecases.utils.make_source_to_target_map(trees: Iterable[TreeNode], project_attr: str, source_project_id: int, target_project_id: int | None) Dict[int, int][source]

Resolve node item ids of source and target projects of each tree

akvo.rsr.usecases.utils.make_trees_from_list(items: Iterable[DictWithId], parent_attr: str) List[TreeNode][source]