* src/GrampsDb/_ReadGedcom.py: improve parsing, comment the code better
* example/gedcom/sample.ged: add new stuff svn: r6863
This commit is contained in:
parent
6a1b76786c
commit
3c45dfe0bb
@ -1,4 +1,6 @@
|
|||||||
2006-06-05 Don Allingham <don@gramps-project.org>
|
2006-06-05 Don Allingham <don@gramps-project.org>
|
||||||
|
* src/GrampsDb/_ReadGedcom.py: improve parsing, comment the code better
|
||||||
|
* example/gedcom/sample.ged: add new stuff
|
||||||
* src/Mime/_PythonMime.py (_type_map): register .gpkg for non-linux
|
* src/Mime/_PythonMime.py (_type_map): register .gpkg for non-linux
|
||||||
platforms
|
platforms
|
||||||
|
|
||||||
|
@ -70,11 +70,22 @@
|
|||||||
1 BIRT Edwin Michael Smith's Birth event
|
1 BIRT Edwin Michael Smith's Birth event
|
||||||
2 DATE 24 MAY 1961
|
2 DATE 24 MAY 1961
|
||||||
2 PLAC San Jose, Santa Clara Co., CA
|
2 PLAC San Jose, Santa Clara Co., CA
|
||||||
|
2 FAMC @F02@
|
||||||
1 OCCU
|
1 OCCU
|
||||||
2 PLAC Software Engineer
|
2 PLAC Software Engineer
|
||||||
1 EDUC
|
1 EDUC
|
||||||
2 DATE BET. 1979 - 1984
|
2 DATE BET. 1979 - 1984
|
||||||
2 PLAC UC Berkeley
|
2 PLAC UC Berkeley
|
||||||
|
1 RESI
|
||||||
|
2 DATE 1 JAN 1985
|
||||||
|
2 ADDR Address Line 0
|
||||||
|
3 ADR1 Adr1 line
|
||||||
|
3 ADR2 Adr2 line
|
||||||
|
3 CITY City line
|
||||||
|
3 STAE State line
|
||||||
|
3 POST Post line
|
||||||
|
2 NOTE This is the residence note
|
||||||
|
2 PHON 123-456-7890
|
||||||
1 SSN 123-456-7890
|
1 SSN 123-456-7890
|
||||||
1 CAST cast keyword
|
1 CAST cast keyword
|
||||||
1 DSCR dscr keyword
|
1 DSCR dscr keyword
|
||||||
@ -115,6 +126,9 @@
|
|||||||
1 DEAT
|
1 DEAT
|
||||||
2 DATE deceased
|
2 DATE deceased
|
||||||
2 PLAC Sweden
|
2 PLAC Sweden
|
||||||
|
1 ADOP
|
||||||
|
2 FAMC @F04@
|
||||||
|
3 ADOP @I38@
|
||||||
1 REFN 366
|
1 REFN 366
|
||||||
1 FAMS @F03@
|
1 FAMS @F03@
|
||||||
1 FAMC @F04@
|
1 FAMC @F04@
|
||||||
|
@ -313,6 +313,7 @@ class CurrentState:
|
|||||||
self.note = ""
|
self.note = ""
|
||||||
self.name_cnt = 0
|
self.name_cnt = 0
|
||||||
self.person = None
|
self.person = None
|
||||||
|
self.level =0
|
||||||
|
|
||||||
def add_to_note(self,text):
|
def add_to_note(self,text):
|
||||||
self.note += text
|
self.note += text
|
||||||
@ -539,6 +540,50 @@ class GedcomParser(UpdateCallback):
|
|||||||
TOKEN_NOTE : self.func_name_note,
|
TOKEN_NOTE : self.func_name_note,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.person_event_map = {
|
||||||
|
TOKEN_TYPE : self.func_person_event_type,
|
||||||
|
TOKEN__PRIV : self.func_person_event_privacy,
|
||||||
|
TOKEN_DATE : self.func_person_event_date,
|
||||||
|
TOKEN_SOUR : self.func_person_event_source,
|
||||||
|
TOKEN_PLAC : self.func_person_event_place,
|
||||||
|
TOKEN_CAUS : self.func_person_event_cause,
|
||||||
|
TOKEN_NOTE : self.func_person_event_note,
|
||||||
|
TOKEN_OFFI : self.func_person_event_note,
|
||||||
|
TOKEN__GODP : self.func_person_event_ignore,
|
||||||
|
TOKEN__WITN : self.func_person_event_ignore,
|
||||||
|
TOKEN__WTN : self.func_person_event_ignore,
|
||||||
|
TOKEN_RELI : self.func_person_event_ignore,
|
||||||
|
TOKEN_TIME : self.func_person_event_ignore,
|
||||||
|
TOKEN_ADDR : self.func_person_event_ignore,
|
||||||
|
TOKEN_IGNORE : self.func_person_event_ignore,
|
||||||
|
TOKEN_STAT : self.func_person_event_ignore,
|
||||||
|
TOKEN_TEMP : self.func_person_event_ignore,
|
||||||
|
TOKEN_OBJE : self.func_person_event_ignore,
|
||||||
|
TOKEN_FAMC : self.func_person_event_ignore,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.person_adopt_map = {
|
||||||
|
TOKEN_TYPE : self.func_person_event_type,
|
||||||
|
TOKEN__PRIV : self.func_person_event_privacy,
|
||||||
|
TOKEN_DATE : self.func_person_event_date,
|
||||||
|
TOKEN_SOUR : self.func_person_event_source,
|
||||||
|
TOKEN_PLAC : self.func_person_event_place,
|
||||||
|
TOKEN_CAUS : self.func_person_event_cause,
|
||||||
|
TOKEN_NOTE : self.func_person_event_note,
|
||||||
|
TOKEN_OFFI : self.func_person_event_note,
|
||||||
|
TOKEN__GODP : self.func_person_event_ignore,
|
||||||
|
TOKEN__WITN : self.func_person_event_ignore,
|
||||||
|
TOKEN__WTN : self.func_person_event_ignore,
|
||||||
|
TOKEN_RELI : self.func_person_event_ignore,
|
||||||
|
TOKEN_TIME : self.func_person_event_ignore,
|
||||||
|
TOKEN_ADDR : self.func_person_event_ignore,
|
||||||
|
TOKEN_IGNORE : self.func_person_event_ignore,
|
||||||
|
TOKEN_STAT : self.func_person_event_ignore,
|
||||||
|
TOKEN_TEMP : self.func_person_event_ignore,
|
||||||
|
TOKEN_OBJE : self.func_person_event_ignore,
|
||||||
|
TOKEN_FAMC : self.func_person_adopt_famc,
|
||||||
|
}
|
||||||
|
|
||||||
self.person_func = {
|
self.person_func = {
|
||||||
TOKEN_NAME : self.func_person_name,
|
TOKEN_NAME : self.func_person_name,
|
||||||
TOKEN_ALIA : self.func_person_alt_name,
|
TOKEN_ALIA : self.func_person_alt_name,
|
||||||
@ -1243,6 +1288,7 @@ class GedcomParser(UpdateCallback):
|
|||||||
"""
|
"""
|
||||||
state = CurrentState()
|
state = CurrentState()
|
||||||
state.person = person
|
state.person = person
|
||||||
|
state.level = 1
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
matches = self.get_next()
|
matches = self.get_next()
|
||||||
@ -1387,35 +1433,6 @@ class GedcomParser(UpdateCallback):
|
|||||||
oref.set_note(note)
|
oref.set_note(note)
|
||||||
self.family.add_media_reference(oref)
|
self.family.add_media_reference(oref)
|
||||||
|
|
||||||
def parse_residence(self,address,level):
|
|
||||||
note = ""
|
|
||||||
while True:
|
|
||||||
matches = self.get_next()
|
|
||||||
|
|
||||||
if int(matches[0]) < level:
|
|
||||||
self.backup()
|
|
||||||
return
|
|
||||||
elif matches[1] == TOKEN_DATE:
|
|
||||||
address.set_date_object(self.extract_date(matches[2]))
|
|
||||||
elif matches[1] == TOKEN_ADDR:
|
|
||||||
address.set_street(matches[2])
|
|
||||||
self.parse_address(address,level+1)
|
|
||||||
elif matches[1] in (TOKEN_IGNORE,TOKEN_CAUS,TOKEN_STAT,
|
|
||||||
TOKEN_TEMP,TOKEN_OBJE,TOKEN_TYPE):
|
|
||||||
self.ignore_sub_junk(level+1)
|
|
||||||
elif matches[1] == TOKEN_SOUR:
|
|
||||||
address.add_source_reference(self.handle_source(matches,level+1))
|
|
||||||
elif matches[1] == TOKEN_PLAC:
|
|
||||||
address.set_street(matches[2])
|
|
||||||
self.parse_address(address,level+1)
|
|
||||||
elif matches[1] == TOKEN_PHON:
|
|
||||||
address.set_street("Unknown")
|
|
||||||
address.set_phone(matches[2])
|
|
||||||
elif matches[1] == TOKEN_NOTE:
|
|
||||||
note = self.parse_note(matches,address,level+1,note)
|
|
||||||
else:
|
|
||||||
self.barf(level+1)
|
|
||||||
|
|
||||||
def parse_address(self,address,level):
|
def parse_address(self,address,level):
|
||||||
first = 0
|
first = 0
|
||||||
note = ""
|
note = ""
|
||||||
@ -1447,10 +1464,8 @@ class GedcomParser(UpdateCallback):
|
|||||||
address.set_phone(matches[2])
|
address.set_phone(matches[2])
|
||||||
elif matches[1] == TOKEN_NOTE:
|
elif matches[1] == TOKEN_NOTE:
|
||||||
note = self.parse_note(matches,address,level+1,note)
|
note = self.parse_note(matches,address,level+1,note)
|
||||||
elif matches[1] == TOKEN__LOC:
|
elif matches[1] in (TOKEN__LOC, TOKEN__NAME):
|
||||||
pass # ignore unsupported extended location syntax
|
pass # ignore unsupported extended location syntax
|
||||||
elif matches[1] == TOKEN__NAME:
|
|
||||||
pass # ignore
|
|
||||||
else:
|
else:
|
||||||
self.barf(level+1)
|
self.barf(level+1)
|
||||||
|
|
||||||
@ -1490,118 +1505,73 @@ class GedcomParser(UpdateCallback):
|
|||||||
else:
|
else:
|
||||||
self.barf(level+1)
|
self.barf(level+1)
|
||||||
|
|
||||||
def parse_person_event(self,event,level):
|
def parse_person_event(self, event, func_map, level):
|
||||||
note = ""
|
|
||||||
while True:
|
while True:
|
||||||
matches = self.get_next()
|
matches = self.get_next()
|
||||||
if int(matches[0]) < level:
|
if self.level_is_finished(matches,level):
|
||||||
if note:
|
|
||||||
event.set_note(note)
|
|
||||||
self.backup()
|
|
||||||
break
|
break
|
||||||
elif matches[1] == TOKEN_TYPE:
|
|
||||||
if event.get_type().is_custom():
|
|
||||||
if ged2gramps.has_key(matches[2]):
|
|
||||||
name = RelLib.EventType(ged2gramps[matches[2]])
|
|
||||||
else:
|
|
||||||
val = self.gedsource.tag2gramps(matches[2])
|
|
||||||
if val:
|
|
||||||
name = RelLib.EventType((RelLib.EventType.CUSTOM,val))
|
|
||||||
else:
|
|
||||||
name = RelLib.EventType((RelLib.EventType.CUSTOM,matches[3]))
|
|
||||||
event.set_type(name)
|
|
||||||
else:
|
|
||||||
event.set_description(matches[2])
|
|
||||||
elif matches[1] == TOKEN__PRIV and matches[2] == "Y":
|
|
||||||
event.set_privacy(True)
|
|
||||||
elif matches[1] == TOKEN_DATE:
|
|
||||||
event.set_date_object(self.extract_date(matches[2]))
|
|
||||||
elif matches[1] == TOKEN_SOUR:
|
|
||||||
event.add_source_reference(self.handle_source(matches,level+1))
|
|
||||||
elif matches[1] == TOKEN_PLAC:
|
|
||||||
val = matches[2]
|
|
||||||
n = event.get_type()
|
|
||||||
if self.is_ftw and int(n) in [RelLib.EventType.OCCUPATION,RelLib.EventType.DEGREE]:
|
|
||||||
event.set_description(val)
|
|
||||||
self.ignore_sub_junk(level+1)
|
|
||||||
else:
|
|
||||||
place = self.find_or_create_place(val)
|
|
||||||
place_handle = place.handle
|
|
||||||
place.set_title(matches[2])
|
|
||||||
load_place_values(place,matches[2])
|
|
||||||
event.set_place_handle(place_handle)
|
|
||||||
self.ignore_sub_junk(level+1)
|
|
||||||
elif matches[1] == TOKEN_CAUS:
|
|
||||||
info = matches[2]
|
|
||||||
event.set_cause(info)
|
|
||||||
self.parse_cause(event,level+1)
|
|
||||||
elif matches[1] in (TOKEN_NOTE,TOKEN_OFFI):
|
|
||||||
info = self.parse_note(matches,event,level+1,note)
|
|
||||||
if note == "":
|
|
||||||
note = info
|
|
||||||
else:
|
|
||||||
note = "\n%s" % info
|
|
||||||
elif matches[1] in (TOKEN__GODP, TOKEN__WITN, TOKEN__WTN):
|
|
||||||
# if matches[2][0] == "@":
|
|
||||||
# witness_handle = self.find_person_handle(self.map_gid(matches[2][1:-1]))
|
|
||||||
# witness = RelLib.Witness(RelLib.Event.ID,witness_handle)
|
|
||||||
# else:
|
|
||||||
# witness = RelLib.Witness(RelLib.Event.NAME,matches[2])
|
|
||||||
# event.add_witness(witness)
|
|
||||||
self.ignore_sub_junk(level+1)
|
|
||||||
elif matches[1] in (TOKEN_RELI, TOKEN_TIME, TOKEN_ADDR,TOKEN_IGNORE,
|
|
||||||
TOKEN_STAT,TOKEN_TEMP,TOKEN_OBJE):
|
|
||||||
self.ignore_sub_junk(level+1)
|
|
||||||
else:
|
else:
|
||||||
self.barf(level+1)
|
func = func_map.get(matches[1], self.func_person_event_undef)
|
||||||
|
func(matches, event, level+1)
|
||||||
|
|
||||||
def parse_adopt_event(self,event,level):
|
def func_person_event_ignore(self, matches, event, level):
|
||||||
note = ""
|
self.ignore_sub_junk(level)
|
||||||
while True:
|
|
||||||
matches = self.get_next()
|
def func_person_event_undef(self, matches, event, level):
|
||||||
if int(matches[0]) < level:
|
self.barf(level)
|
||||||
if note != "":
|
|
||||||
event.set_note(note)
|
def func_person_event_type(self, matches, event, level):
|
||||||
self.backup()
|
if event.get_type().is_custom():
|
||||||
break
|
if ged2gramps.has_key(matches[2]):
|
||||||
elif matches[1] == TOKEN_DATE:
|
name = RelLib.EventType(ged2gramps[matches[2]])
|
||||||
event.set_date_object(self.extract_date(matches[2]))
|
|
||||||
elif matches[1] in (TOKEN_TIME,TOKEN_ADDR,TOKEN_IGNORE,
|
|
||||||
TOKEN_STAT,TOKEN_TEMP,TOKEN_OBJE):
|
|
||||||
self.ignore_sub_junk(level+1)
|
|
||||||
elif matches[1] == TOKEN_SOUR:
|
|
||||||
event.add_source_reference(self.handle_source(matches,level+1))
|
|
||||||
elif matches[1] == TOKEN_FAMC:
|
|
||||||
handle = self.find_family_handle(matches[2][1:-1])
|
|
||||||
mrel,frel = self.parse_adopt_famc(level+1);
|
|
||||||
if self.person.get_main_parents_family_handle() == handle:
|
|
||||||
self.person.set_main_parent_family_handle(None)
|
|
||||||
self.person.add_parent_family_handle(handle)
|
|
||||||
if mrel != RelLib.ChildRefType.BIRTH or frel != RelLib.ChildRefType.BIRTH:
|
|
||||||
print "NOT FIXED YET"
|
|
||||||
elif matches[1] == TOKEN_PLAC:
|
|
||||||
val = matches[2]
|
|
||||||
place = self.find_or_create_place(val)
|
|
||||||
place_handle = place.handle
|
|
||||||
place.set_title(matches[2])
|
|
||||||
load_place_values(place,matches[2])
|
|
||||||
event.set_place_handle(place_handle)
|
|
||||||
self.ignore_sub_junk(level+1)
|
|
||||||
elif matches[1] == TOKEN_TYPE:
|
|
||||||
# eventually do something intelligent here
|
|
||||||
pass
|
|
||||||
elif matches[1] == TOKEN_CAUS:
|
|
||||||
info = matches[2]
|
|
||||||
event.set_cause(info)
|
|
||||||
self.parse_cause(event,level+1)
|
|
||||||
elif matches[1] == TOKEN_NOTE:
|
|
||||||
info = self.parse_note(matches,event,level+1,note)
|
|
||||||
if note == "":
|
|
||||||
note = info
|
|
||||||
else:
|
|
||||||
note = "\n%s" % info
|
|
||||||
else:
|
else:
|
||||||
self.barf(level+1)
|
val = self.gedsource.tag2gramps(matches[2])
|
||||||
|
if val:
|
||||||
|
name = RelLib.EventType((RelLib.EventType.CUSTOM,val))
|
||||||
|
else:
|
||||||
|
name = RelLib.EventType((RelLib.EventType.CUSTOM,matches[3]))
|
||||||
|
event.set_type(name)
|
||||||
|
else:
|
||||||
|
event.set_description(matches[2])
|
||||||
|
|
||||||
|
def func_person_event_privacy(self, matches, event, level):
|
||||||
|
event.set_privacy(True)
|
||||||
|
|
||||||
|
def func_person_adopt_famc(self, matches, event, level):
|
||||||
|
print "ADOPT FAMC"
|
||||||
|
handle = self.find_family_handle(matches[2][1:-1])
|
||||||
|
mrel,frel = self.parse_adopt_famc(level+1);
|
||||||
|
if self.person.get_main_parents_family_handle() == handle:
|
||||||
|
self.person.set_main_parent_family_handle(None)
|
||||||
|
self.person.add_parent_family_handle(handle)
|
||||||
|
if mrel != RelLib.ChildRefType.BIRTH or frel != RelLib.ChildRefType.BIRTH:
|
||||||
|
print "NOT FIXED YET"
|
||||||
|
|
||||||
|
def func_person_event_note(self, matches, event, level):
|
||||||
|
self.parse_note(matches,event,level+1,note)
|
||||||
|
|
||||||
|
def func_person_event_date(self, matches, event, level):
|
||||||
|
event.set_date_object(self.extract_date(matches[2]))
|
||||||
|
|
||||||
|
def func_person_event_source(self, matches, event, level):
|
||||||
|
event.add_source_reference(self.handle_source(matches,level+1))
|
||||||
|
|
||||||
|
def func_person_event_place(self, matches, event, level):
|
||||||
|
val = matches[2]
|
||||||
|
n = event.get_type()
|
||||||
|
if self.is_ftw and int(n) in [RelLib.EventType.OCCUPATION,RelLib.EventType.DEGREE]:
|
||||||
|
event.set_description(val)
|
||||||
|
else:
|
||||||
|
place = self.find_or_create_place(val)
|
||||||
|
place_handle = place.handle
|
||||||
|
place.set_title(matches[2])
|
||||||
|
load_place_values(place,matches[2])
|
||||||
|
event.set_place_handle(place_handle)
|
||||||
|
self.ignore_sub_junk(level+1)
|
||||||
|
|
||||||
|
def func_person_event_cause(self, matches, event, level):
|
||||||
|
event.set_cause(matches[2])
|
||||||
|
self.parse_cause(event,level+1)
|
||||||
|
|
||||||
def parse_adopt_famc(self,level):
|
def parse_adopt_famc(self,level):
|
||||||
mrel = _TYPE_ADOPT
|
mrel = _TYPE_ADOPT
|
||||||
@ -1621,11 +1591,13 @@ class GedcomParser(UpdateCallback):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def parse_person_attr(self,attr,level):
|
def parse_person_attr(self,attr,level):
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
note = ""
|
note = ""
|
||||||
while True:
|
while True:
|
||||||
matches = self.get_next()
|
matches = self.get_next()
|
||||||
if int(matches[0]) < level:
|
if self.level_is_finished(matches,level):
|
||||||
self.backup()
|
|
||||||
break
|
break
|
||||||
elif matches[1] == TOKEN_TYPE:
|
elif matches[1] == TOKEN_TYPE:
|
||||||
if attr.get_type() == "":
|
if attr.get_type() == "":
|
||||||
@ -1647,7 +1619,7 @@ class GedcomParser(UpdateCallback):
|
|||||||
val = matches[2]
|
val = matches[2]
|
||||||
if attr.get_value() == "":
|
if attr.get_value() == "":
|
||||||
attr.set_value(val)
|
attr.set_value(val)
|
||||||
self.ignore_sub_junk(level+1)
|
self.ignore_sub_junk(level+1)
|
||||||
elif matches[1] == TOKEN_DATE:
|
elif matches[1] == TOKEN_DATE:
|
||||||
note = "%s\n\n" % ("Date : %s" % matches[2])
|
note = "%s\n\n" % ("Date : %s" % matches[2])
|
||||||
elif matches[1] == TOKEN_NOTE:
|
elif matches[1] == TOKEN_NOTE:
|
||||||
@ -2075,6 +2047,18 @@ class GedcomParser(UpdateCallback):
|
|||||||
<TEXT>|/<TEXT>/|<TEXT>/<TEXT>/|/<TEXT>/<TEXT>|<TEXT>/<TEXT>/<TEXT>
|
<TEXT>|/<TEXT>/|<TEXT>/<TEXT>/|/<TEXT>/<TEXT>|<TEXT>/<TEXT>/<TEXT>
|
||||||
We have encountered some variations that use:
|
We have encountered some variations that use:
|
||||||
<TEXT>/
|
<TEXT>/
|
||||||
|
|
||||||
|
The basic Name structure is:
|
||||||
|
|
||||||
|
n NAME <NAME_PERSONAL> {1:1}
|
||||||
|
+1 NPFX <NAME_PIECE_PREFIX> {0:1}
|
||||||
|
+1 GIVN <NAME_PIECE_GIVEN> {0:1}
|
||||||
|
+1 NICK <NAME_PIECE_NICKNAME> {0:1}
|
||||||
|
+1 SPFX <NAME_PIECE_SURNAME_PREFIX {0:1}
|
||||||
|
+1 SURN <NAME_PIECE_SURNAME> {0:1}
|
||||||
|
+1 NSFX <NAME_PIECE_SUFFIX> {0:1}
|
||||||
|
+1 <<SOURCE_CITATION>> {0:M}
|
||||||
|
+1 <<NOTE_STRUCTURE>> {0:M}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# build a RelLib.Name structure from the text
|
# build a RelLib.Name structure from the text
|
||||||
@ -2088,10 +2072,10 @@ class GedcomParser(UpdateCallback):
|
|||||||
# of different name types
|
# of different name types
|
||||||
|
|
||||||
if state.name_cnt == 0:
|
if state.name_cnt == 0:
|
||||||
name.set_type(RelLib.set_type(RelLib.NameType.BIRTH)
|
name.set_type(RelLib.NameType.BIRTH)
|
||||||
state.person.set_primary_name(name)
|
state.person.set_primary_name(name)
|
||||||
else:
|
else:
|
||||||
name.set_type(RelLib.set_type(RelLib.NameType.AKA)
|
name.set_type(RelLib.NameType.AKA)
|
||||||
state.person.add_alternate_name(name)
|
state.person.add_alternate_name(name)
|
||||||
state.name_cnt += 1
|
state.name_cnt += 1
|
||||||
|
|
||||||
@ -2114,7 +2098,21 @@ class GedcomParser(UpdateCallback):
|
|||||||
def func_person_asso(self, matches, state):
|
def func_person_asso(self, matches, state):
|
||||||
"""
|
"""
|
||||||
Parse the ASSO tag, add the the referenced person to the person we
|
Parse the ASSO tag, add the the referenced person to the person we
|
||||||
are currently parsing.
|
are currently parsing. The GEDCOM spec indicates that valid ASSOC tag
|
||||||
|
is:
|
||||||
|
|
||||||
|
n ASSO @<XREF:INDI>@ {0:M}
|
||||||
|
|
||||||
|
And the the sub tags are:
|
||||||
|
|
||||||
|
ASSOCIATION_STRUCTURE:=
|
||||||
|
+1 TYPE <RECORD_TYPE> {1:1}
|
||||||
|
+1 RELA <RELATION_IS_DESCRIPTOR> {1:1}
|
||||||
|
+1 <<NOTE_STRUCTURE>> {0:M}
|
||||||
|
+1 <<SOURCE_CITATION>> {0:M}
|
||||||
|
|
||||||
|
GRAMPS only supports ASSO records to people, so if the TYPE is
|
||||||
|
something other than INDI, the record is ignored.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# find the id and person that we are referencing
|
# find the id and person that we are referencing
|
||||||
@ -2126,15 +2124,17 @@ class GedcomParser(UpdateCallback):
|
|||||||
|
|
||||||
ref = RelLib.PersonRef()
|
ref = RelLib.PersonRef()
|
||||||
ref.ref = handle
|
ref.ref = handle
|
||||||
|
ignore = False
|
||||||
state.person.add_person_ref(ref)
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
matches = self.get_next()
|
matches = self.get_next()
|
||||||
|
|
||||||
if int(matches[0]) < 2:
|
if self.level_is_finished(matches,2):
|
||||||
self.backup()
|
if not ignore:
|
||||||
return
|
state.person.add_person_ref(ref)
|
||||||
|
break
|
||||||
|
elif matches[1] == TOKEN_TYPE and matches[2] != "INDI":
|
||||||
|
ignore = True
|
||||||
elif matches[1] == TOKEN_RELA:
|
elif matches[1] == TOKEN_RELA:
|
||||||
ref.rel = matches[2]
|
ref.rel = matches[2]
|
||||||
elif matches[1] == TOKEN_SOUR:
|
elif matches[1] == TOKEN_SOUR:
|
||||||
@ -2154,19 +2154,90 @@ class GedcomParser(UpdateCallback):
|
|||||||
multiple names.
|
multiple names.
|
||||||
"""
|
"""
|
||||||
name = self.parse_name_personal(matches[2])
|
name = self.parse_name_personal(matches[2])
|
||||||
name.set_type(RelLib.set_type(RelLib.NameType.AKA)
|
name.set_type(RelLib.NameType.AKA)
|
||||||
state.person.add_alternate_name(name)
|
state.person.add_alternate_name(name)
|
||||||
|
|
||||||
def func_person_object(self,matches,state):
|
def func_person_object(self, matches, state):
|
||||||
|
"""
|
||||||
|
Currently, the embedded form is not supported
|
||||||
|
|
||||||
|
Embedded form
|
||||||
|
|
||||||
|
n OBJE @<XREF:OBJE>@ {1:1}
|
||||||
|
|
||||||
|
Linked form
|
||||||
|
|
||||||
|
n OBJE {1:1}
|
||||||
|
+1 FORM <MULTIMEDIA_FORMAT> {1:1}
|
||||||
|
+1 TITL <DESCRIPTIVE_TITLE> {0:1}
|
||||||
|
+1 FILE <MULTIMEDIA_FILE_REFERENCE> {1:1}
|
||||||
|
+1 <<NOTE_STRUCTURE>> {0:M}
|
||||||
|
"""
|
||||||
|
|
||||||
if matches[2] and matches[2][0] == '@':
|
if matches[2] and matches[2][0] == '@':
|
||||||
self.barf(2)
|
self.barf(2)
|
||||||
else:
|
else:
|
||||||
self.parse_person_object(2,state)
|
form = ""
|
||||||
|
filename = ""
|
||||||
|
title = "no title"
|
||||||
|
note = ""
|
||||||
|
while True:
|
||||||
|
matches = self.get_next()
|
||||||
|
if self.level_is_finished(matches, state.level+1):
|
||||||
|
break
|
||||||
|
elif matches[1] == TOKEN_FORM:
|
||||||
|
form = matches[2].lower()
|
||||||
|
elif matches[1] == TOKEN_TITL:
|
||||||
|
title = matches[2]
|
||||||
|
elif matches[1] == TOKEN_FILE:
|
||||||
|
filename = matches[2]
|
||||||
|
elif matches[1] == TOKEN_NOTE:
|
||||||
|
note = matches[2]
|
||||||
|
elif matches[1] == TOKEN_UNKNOWN:
|
||||||
|
self.ignore_sub_junk(state.level+2)
|
||||||
|
else:
|
||||||
|
self.barf(state.level+2)
|
||||||
|
|
||||||
|
self.build_media_object(state, form, filename, title, note)
|
||||||
|
|
||||||
|
def build_media_object(self, state, form, filename, title, note):
|
||||||
|
if form == "url":
|
||||||
|
url = RelLib.Url()
|
||||||
|
url.set_path(filename)
|
||||||
|
url.set_description(title)
|
||||||
|
state.person.add_url(url)
|
||||||
|
else:
|
||||||
|
(ok,path) = self.find_file(filename,self.dir_path)
|
||||||
|
if not ok:
|
||||||
|
self.warn(_("Could not import %s") % filename)
|
||||||
|
path = filename.replace('\\','/')
|
||||||
|
photo_handle = self.media_map.get(path)
|
||||||
|
if photo_handle == None:
|
||||||
|
photo = RelLib.MediaObject()
|
||||||
|
photo.set_path(path)
|
||||||
|
photo.set_description(title)
|
||||||
|
photo.set_mime_type(Mime.get_type(os.path.abspath(path)))
|
||||||
|
self.db.add_object(photo, self.trans)
|
||||||
|
self.media_map[path] = photo.handle
|
||||||
|
else:
|
||||||
|
photo = self.db.get_object_from_handle(photo_handle)
|
||||||
|
oref = RelLib.MediaRef()
|
||||||
|
oref.set_reference_handle(photo.handle)
|
||||||
|
oref.set_note(note)
|
||||||
|
state.person.add_media_reference(oref)
|
||||||
|
|
||||||
def func_person_note(self,matches,state):
|
def func_person_note(self,matches,state):
|
||||||
self.note = self.parse_note(matches,self.person,1,state.note)
|
self.note = self.parse_note(matches,self.person,1,state.note)
|
||||||
|
|
||||||
def func_person_sex(self,matches,state):
|
def func_person_sex(self,matches,state):
|
||||||
|
"""
|
||||||
|
+1 SEX <SEX_VALUE> {0:1}
|
||||||
|
|
||||||
|
Valid values for <SEX_VALUE> are:
|
||||||
|
|
||||||
|
M = Male
|
||||||
|
F = Female
|
||||||
|
"""
|
||||||
if matches[2] == '':
|
if matches[2] == '':
|
||||||
state.person.set_gender(RelLib.Person.UNKNOWN)
|
state.person.set_gender(RelLib.Person.UNKNOWN)
|
||||||
elif matches[2][0] == "M":
|
elif matches[2][0] == "M":
|
||||||
@ -2216,11 +2287,59 @@ class GedcomParser(UpdateCallback):
|
|||||||
print "NEED TO CHANGE CHILDREF TO",ftype,ftype
|
print "NEED TO CHANGE CHILDREF TO",ftype,ftype
|
||||||
|
|
||||||
def func_person_resi(self,matches,state):
|
def func_person_resi(self,matches,state):
|
||||||
|
"""
|
||||||
|
The RESI tag follows the EVENT_DETAIL structure, which is:
|
||||||
|
|
||||||
|
n TYPE <EVENT_DESCRIPTOR> {0:1}
|
||||||
|
n DATE <DATE_VALUE> {0:1}
|
||||||
|
n <<PLACE_STRUCTURE>> {0:1}
|
||||||
|
n <<ADDRESS_STRUCTURE>> {0:1}
|
||||||
|
n AGE <AGE_AT_EVENT> {0:1}
|
||||||
|
n AGNC <RESPONSIBLE_AGENCY> {0:1}
|
||||||
|
n CAUS <CAUSE_OF_EVENT> {0:1}
|
||||||
|
n <<SOURCE_CITATION>> {0:M}
|
||||||
|
n <<MULTIMEDIA_LINK>> {0:M}
|
||||||
|
n <<NOTE_STRUCTURE>> {0:M}
|
||||||
|
|
||||||
|
Currently, the TYPE, AGE, CAUSE, STAT, and other tags which
|
||||||
|
do not apply to an address are ignored.
|
||||||
|
"""
|
||||||
|
|
||||||
addr = RelLib.Address()
|
addr = RelLib.Address()
|
||||||
state.person.add_address(addr)
|
state.person.add_address(addr)
|
||||||
self.parse_residence(addr,2)
|
|
||||||
|
note = ""
|
||||||
|
while True:
|
||||||
|
matches = self.get_next()
|
||||||
|
|
||||||
|
if self.level_is_finished(matches, state.level+1):
|
||||||
|
break
|
||||||
|
elif matches[1] == TOKEN_DATE:
|
||||||
|
addr.set_date_object(self.extract_date(matches[2]))
|
||||||
|
elif matches[1] == TOKEN_ADDR:
|
||||||
|
addr.set_street(matches[2])
|
||||||
|
self.parse_address(addr, state.level+1)
|
||||||
|
elif matches[1] == TOKEN_SOUR:
|
||||||
|
addr.add_source_reference(self.handle_source(matches, state.level+1))
|
||||||
|
elif matches[1] == TOKEN_PLAC:
|
||||||
|
addr.set_street(matches[2])
|
||||||
|
self.parse_address(addr, state.level+1)
|
||||||
|
elif matches[1] == TOKEN_PHON:
|
||||||
|
if addr.get_street() == "":
|
||||||
|
addr.set_street("Unknown")
|
||||||
|
addr.set_phone(matches[2])
|
||||||
|
elif matches[1] == TOKEN_NOTE:
|
||||||
|
note = self.parse_note(matches, addr, state.level+1, note)
|
||||||
|
elif matches[1] in (TOKEN_IGNORE, TOKEN_CAUS, TOKEN_STAT,
|
||||||
|
TOKEN_TEMP, TOKEN_OBJE, TOKEN_TYPE):
|
||||||
|
self.ignore_sub_junk(state.level+1)
|
||||||
|
else:
|
||||||
|
self.barf(state.level+1)
|
||||||
|
|
||||||
def func_person_addr(self,matches,state):
|
def func_person_addr(self,matches,state):
|
||||||
|
"""
|
||||||
|
Parses the Address structure by calling parse_address.
|
||||||
|
"""
|
||||||
addr = RelLib.Address()
|
addr = RelLib.Address()
|
||||||
addr.set_street(matches[2])
|
addr.set_street(matches[2])
|
||||||
self.parse_address(addr,2)
|
self.parse_address(addr,2)
|
||||||
@ -2233,12 +2352,19 @@ class GedcomParser(UpdateCallback):
|
|||||||
state.person.add_address(addr)
|
state.person.add_address(addr)
|
||||||
|
|
||||||
def func_person_birt(self,matches,state):
|
def func_person_birt(self,matches,state):
|
||||||
|
"""
|
||||||
|
n BIRT [Y|<NULL>] {1:1}
|
||||||
|
+1 <<EVENT_DETAIL>> {0:1} p.*
|
||||||
|
+1 FAMC @<XREF:FAM>@ {0:1} p.*
|
||||||
|
|
||||||
|
I'm not sure what value the FAMC actually offers here, since
|
||||||
|
the FAMC record should handle this. Why it is a valid sub value
|
||||||
|
is beyond me.
|
||||||
|
"""
|
||||||
event = RelLib.Event()
|
event = RelLib.Event()
|
||||||
event.set_gramps_id(self.emapper.find_next())
|
event.set_gramps_id(self.emapper.find_next())
|
||||||
if matches[2]:
|
|
||||||
event.set_description(matches[2])
|
|
||||||
event.set_type(RelLib.EventType.BIRTH)
|
event.set_type(RelLib.EventType.BIRTH)
|
||||||
self.parse_person_event(event,2)
|
self.parse_person_event(event, self.person_event_map, 2)
|
||||||
|
|
||||||
person_event_name(event,state.person)
|
person_event_name(event,state.person)
|
||||||
self.db.add_event(event, self.trans)
|
self.db.add_event(event, self.trans)
|
||||||
@ -2252,10 +2378,16 @@ class GedcomParser(UpdateCallback):
|
|||||||
state.person.set_birth_ref(event_ref)
|
state.person.set_birth_ref(event_ref)
|
||||||
|
|
||||||
def func_person_adop(self,matches,state):
|
def func_person_adop(self,matches,state):
|
||||||
|
"""
|
||||||
|
n BIRT [Y|<NULL>] {1:1}
|
||||||
|
+1 <<EVENT_DETAIL>> {0:1} p.*
|
||||||
|
+1 FAMC @<XREF:FAM>@ {0:1} p.*
|
||||||
|
+2 ADOP <ADOPTED_BY_WHICH_PARENT> {0:1}
|
||||||
|
"""
|
||||||
event = RelLib.Event()
|
event = RelLib.Event()
|
||||||
event.set_gramps_id(self.emapper.find_next())
|
event.set_gramps_id(self.emapper.find_next())
|
||||||
event.set_type(RelLib.EventType.ADOPT)
|
event.set_type(RelLib.EventType.ADOPT)
|
||||||
self.parse_adopt_event(event,2)
|
self.parse_person_event(event, self.person_adopt_map, 2)
|
||||||
person_event_name(event,state.person)
|
person_event_name(event,state.person)
|
||||||
self.db.add_event(event, self.trans)
|
self.db.add_event(event, self.trans)
|
||||||
|
|
||||||
@ -2264,12 +2396,16 @@ class GedcomParser(UpdateCallback):
|
|||||||
state.person.add_event_ref(event_ref)
|
state.person.add_event_ref(event_ref)
|
||||||
|
|
||||||
def func_person_deat(self,matches,state):
|
def func_person_deat(self,matches,state):
|
||||||
|
"""
|
||||||
|
n DEAT [Y|<NULL>] {1:1}
|
||||||
|
+1 <<EVENT_DETAIL>> {0:1} p.*
|
||||||
|
"""
|
||||||
event = RelLib.Event()
|
event = RelLib.Event()
|
||||||
event.set_gramps_id(self.emapper.find_next())
|
event.set_gramps_id(self.emapper.find_next())
|
||||||
if matches[2]:
|
if matches[2]:
|
||||||
event.set_description(matches[2])
|
event.set_description(matches[2])
|
||||||
event.type.set(RelLib.EventType.DEATH)
|
event.type.set(RelLib.EventType.DEATH)
|
||||||
self.parse_person_event(event,2)
|
self.parse_person_event(event, self.person_event_map, 2)
|
||||||
|
|
||||||
person_event_name(event,state.person)
|
person_event_name(event,state.person)
|
||||||
self.db.add_event(event, self.trans)
|
self.db.add_event(event, self.trans)
|
||||||
@ -2283,11 +2419,15 @@ class GedcomParser(UpdateCallback):
|
|||||||
state.person.set_death_ref(event_ref)
|
state.person.set_death_ref(event_ref)
|
||||||
|
|
||||||
def func_person_even(self,matches,state):
|
def func_person_even(self,matches,state):
|
||||||
|
"""
|
||||||
|
n DEAT [Y|<NULL>] {1:1}
|
||||||
|
+1 <<EVENT_DETAIL>> {0:1} p.*
|
||||||
|
"""
|
||||||
event = RelLib.Event()
|
event = RelLib.Event()
|
||||||
event.set_gramps_id(self.emapper.find_next())
|
event.set_gramps_id(self.emapper.find_next())
|
||||||
if matches[2]:
|
if matches[2]:
|
||||||
event.set_description(matches[2])
|
event.set_description(matches[2])
|
||||||
self.parse_person_event(event,2)
|
self.parse_person_event(event, self.person_event_map, 2)
|
||||||
the_type = event.get_type()
|
the_type = event.get_type()
|
||||||
if int(the_type) == RelLib.EventType.CUSTOM \
|
if int(the_type) == RelLib.EventType.CUSTOM \
|
||||||
and str(the_type) in self.attrs:
|
and str(the_type) in self.attrs:
|
||||||
@ -2346,7 +2486,7 @@ class GedcomParser(UpdateCallback):
|
|||||||
else:
|
else:
|
||||||
event.set_type((RelLib.EventType.CUSTOM,n))
|
event.set_type((RelLib.EventType.CUSTOM,n))
|
||||||
|
|
||||||
self.parse_person_event(event,2)
|
self.parse_person_event(event, self.person_event_map, 2)
|
||||||
if matches[2]:
|
if matches[2]:
|
||||||
event.set_description(matches[2])
|
event.set_description(matches[2])
|
||||||
person_event_name(event,state.person)
|
person_event_name(event,state.person)
|
||||||
|
Loading…
Reference in New Issue
Block a user