Merge pull request #196 from prculley/FTM_photo

Bug (Feature) 9580 Gedcom import of FTM file containing _PHOTO tags
This commit is contained in:
Doug Blank 2016-07-16 11:23:03 -04:00 committed by GitHub
commit 523abbf722
3 changed files with 177 additions and 0 deletions

View File

@ -0,0 +1,43 @@
0 HEAD
1 SOUR FTM
2 VERS Family Tree Maker (21.0.0.723)
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
1 DEST GED55
1 DATE 11 DEC 2013
1 CHAR UTF-8
1 FILE D:\Family Tree Maker\imp_FTM_OCCU_bug.ged
1 SUBM @SUBM@
1 GEDC
2 VERS 5.5
2 FORM LINEAGE-LINKED
0 @SUBM@ SUBM
0 @I1@ INDI
1 NAME The /Tester/
1 NOTE The primary photo should be a male Sourpuss in a Hat 03.jpg or Gid:M3
1 _PHOTO @M3@
1 OBJE @M1@
1 OBJE @M2@
1 OBJE @M3@
1 OBJE @M4@
1 OBJE @M5@
0 @M1@ OBJE
1 FILE O1.jpg
2 TITL Ferry Arriving 1910
0 @M2@ OBJE
1 FILE O2.jpg
2 TITL B&W Kids
0 @M3@ OBJE
1 FILE O3.jpg
2 TITL Sourpuss in Hat
1 NOTE Should be the selected primary photo
0 @M4@ OBJE
1 FILE O4.jpg
2 TITL Girl Eating
0 @M5@ OBJE
1 FILE O5.jpg
2 TITL Edwin & Janice Smith
0 TRLR

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE database PUBLIC "-//Gramps//DTD Gramps XML 1.7.1//EN"
"http://gramps-project.org/xml/1.7.1/grampsxml.dtd">
<database xmlns="http://gramps-project.org/xml/1.7.1/">
<header>
<created date="2016-07-14" version="5.0.0-alpha1"/>
<researcher>
</researcher>
</header>
<people>
<person handle="_0000000100000001" change="1468535650" id="I0001">
<gender>U</gender>
<name type="Birth Name">
<first>The</first>
<surname>Tester</surname>
</name>
<objref hlink="_0000000500000005"/>
<objref hlink="_0000000300000003"/>
<objref hlink="_0000000400000004"/>
<objref hlink="_0000000600000006"/>
<objref hlink="_0000000700000007"/>
<noteref hlink="_0000000200000002"/>
</person>
</people>
<objects>
<object handle="_0000000300000003" change="1468535650" id="M1">
<file src="O1.jpg" mime="image/jpeg" description="Ferry Arriving 1910"/>
<noteref hlink="_0000000800000008"/>
</object>
<object handle="_0000000400000004" change="1468535650" id="M2">
<file src="O2.jpg" mime="image/jpeg" description="B&amp;W Kids"/>
<noteref hlink="_0000000900000009"/>
</object>
<object handle="_0000000500000005" change="1468535650" id="M3">
<file src="O3.jpg" mime="image/jpeg" description="Sourpuss in Hat"/>
<noteref hlink="_0000000a0000000a"/>
<noteref hlink="_0000000b0000000b"/>
</object>
<object handle="_0000000600000006" change="1468535650" id="M4">
<file src="O4.jpg" mime="image/jpeg" description="Girl Eating"/>
<noteref hlink="_0000000c0000000c"/>
</object>
<object handle="_0000000700000007" change="1468535650" id="M5">
<file src="O5.jpg" mime="image/jpeg" description="Edwin &amp; Janice Smith"/>
<noteref hlink="_0000000d0000000d"/>
</object>
</objects>
<notes>
<note handle="_0000000200000002" change="1468535650" id="N0000" type="General">
<text>The primary photo should be a male Sourpuss in a Hat 03.jpg or Gid:M3</text>
</note>
<note handle="_0000000800000008" change="1468535650" id="N0001" type="GEDCOM import">
<text>Records not imported into OBJE (multi-media object) Gramps ID M1:
Could not import O1.jpg Line 28: 1 FILE O1.jpg</text>
<style name="fontface" value="Monospace">
<range start="0" end="161"/>
</style>
</note>
<note handle="_0000000900000009" change="1468535650" id="N0002" type="GEDCOM import">
<text>Records not imported into OBJE (multi-media object) Gramps ID M2:
Could not import O2.jpg Line 31: 1 FILE O2.jpg</text>
<style name="fontface" value="Monospace">
<range start="0" end="161"/>
</style>
</note>
<note handle="_0000000a0000000a" change="1468535650" id="N0003" type="General">
<text>Should be the selected primary photo</text>
</note>
<note handle="_0000000b0000000b" change="1468535650" id="N0004" type="GEDCOM import">
<text>Records not imported into OBJE (multi-media object) Gramps ID M3:
Could not import O3.jpg Line 34: 1 FILE O3.jpg</text>
<style name="fontface" value="Monospace">
<range start="0" end="161"/>
</style>
</note>
<note handle="_0000000c0000000c" change="1468535650" id="N0005" type="GEDCOM import">
<text>Records not imported into OBJE (multi-media object) Gramps ID M4:
Could not import O4.jpg Line 38: 1 FILE O4.jpg</text>
<style name="fontface" value="Monospace">
<range start="0" end="161"/>
</style>
</note>
<note handle="_0000000d0000000d" change="1468535650" id="N0006" type="GEDCOM import">
<text>Records not imported into OBJE (multi-media object) Gramps ID M5:
Could not import O5.jpg Line 41: 1 FILE O5.jpg</text>
<style name="fontface" value="Monospace">
<range start="0" end="161"/>
</style>
</note>
</notes>
</database>

