#!/usr/bin/env python3 """ Generate a huge demo family for Gramps testing """ import random from datetime import datetime, timedelta # Generate unique handles def gen_handle(prefix, num): return f"_{prefix}{num:08d}" # Generate a person def gen_person(pid, first_name, surname, birth_year, death_year=None, gender="M", parentin_families=None, childof_families=None): handle = gen_handle("PERSON", pid) birth_handle = gen_handle("EVENT", pid * 10) death_handle = gen_handle("EVENT", pid * 10 + 1) if death_year else None person_xml = f""" {gender} {first_name} {surname} """ if death_handle: person_xml += f""" """ # Add parentin references (for fathers and mothers) if parentin_families: for family_handle in parentin_families: person_xml += f""" """ # Add childof references (for children) if childof_families: for family_handle in childof_families: person_xml += f""" """ person_xml += """ """ # Birth event birth_month = random.randint(1, 12) birth_day = random.randint(1, 28) birth_event = f""" Birth Birth of {surname}, {first_name} """ # Death event death_event = "" if death_handle and death_year: death_month = random.randint(1, 12) death_day = random.randint(1, 28) death_event = f""" Death Death of {surname}, {first_name} """ return person_xml, birth_event, death_event # Generate a family def gen_family(fid, father_handle, mother_handle, marriage_year, children_handles): handle = gen_handle("FAMILY", fid) marriage_handle = gen_handle("EVENT", fid * 100) family_xml = f""" """ for child_handle in children_handles: family_xml += f""" """ family_xml += f""" """ # Marriage event marriage_month = random.randint(1, 12) marriage_day = random.randint(1, 28) marriage_event = f""" Marriage Marriage """ return family_xml, marriage_event # First names male_names = ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Charles", "Daniel", "Matthew", "Anthony", "Mark", "Donald", "Steven", "Paul", "Andrew", "Joshua", "Kenneth", "Kevin", "Brian", "George", "Timothy", "Ronald", "Jason", "Edward", "Jeffrey", "Ryan", "Jacob", "Gary", "Nicholas", "Eric", "Jonathan", "Stephen", "Larry", "Justin", "Scott", "Brandon", "Benjamin"] female_names = ["Mary", "Patricia", "Jennifer", "Linda", "Elizabeth", "Barbara", "Susan", "Jessica", "Sarah", "Karen", "Nancy", "Lisa", "Betty", "Margaret", "Sandra", "Ashley", "Kimberly", "Emily", "Donna", "Michelle", "Dorothy", "Carol", "Amanda", "Melissa", "Deborah", "Stephanie", "Rebecca", "Sharon", "Laura", "Cynthia", "Kathleen", "Amy", "Angela", "Shirley", "Anna", "Brenda", "Pamela", "Emma", "Nicole", "Helen", "Samantha", "Katherine", "Christine", "Debra"] surnames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez", "Wilson", "Anderson", "Thomas", "Taylor", "Moore", "Jackson", "Martin", "Lee", "Thompson", "White", "Harris", "Sanchez", "Clark", "Ramirez", "Lewis", "Robinson", "Walker", "Young", "Allen", "King", "Wright", "Scott", "Torres", "Nguyen", "Hill", "Flores", "Green", "Adams"] def main(): print("Generating huge demo family...") # Generate main family # Father: John Smith, born 1950, died 2010 father_id = 1 father_handle = gen_handle("PERSON", father_id) main_family_handle = gen_handle("FAMILY", 1) father_person, father_birth, father_death = gen_person( father_id, "John", "Smith", 1950, 2010, "M", parentin_families=[main_family_handle] ) # Mother: Mary Smith, born 1952, died 2015 mother_id = 2 mother_handle = gen_handle("PERSON", mother_id) mother_person, mother_birth, mother_death = gen_person( mother_id, "Mary", "Smith", 1952, 2015, "F", parentin_families=[main_family_handle] ) # Generate 15 children children = [] child_handles = [] child_events = [] child_id = 3 for i in range(15): gender = "M" if i % 2 == 0 else "F" first_name = random.choice(male_names if gender == "M" else female_names) birth_year = 1970 + (i * 2) # Spread births from 1970 to 1998 death_year = birth_year + random.randint(60, 90) if random.random() < 0.3 else None # 30% chance of death child_handle = gen_handle("PERSON", child_id) child_person, child_birth, child_death = gen_person( child_id, first_name, "Smith", birth_year, death_year, gender, childof_families=[main_family_handle] ) children.append(child_person) child_handles.append(child_handle) child_events.append(child_birth) if child_death: child_events.append(child_death) child_id += 1 # Generate family family_id = 1 family_xml, marriage_event = gen_family(family_id, father_handle, mother_handle, 1969, child_handles) # Track person data for regeneration (needed for children who become parents) import re person_data = {} # Store initial person data person_data[father_id] = {"handle": father_handle, "name": "John", "surname": "Smith", "birth": 1950, "death": 2010, "gender": "M", "parentin": [main_family_handle], "childof": []} person_data[mother_id] = {"handle": mother_handle, "name": "Mary", "surname": "Smith", "birth": 1952, "death": 2015, "gender": "F", "parentin": [main_family_handle], "childof": []} for i, child_handle in enumerate(child_handles): child_pid = 3 + i gender = "M" if i % 2 == 0 else "F" # Extract name from generated child XML child_xml = children[i] name_match = re.search(r'([^<]+)', child_xml) first_name = name_match.group(1) if name_match else random.choice(male_names if gender == "M" else female_names) birth_year = 1970 + (i * 2) # Extract death year from child_events if it exists death_year = None for event in child_events: if f"id=\"E{child_pid*10+1:04d}\"" in event: match = re.search(r'val="(\d{4})', event) if match: death_year = int(match.group(1)) person_data[child_pid] = {"handle": child_handle, "name": first_name, "surname": "Smith", "birth": birth_year, "death": death_year, "gender": gender, "parentin": [], "childof": [main_family_handle]} # Generate grandchildren (children of first 5 children) grandchildren = [] grandchild_events = [] grandchild_id = child_id for i in range(5): # First 5 children have children parent_handle = child_handles[i] parent_pid = 3 + i parent_gender = "M" if i % 2 == 0 else "F" spouse_gender = "F" if parent_gender == "M" else "M" # Create spouse spouse_name = random.choice(female_names if spouse_gender == "F" else male_names) spouse_birth = 1970 + (i * 2) + random.randint(-2, 2) spouse_handle = gen_handle("PERSON", grandchild_id) child_family_handle = gen_handle("FAMILY", family_id + 1) person_data[grandchild_id] = {"handle": spouse_handle, "name": spouse_name, "surname": "Smith", "birth": spouse_birth, "death": None, "gender": spouse_gender, "parentin": [child_family_handle], "childof": []} spouse_person, spouse_birth_event, spouse_death_event = gen_person( grandchild_id, spouse_name, "Smith", spouse_birth, None, spouse_gender, parentin_families=[child_family_handle] ) grandchildren.append(spouse_person) grandchild_events.append(spouse_birth_event) if spouse_death_event: grandchild_events.append(spouse_death_event) grandchild_id += 1 # Update parent to include parentin reference person_data[parent_pid]["parentin"].append(child_family_handle) # Create 3-5 children per couple num_grandchildren = random.randint(3, 5) grandchild_handles = [] for j in range(num_grandchildren): gchild_gender = "M" if j % 2 == 0 else "F" gchild_name = random.choice(male_names if gchild_gender == "M" else female_names) gchild_birth = 1995 + (i * 3) + j gchild_handle = gen_handle("PERSON", grandchild_id) person_data[grandchild_id] = {"handle": gchild_handle, "name": gchild_name, "surname": "Smith", "birth": gchild_birth, "death": None, "gender": gchild_gender, "parentin": [], "childof": [child_family_handle]} gchild_person, gchild_birth_event, gchild_death_event = gen_person( grandchild_id, gchild_name, "Smith", gchild_birth, None, gchild_gender, childof_families=[child_family_handle] ) grandchildren.append(gchild_person) grandchild_handles.append(gchild_handle) grandchild_events.append(gchild_birth_event) if gchild_death_event: grandchild_events.append(gchild_death_event) grandchild_id += 1 # Create family for this couple family_id += 1 fam_xml, fam_marriage = gen_family(family_id, parent_handle, spouse_handle, 1990 + i, grandchild_handles) family_xml += fam_xml child_events.append(fam_marriage) # Regenerate children XMLs with updated family references children = [] for i, child_handle in enumerate(child_handles): child_pid = 3 + i data = person_data[child_pid] child_person, _, _ = gen_person( child_pid, data["name"], data["surname"], data["birth"], data["death"], data["gender"], parentin_families=data["parentin"], childof_families=data["childof"] ) children.append(child_person) # Write XML file xml_content = f"""
Demo Family Generator
{father_birth} {father_death} {mother_birth} {mother_death} {marriage_event} """ for event in child_events: xml_content += event for event in grandchild_events: xml_content += event xml_content += """ """ xml_content += father_person xml_content += mother_person for child in children: xml_content += child for grandchild in grandchildren: xml_content += grandchild xml_content += """ """ xml_content += family_xml xml_content += """
""" with open("demo_family.gramps", "w", encoding="utf-8") as f: f.write(xml_content) print(f"Generated demo_family.gramps with:") print(f" - 2 parents (John and Mary Smith)") print(f" - 15 children") print(f" - 5 spouses") print(f" - ~20 grandchildren") print(f" - Multiple families with marriage events") print(f" - Birth and death events for all") if __name__ == "__main__": main()