def __get_json_sosa_tree(graph, id, max_levels, style_rules, last_descendant_known=-1, maxdepthDescendants=1, last_gen_known=-1): """ :param last_gen_known: is the number of the last generation for which the client already has data, and thus do not need to be sent again. -1 to retrieve all. :param maxdepthDescendants: The number of generations for which we compute the children. """ decujus = graph.node_from_id(id) styles = Styles(style_rules, graph, decujus=decujus.main_id) distance = dict() ancestors = graph.people_in_tree( id=decujus.main_id, maxdepthAncestors=max_levels - 1, maxdepthDescendants=0, distance=distance) ancestors = [a for a in ancestors if distance[a] >= last_gen_known] descendants = graph.people_in_tree( id=decujus.main_id, maxdepthAncestors=0, distance=distance, maxdepthDescendants=maxdepthDescendants) descendants = [ a for a in descendants if a != decujus and distance[a] >= last_descendant_known] sosa_tree = dict() marriage = dict() children = {} persons = {} all_person_nodes = set(ancestors).union(descendants) if all_person_nodes: persons = extended_personas( all_person_nodes, styles, event_types=event_types_for_pedigree, graph=graph) def add_parents(p): p.generation = distance[graph.node_from_id(p.id)] if p.generation >= max_levels: return fathers = graph.fathers(p.id) mothers = graph.mothers(p.id) p.parents = [ None if not fathers else persons.get(fathers[0].main_id, None), None if not mothers else persons.get(mothers[0].main_id, None)] for pa in p.parents: if pa: add_parents(pa) def add_children(p, gen): p.children = [] sorted = [(persons[node.main_id] if node.main_id in persons else None, node) for node in graph.children(p.id)] sorted.sort( key=lambda c: c[0].birth.Date if c[0] and c[0].birth else None) for c in sorted: if c[0]: c[0].generation = -gen # distance[c[1]] p.children.append(c[0]) if gen < maxdepthDescendants: add_children(c[0], gen + 1) main = persons[decujus.main_id] add_parents(main) add_children(main, gen=1) # We will however return a simpler version of the information computed # above (which includes all known events for the persons) show_age = False def person_to_json_for_pedigree(obj): if isinstance(obj, models.Persona): d = obj.death if show_age and obj.birth: if d: if d.Date: d.Date += " (age %s)" % ( str(d.Date.years_since(obj.birth.Date)), ) else: d = {Date: " (age %s)" % ( str(DateRange.today().years_since(obj.birth.Date)), )} return { 'id': obj.id, 'givn': obj.given_name, 'surn': obj.surname, 'sex': obj.sex, 'generation': obj.generation, 'parents': obj.parents if hasattr(obj, 'parents') else None, 'children': obj.children if hasattr(obj, 'children') else None, 'style': obj.styles, 'birth': obj.birth, 'marriage': obj.marriage, 'death': d} return to_json( obj= {'generations': max_levels, 'descendants': maxdepthDescendants, 'decujus': main, 'styles': styles.all_styles()}, custom=person_to_json_for_pedigree)
def get_json(self, params, id): # ??? Should lock until the view has been generated graph.update_if_needed() max_levels = int(params.get("gens", 5)) last_descendant_known = int(params.get("desc_known", -1)) # The number of generations for which we compute the children. maxdepthDescendants = int(params.get("descendant_gens", 1)) # the number of the last generation for which the client already has # data, and thus do not need to be sent again. -1 to retrieve all. last_gen_known = int(params.get("gens_known", -1)) # Whether to show full dates or only the year self.year_only = params.get('year_only', '') == 'true' decujus = graph.node_from_id(id) styles = Styles(style_rules, graph, decujus=decujus.main_id) distance = dict() people = graph.people_in_tree( id=decujus.main_id, maxdepthAncestors=max_levels - 1, maxdepthDescendants=maxdepthDescendants, distance=distance) ancestors = [a for a in people if distance[a] >= 0 and distance[a] >= last_gen_known] descendants = [a for a in people if a != decujus and distance[a] < 0 and distance[a] <= -last_descendant_known] sosa_tree = dict() marriage = dict() children = {} persons = {} all_person_nodes = set(ancestors).union(descendants) if all_person_nodes: persons = extended_personas( all_person_nodes, styles, event_types=event_types_for_pedigree, graph=graph) def add_parents(p): p.generation = distance[graph.node_from_id(p.id)] if p.generation >= max_levels: return fathers = graph.fathers(p.id) mothers = graph.mothers(p.id) p.parents = [ None if not fathers else persons.get(fathers[0].main_id, None), None if not mothers else persons.get(mothers[0].main_id, None)] for pa in p.parents: if pa: add_parents(pa) def add_children(p, gen): p.children = [] sorted = [(persons[node.main_id] if node.main_id in persons else None, node) for node in graph.children(p.id)] sorted.sort( key=lambda c: c[0].birth.Date if c[0] and c[0].birth else None) for c in sorted: if c[0]: c[0].generation = -gen # distance[c[1]] p.children.append(c[0]) if gen < maxdepthDescendants: add_children(c[0], gen + 1) main = persons[decujus.main_id] add_parents(main) add_children(main, gen=1) return {'generations': max_levels, 'descendants': maxdepthDescendants, 'decujus': main, 'styles': styles.all_styles()}
def get_sosa_tree(graph, id, max_levels, style_rules, last_descendant_known=-1, maxdepthDescendants=1, last_gen_known=-1): """ :param last_gen_known: is the number of the last generation for which the client already has data, and thus do not need to be sent again. -1 to retrieve all. :param maxdepthDescendants: The number of generations for which we compute the children. """ decujus = graph.node_from_id(id) styles = Styles(style_rules, graph, decujus=decujus.main_id) distance = dict() ancestors = graph.people_in_tree( id=decujus.main_id, maxdepthAncestors=max_levels - 1, maxdepthDescendants=0, distance=distance) ancestors = [a for a in ancestors if distance[a] >= last_gen_known] descendants = graph.people_in_tree( id=decujus.main_id, maxdepthAncestors=0, distance=distance, maxdepthDescendants=maxdepthDescendants) descendants.remove(decujus) descendants = [a for a in descendants if distance[a] >= last_descendant_known] sosa_tree = dict() marriage = dict() children = {} persons = {} all_person_nodes = set(ancestors).union(descendants) if all_person_nodes: persons = extended_personas( all_person_nodes, styles, event_types=event_types_for_pedigree, graph=graph) def build_sosa_tree(sosa_tree, marriage, sosa, id): # A person might not be in 'persons', and yet its parent be there, # in case we have filtered out earlier generations. if id in persons: sosa_tree[sosa] = id persons[id].generation = distance[graph.node_from_id(id)] if persons[id].marriage: marriage[sosa] = persons[id].marriage fathers = graph.fathers(id) if fathers: build_sosa_tree(sosa_tree, marriage, sosa * 2, fathers[0].main_id) mothers = graph.mothers(id) if mothers: build_sosa_tree( sosa_tree, marriage, sosa * 2 + 1, mothers[0].main_id) def build_children_tree(children, id, gen): if id in persons: children[id] = [] sorted = [(persons[node.main_id] if node.main_id in persons else None, node) for node in graph.children(id)] sorted.sort(key=lambda p: p[0].birth.Date if p[0] and p[0].birth else None) for p in sorted: if p[0]: p[0].generation = -distance[p[1]] if id in persons: children[id].append(p[0].id) if gen < maxdepthDescendants: build_children_tree(children, id=p[0].id, gen=gen + 1) build_sosa_tree(sosa_tree, marriage, 1, decujus.main_id) build_children_tree(children, id=decujus.main_id, gen=1) return {'generations': max_levels, 'descendants': maxdepthDescendants, 'persons': persons, # All persons indexed by id 'sosa': sosa_tree, # sosa_number -> person_id 'children': children, # personId -> [children_id*] 'marriage': marriage, # sosa_number -> marriage info 'styles': styles.all_styles()}
def get_json(self, params, id): # ??? Should lock until the view has been generated global_graph.update_if_needed() max_levels = int(params.get("gens", 5)) last_descendant_known = int(params.get("desc_known", -1)) # The number of generations for which we compute the children. maxdepthDescendants = int(params.get("descendant_gens", 1)) # the number of the last generation for which the client already has # data, and thus do not need to be sent again. -1 to retrieve all. last_gen_known = int(params.get("gens_known", -1)) self.year_only = params.get('year_only', '') == 'true' decujus = global_graph.node_from_id(id) styles = Styles(style_rules(), global_graph, decujus=decujus.main_id) styles = None # disabled for now distance = dict() people = global_graph.people_in_tree( id=decujus.main_id, maxdepthAncestors=max_levels - 1, maxdepthDescendants=maxdepthDescendants, distance=distance) ancestors = [a for a in people if distance[a] >= 0 and distance[a] >= last_gen_known] descendants = [a for a in people if a != decujus and distance[a] < 0 and distance[a] <= -last_descendant_known] sosa_tree = dict() marriage = dict() children = {} persons = {} all_person_nodes = set(ancestors).union(descendants) if all_person_nodes: persons = extended_personas( all_person_nodes, styles, event_types=event_types_for_pedigree(), graph=global_graph) def add_parents(p): p.generation = distance[global_graph.node_from_id(p.id)] if p.generation >= max_levels: return fathers = global_graph.fathers(p.id) mothers = global_graph.mothers(p.id) p.parents = [ None if not fathers else fathers[0].main_id, None if not mothers else mothers[0].main_id] if fathers and fathers[0].main_id in persons: add_parents(persons[fathers[0].main_id]) if mothers and mothers[0].main_id in persons: add_parents(persons[mothers[0].main_id]) def add_children(p, gen): p.children = [] sorted = [ (persons[node.main_id] if node.main_id in persons else None, node) for node in global_graph.children(p.id)] for c in sorted: if c[0]: c[0].generation = -gen # distance[c[1]] p.children.append(c[0].id) if gen < maxdepthDescendants: add_children(c[0], gen + 1) main = persons[decujus.main_id] add_parents(main) add_children(main, gen=1) main = persons[decujus.main_id] layout = {} for p in persons.values(): layout[p.id] = {'children': getattr(p, 'children', None), 'parents': getattr(p, 'parents', None)} return {'generations': max_levels, 'descendants': maxdepthDescendants, 'decujus': decujus.main_id, 'persons': list(persons.values()), 'layout': layout, 'styles': styles.all_styles() if styles is not None else None}