View File

@ -267,6 +267,7 @@ TOKEN__MAR = 128
TOKEN__MARN = 129 TOKEN__MARN = 129
TOKEN__ADPN = 130 TOKEN__ADPN = 130
TOKEN__FSFTID = 131 TOKEN__FSFTID = 131
TOKEN__PHOTO = 132
TOKENS = { TOKENS = {
"HEAD" : TOKEN_HEAD, "MEDI" : TOKEN_MEDI, "HEAD" : TOKEN_HEAD, "MEDI" : TOKEN_MEDI,
@ -373,6 +374,7 @@ TOKENS = {
"_URL" : TOKEN_URL, "URL" : TOKEN_URL, "_URL" : TOKEN_URL, "URL" : TOKEN_URL,
"_MAR" : TOKEN__MAR, "_MARN" : TOKEN__MARN, "_MAR" : TOKEN__MAR, "_MARN" : TOKEN__MARN,
"_ADPN" : TOKEN__ADPN, "_FSFTID" : TOKEN__FSFTID, "_ADPN" : TOKEN__ADPN, "_FSFTID" : TOKEN__FSFTID,
"_PHOTO" : TOKEN__PHOTO,
} }
ADOPT_NONE = 0 ADOPT_NONE = 0
@ -1622,6 +1624,7 @@ class CurrentState:
self.repo_ref = None self.repo_ref = None
self.place = None self.place = None
self.media = None self.media = None
self.photo = "" # prc Person primary photo
def __getattr__(self, name): def __getattr__(self, name):
""" """
@ -2087,6 +2090,7 @@ class GedcomParser(UpdateCallback):
TOKEN_URL : self.__person_url, TOKEN_URL : self.__person_url,
TOKEN__TODO : self.__skip_record, TOKEN__TODO : self.__skip_record,
TOKEN_TITL : self.__person_titl, TOKEN_TITL : self.__person_titl,
TOKEN__PHOTO: self.__person_photo,
} }
self.func_list.append(self.indi_parse_tbl) self.func_list.append(self.indi_parse_tbl)
@ -3614,6 +3618,9 @@ class GedcomParser(UpdateCallback):
# Add a default tag if provided # Add a default tag if provided
self.__add_default_tag(person) self.__add_default_tag(person)
# Set up primary photo if present
self.__do_photo(state)
self.__check_msgs(_("INDI (individual) Gramps ID %s") % self.__check_msgs(_("INDI (individual) Gramps ID %s") %
person.get_gramps_id(), state, person) person.get_gramps_id(), state, person)
# commit the person to the database # commit the person to the database
@ -3816,6 +3823,13 @@ class GedcomParser(UpdateCallback):
self.__add_msg(_("Form omitted"), line, state) self.__add_msg(_("Form omitted"), line, state)
self.build_media(state.person, form, filename, title, note) self.build_media(state.person, form, filename, title, note)
def __person_photo(self, line, state):
"""
This handles the FTM _PHOTO feature, which identifies an OBJE to use
as the person's primary photo.
"""
state.photo = line.data # Just save it for now.
def __person_name(self, line, state): def __person_name(self, line, state):
""" """
Parsers the NAME token in a GEDCOM file. The text is in the format Parsers the NAME token in a GEDCOM file. The text is in the format
@ -7745,6 +7759,30 @@ class GedcomParser(UpdateCallback):
event_ref.set_reference_handle(event.handle) event_ref.set_reference_handle(event.handle)
return event_ref return event_ref
def __do_photo(self, state):
"""
Choose the primary photo from the list of media present for this
person. Supports FTM _PHOTO feature.
0 INDI
+1 _PHOTO @<XREF:OBJE>@ {1:1}
Since Gramps currently uses the first media in the list as the
primary, find the primary photo if already in the list, if present,
move to beginning. If not present, add at the beginning.
This is run after all of the person processing is complete but before
committing the person.
"""
if state.photo:
gramps_id = self.oid_map[state.photo]
handle = self.__find_media_handle(gramps_id)
for mref in state.person.media_list:
if handle == mref.ref:
state.person.media_list.remove(mref)
state.person.media_list.insert(0, mref)
return
mref = MediaRef()
mref.set_reference_handle(handle)
state.person.media_list.insert(0, mref)
def __extract_temple(self, line): def __extract_temple(self, line):
def get_code(code): def get_code(code):
if TEMPLES.is_valid_code(code): if TEMPLES.is_valid_code(code):