def run(database, document, date): """ Display people probably alive and their ages on a particular date. """ # setup the simple access functions sdb = SimpleAccess(database) sdoc = SimpleDoc(document) stab = QuickTable(sdb) if not date.get_valid(): sdoc.paragraph("Date is not a valid date.") return # display the title if date.get_day_valid(): sdoc.title(_("People and their ages the %s") % displayer.display(date)) else: sdoc.title(_("People and their ages on %s") % displayer.display(date)) stab.columns(_("Person"), _("Age"), _("Status")) # Actual Date makes column unicode alive_matches = 0 dead_matches = 0 for person in sdb.all_people(): alive, birth, death, explain, relative = \ probably_alive(person, database, date, return_range=True) # Doesn't show people probably alive but no way of figuring an age: if alive: if birth: diff_span = (date - birth) stab.row(person, str(diff_span), _("Alive: %s") % explain) stab.row_sort_val(1, int(diff_span)) else: stab.row(person, "", _("Alive: %s") % explain) stab.row_sort_val(1, 0) alive_matches += 1 else: # not alive if birth: diff_span = (date - birth) stab.row(person, str(diff_span), _("Deceased: %s") % explain) stab.row_sort_val(1, int(diff_span)) else: stab.row(person, "", _("Deceased: %s") % explain) stab.row_sort_val(1, 1) dead_matches += 1 document.has_data = (alive_matches + dead_matches) > 0 sdoc.paragraph( _("\nLiving matches: %(alive)d, " "Deceased matches: %(dead)d\n") % { 'alive': alive_matches, 'dead': dead_matches }) if document.has_data: stab.write(sdoc) sdoc.paragraph("")
def run(database, document, date): """ Display people probably alive and their ages on a particular date. """ # setup the simple access functions sdb = SimpleAccess(database) sdoc = SimpleDoc(document) stab = QuickTable(sdb) if not date.get_valid(): sdoc.paragraph("Date is not a valid date.") return # display the title if date.get_day_valid(): sdoc.title(_("People and their ages the %s") % displayer.display(date)) else: sdoc.title(_("People and their ages on %s") % displayer.display(date)) stab.columns(_("Person"), _("Age"), _("Status")) # Actual Date makes column unicode alive_matches = 0 dead_matches = 0 for person in sdb.all_people(): alive, birth, death, explain, relative = \ probably_alive(person, database, date, return_range=True) # Doesn't show people probably alive but no way of figuring an age: if alive: if birth: diff_span = (date - birth) stab.row(person, str(diff_span), _("Alive: %s") % explain) stab.row_sort_val(1, int(diff_span)) else: stab.row(person, "", _("Alive: %s") % explain) stab.row_sort_val(1, 0) alive_matches += 1 else: # not alive if birth: diff_span = (date - birth) stab.row(person, str(diff_span), _("Deceased: %s") % explain) stab.row_sort_val(1, int(diff_span)) else: stab.row(person, "", _("Deceased: %s") % explain) stab.row_sort_val(1, 1) dead_matches += 1 document.has_data = (alive_matches + dead_matches) > 0 sdoc.paragraph(_("\nLiving matches: %(alive)d, " "Deceased matches: %(dead)d\n") % {'alive' : alive_matches, 'dead' : dead_matches}) if document.has_data: stab.write(sdoc) sdoc.paragraph("")
def get(self, args: Dict, handle: Handle) -> Response: """Determine if person alive.""" db_handle = get_db_handle() person = get_person_by_handle(db_handle, handle) if person == {}: abort(404) data = probably_alive( person, db_handle, max_sib_age_diff=args["max_sibling_age_difference"], max_age_prob_alive=args["max_age_probably_alive"], avg_generation_gap=args["average_generation_gap"], ) return self.response(200, {"living": data})
def get_full_person_info(self, person): retval = "" b_date = "0" b_place = "" birth_ref = person.get_birth_ref() for event_ref in person.get_event_ref_list(): role = int(event_ref.get_role()) if role != EventRoleType.PRIMARY: next event = self.db.get_event_from_handle(event_ref.ref) etype = int(event.get_type()) val = PERSONCONSTANTEVENTS.get(etype) if birth_ref: birth = self.db.get_event_from_handle(birth_ref.ref) if birth: b_date = self.format_date(birth.get_date_object()) if not b_date: b_date = "0" place_handle = birth.get_place_handle() if place_handle: b_place = _pd.display_event(self.db, birth) if probably_alive(person, self.db): d_date = "" else: d_date = "0" d_place = "" death_ref = person.get_death_ref() if death_ref: death = self.db.get_event_from_handle(death_ref.ref) if death: d_date = self.format_date(death.get_date_object()) place_handle = death.get_place_handle() if place_handle: d_place = _pd.display_event(self.db, death) retval = retval + "%s " % b_date if b_place != "": retval = retval + "#bp %s " % self.rem_spaces(b_place) retval = retval + "%s " % d_date if d_place != "": retval = retval + "#dp %s " % self.rem_spaces(d_place) return retval
def get_full_person_info(self, person): # FIXME: #if self.restrict: # return "0 " retval = "" b_date = "0" b_place = "" birth_ref = person.get_birth_ref() if birth_ref: birth = self.db.get_event_from_handle(birth_ref.ref) if birth: b_date = self.format_date(birth.get_date_object()) place_handle = birth.get_place_handle() if place_handle: place = self.db.get_place_from_handle(place_handle) b_place = place.get_title() if probably_alive(person, self.db): d_date = "" else: d_date = "0" d_place = "" death_ref = person.get_death_ref() if death_ref: death = self.db.get_event_from_handle(death_ref.ref) if death: d_date = self.format_date(death.get_date_object()) place_handle = death.get_place_handle() if place_handle: place = self.db.get_place_from_handle(place_handle) d_place = place.get_title() retval = retval + "%s " % b_date if b_place != "": retval = retval + "#bp %s " % self.rem_spaces(b_place) retval = retval + "%s " % d_date if d_place != "": retval = retval + "#dp %s " % self.rem_spaces(d_place) return retval
def get_full_person_info(self, person): # FIXME: #if self.restrict: # return "0 " retval = "" b_date = "0" b_place = "" birth_ref = person.get_birth_ref() if birth_ref: birth = self.db.get_event_from_handle(birth_ref.ref) if birth: b_date = self.format_date( birth.get_date_object()) place_handle = birth.get_place_handle() if place_handle: b_place = _pd.display_event(self.db, birth) if probably_alive(person,self.db): d_date = "" else: d_date = "0" d_place = "" death_ref = person.get_death_ref() if death_ref: death = self.db.get_event_from_handle(death_ref.ref) if death: d_date = self.format_date( death.get_date_object()) place_handle = death.get_place_handle() if place_handle: d_place = _pd.display_event(self.db, death) retval = retval + "%s " % b_date if b_place != "": retval = retval + "#bp %s " % self.rem_spaces(b_place) retval = retval + "%s " % d_date if d_place != "": retval = retval + "#dp %s " % self.rem_spaces(d_place) return retval
def _count_descendants(database, person, root_death_date, generation, total, seen, outlived, alive, handles): # "total", "seen", "outlived" and "alive" are lists with the respective # descendant count per generation. "handles" is a list of lists of person # handles per generation. These parameters are modified by this function! for family_handle in person.get_family_handle_list(): family = database.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): child = database.get_person_from_handle(child_ref.ref) birth_date = _get_date(database, child.get_birth_ref()) death_date = _get_date(database, child.get_death_ref()) # Total number of descendants. _increment(total, 0, 1, generation) # Number of descendants born during lifetime of queried person. if root_death_date and birth_date and \ birth_date.match(root_death_date, "<<"): _increment(seen, 0, 1, generation) # Number of descendants that queried person outlived. if root_death_date and death_date and \ death_date.match(root_death_date, "<<"): _increment(outlived, 0, 1, generation) # Number of descendants now alive. if probably_alive(child, database): _increment(alive, 0, 1, generation) # Handle to this descendant. _increment(handles, [], [child.handle], generation) _count_descendants(database, child, root_death_date, generation + 1, total, seen, outlived, alive, handles)
def write_person(self, key): """ Output birth, death, parentage, marriage and notes information """ def write_more_header(first, name): """ convenience function """ if first: self.doc.start_paragraph('DAR-MoreHeader') self.doc.write_text( self._('More about %(person_name)s:') % {'person_name': name}) self.doc.end_paragraph() return False person_handle = self.map[key] person = self._db.get_person_from_handle(person_handle) plist = person.get_media_list() self.__narrator.set_subject(person) if self.addimages and len(plist) > 0: photo = plist[0] utils.insert_image(self._db, self.doc, photo, self._user) self.doc.start_paragraph("DAR-First-Entry", "%d." % self._get_s_s(key)) name = self._nd.display(person) if not name: name = self._("Unknown") mark = utils.get_person_mark(self._db, person) self.doc.start_bold() self.doc.write_text(name, mark) if name[-1:] == '.': self.doc.write_text_citation("%s " % self.endnotes(person)) elif name: self.doc.write_text_citation("%s. " % self.endnotes(person)) self.doc.end_bold() if self.want_ids: self.doc.write_text('(%s) ' % person.get_gramps_id()) if self.dupperson: # Check for duplicate record (result of distant cousins marrying) for dkey in sorted(self.map): if dkey >= key: break if self.map[key] == self.map[dkey]: self.doc.write_text( self._("%(name)s is the same person as [%(id_str)s].") % { 'name': '', 'id_str': str(dkey) }) self.doc.end_paragraph() return 1 # Duplicate person if not self.verbose: self.write_parents(person) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) # Write Death and/or Burial text only if not probably alive if not probably_alive(person, self.database): text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) if self.verbose: self.write_parents(person) if not key % 2 or key == 1: self.write_marriage(person) self.doc.end_paragraph() if key == 1: self.write_mate(person) notelist = person.get_note_list() if len(notelist) > 0 and self.includenotes: self.doc.start_paragraph("DAR-NoteHeader") # feature request 2356: avoid genitive form self.doc.write_text(self._("Notes for %s") % name) self.doc.end_paragraph() for notehandle in notelist: note = self._db.get_note_from_handle(notehandle) self.doc.write_styled_note( note.get_styledtext(), note.get_format(), "DAR-Entry", contains_html=(note.get_type() == NoteType.HTML_CODE)) first = True if self.inc_names: for alt_name in person.get_alternate_names(): first = write_more_header(first, name) self.doc.start_paragraph('DAR-MoreDetails') atype = self._get_type(alt_name.get_type()) self.doc.write_text_citation( self._('%(type)s: %(value)s%(endnotes)s') % { 'type': self._(atype), 'value': alt_name.get_regular_name(), 'endnotes': self.endnotes(alt_name) }) self.doc.end_paragraph() if self.inc_events: birth_ref = person.get_birth_ref() death_ref = person.get_death_ref() for event_ref in person.get_primary_event_ref_list(): if event_ref == birth_ref or event_ref == death_ref: continue first = write_more_header(first, name) self.write_event(event_ref) if self.other_events: for event_ref in person.get_event_ref_list(): role = event_ref.get_role() if role in (EventRoleType.PRIMARY, EventRoleType.FAMILY): continue first = write_more_header(first, name) self.write_event(event_ref) if self.inc_addr: for addr in person.get_address_list(): first = write_more_header(first, name) self.doc.start_paragraph('DAR-MoreDetails') text = utils.get_address_str(addr) self.doc.write_text(self._('Address: ')) if self.fulldate: date = self._get_date(addr.get_date_object()) else: date = addr.get_date_object().get_year() if date: # translators: needed for Arabic, ignore otherwise self.doc.write_text(self._('%s, ') % date) self.doc.write_text(text) self.doc.write_text_citation(self.endnotes(addr)) self.doc.end_paragraph() if self.inc_attrs: attrs = person.get_attribute_list() if attrs: first = write_more_header(first, name) for attr in attrs: self.doc.start_paragraph('DAR-MoreDetails') attr_name = attr.get_type().type2base() # translators: needed for French, ignore otherwise text = self._("%(type)s: %(value)s%(endnotes)s") % { 'type': self._(attr_name), 'value': attr.get_value(), 'endnotes': self.endnotes(attr) } self.doc.write_text_citation(text) self.doc.end_paragraph() return 0 # Not duplicate person
def exportData(database, filename, error_dialog=None, option_box=None, callback=None): if not callable(callback): callback = lambda percent: None # dummy with OpenFileOrStdout(filename) as fp: total = (len(database.note_map) + len(database.person_map) + len(database.event_map) + len(database.family_map) + len(database.repository_map) + len(database.place_map) + len(database.media_map) + len(database.source_map)) count = 0.0 # GProlog ISO directives: # /number must match the number of arguments to functions: fp.write(":- discontiguous(data/2).\n") fp.write(":- discontiguous(is_alive/2).\n") fp.write(":- discontiguous(parent/2).\n") # Rules: fp.write("grandparent(X, Y) :- parent(X, Z), parent(Z, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).\n") fp.write("sibling(X, Y) :- parent(Z, X), parent(Z, Y), X \= Y.\n") # --------------------------------- # Notes # --------------------------------- for note_handle in database.note_map.keys(): note = database.note_map[note_handle] #write_line(fp, "note_details(%s, %s)" % (note_handle, note)) count += 1 callback(100 * count / total) # --------------------------------- # Event # --------------------------------- for event_handle in database.event_map.keys(): event = database.event_map[event_handle] #write_line(fp, "event:", event_handle, event) count += 1 callback(100 * count / total) # --------------------------------- # Person # --------------------------------- for person_handle in database.person_map.keys(): data = database.person_map[person_handle] person = Person.create(data) gid = person.gramps_id.lower() fp.write("data(%s, '%s').\n" % (gid, escape(name_displayer.display(person)))) fp.write("is_alive(%s, '%s').\n" % (gid, probably_alive(person, database))) count += 1 callback(100 * count / total) # --------------------------------- # Family # --------------------------------- for family_handle in database.family_map.keys(): data = database.family_map[family_handle] family = Family.create(data) father_handle = family.get_father_handle() mother_handle = family.get_mother_handle() parents = [] if mother_handle: mother = database.get_person_from_handle(mother_handle) if mother: parents.append(mother.gramps_id.lower()) if father_handle: father = database.get_person_from_handle(father_handle) if father: parents.append(father.gramps_id.lower()) children = [] for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = database.get_person_from_handle(child_handle) if child: children.append(child.gramps_id.lower()) for pid in parents: for cid in children: fp.write("parent(%s, %s).\n" % (pid, cid)) count += 1 callback(100 * count / total) # --------------------------------- # Repository # --------------------------------- for repository_handle in database.repository_map.keys(): repository = database.repository_map[repository_handle] #write_line(fp, "repository:", repository_handle, repository) count += 1 callback(100 * count / total) # --------------------------------- # Place # --------------------------------- for place_handle in database.place_map.keys(): place = database.place_map[place_handle] #write_line(fp, "place:", place_handle, place) count += 1 callback(100 * count / total) # --------------------------------- # Source # --------------------------------- for source_handle in database.source_map.keys(): source = database.source_map[source_handle] #write_line(fp, "source:", source_handle, source) count += 1 callback(100 * count / total) # --------------------------------- # Media # --------------------------------- for media_handle in database.media_map.keys(): media = database.media_map[media_handle] #write_line(fp, "media:", media_handle, media) count += 1 callback(100 * count / total) return True
def find_records(db, filter, top_size, callname, trans_text=glocale.translation.sgettext, name_format=None, living_mode=LivingProxyDb.MODE_INCLUDE_ALL): """ @param trans_text: allow deferred translation of strings @type trans_text: a GrampsLocale sgettext instance trans_text is a defined keyword (see po/update_po.py, po/genpot.sh) :param name_format: optional format to control display of person's name :type name_format: None or int :param living_mode: enable optional control of living people's records :type living_mode: int """ def get_unfiltered_person_from_handle(person_handle): if living_mode == LivingProxyDb.MODE_INCLUDE_ALL: return db.get_person_from_handle(person_handle) else: # we are in the proxy so get the person before proxy changes return db.get_unfiltered_person(person_handle) today = datetime.date.today() today_date = Date(today.year, today.month, today.day) # Person records person_youngestliving = [] person_oldestliving = [] person_youngestdied = [] person_oldestdied = [] person_youngestmarried = [] person_oldestmarried = [] person_youngestdivorced = [] person_oldestdivorced = [] person_youngestfather = [] person_youngestmother = [] person_oldestfather = [] person_oldestmother = [] person_handle_list = db.iter_person_handles() if filter: person_handle_list = filter.apply(db, person_handle_list) for person_handle in person_handle_list: person = db.get_person_from_handle(person_handle) unfil_person = get_unfiltered_person_from_handle(person_handle) if person is None: continue # FIXME this should check for a "fallback" birth also/instead birth_ref = person.get_birth_ref() if not birth_ref: # No birth event, so we can't calculate any age. continue birth = db.get_event_from_handle(birth_ref.ref) birth_date = birth.get_date_object() death_date = _find_death_date(db, person) if not _good_date(birth_date): # Birth date unknown or incomplete, so we can't calculate any age. continue name = _get_styled_primary_name(person, callname, trans_text=trans_text, name_format=name_format) if death_date is None: if probably_alive(unfil_person, db): # Still living, look for age records _record(person_youngestliving, person_oldestliving, today_date - birth_date, name, 'Person', person_handle, top_size) elif _good_date(death_date): # Already died, look for age records _record(person_youngestdied, person_oldestdied, death_date - birth_date, name, 'Person', person_handle, top_size) for family_handle in person.get_family_handle_list(): family = db.get_family_from_handle(family_handle) marriage_date = None divorce_date = None for event_ref in family.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) if (event.get_type().is_marriage() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): marriage_date = event.get_date_object() elif (event.get_type().is_divorce() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): divorce_date = event.get_date_object() if _good_date(marriage_date): _record(person_youngestmarried, person_oldestmarried, marriage_date - birth_date, name, 'Person', person_handle, top_size) if _good_date(divorce_date): _record(person_youngestdivorced, person_oldestdivorced, divorce_date - birth_date, name, 'Person', person_handle, top_size) for child_ref in family.get_child_ref_list(): if person.get_gender() == person.MALE: relation = child_ref.get_father_relation() elif person.get_gender() == person.FEMALE: relation = child_ref.get_mother_relation() else: continue if relation != ChildRefType.BIRTH: continue child = db.get_person_from_handle(child_ref.ref) # FIXME this should check for a "fallback" birth also/instead child_birth_ref = child.get_birth_ref() if not child_birth_ref: continue child_birth = db.get_event_from_handle(child_birth_ref.ref) child_birth_date = child_birth.get_date_object() if not _good_date(child_birth_date): continue if person.get_gender() == person.MALE: _record(person_youngestfather, person_oldestfather, child_birth_date - birth_date, name, 'Person', person_handle, top_size) elif person.get_gender() == person.FEMALE: _record(person_youngestmother, person_oldestmother, child_birth_date - birth_date, name, 'Person', person_handle, top_size) # Family records family_mostchildren = [] family_youngestmarried = [] family_oldestmarried = [] family_shortest = [] family_longest = [] family_smallestagediff = [] family_biggestagediff = [] for family in db.iter_families(): #family = db.get_family_from_handle(family_handle) if living_mode != LivingProxyDb.MODE_INCLUDE_ALL: # FIXME no iter_families method in LivingProxyDb so do it this way family = db.get_family_from_handle(family.get_handle()) father_handle = family.get_father_handle() if not father_handle: continue mother_handle = family.get_mother_handle() if not mother_handle: continue # Test if either father or mother are in filter if filter: if not filter.apply(db, [father_handle, mother_handle]): continue father = db.get_person_from_handle(father_handle) unfil_father = get_unfiltered_person_from_handle(father_handle) if father is None: continue mother = db.get_person_from_handle(mother_handle) unfil_mother = get_unfiltered_person_from_handle(mother_handle) if mother is None: continue name = StyledText(trans_text("%(father)s and %(mother)s")) % { 'father': _get_styled_primary_name(father, callname, trans_text=trans_text, name_format=name_format), 'mother': _get_styled_primary_name(mother, callname, trans_text=trans_text, name_format=name_format) } if (living_mode == LivingProxyDb.MODE_INCLUDE_ALL or (not probably_alive(unfil_father, db) and not probably_alive(unfil_mother, db))): _record(None, family_mostchildren, len(family.get_child_ref_list()), name, 'Family', family.handle, top_size) father_birth_ref = father.get_birth_ref() if father_birth_ref: father_birth_date = db.get_event_from_handle( father_birth_ref.ref).get_date_object() else: father_birth_date = None mother_birth_ref = mother.get_birth_ref() if mother_birth_ref: mother_birth_date = db.get_event_from_handle( mother_birth_ref.ref).get_date_object() else: mother_birth_date = None if _good_date(father_birth_date) and _good_date(mother_birth_date): if father_birth_date >> mother_birth_date: _record(family_smallestagediff, family_biggestagediff, father_birth_date - mother_birth_date, name, 'Family', family.handle, top_size) elif mother_birth_date >> father_birth_date: _record(family_smallestagediff, family_biggestagediff, mother_birth_date - father_birth_date, name, 'Family', family.handle, top_size) marriage_date = None divorce = None divorce_date = None for event_ref in family.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) if (event.get_type().is_marriage() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): marriage_date = event.get_date_object() if (event and event.get_type().is_divorce() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): divorce = event divorce_date = event.get_date_object() father_death_date = _find_death_date(db, father) mother_death_date = _find_death_date(db, mother) if not _good_date(marriage_date): # Not married or marriage date unknown continue if divorce is not None and not _good_date(divorce_date): # Divorced but date unknown or inexact continue if (not probably_alive(unfil_father, db) and not _good_date(father_death_date)): # Father died but death date unknown or inexact continue if (not probably_alive(unfil_mother, db) and not _good_date(mother_death_date)): # Mother died but death date unknown or inexact continue if (divorce_date is None and father_death_date is None and mother_death_date is None): # Still married and alive if (probably_alive(unfil_father, db) and probably_alive(unfil_mother, db)): _record(family_youngestmarried, family_oldestmarried, today_date - marriage_date, name, 'Family', family.handle, top_size) elif (_good_date(divorce_date) or _good_date(father_death_date) or _good_date(mother_death_date)): end = None if _good_date(father_death_date) and _good_date(mother_death_date): end = min(father_death_date, mother_death_date) elif _good_date(father_death_date): end = father_death_date elif _good_date(mother_death_date): end = mother_death_date if _good_date(divorce_date): if end: end = min(end, divorce_date) else: end = divorce_date duration = end - marriage_date _record(family_shortest, family_longest, duration, name, 'Family', family.handle, top_size) #python 3 workaround: assign locals to tmp so we work with runtime version tmp = locals() return [(trans_text(text), varname, tmp[varname]) for (text, varname, default) in RECORDS]
def collect_data(self): """ This method runs through the data, and collects the relevant dates and text. """ people = self.database.iter_person_handles() with self._user.progress(_('Birthday and Anniversary Report'), _('Applying Filter...'), self.database.get_number_of_people()) as step: people = self.filter.apply(self.database, people, step) ngettext = self._locale.translation.ngettext # to see "nearby" comments rel_calc = get_relationship_calculator(reinit=True, clocale=self._locale) with self._user.progress(_('Birthday and Anniversary Report'), _('Reading database...'), len(people)) as step: for person_handle in people: step() person = self.database.get_person_from_handle(person_handle) birth_ref = person.get_birth_ref() birth_date = None if birth_ref: birth_event = self.database.get_event_from_handle(birth_ref.ref) birth_date = birth_event.get_date_object() if (self.birthdays and birth_date is not None and birth_date.is_valid()): birth_date = gregorian(birth_date) year = birth_date.get_year() month = birth_date.get_month() day = birth_date.get_day() prob_alive_date = Date(self.year, month, day) nyears = self.year - year # add some things to handle maiden name: father_lastname = None # husband, actually if self.maiden_name in ['spouse_first', 'spouse_last']: # get husband's last name: if person.get_gender() == Person.FEMALE: family_list = person.get_family_handle_list() if len(family_list) > 0: if self.maiden_name == 'spouse_first': fhandle = family_list[0] else: fhandle = family_list[-1] fam = self.database.get_family_from_handle(fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if mother_handle == person_handle: if father_handle: father = self.database.get_person_from_handle(father_handle) if father is not None: primary_name = father.get_primary_name() if primary_name: father_lastname = Surname.get_surname(primary_name.get_primary_surname()) short_name = self.get_name(person, father_lastname) alive = probably_alive(person, self.database, prob_alive_date) if ((self.alive and alive) or not self.alive): comment = "" if self.relationships: relation = rel_calc.get_one_relationship( self.database, self.center_person, person, olocale=self._locale) if relation: # FIXME this won't work for RTL languages comment = " --- %s" % relation if nyears == 0: text = self._('%(person)s, birth%(relation)s') % { 'person' : short_name, 'relation' : comment} else: # translators: leave all/any {...} untranslated text = ngettext('{person}, {age}{relation}', '{person}, {age}{relation}', nyears).format(person=short_name, age=nyears, relation=comment) self.add_day_item(text, month, day, person) if self.anniversaries: family_list = person.get_family_handle_list() for fhandle in family_list: fam = self.database.get_family_from_handle(fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if father_handle == person.get_handle(): spouse_handle = mother_handle else: continue # with next person if the father is not "person" # this will keep from duplicating the anniversary if spouse_handle: spouse = self.database.get_person_from_handle(spouse_handle) if spouse: spouse_name = self.get_name(spouse) short_name = self.get_name(person) # TEMP: this will handle ordered events # Gramps 3.0 will have a new mechanism for start/stop events are_married = None for event_ref in fam.get_event_ref_list(): event = self.database.get_event_from_handle(event_ref.ref) if event.type in [EventType.MARRIAGE, EventType.MARR_ALT]: are_married = event elif event.type in [EventType.DIVORCE, EventType.ANNULMENT, EventType.DIV_FILING]: are_married = None if are_married is not None: for event_ref in fam.get_event_ref_list(): event = self.database.get_event_from_handle(event_ref.ref) event_obj = event.get_date_object() if event_obj is not Date.EMPTY and event_obj.is_valid(): event_obj = gregorian(event_obj) year = event_obj.get_year() month = event_obj.get_month() day = event_obj.get_day() nyears = self.year - year if event_obj.is_valid(): if nyears == 0: text = self._("%(spouse)s and\n %(person)s, wedding") % { 'spouse' : spouse_name, 'person' : short_name} else: # translators: leave all/any {...} untranslated text = ngettext("{spouse} and\n {person}, {nyears}", "{spouse} and\n {person}, {nyears}", nyears).format(spouse=spouse_name, person=short_name, nyears=nyears) prob_alive_date = Date(self.year, month, day) alive1 = probably_alive(person, self.database, prob_alive_date) alive2 = probably_alive(spouse, self.database, prob_alive_date) if (self.alive and alive1 and alive2) or not self.alive: self.add_day_item(text, month, day, spouse)
def collect_data(self): """ This method runs through the data, and collects the relevant dates and text. """ db = self.database people = db.iter_person_handles() with self._user.progress(_('Calendar Report'), _('Applying Filter...'), db.get_number_of_people()) as step: people = self.filter.apply(self.database, people, step) ngettext = self._locale.translation.ngettext # to see "nearby" comments with self._user.progress(_('Calendar Report'), _('Reading database...'), len(people)) as step: for person_handle in people: step() person = db.get_person_from_handle(person_handle) mark = ReportUtils.get_person_mark(db, person) birth_ref = person.get_birth_ref() birth_date = None if birth_ref: birth_event = db.get_event_from_handle(birth_ref.ref) birth_date = birth_event.get_date_object() if (self.birthdays and birth_date is not None and birth_date.is_valid()): birth_date = gregorian(birth_date) year = birth_date.get_year() month = birth_date.get_month() day = birth_date.get_day() prob_alive_date = Date(self.year, month, day) nyears = self.year - year # add some things to handle maiden name: father_lastname = None # husband, actually if self.maiden_name in ['spouse_first', 'spouse_last' ]: # get husband's last name: if person.get_gender() == Person.FEMALE: family_list = person.get_family_handle_list() if family_list: if self.maiden_name == 'spouse_first': fhandle = family_list[0] else: fhandle = family_list[-1] fam = db.get_family_from_handle(fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if mother_handle == person_handle: if father_handle: father = db.get_person_from_handle( father_handle) if father: father_lastname = father.get_primary_name( ).get_surname() short_name = self.get_name(person, father_lastname) alive = probably_alive(person, db, prob_alive_date) if not self.alive or alive: if nyears == 0: text = self._('%(person)s, birth') % { 'person': short_name } else: # translators: leave all/any {...} untranslated text = ngettext('{person}, {age}', '{person}, {age}', nyears).format(person=short_name, age=nyears) self.add_day_item(text, month, day, marks=[mark]) if self.anniversaries: family_list = person.get_family_handle_list() for fhandle in family_list: fam = db.get_family_from_handle(fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if father_handle == person.get_handle(): spouse_handle = mother_handle else: continue # with next person if the father is not "person" # this will keep from duplicating the anniversary if spouse_handle: spouse = db.get_person_from_handle(spouse_handle) if spouse: s_m = ReportUtils.get_person_mark(db, spouse) spouse_name = self.get_name(spouse) short_name = self.get_name(person) # TEMP: this will handle ordered events # Gramps 3.0 will have a new mechanism for start/stop events are_married = None for event_ref in fam.get_event_ref_list(): event = db.get_event_from_handle( event_ref.ref) et = EventType rt = EventRoleType if event.type in [et.MARRIAGE, et.MARR_ALT] and \ (event_ref.get_role() == rt.FAMILY or event_ref.get_role() == rt.PRIMARY ): are_married = event elif event.type in [et.DIVORCE, et.ANNULMENT, et.DIV_FILING] and \ (event_ref.get_role() == rt.FAMILY or event_ref.get_role() == rt.PRIMARY ): are_married = None if are_married is not None: for event_ref in fam.get_event_ref_list(): event = db.get_event_from_handle( event_ref.ref) event_obj = event.get_date_object() if event_obj.is_valid(): event_obj = gregorian(event_obj) year = event_obj.get_year() month = event_obj.get_month() day = event_obj.get_day() prob_alive_date = Date( self.year, month, day) nyears = self.year - year if nyears == 0: text = self._( '%(spouse)s and\n %(person)s, wedding' ) % { 'spouse': spouse_name, 'person': short_name, } else: # translators: leave all/any {...} untranslated text = ngettext( "{spouse} and\n {person}, {nyears}", "{spouse} and\n {person}, {nyears}", nyears).format( spouse=spouse_name, person=short_name, nyears=nyears) alive1 = probably_alive( person, self.database, prob_alive_date) alive2 = probably_alive( spouse, self.database, prob_alive_date) if ((self.alive and alive1 and alive2) or not self.alive): self.add_day_item( text, month, day, marks=[mark, s_m])
def collect_data(self): """ This method runs through the data, and collects the relevant dates and text. """ db = self.database people = db.iter_person_handles() with self._user.progress(_('Calendar Report'), _('Applying Filter...'), db.get_number_of_people()) as step: people = self.filter.apply(self.database, people, step) ngettext = self._locale.translation.ngettext # to see "nearby" comments with self._user.progress(_('Calendar Report'), _('Reading database...'), len(people)) as step: for person_handle in people: step() person = db.get_person_from_handle(person_handle) mark = ReportUtils.get_person_mark(db, person) birth_ref = person.get_birth_ref() birth_date = None if birth_ref: birth_event = db.get_event_from_handle(birth_ref.ref) birth_date = birth_event.get_date_object() if (self.birthdays and birth_date is not None and birth_date.is_valid()): birth_date = gregorian(birth_date) year = birth_date.get_year() month = birth_date.get_month() day = birth_date.get_day() prob_alive_date = Date(self.year, month, day) nyears = self.year - year # add some things to handle maiden name: father_lastname = None # husband, actually if self.maiden_name in ['spouse_first', 'spouse_last']: # get husband's last name: if person.get_gender() == Person.FEMALE: family_list = person.get_family_handle_list() if family_list: if self.maiden_name == 'spouse_first': fhandle = family_list[0] else: fhandle = family_list[-1] fam = db.get_family_from_handle(fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if mother_handle == person_handle: if father_handle: father = db.get_person_from_handle(father_handle) if father: father_lastname = father.get_primary_name().get_surname() short_name = self.get_name(person, father_lastname) alive = probably_alive(person, db, prob_alive_date) if not self.alive or alive: if nyears == 0: text = self._('%(person)s, birth') % { 'person' : short_name } else: # translators: leave all/any {...} untranslated text = ngettext('{person}, {age}', '{person}, {age}', nyears).format(person=short_name, age=nyears) self.add_day_item(text, month, day, marks=[mark]) if self.anniversaries: family_list = person.get_family_handle_list() for fhandle in family_list: fam = db.get_family_from_handle(fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if father_handle == person.get_handle(): spouse_handle = mother_handle else: continue # with next person if the father is not "person" # this will keep from duplicating the anniversary if spouse_handle: spouse = db.get_person_from_handle(spouse_handle) if spouse: s_m = ReportUtils.get_person_mark(db, spouse) spouse_name = self.get_name(spouse) short_name = self.get_name(person) # TEMP: this will handle ordered events # GRAMPS 3.0 will have a new mechanism for start/stop events are_married = None for event_ref in fam.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) et = EventType rt = EventRoleType if event.type in [et.MARRIAGE, et.MARR_ALT] and \ (event_ref.get_role() == rt.FAMILY or event_ref.get_role() == rt.PRIMARY ): are_married = event elif event.type in [et.DIVORCE, et.ANNULMENT, et.DIV_FILING] and \ (event_ref.get_role() == rt.FAMILY or event_ref.get_role() == rt.PRIMARY ): are_married = None if are_married is not None: for event_ref in fam.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) event_obj = event.get_date_object() if event_obj.is_valid(): event_obj = gregorian(event_obj) year = event_obj.get_year() month = event_obj.get_month() day = event_obj.get_day() prob_alive_date = Date(self.year, month, day) nyears = self.year - year if nyears == 0: text = self._('%(spouse)s and\n %(person)s, wedding') % { 'spouse' : spouse_name, 'person' : short_name, } else: # translators: leave all/any {...} untranslated text = ngettext("{spouse} and\n {person}, {nyears}", "{spouse} and\n {person}, {nyears}", nyears).format(spouse=spouse_name, person=short_name, nyears=nyears) alive1 = probably_alive(person, self.database, prob_alive_date) alive2 = probably_alive(spouse, self.database, prob_alive_date) if ((self.alive and alive1 and alive2) or not self.alive): self.add_day_item(text, month, day, marks=[mark,s_m])
def exportData(db, filename, error_dialog=None, option_box=None, callback=None): if not callable(callback): callback = lambda percent: None # dummy with OpenFileOrStdout(filename) as fp: total = (db.get_number_of_notes() + db.get_number_of_people() + db.get_number_of_events() + db.get_number_of_families() + db.get_number_of_repositories() + db.get_number_of_places() + db.get_number_of_media() + db.get_number_of_sources()) count = 0.0 # GProlog ISO directives: # /number must match the number of arguments to functions: fp.write(":- discontiguous(data/2).\n") fp.write(":- discontiguous(is_alive/2).\n") fp.write(":- discontiguous(parent/2).\n") # Rules: fp.write("grandparent(X, Y) :- parent(X, Z), parent(Z, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).\n") fp.write("sibling(X, Y) :- parent(Z, X), parent(Z, Y), X \= Y.\n") # --------------------------------- # Notes # --------------------------------- for note in db.iter_notes(): #write_line(fp, "note_details(%s, %s)" % (note.handle, note)) count += 1 callback(100 * count/total) # --------------------------------- # Event # --------------------------------- for event in db.iter_events(): #write_line(fp, "event:", event.handle, event) count += 1 callback(100 * count/total) # --------------------------------- # Person # --------------------------------- for person in db.iter_people(): gid = person.gramps_id.lower() fp.write("data(%s, '%s').\n" % (gid, escape(name_displayer.display(person)))) fp.write("is_alive(%s, '%s').\n" % (gid, probably_alive(person, database))) count += 1 callback(100 * count/total) # --------------------------------- # Family # --------------------------------- for family in db.iter_families(): father_handle = family.get_father_handle() mother_handle = family.get_mother_handle() parents = [] if mother_handle: mother = database.get_person_from_handle(mother_handle) if mother: parents.append(mother.gramps_id.lower()) if father_handle: father = database.get_person_from_handle(father_handle) if father: parents.append(father.gramps_id.lower()) children = [] for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = database.get_person_from_handle(child_handle) if child: children.append(child.gramps_id.lower()) for pid in parents: for cid in children: fp.write("parent(%s, %s).\n" % (pid, cid)) count += 1 callback(100 * count/total) # --------------------------------- # Repository # --------------------------------- for repository in db.iter_repositories(): #write_line(fp, "repository:", repository.handle, repository) count += 1 callback(100 * count/total) # --------------------------------- # Place # --------------------------------- for place in db.iter_places(): #write_line(fp, "place:", place.handle, place) count += 1 callback(100 * count/total) # --------------------------------- # Source # --------------------------------- for source in db.iter_sources(): #write_line(fp, "source:", source.handle, source) count += 1 callback(100 * count/total) # --------------------------------- # Media # --------------------------------- for media in db.iter_media(): #write_line(fp, "media:", media.handle, media) count += 1 callback(100 * count/total) return True
def write_children(self, family): """ List children. :param family: Family :return: """ if not family.get_child_ref_list(): return mother_handle = family.get_mother_handle() if mother_handle: mother = self._db.get_person_from_handle(mother_handle) mother_name = self._nd.display(mother) if not mother_name: mother_name = self._("Unknown") else: mother_name = self._("Unknown") father_handle = family.get_father_handle() if father_handle: father = self._db.get_person_from_handle(father_handle) father_name = self._nd.display(father) if not father_name: father_name = self._("Unknown") else: father_name = self._("Unknown") self.doc.start_paragraph("DAR-ChildTitle") self.doc.write_text( self._("Children of %(mother_name)s and %(father_name)s") % { 'father_name': father_name, 'mother_name': mother_name }) self.doc.end_paragraph() cnt = 1 for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = self._db.get_person_from_handle(child_handle) child_name = self._nd.display(child) if not child_name: child_name = self._("Unknown") child_mark = utils.get_person_mark(self._db, child) if self.childref and self.prev_gen_handles.get(child_handle): value = int(self.prev_gen_handles.get(child_handle)) child_name += " [%d]" % self._get_s_s(value) self.doc.start_paragraph("DAR-ChildList", utils.roman(cnt).lower() + ".") cnt += 1 self.__narrator.set_subject(child) if child_name: self.doc.write_text("%s. " % child_name, child_mark) if self.want_ids: self.doc.write_text('(%s) ' % child.get_gramps_id()) self.doc.write_text_citation( self.__narrator.get_born_string() or self.__narrator.get_christened_string() or self.__narrator.get_baptised_string()) # Write Death and/or Burial text only if not probably alive if not probably_alive(child, self.database): self.doc.write_text_citation( self.__narrator.get_died_string() or self.__narrator.get_buried_string()) # if the list_children_spouses option is selected: if self.list_children_spouses: # get the family of the child that contains the spouse # of the child. There may be more than one spouse for each # child family_handle_list = child.get_family_handle_list() # for the first spouse, this is true. # For subsequent spouses, make it false is_first_family = True for family_handle in family_handle_list: child_family = self.database.get_family_from_handle( family_handle) self.doc.write_text_citation( self.__narrator.get_married_string( child_family, is_first_family, self._name_display)) is_first_family = False self.doc.end_paragraph()
def write_mate(self, person): """Output birth, death, parentage, marriage and notes information """ ind = None has_info = False for family_handle in person.get_family_handle_list(): family = self._db.get_family_from_handle(family_handle) ind_handle = None if person.get_gender() == Person.MALE: ind_handle = family.get_mother_handle() else: ind_handle = family.get_father_handle() if ind_handle: ind = self._db.get_person_from_handle(ind_handle) for event_ref in ind.get_primary_event_ref_list(): event = self._db.get_event_from_handle(event_ref.ref) if event: etype = event.get_type() if (etype == EventType.BAPTISM or etype == EventType.BURIAL or etype == EventType.BIRTH or etype == EventType.DEATH): has_info = True break if not has_info: family_handle = ind.get_main_parents_family_handle() if family_handle: fam = self._db.get_family_from_handle(family_handle) if fam.get_mother_handle() or fam.get_father_handle(): has_info = True break if has_info: self.doc.start_paragraph("DAR-MoreHeader") plist = ind.get_media_list() if self.addimages and len(plist) > 0: photo = plist[0] utils.insert_image(self._db, self.doc, photo, self._user) name = self._nd.display(ind) if not name: name = self._("Unknown") mark = utils.get_person_mark(self._db, ind) if family.get_relationship() == FamilyRelType.MARRIED: self.doc.write_text(self._("Spouse: %s") % name, mark) else: self.doc.write_text( self._("Relationship with: %s") % name, mark) if name[-1:] != '.': self.doc.write_text(".") if self.want_ids: self.doc.write_text(' (%s)' % ind.get_gramps_id()) self.doc.write_text_citation(self.endnotes(ind)) self.doc.end_paragraph() self.doc.start_paragraph("DAR-Entry") self.__narrator.set_subject(ind) text = self.__narrator.get_born_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_baptised_string() if text: self.doc.write_text_citation(text) text = self.__narrator.get_christened_string() if text: self.doc.write_text_citation(text) # Write Death and/or Burial text only if not probably alive if not probably_alive(ind, self.database): text = self.__narrator.get_died_string(self.calcageflag) if text: self.doc.write_text_citation(text) text = self.__narrator.get_buried_string() if text: self.doc.write_text_citation(text) self.write_parents(ind) self.doc.end_paragraph()
def find_records(db, filter, top_size, callname, trans_text=glocale.translation.sgettext, name_format=None, living_mode=LivingProxyDb.MODE_INCLUDE_ALL, user=None): """ @param trans_text: allow deferred translation of strings @type trans_text: a GrampsLocale sgettext instance trans_text is a defined keyword (see po/update_po.py, po/genpot.sh) :param name_format: optional format to control display of person's name :type name_format: None or int :param living_mode: enable optional control of living people's records :type living_mode: int """ def get_unfiltered_person_from_handle(person_handle): if living_mode == LivingProxyDb.MODE_INCLUDE_ALL: return db.get_person_from_handle(person_handle) else: # we are in the proxy so get the person before proxy changes return db.get_unfiltered_person(person_handle) today = datetime.date.today() today_date = Date(today.year, today.month, today.day) # Person records person_youngestliving = [] person_oldestliving = [] person_youngestdied = [] person_oldestdied = [] person_youngestmarried = [] person_oldestmarried = [] person_youngestdivorced = [] person_oldestdivorced = [] person_youngestfather = [] person_youngestmother = [] person_oldestfather = [] person_oldestmother = [] person_mostkidsfather = [] person_mostkidsmother = [] person_mostgrandkidsfather = [] person_mostgrandkidsmother = [] person_handle_list = db.iter_person_handles() # the next "if" will turn person_handle_list from a generator into a # list, but only when this code is called from a report (which has a # filter) and not when called from a gramplet (which has no filter); # so the next line drains the generator and turns it into a list # always, so the gramplet can use it later, in the second loop person_handle_list = list(person_handle_list) if filter: person_handle_list = filter.apply(db, person_handle_list, user=user) for person_handle in person_handle_list: person = db.get_person_from_handle(person_handle) unfil_person = get_unfiltered_person_from_handle(person_handle) if person is None: continue # FIXME this should check for a "fallback" birth also/instead birth_ref = person.get_birth_ref() if not birth_ref: # No birth event, so we can't calculate any age. continue birth = db.get_event_from_handle(birth_ref.ref) birth_date = birth.get_date_object() death_date = _find_death_date(db, person) if not _good_date(birth_date): # Birth date unknown or incomplete, so we can't calculate any age. continue name = _get_styled_primary_name(person, callname, trans_text=trans_text, name_format=name_format) if death_date is None: if probably_alive(unfil_person, db): # Still living, look for age records _record(person_youngestliving, person_oldestliving, today_date - birth_date, name, 'Person', person_handle, top_size) elif _good_date(death_date): # Already died, look for age records _record(person_youngestdied, person_oldestdied, death_date - birth_date, name, 'Person', person_handle, top_size) for family_handle in person.get_family_handle_list(): family = db.get_family_from_handle(family_handle) marriage_date = None divorce_date = None for event_ref in family.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) if (event.get_type().is_marriage() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): marriage_date = event.get_date_object() elif (event.get_type().is_divorce() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): divorce_date = event.get_date_object() if _good_date(marriage_date): _record(person_youngestmarried, person_oldestmarried, marriage_date - birth_date, name, 'Person', person_handle, top_size) if _good_date(divorce_date): _record(person_youngestdivorced, person_oldestdivorced, divorce_date - birth_date, name, 'Person', person_handle, top_size) for child_ref in family.get_child_ref_list(): if person.get_gender() == person.MALE: relation = child_ref.get_father_relation() elif person.get_gender() == person.FEMALE: relation = child_ref.get_mother_relation() else: continue if relation != ChildRefType.BIRTH: continue child = db.get_person_from_handle(child_ref.ref) # FIXME this should check for a "fallback" birth also/instead child_birth_ref = child.get_birth_ref() if not child_birth_ref: continue child_birth = db.get_event_from_handle(child_birth_ref.ref) child_birth_date = child_birth.get_date_object() if not _good_date(child_birth_date): continue if person.get_gender() == person.MALE: _record(person_youngestfather, person_oldestfather, child_birth_date - birth_date, name, 'Person', person_handle, top_size) elif person.get_gender() == person.FEMALE: _record(person_youngestmother, person_oldestmother, child_birth_date - birth_date, name, 'Person', person_handle, top_size) for person_handle in person_handle_list: # this "person loop" doesn't care about a person's birth or death person = db.get_person_from_handle(person_handle) if person is None: continue name = _get_styled_primary_name(person, callname, trans_text=trans_text, name_format=name_format) person_child_list = get_birth_children(db, person) if person.get_gender() == person.MALE: _record(None, person_mostkidsfather, len(person_child_list), name, 'Person', person_handle, top_size) elif person.get_gender() == person.FEMALE: _record(None, person_mostkidsmother, len(person_child_list), name, 'Person', person_handle, top_size) person_grandchild_list = [] for child in person_child_list: person_grandchild_list += get_birth_children(db, child) if person.get_gender() == person.MALE: _record(None, person_mostgrandkidsfather, len(person_grandchild_list), name, 'Person', person_handle, top_size) elif person.get_gender() == person.FEMALE: _record(None, person_mostgrandkidsmother, len(person_grandchild_list), name, 'Person', person_handle, top_size) # Family records family_mostchildren = [] family_youngestmarried = [] family_oldestmarried = [] family_shortest = [] family_longest = [] family_smallestagediff = [] family_biggestagediff = [] for family in db.iter_families(): #family = db.get_family_from_handle(family_handle) if living_mode != LivingProxyDb.MODE_INCLUDE_ALL: # FIXME no iter_families method in LivingProxyDb so do it this way family = db.get_family_from_handle(family.get_handle()) father_handle = family.get_father_handle() if not father_handle: continue mother_handle = family.get_mother_handle() if not mother_handle: continue # Test if either father or mother are in filter if filter: # we don't want many progress reports popping up, so no user=user if not filter.apply(db, [father_handle, mother_handle]): continue father = db.get_person_from_handle(father_handle) unfil_father = get_unfiltered_person_from_handle(father_handle) if father is None: continue mother = db.get_person_from_handle(mother_handle) unfil_mother = get_unfiltered_person_from_handle(mother_handle) if mother is None: continue name = StyledText(trans_text("%(father)s and %(mother)s")) % { 'father': _get_styled_primary_name(father, callname, trans_text=trans_text, name_format=name_format), 'mother': _get_styled_primary_name(mother, callname, trans_text=trans_text, name_format=name_format)} if (living_mode == LivingProxyDb.MODE_INCLUDE_ALL or (not probably_alive(unfil_father, db) and not probably_alive(unfil_mother, db))): _record(None, family_mostchildren, len(family.get_child_ref_list()), name, 'Family', family.handle, top_size) father_birth_ref = father.get_birth_ref() if father_birth_ref: father_birth_date = db.get_event_from_handle(father_birth_ref.ref).get_date_object() else: father_birth_date = None mother_birth_ref = mother.get_birth_ref() if mother_birth_ref: mother_birth_date = db.get_event_from_handle(mother_birth_ref.ref).get_date_object() else: mother_birth_date = None if _good_date(father_birth_date) and _good_date(mother_birth_date): if father_birth_date >> mother_birth_date: _record(family_smallestagediff, family_biggestagediff, father_birth_date - mother_birth_date, name, 'Family', family.handle, top_size) elif mother_birth_date >> father_birth_date: _record(family_smallestagediff, family_biggestagediff, mother_birth_date - father_birth_date, name, 'Family', family.handle, top_size) marriage_date = None divorce = None divorce_date = None for event_ref in family.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) if (event.get_type().is_marriage() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): marriage_date = event.get_date_object() if (event and event.get_type().is_divorce() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): divorce = event divorce_date = event.get_date_object() father_death_date = _find_death_date(db, father) mother_death_date = _find_death_date(db, mother) if not _good_date(marriage_date): # Not married or marriage date unknown continue if divorce is not None and not _good_date(divorce_date): # Divorced but date unknown or inexact continue if (not probably_alive(unfil_father, db) and not _good_date(father_death_date)): # Father died but death date unknown or inexact continue if (not probably_alive(unfil_mother, db) and not _good_date(mother_death_date)): # Mother died but death date unknown or inexact continue if (divorce_date is None and father_death_date is None and mother_death_date is None): # Still married and alive if (probably_alive(unfil_father, db) and probably_alive(unfil_mother, db)): _record(family_youngestmarried, family_oldestmarried, today_date - marriage_date, name, 'Family', family.handle, top_size) elif (_good_date(divorce_date) or _good_date(father_death_date) or _good_date(mother_death_date)): end = None if _good_date(father_death_date) and _good_date(mother_death_date): end = min(father_death_date, mother_death_date) elif _good_date(father_death_date): end = father_death_date elif _good_date(mother_death_date): end = mother_death_date if _good_date(divorce_date): if end: end = min(end, divorce_date) else: end = divorce_date duration = end - marriage_date _record(family_shortest, family_longest, duration, name, 'Family', family.handle, top_size) #python 3 workaround: assign locals to tmp so we work with runtime version tmp = locals() return [(trans_text(text), varname, tmp[varname]) for (text, varname, default) in RECORDS]
def collect_data(self): """ This method runs through the data, and collects the relevant dates and text. """ people = self.database.iter_person_handles() people = self.filter.apply(self.database, people, user=self._user) ngettext = self._locale.translation.ngettext # to see "nearby" comments rel_calc = get_relationship_calculator(reinit=True, clocale=self._locale) with self._user.progress(_('Birthday and Anniversary Report'), _('Reading database...'), len(people)) as step: for person_handle in people: step() person = self.database.get_person_from_handle(person_handle) birth_ref = person.get_birth_ref() birth_date = None if birth_ref: birth_event = self.database.get_event_from_handle( birth_ref.ref) birth_date = birth_event.get_date_object() if (self.birthdays and birth_date is not None and birth_date.is_valid()): birth_date = gregorian(birth_date) year = birth_date.get_year() month = birth_date.get_month() day = birth_date.get_day() prob_alive_date = Date(self.year, month, day) nyears = self.year - year # add some things to handle maiden name: father_lastname = None # husband, actually if self.maiden_name in ['spouse_first', 'spouse_last' ]: # get husband's last name: if person.get_gender() == Person.FEMALE: family_list = person.get_family_handle_list() if len(family_list) > 0: if self.maiden_name == 'spouse_first': fhandle = family_list[0] else: fhandle = family_list[-1] fam = self.database.get_family_from_handle( fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if mother_handle == person_handle: if father_handle: father = self.database.get_person_from_handle( father_handle) if father is not None: primary_name = father.get_primary_name( ) if primary_name: father_lastname = Surname.get_surname( primary_name. get_primary_surname()) short_name = self.get_name(person, father_lastname) alive = probably_alive(person, self.database, prob_alive_date) if ((self.alive and alive) or not self.alive): comment = "" if self.relationships: relation = rel_calc.get_one_relationship( self.database, self.center_person, person, olocale=self._locale) if relation: # FIXME this won't work for RTL languages comment = " --- %s" % relation if nyears == 0: text = self._('%(person)s, birth%(relation)s') % { 'person': short_name, 'relation': comment } else: # translators: leave all/any {...} untranslated text = ngettext('{person}, {age}{relation}', '{person}, {age}{relation}', nyears).format(person=short_name, age=nyears, relation=comment) self.add_day_item(text, month, day, person) if self.anniversaries: family_list = person.get_family_handle_list() for fhandle in family_list: fam = self.database.get_family_from_handle(fhandle) father_handle = fam.get_father_handle() mother_handle = fam.get_mother_handle() if father_handle == person.get_handle(): spouse_handle = mother_handle else: continue # with next person if the father is not "person" # this will keep from duplicating the anniversary if spouse_handle: spouse = self.database.get_person_from_handle( spouse_handle) if spouse: spouse_name = self.get_name(spouse) short_name = self.get_name(person) # TEMP: this will handle ordered events # Gramps 3.0 will have a new mechanism for start/stop events are_married = None for event_ref in fam.get_event_ref_list(): event = self.database.get_event_from_handle( event_ref.ref) if event.type in [ EventType.MARRIAGE, EventType.MARR_ALT ]: are_married = event elif event.type in [ EventType.DIVORCE, EventType.ANNULMENT, EventType.DIV_FILING ]: are_married = None if are_married is not None: for event_ref in fam.get_event_ref_list(): event = self.database.get_event_from_handle( event_ref.ref) event_obj = event.get_date_object() if event_obj is not Date.EMPTY and event_obj.is_valid( ): event_obj = gregorian(event_obj) year = event_obj.get_year() month = event_obj.get_month() day = event_obj.get_day() nyears = self.year - year if event_obj.is_valid(): if nyears == 0: text = self._( "%(spouse)s and\n %(person)s, wedding" ) % { 'spouse': spouse_name, 'person': short_name } else: # translators: leave all/any {...} untranslated text = ngettext( "{spouse} and\n {person}, {nyears}", "{spouse} and\n {person}, {nyears}", nyears).format( spouse=spouse_name, person=short_name, nyears=nyears) prob_alive_date = Date( self.year, month, day) alive1 = probably_alive( person, self.database, prob_alive_date) alive2 = probably_alive( spouse, self.database, prob_alive_date) if (self.alive and alive1 and alive2 ) or not self.alive: self.add_day_item( text, month, day, spouse)
def write_title(self, person): self.handle = person.handle grid = Gtk.Grid() grid.set_column_spacing(12) grid.set_row_spacing(0) # name and edit button name = name_displayer.display(person) fmt = '<span size="larger" weight="bold">%s</span>' text = fmt % escape(name) label = widgets.DualMarkupLabel(text, _GenderCode[person.gender], halign=Gtk.Align.END) if self._config.get('preferences.releditbtn'): button = widgets.IconButton(self.edit_person_button, person.handle) button.set_tooltip_text(_('Edit %s') % name) else: button = None hbox = widgets.LinkBox(label, button) if self.show_tags: tag_list = TagList(self.get_tag_list(person)) hbox.pack_start(tag_list, False, False, 0) eventbox = self.make_dragbox(hbox, 'Person', person.get_handle()) grid.attach(eventbox, 0, 0, 2, 1) subgrid = Gtk.Grid() subgrid.set_column_spacing(12) subgrid.set_row_spacing(0) eventbox = self.make_dragbox(subgrid, 'Person', person.get_handle()) grid.attach(eventbox, 1, 1, 1, 1) # GRAMPS ID subgrid.attach(widgets.BasicLabel("%s:" % _('ID')), 1, 0, 1, 1) label = widgets.BasicLabel(person.gramps_id) label.set_hexpand(True) subgrid.attach(label, 2, 0, 1, 1) # Birth event. birth = get_birth_or_fallback(self.dbstate.db, person) if birth: birth_title = birth.get_type() else: birth_title = _("Birth") subgrid.attach(widgets.BasicLabel("%s:" % birth_title), 1, 1, 1, 1) subgrid.attach(widgets.BasicLabel(self.format_event(birth)), 2, 1, 1, 1) death = get_death_or_fallback(self.dbstate.db, person) if death: death_title = death.get_type() else: death_title = _("Death") showed_death = False if birth: birth_date = birth.get_date_object() if (birth_date and birth_date.get_valid()): if death: death_date = death.get_date_object() if (death_date and death_date.get_valid()): age = death_date - birth_date subgrid.attach(widgets.BasicLabel("%s:" % death_title), 1, 2, 1, 1) subgrid.attach(widgets.BasicLabel("%s (%s)" % (self.format_event(death), age), Pango.EllipsizeMode.END), 2, 2, 1, 1) showed_death = True if not showed_death: age = Today() - birth_date if probably_alive(person, self.dbstate.db): subgrid.attach(widgets.BasicLabel("%s:" % _("Alive")), 1, 2, 1, 1) subgrid.attach(widgets.BasicLabel("(%s)" % age, Pango.EllipsizeMode.END), 2, 2, 1, 1) else: subgrid.attach(widgets.BasicLabel("%s:" % _("Death")), 1, 2, 1, 1) subgrid.attach(widgets.BasicLabel("%s (%s)" % (_("unknown"), age), Pango.EllipsizeMode.END), 2, 2, 1, 1) showed_death = True if not showed_death: subgrid.attach(widgets.BasicLabel("%s:" % death_title), 1, 2, 1, 1) subgrid.attach(widgets.BasicLabel(self.format_event(death)), 2, 2, 1, 1) mbox = Gtk.Box() mbox.add(grid) # image image_list = person.get_media_list() if image_list: button = self.get_thumbnail(image_list[0], size=SIZE_NORMAL) if button: mbox.pack_end(button, False, True, 0) mbox.show_all() return mbox
def exportData(database, filename, error_dialog=None, option_box=None, callback=None): if not callable(callback): callback = lambda percent: None # dummy with OpenFileOrStdout(filename) as fp: total = (len(database.note_map) + len(database.person_map) + len(database.event_map) + len(database.family_map) + len(database.repository_map) + len(database.place_map) + len(database.media_map) + len(database.source_map)) count = 0.0 # GProlog ISO directives: # /number must match the number of arguments to functions: fp.write(":- discontiguous(data/2).\n") fp.write(":- discontiguous(is_alive/2).\n") fp.write(":- discontiguous(parent/2).\n") # Rules: fp.write("grandparent(X, Y) :- parent(X, Z), parent(Z, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Y).\n") fp.write("ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).\n") fp.write("sibling(X, Y) :- parent(Z, X), parent(Z, Y), X \= Y.\n") # --------------------------------- # Notes # --------------------------------- for note_handle in database.note_map.keys(): note = database.note_map[note_handle] #write_line(fp, "note_details(%s, %s)" % (note_handle, note)) count += 1 callback(100 * count/total) # --------------------------------- # Event # --------------------------------- for event_handle in database.event_map.keys(): event = database.event_map[event_handle] #write_line(fp, "event:", event_handle, event) count += 1 callback(100 * count/total) # --------------------------------- # Person # --------------------------------- for person_handle in database.person_map.keys(): data = database.person_map[person_handle] person = Person.create(data) gid = person.gramps_id.lower() fp.write("data(%s, '%s').\n" % (gid, escape(name_displayer.display(person)))) fp.write("is_alive(%s, '%s').\n" % (gid, probably_alive(person, database))) count += 1 callback(100 * count/total) # --------------------------------- # Family # --------------------------------- for family_handle in database.family_map.keys(): data = database.family_map[family_handle] family = Family.create(data) father_handle = family.get_father_handle() mother_handle = family.get_mother_handle() parents = [] if mother_handle: mother = database.get_person_from_handle(mother_handle) if mother: parents.append(mother.gramps_id.lower()) if father_handle: father = database.get_person_from_handle(father_handle) if father: parents.append(father.gramps_id.lower()) children = [] for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = database.get_person_from_handle(child_handle) if child: children.append(child.gramps_id.lower()) for pid in parents: for cid in children: fp.write("parent(%s, %s).\n" % (pid, cid)) count += 1 callback(100 * count/total) # --------------------------------- # Repository # --------------------------------- for repository_handle in database.repository_map.keys(): repository = database.repository_map[repository_handle] #write_line(fp, "repository:", repository_handle, repository) count += 1 callback(100 * count/total) # --------------------------------- # Place # --------------------------------- for place_handle in database.place_map.keys(): place = database.place_map[place_handle] #write_line(fp, "place:", place_handle, place) count += 1 callback(100 * count/total) # --------------------------------- # Source # --------------------------------- for source_handle in database.source_map.keys(): source = database.source_map[source_handle] #write_line(fp, "source:", source_handle, source) count += 1 callback(100 * count/total) # --------------------------------- # Media # --------------------------------- for media_handle in database.media_map.keys(): media = database.media_map[media_handle] #write_line(fp, "media:", media_handle, media) count += 1 callback(100 * count/total) return True
def find_records(db, filter, top_size, callname, trans_text=glocale.translation.sgettext, name_format=None): """ @param trans_text: allow deferred translation of strings @type trans_text: a GrampsLocale sgettext instance trans_text is a defined keyword (see po/update_po.py, po/genpot.sh) :param name_format: optional format to control display of person's name :type name_format: None or int """ today = datetime.date.today() today_date = Date(today.year, today.month, today.day) # Person records person_youngestliving = [] person_oldestliving = [] person_youngestdied = [] person_oldestdied = [] person_youngestmarried = [] person_oldestmarried = [] person_youngestdivorced = [] person_oldestdivorced = [] person_youngestfather = [] person_youngestmother = [] person_oldestfather = [] person_oldestmother = [] person_handle_list = db.iter_person_handles() if filter: person_handle_list = filter.apply(db, person_handle_list) for person_handle in person_handle_list: person = db.get_person_from_handle(person_handle) # FIXME this should check for a "fallback" birth also/instead birth_ref = person.get_birth_ref() if not birth_ref: # No birth event, so we can't calculate any age. continue birth = db.get_event_from_handle(birth_ref.ref) birth_date = birth.get_date_object() death_date = _find_death_date(db, person) if not _good_date(birth_date): # Birth date unknown or incomplete, so we can't calculate any age. continue name = _get_styled_primary_name(person, callname, name_format=name_format) if death_date is None: if probably_alive(person, db): # Still living, look for age records _record(person_youngestliving, person_oldestliving, today_date - birth_date, name, 'Person', person_handle, top_size) elif _good_date(death_date): # Already died, look for age records _record(person_youngestdied, person_oldestdied, death_date - birth_date, name, 'Person', person_handle, top_size) for family_handle in person.get_family_handle_list(): family = db.get_family_from_handle(family_handle) marriage_date = None divorce_date = None for event_ref in family.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) if (event.get_type().is_marriage() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): marriage_date = event.get_date_object() elif (event.get_type().is_divorce() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): divorce_date = event.get_date_object() if _good_date(marriage_date): _record(person_youngestmarried, person_oldestmarried, marriage_date - birth_date, name, 'Person', person_handle, top_size) if _good_date(divorce_date): _record(person_youngestdivorced, person_oldestdivorced, divorce_date - birth_date, name, 'Person', person_handle, top_size) for child_ref in family.get_child_ref_list(): if person.get_gender() == person.MALE: relation = child_ref.get_father_relation() elif person.get_gender() == person.FEMALE: relation = child_ref.get_mother_relation() else: continue if relation != ChildRefType.BIRTH: continue child = db.get_person_from_handle(child_ref.ref) # FIXME this should check for a "fallback" birth also/instead child_birth_ref = child.get_birth_ref() if not child_birth_ref: continue child_birth = db.get_event_from_handle(child_birth_ref.ref) child_birth_date = child_birth.get_date_object() if not _good_date(child_birth_date): continue if person.get_gender() == person.MALE: _record(person_youngestfather, person_oldestfather, child_birth_date - birth_date, name, 'Person', person_handle, top_size) elif person.get_gender() == person.FEMALE: _record(person_youngestmother, person_oldestmother, child_birth_date - birth_date, name, 'Person', person_handle, top_size) # Family records family_mostchildren = [] family_youngestmarried = [] family_oldestmarried = [] family_shortest = [] family_longest = [] family_smallestagediff = [] family_biggestagediff = [] for family in db.iter_families(): #family = db.get_family_from_handle(family_handle) father_handle = family.get_father_handle() if not father_handle: continue mother_handle = family.get_mother_handle() if not mother_handle: continue # Test if either father or mother are in filter if filter: if not filter.apply(db, [father_handle, mother_handle]): continue father = db.get_person_from_handle(father_handle) mother = db.get_person_from_handle(mother_handle) name = StyledText(trans_text("%(father)s and %(mother)s")) % { 'father': _get_styled_primary_name(father, callname, name_format=name_format), 'mother': _get_styled_primary_name(mother, callname, name_format=name_format)} _record(None, family_mostchildren, len(family.get_child_ref_list()), name, 'Family', family.handle, top_size) father_birth_ref = father.get_birth_ref() if father_birth_ref: father_birth_date = db.get_event_from_handle(father_birth_ref.ref).get_date_object() else: father_birth_date = None mother_birth_ref = mother.get_birth_ref() if mother_birth_ref: mother_birth_date = db.get_event_from_handle(mother_birth_ref.ref).get_date_object() else: mother_birth_date = None if _good_date(father_birth_date) and _good_date(mother_birth_date): if father_birth_date >> mother_birth_date: _record(family_smallestagediff, family_biggestagediff, father_birth_date - mother_birth_date, name, 'Family', family.handle, top_size) elif mother_birth_date >> father_birth_date: _record(family_smallestagediff, family_biggestagediff, mother_birth_date - father_birth_date, name, 'Family', family.handle, top_size) marriage_date = None divorce = None divorce_date = None for event_ref in family.get_event_ref_list(): event = db.get_event_from_handle(event_ref.ref) if (event.get_type().is_marriage() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): marriage_date = event.get_date_object() if (event and event.get_type().is_divorce() and (event_ref.get_role().is_family() or event_ref.get_role().is_primary())): divorce = event divorce_date = event.get_date_object() father_death_date = _find_death_date(db, father) mother_death_date = _find_death_date(db, mother) if not _good_date(marriage_date): # Not married or marriage date unknown continue if divorce is not None and not _good_date(divorce_date): # Divorced but date unknown or inexact continue if not probably_alive(father, db) and not _good_date(father_death_date): # Father died but death date unknown or inexact continue if not probably_alive(mother, db) and not _good_date(mother_death_date): # Mother died but death date unknown or inexact continue if (divorce_date is None and father_death_date is None and mother_death_date is None): # Still married and alive if probably_alive(father, db) and probably_alive(mother, db): _record(family_youngestmarried, family_oldestmarried, today_date - marriage_date, name, 'Family', family.handle, top_size) elif (_good_date(divorce_date) or _good_date(father_death_date) or _good_date(mother_death_date)): end = None if _good_date(father_death_date) and _good_date(mother_death_date): end = min(father_death_date, mother_death_date) elif _good_date(father_death_date): end = father_death_date elif _good_date(mother_death_date): end = mother_death_date if _good_date(divorce_date): if end: end = min(end, divorce_date) else: end = divorce_date duration = end - marriage_date _record(family_shortest, family_longest, duration, name, 'Family', family.handle, top_size) #python 3 workaround: assign locals to tmp so we work with runtime version tmp = locals() return [(trans_text(text), varname, tmp[varname]) for (text, varname, default) in RECORDS]