Genealetter/src/event.py
2021-09-02 07:05:51 +02:00

203 lines
7.3 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import date
from person import Person
from mariage import Mariage
event_types = ['N', 'M', 'A', 'D']
class Event:
def __init__(self, event_type: str, event_date: date, current_date: date,
person_a: Person, person_b: Person = None, union_type=None):
if event_type not in event_types:
raise ValueError('{} is not in {}'.format(event_type, event_types))
self._type = event_type
self._date = event_date
self._current_date = current_date
self._p_a = person_a
self._p_b = person_b
self._union_type = union_type
def get_year_span(self) -> int:
return self._current_date.year - self._date.year
def event_description(self) -> str:
y = self.get_year_span()
union_descr = ''
if self._union_type == 'A':
union_descr = 's\'est uni{} à'.format('' if self._p_a.is_male() else 'e')
elif self._union_type == 'M':
union_descr = 'a épousé'
union_str = ' ({} {})'.format(union_descr, self._p_b.formatted_name()) if self._p_b else ''
if self._type == 'N':
return '{}{}{} il y a {} an{}'.format(
self._p_a.formatted_name(),
union_str,
'' if self._p_a.is_male() else 'e',
y,
's' if y > 1 else ''
)
if self._type == 'M':
return '{} a épousé {} il y a {} an{}'.format(
self._p_a.formatted_name(),
self._p_b.formatted_name(),
y,
's' if y > 1 else ''
)
if self._type == 'A':
return '{} s\'est uni{} à {} il y a {} an{}'.format(
self._p_a.formatted_name(),
'' if self._p_a.is_male() else 'e',
self._p_b.formatted_name(),
y,
's' if y > 1 else ''
)
return '{}{} décédé{} il y a {} an{}'.format(
self._p_a.formatted_name(),
union_str,
'' if self._p_a.is_male() else 'e',
y,
's' if y > 1 else ''
)
def event_date_as_str(self) -> str:
day = str(self._date.day) if self._date.day > 9 else '0' + str(self._date.day)
month = str(self._date.month) if self._date.month > 9 else '0' + str(self._date.month)
return '{}/{}/{}'.format(day, month, self._date.year)
def get_actual_weekday(self) -> int:
return self._current_date.weekday()
def type_str(self):
if self._type == 'A':
return 'U'
return self._type
def load_persons_to_dict(members_file: str) -> dict:
id_to_person = {}
first_line = True
# CSV structure from Heredis
# Gender,Name,First Names,N : Date of Birth,D : Date of Death,Name of father (to detect in laws)
with open(members_file, 'r', encoding='utf-8') as members:
for line in members:
if first_line:
first_line = False
continue
line.strip()
infos = line.split(',')
birth = infos[3][4:].split('/')
death = None if infos[4] == '' else infos[4][4:].split('/')
p = Person(infos[0], # Gender
infos[2], # First names
infos[1], # Last name
date(int(birth[2]), int(birth[1]), int(birth[0])), # Date of birth YYYY MM DD
None if not death else date(int(death[2]), int(death[1]), int(death[0])), # Date of death YYYY MM DD
infos[5] == '') # If empty, this is an in law
id_to_person[p.get_hash_id()] = p
return id_to_person
def load_mariage_to_list(mariages_file: str) -> list:
mariage_lst = []
first_line = True
# CSV format from Heredis
# T : Date of Event,Name1 | Name2, FirstName1 | FirstName 2, Event long name, DoB1 | DoB2
with open(mariages_file, 'r', encoding='utf-8') as mariages:
for line in mariages:
if first_line:
first_line = False
continue
line.strip()
infos = line.split(',')
union_type = infos[0][0]
doe = infos[0][4:].split('/')
name1 = infos[1].split('|')[0].strip()
name2 = infos[1].split('|')[1].strip()
first_name1 = infos[2].split('|')[0].strip()
first_name2 = infos[2].split('|')[1].strip()
dob1 = infos[4].split('|')[0].strip()[4:].split('/')
dob2 = infos[4].split('|')[1].strip()[4:].split('/')
id1 = Person.get_id(first_name1, name1, date(int(dob1[2]), int(dob1[1]), int(dob1[0])))
id2 = Person.get_id(first_name2, name2, date(int(dob2[2]), int(dob2[1]), int(dob2[0])))
m = Mariage(
id1,
id2,
date(int(doe[2]), int(doe[1]), int(doe[0])),
union_type
)
mariage_lst.append(m)
return mariage_lst
def find_significant_other(mariages: list, uid: int) -> (int, str):
for m in mariages:
if m.in_this_union(uid):
return m.get_so(uid), m.union()
return -1, ''
def create_events_from_span(start: date, end: date, id_to_person: dict, mariages: list) -> list:
cur_year = start.year
events = []
for p in id_to_person.values():
so, union = find_significant_other(mariages, p.get_hash_id())
if so == p.get_hash_id():
print(f"What ??? {so}")
if not p.is_dead():
birth = p.birth()
birth_in_year = date(cur_year, birth.month, birth.day)
if start <= birth_in_year <= end:
e = Event('N', birth, birth_in_year,
p, None if so == -1 else id_to_person[so], None if so == -1 else union)
events.append(e)
birth_in_year = date(cur_year + 1, birth.month, birth.day)
if start <= birth_in_year <= end:
e = Event('N', birth, birth_in_year,
p, None if so == -1 else id_to_person[so], None if so == -1 else union)
events.append(e)
else:
death = p.death()
death_in_year = date(cur_year, death.month, death.day)
if start <= death_in_year <= end:
e = Event('D', death, death_in_year,
p, None if so == -1 else id_to_person[so], None if so == -1 else union)
events.append(e)
death_in_year = date(cur_year + 1, death.month, death.day)
if start <= death_in_year <= end:
e = Event('D', death, death_in_year,
p, None if so == -1 else id_to_person[so], None if so == -1 else union)
events.append(e)
for m in mariages:
m_date = m.event_date()
date_in_year = date(cur_year, m_date.month, m_date.day)
if start <= date_in_year <= end:
e = Event(m.union(), m_date, date_in_year,
id_to_person[m.id_a()], id_to_person[m.id_b()])
events.append(e)
date_in_year = date(cur_year + 1, m_date.month, m_date.day)
if start <= date_in_year <= end:
e = Event(m.union(), m_date, date_in_year,
id_to_person[m.id_a()], id_to_person[m.id_b()])
events.append(e)
return events