From 49632d87899a68373cd01f97fd63767cd577be9d Mon Sep 17 00:00:00 2001 From: Paul Culley Date: Sun, 18 Aug 2019 10:09:29 -0500 Subject: [PATCH] Add support for GEDCOM import _FREL/_MREL tags in INDI/FAMC (#866) Improve support for GEDCOM export of _FREL/_MREL in INDI/FAMC Fixes #10750 --- data/tests/exp_sample.gramps | 2 +- data/tests/exp_sample_ged.ged | 12 +++-- data/tests/imp_sample.ged | 2 + data/tests/imp_sample.gramps | 36 ++++++------- gramps/plugins/export/exportgedcom.py | 6 +-- gramps/plugins/lib/libgedcom.py | 74 +++++++++++++++++++-------- gramps/plugins/test/imports_test.py | 6 ++- 7 files changed, 90 insertions(+), 48 deletions(-) diff --git a/data/tests/exp_sample.gramps b/data/tests/exp_sample.gramps index c18b9b805..4104ebc0a 100644 --- a/data/tests/exp_sample.gramps +++ b/data/tests/exp_sample.gramps @@ -1278,7 +1278,7 @@ - + diff --git a/data/tests/exp_sample_ged.ged b/data/tests/exp_sample_ged.ged index ebbb780ac..548122334 100644 --- a/data/tests/exp_sample_ged.ged +++ b/data/tests/exp_sample_ged.ged @@ -2,8 +2,8 @@ 1 SOUR Gramps 2 VERS 5.0.2 2 NAME Gramps -1 DATE 31 JUL 2019 -2 TIME 10:58:33 +1 DATE 4 AUG 2019 +2 TIME 15:26:44 1 SUBM @SUBM@ 1 FILE C:\Users\prc\AppData\Roaming\gramps\temp\exp_sample_ged.ged 1 COPR Copyright (c) 2019 Alex Roitman,,,. @@ -629,8 +629,12 @@ 2 TYPE Birth of Lloyd Smith 2 DATE 13 MAR 1935 2 PLAC San Francisco, San Francisco Co., CA +1 ADOP Y +2 FAMC @F0009@ +3 ADOP HUSB 1 FAMC @F0009@ -2 PEDI birth +2 _FREL Adopted +2 _MREL Foster 1 FAMS @F0008@ 1 CHAN 2 DATE 4 SEP 2016 @@ -1040,7 +1044,7 @@ 2 SURN Tester 1 SEX M 1 FAMC @F0016@ -2 PEDI Unknown +2 PEDI Sponsored 1 CHAN 2 DATE 29 OCT 2016 3 TIME 16:27:59 diff --git a/data/tests/imp_sample.ged b/data/tests/imp_sample.ged index 99d15e7b3..1afc41cff 100644 --- a/data/tests/imp_sample.ged +++ b/data/tests/imp_sample.ged @@ -83,6 +83,8 @@ 2 DATE 11 AUG 1966 2 PLAC San Francisco, San Francisco Co., CA 1 FAMC @F8@ +2 _FREL Adopted +2 _MREL Foster 1 CHAN 2 DATE 21 DEC 2007 3 TIME 01:35:26 diff --git a/data/tests/imp_sample.gramps b/data/tests/imp_sample.gramps index 4cc712888..d4afac061 100644 --- a/data/tests/imp_sample.gramps +++ b/data/tests/imp_sample.gramps @@ -3,7 +3,7 @@ "http://gramps-project.org/xml/1.7.1/grampsxml.dtd">
- + Alex Roitman,,, Not Provided @@ -1134,7 +1134,7 @@ - + @@ -1566,8 +1566,8 @@ Filename omitted Line 48: Records not imported into INDI (individual) Gramps ID I0016: -Warn: ADDR overwritten Line 204: 3 ADR1 456 Main St again -ADDR element ignored '459 Main St.' Line 202: 2 ADDR 459 Main St., The Village, San Francisco, CA, USA +Warn: ADDR overwritten Line 206: 3 ADR1 456 Main St again +ADDR element ignored '459 Main St.' Line 204: 2 ADDR 459 Main St., The Village, San Francisco, CA, USA - + Objects referenced by this note were missing in a file imported on 12/25/1999 12:00:00 AM. diff --git a/gramps/plugins/export/exportgedcom.py b/gramps/plugins/export/exportgedcom.py index 919948c14..2c8e526a1 100644 --- a/gramps/plugins/export/exportgedcom.py +++ b/gramps/plugins/export/exportgedcom.py @@ -735,14 +735,14 @@ class GedcomWriter(UpdateCallback): child.mrel == ChildRefType.FOSTER: self._writeln(2, 'PEDI foster') elif child.frel == child.mrel: - self._writeln(2, 'PEDI Unknown') + self._writeln(2, 'PEDI %s' % str(child.frel)) else: self._writeln(2, '_FREL %s' % PEDIGREE_TYPES.get(child.frel.value, - "Unknown")) + str(child.frel))) self._writeln(2, '_MREL %s' % PEDIGREE_TYPES.get(child.mrel.value, - "Unknown")) + str(child.mrel))) def _parent_families(self, person): """ diff --git a/gramps/plugins/lib/libgedcom.py b/gramps/plugins/lib/libgedcom.py index 43ed89b22..b645945e6 100644 --- a/gramps/plugins/lib/libgedcom.py +++ b/gramps/plugins/lib/libgedcom.py @@ -528,7 +528,7 @@ RELATION_TYPES = ( PEDIGREE_TYPES = { 'birth' : ChildRefType(), 'natural': ChildRefType(), - 'step' : TYPE_ADOPT, + 'step' : ChildRefType(ChildRefType.STEPCHILD), 'adopted': TYPE_ADOPT, 'foster' : TYPE_FOSTER, } @@ -2226,8 +2226,12 @@ class GedcomParser(UpdateCallback): self.famc_parse_tbl = { # n FAMC @@ {1:1} - # +1 PEDI {0:M} p.* + # +1 PEDI {0:1} p.* TOKEN_PEDI : self.__person_famc_pedi, + # +1 _FREL {0:1} non-standard + TOKEN__FREL : self.__person_famc_frel, + # +1 _MREL {0:1} non-standard + TOKEN__MREL : self.__person_famc_mrel, # +1 <> {0:M} p.* TOKEN_NOTE : self.__person_famc_note, TOKEN_RNOTE : self.__person_famc_note, @@ -4717,7 +4721,9 @@ class GedcomParser(UpdateCallback): person is a child of. n FAMC @@ {1:1} - +1 PEDI {0:M} p.* + +1 PEDI {0:1} p.* + +1 _FREL {0:1} non-standard Extension + +1 _MREL {0:1} non-standard Extension +1 <> {0:M} p.* @param line: The current line in GedLine format @@ -4744,15 +4750,9 @@ class GedcomParser(UpdateCallback): # if the handle is not already in the person's parent family list, we # need to add it to thie list. - flist = [fam[0] for fam in - state.person.get_parent_family_handle_list()] + flist = state.person.get_parent_family_handle_list() if handle not in flist: - if sub_state.ftype and int(sub_state.ftype) in RELATION_TYPES: - state.person.add_parent_family_handle(handle) - else: - if state.person.get_main_parents_family_handle() == handle: - state.person.set_main_parent_family_handle(None) - state.person.add_parent_family_handle(handle) + state.person.add_parent_family_handle(handle) # search childrefs family, _new = self.dbase.find_family_from_handle(handle, @@ -4761,17 +4761,19 @@ class GedcomParser(UpdateCallback): for ref in family.get_child_ref_list(): if ref.ref == state.person.handle: - if sub_state.ftype: - ref.set_mother_relation(sub_state.ftype) - ref.set_father_relation(sub_state.ftype) break else: ref = ChildRef() ref.ref = state.person.handle - if sub_state.ftype: - ref.set_mother_relation(sub_state.ftype) - ref.set_father_relation(sub_state.ftype) family.add_child_ref(ref) + if sub_state.ftype: + ref.set_mother_relation(sub_state.ftype) + ref.set_father_relation(sub_state.ftype) + else: + if sub_state.frel: + ref.set_father_relation(sub_state.frel) + if sub_state.mrel: + ref.set_mother_relation(sub_state.mrel) self.dbase.commit_family(family, self.trans) def __person_famc_pedi(self, line, state): @@ -4790,6 +4792,40 @@ class GedcomParser(UpdateCallback): state.ftype = PEDIGREE_TYPES.get(line.data.lower(), ChildRefType.UNKNOWN) + def __person_famc_frel(self, line, state): + """ + Parses the _FREL tag attached to a INDI.FAMC record. No values are set + at this point, because we have to do some post processing. Instead, we + assign the frel field of the state variable. We convert the text from + the line to an index into the PEDIGREE_TYPES dictionary, which will map + to the correct ChildTypeRef. + + @param line: The current line in GedLine format + @type line: GedLine + @param state: The current state + @type state: CurrentState + """ + state.frel = PEDIGREE_TYPES.get(line.data.lower().strip(), None) + if state.frel is None: + state.frel = ChildRefType(line.data.capitalize().strip()) + + def __person_famc_mrel(self, line, state): + """ + Parses the _MREL tag attached to a INDI.FAMC record. No values are set + at this point, because we have to do some post processing. Instead, we + assign the mrel field of the state variable. We convert the text from + the line to an index into the PEDIGREE_TYPES dictionary, which will map + to the correct ChildTypeRef. + + @param line: The current line in GedLine format + @type line: GedLine + @param state: The current state + @type state: CurrentState + """ + state.mrel = PEDIGREE_TYPES.get(line.data.lower().strip(), None) + if state.mrel is None: + state.mrel = ChildRefType(line.data.capitalize().strip()) + def __person_famc_note(self, line, state): """ Parses the INDI.FAMC.NOTE tag . @@ -6090,8 +6126,6 @@ class GedcomParser(UpdateCallback): int(sub_state.frel) == ChildRefType.BIRTH): sub_state.mrel = sub_state.frel = TYPE_ADOPT - if state.person.get_main_parents_family_handle() == handle: - state.person.set_main_parent_family_handle(None) state.person.add_parent_family_handle(handle) reflist = [ref for ref in family.get_child_ref_list() @@ -6132,8 +6166,6 @@ class GedcomParser(UpdateCallback): """ handle = self.__find_family_handle(self.fid_map[line.data]) - if state.person.get_main_parents_family_handle() == handle: - state.person.set_main_parent_family_handle(None) state.person.add_parent_family_handle(handle) frel = mrel = ChildRefType.BIRTH diff --git a/gramps/plugins/test/imports_test.py b/gramps/plugins/test/imports_test.py index c3a6b3948..dcf613ea2 100644 --- a/gramps/plugins/test/imports_test.py +++ b/gramps/plugins/test/imports_test.py @@ -51,7 +51,11 @@ TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) # ------------------------------------------------------------------ # These tests assume a US date and time format. -locale.setlocale(locale.LC_ALL, 'en_US.utf8') +try: + locale.setlocale(locale.LC_ALL, 'en_US.utf8') +except locale.Error: # seems to fail on Windows system for some reason + locale.setlocale(locale.LC_ALL, 'English_United States') + def mock_time(*args): """