gedcom_export.py
Dec 25, 2023 23:45:16 GMT -8
Post by Uncle Buddy on Dec 25, 2023 23:45:16 GMT -8
<drive>:\treebard\app\python\gedcom_export.py Last Changed 2024-03-21
# gedcom_export.py
import tkinter as tk
import sqlite3
from datetime import datetime
from textwrap import wrap
from files import current_drive, appwide_db_path, treebard_path, tree_path
import gedcom_constants as gcc
from dates import format_stored_date, get_date_formats
from widgets import (
Scrollbar, make_formats_dict, configall, ScrolledDialog, Combobox)
import dev_tools as dt
from dev_tools import look, seeline
exceptions = {
"event_assertions": [], "couple_event_assertions": [], "name_assertions": []}
class ExportGEDCOM(ScrolledDialog):
def __init__(
self, master, *args, **kwargs):
ScrolledDialog.__init__(self, master, *args, **kwargs)
self.treebard = master
self.geometry("+100+50")
self.protocol("WM_DELETE_WINDOW", self.cancel)
self.title("Export a Treebard Family Tree to a .ged File")
self.source_tree_id = None
self.conn = sqlite3.connect(appwide_db_path)
self.cur = self.conn.cursor()
self.cur.execute(
'''SELECT full_path, directory, user_tree_title FROM family_tree
''')
self.all_trees = self.cur.fetchall()
self.all_tree_titles = [i[2] for i in self.all_trees]
self.make_widgets()
ScrolledDialog.bind_canvas_to_mousewheel(self.canvas)
configall(self, self.treebard.formats)
self.resize_scrolled_content(self, self.canvas, add_x=16, add_y=24)
self.cur.close()
self.conn.close()
self.export_file_input.entry.focus_set()
def make_widgets(self):
self.columnconfigure(1, weight=1)
self.window.columnconfigure(2, weight=1)
self.window.rowconfigure(1, minsize=60)
self.window.columnconfigure(0, weight=1)
self.window.rowconfigure(0, weight=1)
headlab = tk.Label(
self.window,
text= f"Some of information from the source Treebard file "
f"could not be exported. \n\nThe "
f"exceptions log detailing these unexported data will be stored in the "
f"`etc` folder of your Treebard app.",
justify="left", wraplength=600, bd=1, relief="raised")
frm = tk.Frame(self.window)
lab = tk.Label(frm, text="Select the name of an existing tree:")
self.export_file_input = Combobox(
frm, self.treebard.formats, family_tree=self.treebard, #entry_width=32,
values=self.all_tree_titles)
lab2 = tk.Label(frm, text="Who created this family tree?")
self.creator_input = tk.Entry(frm, width=32)
but = tk.Button(
frm, text="Export to GEDCOM File", cursor="hand2",
command=self.get_primary_data)
cancel = tk.Button(self.window, text="CANCEL", command=self.cancel)
# children of self.window
headlab.grid(column=0, row=0, pady=12, ipadx=6, ipady=6, padx=12)
frm.grid(column=0, row=1)
cancel.grid(column=0, row=2, sticky="e", pady=12)
# children of frm
lab.grid()
self.export_file_input.grid()
lab2.grid()
self.creator_input.grid()
but.grid()
def collect_data(self, cur):
self.get_persons(cur)
self.get_couples(cur)
self.get_media(cur)
self.get_notes(cur)
self.get_repositories(cur)
self.get_sources(cur)
def get_primary_data(self):
conn = sqlite3.connect(appwide_db_path)
cur = conn.cursor()
user_tree_title = self.export_file_input.entry.get()
for tup in self.all_trees:
if user_tree_title == tup[2]:
source_file_path, self.directory = tup[0:2]
break
time_stamp = datetime.now().strftime("%Y%m%d%H%M")
self.source_file_path = f"{current_drive}{source_file_path}"
output_file_path = f"{treebard_path}/etc/{self.directory}_{time_stamp}.ged"
cur.execute("ATTACH ? as tree", (self.source_file_path,))
self.creator = self.creator_input.get().strip()
if len(self.creator) == 0:
self.creator = "unknown"
self.collect_data(cur)
self.write_gedcom(output_file_path, cur)
cur.execute("DETACH tree")
cur.close()
conn.close()
def write_gedcom(self, output_file_path, cur):
with open(output_file_path, mode="w", encoding="utf-8-sig") as ged:
self.write_head(ged)
self.write_persons(ged, cur)
self.write_couples(ged, cur)
self.write_media(ged, cur)
self.write_notes(ged, cur)
self.write_repositories(ged, cur)
self.write_sources(ged, cur)
ged.write("0 TRLR")
self.print_stuff()
def write_sources(self, ged, cur):
for tup in self.sources:
source_id, title, author, description = tup
ged.write(f"0 @S{source_id}@ SOUR\n")
if title:
ged.write(f"1 TITL {title}\n")
if author:
ged.write(f"1 AUTH {author}\n")
if description:
ged.write(f"1 PUBL {description}\n")
self.write_source_note(source_id, cur, ged)
def write_repositories(self, ged, cur):
for tup in self.repositories:
repository_id, repository = tup
ged.write(f"0 @R{repository_id}@ REPO\n")
ged.write(f"1 NAME {repository}\n")
self.write_repository_note(repository_id, cur, ged)
def write_notes(self, ged, cur):
for tup in self.notes:
note_id, note = tup
note_concatenations = self.split_string(note)
ged.write(f"0 @N{note_id}@ NOTE\n")
cont_next = False
for lst in note_concatenations:
for line in lst:
if line == "\n":
ged.write(f"1 CONT \n")
cont_next = True
elif line.endswith("\n") and cont_next:
ged.write(f"1 CONT {line}")
cont_next = False
elif line.endswith("\n"):
ged.write(f"1 CONC {line}")
cont_next = False
elif cont_next:
ged.write(f"1 CONT {line}\n")
cont_next = False
else:
ged.write(f"1 CONC {line}\n")
cont_next = False
def write_media(self, ged, cur):
for tup in self.media:
media_id, file_name, title, caption, media_type = tup
extension = None
splt = file_name.split(".")
if len(splt) > 1:
extension = splt[-1]
if len(title) == 0:
title = "untitled"
full_path = f"{tree_path}/{self.directory}/images/{file_name}"
ged.write(f"0 @O{media_id}@ OBJE\n")
ged.write(f"1 FILE {full_path}\n")
if extension:
ged.write(f"2 FORM {extension}\n")
if media_type in gcc.GEDCOM_MEDIA_TYPES:
ged.write(f"3 TYPE {media_type}\n")
if title != "untitled" and len(title) != 0:
ged.write(f"2 {title}\n")
if caption:
media_note = [
(f"Caption from {media_type} (media ID #{media_id}) "
f"entitled '{title}'"),
f"'{caption}'."]
ged.write(f"1 NOTE {': '.join(media_note)}\n")
self.write_media_note_pointers(media_id, cur, ged)
self.write_media_source(media_id, cur, ged)
def write_persons(self, ged, cur):
for lst in self.persons:
person_id, gender = lst
ged.write(f"0 @I{person_id}@ INDI\n")
ged.write(f"1 SEX {gcc.RENAME[gender]}\n")
self.write_names(person_id, cur, ged)
self.write_events(person_id, cur, ged)
self.write_person_media_pointers(person_id, cur, ged)
self.write_person_note_pointers(person_id, cur, ged)
self.write_source_note_person(person_id, cur, ged)
def write_couples(self, ged, cur):
for tup in self.couples:
couple_id, person_id1, person_id2 = tup
ged.write(f"0 @F{couple_id}@ FAM\n")
if person_id1:
ged.write(f"1 HUSB @I{person_id1}@\n")
if person_id2:
ged.write(f"1 WIFE @I{person_id2}@\n")
child_ids = self.get_children(couple_id, cur)
for child_id in child_ids:
ged.write(f"1 CHIL @I{child_id}@\n")
cur.execute(gcc.SELECT_COUPLE_EVENTS, (couple_id,))
events = cur.fetchall()
for tup in events:
(event_type, particulars, age1, age2, date, nested_place_id,
event_id) = tup
ged.write(f"1 EVEN {particulars}\n")
ged.write(f"2 TYPE {event_type}\n")
if len(age1) != 0:
ged.write(f"2 HUSB\n")
ged.write(f"3 AGE {age1}\n")
if len(age2) != 0:
ged.write(f"2 WIFE\n")
ged.write(f"3 AGE {age2}\n")
if date != "-0000-00-00-------":
ged_date = self.fix_date(date)
ged.write(f"2 DATE {ged_date}\n")
if nested_place_id != 1:
place_id = self.get_place_id(nested_place_id, cur, ged)
self.write_place_note_pointers(place_id, event_id, cur, ged)
self.write_event_note_pointers(event_id, cur, ged)
self.write_sources_event_couple(cur, event_id, couple_id, ged)
self.write_couple_note(couple_id, cur, ged)
self.write_couple_media_pointer(couple_id, cur, ged)
def write_events(self, person_id, cur, ged):
generic_events = self.get_events(person_id, cur)
for event in generic_events:
(event_type, date, nested_place_id, particulars, age,
couple_id, event_id) = event
if event_type and event_type not in (
"birth", "adoption", "guardianship", "fosterage"):
ged.write(f"1 EVEN {particulars}\n")
ged.write(f"2 TYPE {event_type}\n")
elif event_type in ("birth", "adoption", "fosterage", "guardianship"):
if event_type != "birth":
particulars = event_type
ged.write(f"1 ADOP {event_type}\n")
else:
ged.write(f"1 BIRT {particulars}\n")
if couple_id:
ged.write(f"2 FAMC @F{couple_id}@\n")
if event_type != "birth":
adopter = self.get_adopter(person_id, couple_id, cur)
if adopter:
ged.write(f"3 ADOP {adopter}\n")
self.write_event_media(person_id, event_id, cur, ged)
self.write_sources_event(cur, event_id, person_id, ged)
self.write_event_note_pointers(event_id, cur, ged)
if date != "-0000-00-00-------":
ged_date = self.fix_date(date)
ged.write(f"2 DATE {ged_date}\n")
if nested_place_id != 1:
place_id = self.get_place_id(nested_place_id, cur, ged)
self.write_place_note_pointers(place_id, event_id, cur, ged)
if age != "0" and len(age) != 0:
ged.write(f"2 AGE {age}\n")
if couple_id and event_type in ("birth", "adoption", "guardianship", "fosterage"):
# if couple_id and event_type == "birth":
ged.write(f"1 FAMC @F{couple_id}@\n")
# See separate method for events done in FAM record, this is just FAMS.
couple_events = self.get_couple_events(person_id, cur)
fams = set()
for couple_id in couple_events:
fams.add(couple_id)
eventless_couples = self.get_eventless_couples(person_id, cur)
for couple_id in eventless_couples:
fams.add(couple_id)
for couple_id in fams:
ged.write(f"1 FAMS @F{couple_id}@\n")
def get_place_id(self, nested_place_id, cur, ged):
nested_place = self.get_nested_place_string(nested_place_id, cur)
ged.write(f"2 PLAC {nested_place}\n")
place_id = self.get_smallest_place_nest(nested_place_id, cur)
cur.execute(gcc.SELECT_PLACE_TYPE, (place_id,))
result = cur.fetchone()
if result:
place_type = result[0]
ged.write(f"3 FORM {place_type}\n")
cur.execute(gcc.SELECT_COORDINATES, (place_id, ))
coords = cur.fetchone()
if coords:
latitude, longitude = coords
if len(latitude) != 0 or len(longitude) != 0:
ged.write(f"3 MAP\n")
if len(latitude) != 0:
ged.write(f"4 LATI {latitude}\n")
if len(longitude) != 0:
ged.write(f"4 LONG {longitude}\n")
cur.execute(gcc.SELECT_TRANSCRIPTIONS_PLACE, (nested_place_id,))
results = cur.fetchall()
for tup in results:
tag = None
romanized, phonetic, transcription, transcription_type = tup
if romanized == 1:
tag = "ROMN"
elif phonetic == 1:
tag = "FONE"
if tag:
ged.write(f"3 {tag} {transcription}\n")
if transcription_type:
ged.write(f"4 TYPE {transcription_type}\n")
return place_id
def get_children(self, couple_id, cur):
cur.execute(gcc.SELECT_OFFSPRING_EVENTS, (couple_id,))
return [i[0] for i in cur.fetchall()]
def write_person_media_pointers(self, person_id, cur, ged):
cur.execute(gcc.SELECT_MEDIA_PERSON_LINK, (person_id,))
media_ids = cur.fetchall()
for media_id in media_ids:
ged.write(f"1 OBJE @O{str(media_id[0])}@\n")
def write_couple_media_pointer(self, couple_id, cur, ged):
cur.execute(gcc.SELECT_MEDIA_COUPLE_LINK, (couple_id,))
media_ids = cur.fetchall()
for media_id in media_ids:
ged.write(f"1 OBJE @O{str(media_id[0])}@\n")
def write_person_note_pointers(self, person_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_PERSON_LINKS, (person_id,))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"1 NOTE @N{str(note_id[0])}@\n")
def write_media_note_pointers(self, media_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_MEDIA_LINKS, (media_id,))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"1 NOTE @N{str(note_id[0])}@\n")
def write_media_source(self, media_id, cur, ged):
cur.execute(gcc.SELECT_SOURCE_MEDIA_LINKS, (media_id,))
results = cur.fetchall()
for tup in results:
source_id, citation_id = tup
if source_id:
ged.write(f"1 SOUR @S{source_id}@\n")
elif citation_id:
cur.execute(gcc.SELECT_SOURCE_CITATION_LINK, (citation_id,))
source_id, citation = cur.fetchone()
ged.write(f"1 SOUR @S{source_id}@\n")
self.write_citation("2", citation, ged)
def write_event_note_pointers(self, event_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_EVENT_LINKS, (event_id,))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"2 NOTE @N{str(note_id[0])}@\n")
def write_name_note_pointers(self, name_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_NAME_LINKS, (name_id,))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"2 NOTE @N{str(note_id[0])}@\n")
def write_place_note_pointers(self, place_id, event_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_PLACE_LINKS, (place_id, event_id))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"3 NOTE @N{str(note_id[0])}@\n")
def write_event_media(self, person_id, event_id, cur, ged):
cur.execute(gcc.SELECT_MEDIA_EVENT_LINKS, (event_id,))
media_ids = cur.fetchall()
for media_id in media_ids:
ged.write(f"2 OBJE @O{str(media_id[0])}@\n")
def write_source_note_person(self, person_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_SOURCE_PERSON_LINK, (person_id,))
results = cur.fetchall()
for source_id, note_id in results:
ged.write(f"1 SOUR @S{str(source_id)}@\n")
ged.write(f"2 NOTE @N{str(note_id)}@\n")
def write_source_media_name(self, source_id, person_id, cur, ged):
cur.execute(gcc.SELECT_MEDIA_SOURCE_NAME_LINK, (person_id, source_id))
media_ids = cur.fetchall()
for media_id in media_ids:
ged.write(f"3 OBJE @O{str(media_id[0])}@\n")
def write_source_note_name(self, source_id, person_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_SOURCE_NAME_LINK, (person_id, source_id))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"3 NOTE @N{str(note_id[0])}@\n")
def write_source_media_event(self, source_id, person_id, cur, ged):
cur.execute(gcc.SELECT_MEDIA_SOURCE_EVENT_LINK, (person_id, source_id))
media_ids = cur.fetchall()
for media_id in media_ids:
ged.write(f"3 OBJE @O{str(media_id[0])}@\n")
def write_source_media_event_couple(self, source_id, couple_id, cur, ged):
cur.execute(gcc.SELECT_MEDIA_SOURCE_EVENT_LINK_COUPLE, (couple_id, source_id))
media_ids = cur.fetchall()
for media_id in media_ids:
ged.write(f"3 OBJE @O{str(media_id[0])}@\n")
def write_source_note_event(self, source_id, event_id, cur, ged):
cur.execute(
gcc.SELECT_NOTE_SOURCE_EVENT_LINK, (event_id, source_id))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"2 SOUR @S{str(source_id)}@\n")
ged.write(f"3 NOTE @N{str(note_id[0])}@\n")
def write_couple_note(self, couple_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_COUPLE_LINKS, (couple_id,))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"1 NOTE @N{str(note_id[0])}@\n")
def write_repository_note(self, repository_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_REPOSITORY_LINKS, (repository_id,))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"1 NOTE @N{str(note_id[0])}@\n")
def write_source_note(self, source_id, cur, ged):
cur.execute(gcc.SELECT_NOTE_SOURCE_LINKS, (source_id,))
note_ids = cur.fetchall()
for note_id in note_ids:
ged.write(f"1 NOTE @N{str(note_id[0])}@\n")
def get_eventless_couples(self, person_id, cur):
cur.execute(gcc.SELECT_COUPLE_PER_PERSON, (person_id, person_id))
eventless_couples = [i[0] for i in cur.fetchall()]
return eventless_couples
def get_adopter(self, person_id, couple_id, cur):
cur.execute(gcc.SELECT_COUPLE_PARTNERS, (couple_id,))
result = cur.fetchone()
if result == (None, None):
adopter = None
elif result[0] is None:
adopter = "WIFE"
elif result[1] is None:
adopter = "HUSB"
else:
adopter = "BOTH"
return adopter
def write_names(self, person_id, cur, ged):
all_names = self.get_names(person_id, cur)
for aka in all_names:
sort_order, name_type, name_id = aka
split = sort_order.split()
surname = split.pop(0).rstrip(", ")
given = " ".join(split)
name = f"{given} /{surname}/"
ged.write(f"1 NAME {name}\n")
if name_type != "birth name":
ged.write(f"2 TYPE {name_type}\n")
self.write_sources_name(cur, person_id, name_id, ged)
self.write_name_note_pointers(name_id, cur, ged)
cur.execute(gcc.SELECT_TRANSCRIPTIONS_NAME, (name_id,))
results = cur.fetchall()
for tup in results:
tag = None
romanized, phonetic, transcription, transcription_type = tup
if romanized == 1:
tag = "ROMN"
elif phonetic == 1:
tag = "FONE"
if tag:
ged.write(f"2 {tag} {transcription}\n")
if transcription_type:
ged.write(f"3 TYPE {transcription_type}\n")
def split_string(self, stored_text):
def split_paragraph(paragraph):
concatenations = wrap(
paragraph, width=width, subsequent_indent=" ",
break_on_hyphens=False)
return concatenations
width = 248
text = stored_text.strip()
if len(text) <= width and "\n" not in text:
return [[text]]
paragraph_list = []
paragraphs = text.split("\n")
for paragraph in paragraphs:
if len(paragraph) <= width:
paragraph_list.append([f"{paragraph}\n"])
else:
concatenations = split_paragraph(paragraph)
paragraph_list.append(concatenations)
return paragraph_list
def write_citation(self, num, citation, ged):
""" Based on `write_notes()`. """
concnum = str(int(num) + 1)
concatenations = self.split_string(citation)
cont_next = False
for lst in concatenations:
for idx, line in enumerate(lst):
if line == "\n":
ged.write(f"{num} CONT \n")
cont_next = True
elif line.endswith("\n") and cont_next:
ged.write(f"{num} CONT {line}")
cont_next = False
elif line.endswith("\n"):
ged.write(f"{num} CONC {line}")
cont_next = False
elif cont_next:
ged.write(f"{num} CONT {line}\n")
cont_next = False
else:
if idx == 0:
tag = "PAGE"
else:
tag = "CONC"
num = concnum
ged.write(f"{num} {tag} {line}\n")
cont_next = False
def write_assertion(self, num, assertion, ged):
""" Based on `write_notes()`. """
concnum = str(int(num) + 1)
assertion_concatenations = self.split_string(assertion)
cont_next = False
for lst in assertion_concatenations:
for idx, line in enumerate(lst):
if line == "\n":
ged.write(f"{num} CONT \n")
cont_next = True
elif line.endswith("\n") and cont_next:
ged.write(f"{num} CONT {line}")
cont_next = False
elif line.endswith("\n"):
ged.write(f"{num} CONC {line}")
cont_next = False
elif cont_next:
ged.write(f"{num} CONT {line}\n")
cont_next = False
else:
if idx == 0:
tag = "TEXT"
else:
tag = "CONC"
num = concnum
ged.write(f"{num} {tag} {line}\n")
cont_next = False
def write_sources_name(self, cur, person_id, name_id, ged):
""" INDI.NAME.SOUR.DATA.TEXT """
cur.execute(gcc.SELECT_CITATION_SOURCE_NAME, (name_id, person_id))
results = cur.fetchall()
for tup in results:
source_id, citation, assertion, surety = tup
ged.write(f"2 SOUR @S{str(source_id)}@\n")
self.write_citation("3", citation, ged)
ged.write(f"3 DATA\n")
self.write_assertion("4", assertion, ged)
if surety:
gedcom_surety = round(surety * 0.6)
ged.write(f"3 QUAY {gedcom_surety}\n")
self.write_source_media_name(source_id, person_id, cur, ged)
self.write_source_note_name(source_id, person_id, cur, ged)
def write_sources_event(self, cur, event_id, person_id, ged):
""" INDI.EVEN.SOUR.DATA.TEXT """
cur.execute(gcc.SELECT_CITATION_SOURCE_EVENT, (event_id,))
results = cur.fetchall()
for idx, tup in enumerate(results):
lst = [i for i in tup[0:-1] if i or len(i) != 0]
lst.append(tup[-1])
source_id, citation, assertion, surety = lst
ged.write(f"2 SOUR @S{str(source_id)}@\n")
self.write_citation("3", citation, ged)
ged.write(f"3 DATA\n")
self.write_assertion("4", assertion, ged)
if surety:
gedcom_surety = round(surety * 0.6)
ged.write(f"3 QUAY {gedcom_surety}\n")
self.write_source_media_event(source_id, person_id, cur, ged)
self.write_source_note_event(source_id, event_id, cur, ged)
def write_sources_event_couple(self, cur, event_id, couple_id, ged):
""" FAM.EVEN.SOUR.DATA.TEXT """
cur.execute(gcc.SELECT_CITATION_SOURCE_EVENT_COUPLE, (event_id,))
results = cur.fetchall()
for idx, tup in enumerate(results):
lst = [i for i in tup[0:-1] if i or len(i) != 0]
lst.append(tup[-1])
source_id, citation, assertion, surety = lst
ged.write(f"2 SOUR @S{str(source_id)}@\n")
self.write_citation("3", citation, ged)
ged.write(f"3 DATA\n")
self.write_assertion("4", assertion, ged)
if surety:
gedcom_surety = round(surety * 0.6)
ged.write(f"3 QUAY {gedcom_surety}\n")
self.write_source_media_event_couple(source_id, couple_id, cur, ged)
self.write_source_note_event(source_id, event_id, cur, ged)
def get_couple_events(self, person_id, cur):
cur.execute(gcc.SELECT_EVENTS_COUPLE, (person_id, person_id))
couple_events = [i[0] for i in cur.fetchall()]
return couple_events
def fix_date(self, date):
""" Still haven't done gregorian/julian/OS/NS/AD/BC. """
rangge = False
span = False
model = list(gcc.MODEL_DATE)
slots = date.split("-")
for idx, part in enumerate(slots):
if len(part) == 0:
pass
else:
model[idx] = part
# Make prefixes all caps.
if model[0]:
model[0] = model[0].upper()
if model[6]:
model[6] = model[6].upper()
# Get rid of leading zeroes in years < 1000.
if model[1]:
model[1] = str(int(model[1]))
if model[7]:
model[7] = str(int(model[7]))
# Change month to GEDCOM abbreviation & change to all caps.
if model[2]:
model[2] = gcc.MONTHS2[model[2]].upper()
if model[8]:
model[8] = gcc.MONTHS2[model[8]].upper()
# Get rid of leading zeroes in days.
if model[3]:
model[3] = str(int(model[3]))
if model[3] == "0":
model[3] = ""
if model[9]:
model[9] = str(int(model[9]))
if model[9] == "0":
model[9] = ""
# Change suffix to all caps but fix this per specs someday.
if model[4]:
model[4] = model[4].upper()
if model[10]:
model[10] = model[10].upper()
# Change link to all caps. Flag compound dates.
if model[5]:
model[5] = model[5].upper()
if model[5] == "AND":
rangge = True
elif model[5] == "TO":
span = True
# Reorder date parts per GEDCOM specs.
ged_order = [
model[0], model[3], model[2], model[1], model[4], model[5],
model[6], model[9], model[8], model[7], model[10]]
# Add leading prefix for spans and ranges.
if rangge:
ged_order.insert(0, "BET")
elif span:
ged_order.insert(0, "FROM")
# Replace nulls with empty strings.
fixed = []
for part in ged_order:
if part:
fixed.append(part)
ged_date = " ".join(fixed)
return ged_date
def get_nested_place_string(self, nested_place_id, cur):
""" Dumb down UNIGEDS place to GEDCOM place. """
place_names = []
cur.execute(gcc.SELECT_NESTED_PLACES, (nested_place_id,))
result = cur.fetchone()
nesting = [i for i in result]
for nest in nesting:
if nest != 1:
cur.execute(gcc.SELECT_PLACE_NAMES, (nest,))
name = cur.fetchone()[0]
place_names.append(name)
else:
break
return ", ".join(place_names)
def get_smallest_place_nest(self, nested_place_id, cur):
cur.execute(gcc.SELECT_PLACE_NEST0, (nested_place_id,))
return cur.fetchone()[0]
def get_events(self, person_id, cur):
cur.execute(gcc.SELECT_GENERIC_EVENTS, (person_id,))
return [list(i) for i in cur.fetchall()]
def get_names(self, person_id, cur):
cur.execute(gcc.SELECT_PERSON_NAMES, (person_id,))
return [list(i) for i in cur.fetchall()]
def get_persons(self, cur):
cur.execute(gcc.SELECT_PERSON_VALUES)
self.persons = [list(i) for i in cur.fetchall()]
def get_couples(self, cur):
cur.execute(gcc.SELECT_COUPLE_VALUES)
self.couples = cur.fetchall()
def get_media(self, cur):
cur.execute(gcc.SELECT_MEDIA_VALUES)
self.media = cur.fetchall()
def get_notes(self, cur):
cur.execute(gcc.SELECT_NOTES_VALUES)
self.notes = cur.fetchall()
def get_repositories(self, cur):
cur.execute(gcc.SELECT_REPOSITORIES_VALUES)
self.repositories = cur.fetchall()
def get_sources(self, cur):
cur.execute(gcc.SELECT_SOURCES_VALUES)
self.sources = cur.fetchall()
def write_buts(self, key):
except_funx = {
'assertions': self.except_assertions,}
for kk,vv in except_funx.items():
if kk == key:
except_funx[kk](key)
def except_assertions(self, key):
lst = exceptions[key]
for tup in lst:
if len(tup) == 13:
(source, citation, date_assertion, place_assertion,
particulars_assertion, age_assertion, role_assertion,
person_id, person_name, event_type, event_date, event_place,
event_particulars) = tup
if event_date == "-0000-00-00-------":
event_date = "unknown date"
else:
event_date = self.fix_date(event_date)
spaces = event_date.count(" ")
if spaces == 2 or event_date == "unknown date":
link = "on"
elif spaces in (0, 1):
link = "in"
if len(event_place) == 0 or event_place == "unknown":
event_place = "unknown place"
if len(event_particulars) == 0:
event_particulars = "nothing further"
not_blank = ""
for assertion in (
date_assertion, place_assertion, particulars_assertion,
age_assertion, role_assertion):
if len(assertion) != 0:
not_blank = assertion
break
instrux = (
f"{person_name} (ID #{person_id}): mentioned in the "
f"assertion '{not_blank}' by the source ({source}) at the "
f"citation '{citation}' regarding the {event_type} event "
f"that happened at {event_place} {link} {event_date}. "
f"Further details for the event: {event_particulars}.")
elif len(tup) == 5:
source, citation, name_assertion, person_id, person_name = tup
instrux = (f"{person_name} (ID #{person_id}): mentioned in "
f"the assertion: '{name_assertion}' by the source ({source}) "
f"at the citation '{citation}'.")
self.buts.write(f"\n\n{instrux}")
def write_head(self, ged):
ged.write("0 HEAD\n")
ged.write("1 SOUR TREEBARD\n")
ged.write("1 SUBM @SUBM1@\n")
ged.write("1 GEDC\n")
ged.write("2 VERS 5.5.1\n")
ged.write("2 FORM LINEAGE-LINKED\n")
ged.write("1 CHAR UTF-8\n")
ged.write("0 @SUBM1@ SUBM\n")
ged.write(f"1 NAME {self.creator}\n")
def cancel(self):
self.destroy()
def print_stuff(self):
# print("line", look(seeline()).lineno, "self.persons", self.persons)
# print("line", look(seeline()).lineno, "self.names", self.names)
# print("line", look(seeline()).lineno, "self.couples", self.couples)
# print("line", look(seeline()).lineno, "self.media", self.media)
# print("line", look(seeline()).lineno, "self.notes", self.notes)
# print("line", look(seeline()).lineno, "self.repositories", self.repositories)
# print("line", look(seeline()).lineno, "self.sources", self.sources)
# print("line", look(seeline()).lineno, "exceptions", exceptions)
pass