diff --git a/data/tests/imp_PhonFax_dfs.ged b/data/tests/imp_PhonFax_dfs.ged new file mode 100644 index 000000000..05b81b2ba --- /dev/null +++ b/data/tests/imp_PhonFax_dfs.ged @@ -0,0 +1,90 @@ +0 HEAD +1 SOUR FTM +2 VERS Family Tree Maker (22.0.0.1410) +2 NAME Family Tree Maker for Windows +2 CORP Ancestry.com +3 ADDR 360 W 4800 N +4 CONT Provo, UT 84604 +3 PHON (801) 705-7000 +3 PHON (800) 705-7000 +3 FAX (801) 705-7001 +3 EMAIL help@ancestry.com +3 WWW http://www.ancestry.com +1 DEST GED55 +1 DATE 01 MAR 2016 +1 CHAR UTF-8 +1 FILE D:\Family Tree Maker\imp_FTM_LINK.ged +1 SUBM @SUBM@ +1 GEDC +2 VERS 5.5 +2 FORM LINEAGE-LINKED +0 @SUBM@ SUBM +1 NAME The Subm /Tester/ +1 ADDR 123 Main St., Winslow, PA, 12345 +2 ADR1 123 Main St. +2 CITY Winslow +2 STAE PA +2 POST 12345 +1 PHON 440-871-3401 +1 PHON 800-871-3401 +1 EMAIL mrstester@gmail.com +1 FAX 440-321-4568 +1 WWW http://mrstester.com +0 @I0@ INDI +1 NAME The /Tester/ +1 BIRT +2 DATE 29 DEC 1954 +2 PLAC 123 High St, Cleveland, Cuyahoga, Ohio, USA, 44140 +3 FORM Street, City, County, State, Country, Zip code +2 PHON 440-871-3400 +2 PHON 800-871-3400 +2 EMAIL thetester@gmail.com +2 FAX 440-123-4567 +2 WWW http://thetester.com +0 @I1@ INDI +1 NAME Mrs /Tester/ +1 ADDR 123 Main St., Winslow, PA, 12345 +2 ADR1 123 Main St. +2 CITY Winslow +2 STAE PA +2 POST 12345 +1 PHON 440-871-3401 +1 PHON 800-871-3401 +1 EMAIL mrstester@gmail.com +1 FAX 440-321-4568 +1 WWW http://mrstester.com +1 NOTE Address with PHON,FAX,EMAIL,WWW. attached directly to person +2 CONC is not legal Gedcom, but allowed here. +1 RESI +2 DATE 30 DEC 1954 +2 ADDR 123 Main St., Winslow, PA, 12345 +3 ADR1 123 Main St. +3 CITY Winslow +3 STAE PA +3 POST 12345 +2 NOTE Address as event is legal, with PHON,FAX,EMAIL,WWW +2 PHON 440-871-3401 +2 EMAIL mrstester@gmail.com +2 FAX 440-321-4568 +2 WWW http://mrstester.com +0 @I2@ INDI +1 NAME Tom /Tester/ +1 RESI +2 DATE 1964 +2 PHON 440-871-3402 +2 EMAIL tomtester@gmail.com +2 FAX 440-321-4569 +2 WWW http://tomtester.com +0 @S6@ SOUR +1 TITL Ohio Births, 1958-2002 +1 REPO @R1@ +0 @R1@ REPO +1 NAME Testers Repository +1 ADDR 123 High St., OSF village, CA, USA +1 EMAIL tester_repo@osf.com +1 FAX 987-654-3210 +1 PHON 988-765-4321 +1 PHON 800-765-4321 +1 WWW http://www.tester_repo.com +1 NOTE The repository record +0 TRLR diff --git a/data/tests/imp_PhonFax_dfs.gramps b/data/tests/imp_PhonFax_dfs.gramps new file mode 100644 index 000000000..c2c341fa6 --- /dev/null +++ b/data/tests/imp_PhonFax_dfs.gramps @@ -0,0 +1,228 @@ + + + +
+ + + The Subm /Tester/ + 123 Main St. + Winslow + PA + 12345 + 440-871-3401 + mrstester@gmail.com + +
+ + + Birth + + + + + + + + + + Residence + + + + + + + + + + Residence + + + + + + + + + + U + + The + Tester + + + + + + U + + Mrs + Tester + + +
+ 123 Main St. + Winslow + PA + 12345 +
+ + + + + + + +
+ + U + + Tom + Tester + + + + +
+ + + 2 + + + + 2 + + + + 2 + + + + + + Import from imp_FTM_LINK.ged + + + + + + + + + + + + Ohio Births, 1958-2002 + + + + + + 123 High St, Cleveland, Cuyahoga, Ohio, USA, 44140 + 44140 + + + + + 123 Main St., Winslow, PA, 12345 + + + + + USA + + + + Ohio, USA + + + + + Cuyahoga, Ohio, USA + + + + + Cleveland, Cuyahoga, Ohio, USA + + + + + + + Business that produced the product: Ancestry.com + GEDCOM data +
+ 360 W 4800 N, Provo, UT 84604 + (801) 705-7000 +
+ + + +
+ + SUBM (Submitter): (@SUBM@) The Subm /Tester/ + GEDCOM data +
+ 123 Main St. + Winslow + PA + 12345 + 440-871-3401 +
+ + + + +
+ + Testers Repository + Library +
+ 123 High St., OSF village, CA, USA + 988-765-4321 +
+ + + + + +
+
+ + + Records not imported into HEAD (header): + +Only one phone number supported Line 9: 3 PHON (800) 705-7000 + + + + Records not imported into SUBM (Submitter): (@SUBM@) The Subm /Tester/: + +Only one phone number supported Line 29: 1 PHON 800-871-3401 + + + + Address with PHON,FAX,EMAIL,WWW. attached directly to person is not legal Gedcom, but allowed here. + + + Address as event is legal, with PHON,FAX,EMAIL,WWW + + + The repository record + + + Records not imported into REPO (repository) Gramps ID R0002: + +Only one phone number supported Line 87: 1 PHON 800-765-4321 + + + +
diff --git a/gramps/gen/merge/diff.py b/gramps/gen/merge/diff.py index 89f5898ff..dac78bcdd 100644 --- a/gramps/gen/merge/diff.py +++ b/gramps/gen/merge/diff.py @@ -82,7 +82,7 @@ def parse(string): retval.append(current) return retval -def import_as_dict(filename, user=None): +def import_as_dict(filename, user=None, skp_imp_adds=True): """ Import the filename into a InMemoryDB and return it. """ @@ -90,7 +90,7 @@ def import_as_dict(filename, user=None): user = User() db = make_database("inmemorydb") db.load(None) - db.set_feature("skip-import-additions", True) + db.set_feature("skip-import-additions", skp_imp_adds) dbstate = DbState() climanager = CLIManager(dbstate, setloader=False, user=user) climanager.do_reg_plugins(dbstate, None) diff --git a/gramps/plugins/lib/libgedcom.py b/gramps/plugins/lib/libgedcom.py index b7d983eb3..fb74beade 100644 --- a/gramps/plugins/lib/libgedcom.py +++ b/gramps/plugins/lib/libgedcom.py @@ -261,7 +261,7 @@ TOKEN_LONG = 122 TOKEN_FACT = 123 TOKEN_EMAIL = 124 TOKEN_WWW = 125 -TOKEN_URL = 126 +TOKEN_FAX = 126 TOKEN_ROLE = 127 TOKEN__MAR = 128 TOKEN__MARN = 129 @@ -373,12 +373,14 @@ TOKENS = { "LONG" : TOKEN_LONG, "_ITALIC" : TOKEN_IGNORE, "_PLACE" : TOKEN_IGNORE, "FACT" : TOKEN_FACT, "EMAIL" : TOKEN_EMAIL, + "_E-MAIL" : TOKEN_EMAIL, "_EMAIL" : TOKEN_EMAIL, "EMAI" : TOKEN_EMAIL, "WWW" : TOKEN_WWW, - "_URL" : TOKEN_URL, "URL" : TOKEN_URL, + "_URL" : TOKEN_WWW, "URL" : TOKEN_WWW, "_MAR" : TOKEN__MAR, "_MARN" : TOKEN__MARN, "_ADPN" : TOKEN__ADPN, "_FSFTID" : TOKEN__FSFTID, "_LINK" : TOKEN__LINK, "_PHOTO" : TOKEN__PHOTO, "_JUST" : TOKEN__JUST, # FTM Citation Quality Justification + "FAX" : TOKEN_FAX, } ADOPT_NONE = 0 @@ -2031,6 +2033,8 @@ class GedcomParser(UpdateCallback): TOKEN_ADDR : self.__subm_addr, TOKEN_PHON : self.__subm_phon, TOKEN_EMAIL : self.__subm_email, + TOKEN_WWW : self.__repo_www, + TOKEN_FAX : self.__repo_fax, # +1 <> # +1 LANG # +1 RFN @@ -2123,11 +2127,13 @@ class GedcomParser(UpdateCallback): TOKEN_RIN : self.__person_attr, # +1 <> {0:1} TOKEN_CHAN : self.__person_chan, - + # The following tags are not part of Gedcom spec but are commonly + # found here anyway TOKEN_ADDR : self.__person_addr, TOKEN_PHON : self.__person_phon, + TOKEN_FAX : self.__person_fax, TOKEN_EMAIL : self.__person_email, - TOKEN_URL : self.__person_url, + TOKEN_WWW : self.__person_www, TOKEN__TODO : self.__skip_record, TOKEN_TITL : self.__person_titl, TOKEN__PHOTO: self.__person_photo, @@ -2192,6 +2198,7 @@ class GedcomParser(UpdateCallback): TOKEN_PHON : self.__repo_phon, TOKEN_EMAIL : self.__repo_email, TOKEN_WWW : self.__repo_www, + TOKEN_FAX : self.__repo_fax, } self.func_list.append(self.repo_parse_tbl) @@ -2242,6 +2249,7 @@ class GedcomParser(UpdateCallback): TOKEN_ATTR : self.__event_attr, # FTB for _UID TOKEN_EMAIL : self.__event_email, # FTB for RESI events TOKEN_WWW : self.__event_www, # FTB for RESI events + TOKEN_FAX : self.__event_fax, # legal... } self.func_list.append(self.event_parse_tbl) @@ -2701,6 +2709,9 @@ class GedcomParser(UpdateCallback): self.header_corp_addr = { TOKEN_ADDR : self.__repo_addr, TOKEN_PHON : self.__repo_phon, + TOKEN_FAX : self.__repo_fax, + TOKEN_WWW : self.__repo_www, + TOKEN_EMAIL : self.__repo_email, } self.func_list.append(self.header_corp_addr) @@ -3523,13 +3534,6 @@ class GedcomParser(UpdateCallback): addr.set_county(state.res.get_county()) addr.set_phone(state.res.get_phone()) repo.add_address(addr) - - if state.res.get_email(): - url = Url() - url.set_path(state.res.get_email()) - url.set_type(UrlType(UrlType.EMAIL)) - repo.add_url(url) - rtype = RepositoryType() rtype.set((RepositoryType.CUSTOM, _('GEDCOM data'))) repo.set_type(rtype) @@ -3870,6 +3874,7 @@ class GedcomParser(UpdateCallback): """ self.__obje(line, state, state.person) + def __person_photo(self, line, state): """ This handles the FTM _PHOTO feature, which identifies an OBJE to use @@ -4136,12 +4141,25 @@ class GedcomParser(UpdateCallback): @param state: The current state @type state: CurrentState """ - addr = Address() - addr.set_street("Unknown") - addr.set_phone(line.data) - state.person.add_address(addr) - self.__skip_subordinate_levels(state.level+1, state) + url = Url() + url.set_path(line.data) + url.set_type(UrlType(_('Phone'))) + state.person.add_url(url) + def __person_fax(self, line, state): + """ + O INDI + 1 FAX {0:3} + + @param line: The current line in GedLine format + @type line: GedLine + @param state: The current state + @type state: CurrentState + """ + url = Url() + url.set_path(line.data) + url.set_type(UrlType(_('FAX'))) + state.person.add_url(url) def __person_email(self, line, state): """ @@ -4158,10 +4176,10 @@ class GedcomParser(UpdateCallback): url.set_type(UrlType(UrlType.EMAIL)) state.person.add_url(url) - def __person_url(self, line, state): + def __person_www(self, line, state): """ O INDI - 1 URL {0:3} + 1 WWW {0:3} @param line: The current line in GedLine format @type line: GedLine @@ -5206,6 +5224,7 @@ class GedcomParser(UpdateCallback): """ self.__obje(line, state, state.family) + def __family_comm(self, line, state): """ @param line: The current line in GedLine format @@ -5541,6 +5560,7 @@ class GedcomParser(UpdateCallback): """ self.__obje(line, state, state.event) + def __event_type(self, line, state): """ Parses the TYPE line for an event. @@ -5660,6 +5680,7 @@ class GedcomParser(UpdateCallback): """ self.__obje(line, state, state.place) + def __event_place_sour(self, line, state): """ @param line: The current line in GedLine format @@ -5801,18 +5822,6 @@ class GedcomParser(UpdateCallback): else: return place.get_alternate_locations()[0] - def __event_phon(self, line, state): - """ - @param line: The current line in GedLine format - @type line: GedLine - @param state: The current state - @type state: CurrentState - """ - place = state.place - if place: - codes = [place.get_code(), line.data] - place.set_code(' '.join(code for code in codes if code)) - def __event_privacy(self, line, state): """ @param line: The current line in GedLine format @@ -5883,6 +5892,30 @@ class GedcomParser(UpdateCallback): """ state.event.add_attribute(line.data) + def __event_phon(self, line, state): + """ + @param line: The current line in GedLine format + @type line: GedLine + @param state: The current state + @type state: CurrentState + """ + attr = Attribute() + attr.set_type(_("Phone")) + attr.set_value(line.data) + state.event.add_attribute(attr) + + def __event_fax(self, line, state): + """ + @param line: The current line in GedLine format + @type line: GedLine + @param state: The current state + @type state: CurrentState + """ + attr = Attribute() + attr.set_type(_("FAX")) + attr.set_value(line.data) + state.event.add_attribute(attr) + def __event_email(self, line, state): """ @param line: The current line in GedLine format @@ -5891,7 +5924,7 @@ class GedcomParser(UpdateCallback): @type state: CurrentState """ attr = Attribute() - attr.set_type(line.token_text) + attr.set_type(_("EMAIL")) attr.set_value(line.data) state.event.add_attribute(attr) @@ -5903,7 +5936,7 @@ class GedcomParser(UpdateCallback): @type state: CurrentState """ attr = Attribute() - attr.set_type(line.token_text) + attr.set_type(_("WWW")) attr.set_value(line.data) state.event.add_attribute(attr) @@ -6345,6 +6378,7 @@ class GedcomParser(UpdateCallback): """ self.__obje(line, state, state.citation) + def __citation_refn(self, line, state): """ Parses the REFN line of an SOUR instance tag @@ -6484,6 +6518,7 @@ class GedcomParser(UpdateCallback): """ self.__obje(line, state, state.source) + def __source_chan(self, line, state): """ @param line: The current line in GedLine format @@ -7011,7 +7046,22 @@ class GedcomParser(UpdateCallback): """ address_list = state.repo.get_address_list() if address_list: - address_list[0].set_phone(line.data) + if address_list[0].get_phone(): + self.__add_msg(_("Only one phone number supported"), line, state) + else: + address_list[0].set_phone(line.data) + + def __repo_fax(self, line, state): + """ + @param line: The current line in GedLine format + @type line: GedLine + @param state: The current state + @type state: CurrentState + """ + url = Url() + url.set_path(line.data) + url.set_type(UrlType(_('FAX'))) + state.repo.add_url(url) def __repo_www(self, line, state): """ @@ -7969,7 +8019,10 @@ class GedcomParser(UpdateCallback): @param state: The current state @type state: CurrentState """ - state.res.set_phone(line.data) + if state.res.get_phone(): + self.__add_msg(_("Only one phone number supported"), line, state) + else: + state.res.set_phone(line.data) def __subm_email(self, line, state): """ @@ -7980,7 +8033,10 @@ class GedcomParser(UpdateCallback): @param state: The current state @type state: CurrentState """ - state.res.set_email(line.data) + # only record the first multiple emails for researcher + if not state.res.get_email(): + state.res.set_email(line.data) + self.__repo_email(line, state) #------------------------------------------------------------------------- # diff --git a/gramps/plugins/test/test_imports.py b/gramps/plugins/test/test_imports.py index dae89841e..49011a4df 100644 --- a/gramps/plugins/test/test_imports.py +++ b/gramps/plugins/test/test_imports.py @@ -32,6 +32,8 @@ from gramps.gen.simple import SimpleAccess from gramps.gen.utils.id import set_det_id from gramps.cli.user import User from gramps.gen.const import TEMP_DIR, DATA_DIR +from gramps.gen.utils.config import config +from gramps.plugins.export.exportxml import XmlWriter logger = logging.getLogger(__name__) @@ -179,13 +181,21 @@ def make_tst_function(tstfile, file_name): fn1 = os.path.join(TEST_DIR, tstfile) fn2 = os.path.join(TEST_DIR, (file_name + ".gramps")) fres = os.path.join(TEMP_DIR, (file_name + ".difs")) + fout = os.path.join(TEMP_DIR, (file_name + ".gramps")) + if "_dfs" in tstfile: + config.set('preferences.default-source', True) + skp_imp_adds = False + else: + skp_imp_adds = True try: os.remove(fres) + os.remove(fout) except OSError: pass logging.info("\n**** %s ****", tstfile) set_det_id(True) - self.database1 = import_as_dict(fn1, self.user) + self.database1 = import_as_dict(fn1, self.user, + skp_imp_adds=skp_imp_adds) set_det_id(True) self.database2 = import_as_dict(fn2, self.user) self.assertIsNotNone(self.database1, @@ -200,7 +210,12 @@ def make_tst_function(tstfile, file_name): deltas = self.prepare_result(diffs, added, missing) # We save a copy of any issues in the users Gramps TEMP_DIR in a file # with a '.difs' extension, as well as usual unittest report + # Also we save the .gramps file from the import so user can perform + # Diff himself for better context. if deltas: + writer = XmlWriter(self.database1, self.user, + strip_photos=0, compress=0) + writer.write(fout) hres = open(fres, mode='w', encoding='utf-8', errors='replace') hres.write(self.msg)