GEDCOM parsing/writing fixes

svn: r552
This commit is contained in:
Don Allingham 2001-11-05 03:06:21 +00:00
parent d3ce0ee54b
commit 31cf1dbf9d
2 changed files with 16 additions and 384 deletions

View File

@ -178,11 +178,6 @@ class GedcomParser:
SyntaxError = "Syntax Error" SyntaxError = "Syntax Error"
BadFile = "Not a GEDCOM file" BadFile = "Not a GEDCOM file"
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def __init__(self, db, file, window): def __init__(self, db, file, window):
self.db = db self.db = db
self.person = None self.person = None
@ -212,21 +207,11 @@ class GedcomParser:
self.update(self.file_obj,file) self.update(self.file_obj,file)
self.code = 0 self.code = 0
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def update(self,field,text): def update(self,field,text):
field.set_text(text) field.set_text(text)
while events_pending(): while events_pending():
mainiteration() mainiteration()
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def get_next(self): def get_next(self):
if self.backoff == 0: if self.backoff == 0:
self.text = _cnv(string.strip(self.f.readline())) self.text = _cnv(string.strip(self.f.readline()))
@ -249,11 +234,6 @@ class GedcomParser:
self.backoff = 0 self.backoff = 0
return self.groups return self.groups
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def barf(self,level): def barf(self,level):
msg = _("Warning: line %d was not understood, so it was ignored.") % self.index msg = _("Warning: line %d was not understood, so it was ignored.") % self.index
self.error_text_obj.insert_defaults(msg) self.error_text_obj.insert_defaults(msg)
@ -263,29 +243,14 @@ class GedcomParser:
self.update(self.errors_obj,str(self.error_count)) self.update(self.errors_obj,str(self.error_count))
self.ignore_sub_junk(level) self.ignore_sub_junk(level)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def warn(self,msg): def warn(self,msg):
self.error_text_obj.insert_defaults(msg) self.error_text_obj.insert_defaults(msg)
self.error_count = self.error_count + 1 self.error_count = self.error_count + 1
self.update(self.errors_obj,str(self.error_count)) self.update(self.errors_obj,str(self.error_count))
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def backup(self): def backup(self):
self.backoff = 1 self.backoff = 1
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_gedcom_file(self): def parse_gedcom_file(self):
self.index = 0 self.index = 0
self.fam_count = 0 self.fam_count = 0
@ -297,11 +262,6 @@ class GedcomParser:
self.update(self.families_obj,str(self.fam_count)) self.update(self.families_obj,str(self.fam_count))
self.update(self.people_obj,str(self.indi_count)) self.update(self.people_obj,str(self.indi_count))
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_trailer(self): def parse_trailer(self):
matches = self.get_next() matches = self.get_next()
@ -309,25 +269,9 @@ class GedcomParser:
self.barf(0) self.barf(0)
self.f.close() self.f.close()
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header(self): def parse_header(self):
self.parse_header_head() self.parse_header_head()
self.parse_header_source() self.parse_header_source()
self.parse_header_dest()
self.parse_header_date()
self.parse_header_subm()
self.parse_header_subn()
self.parse_header_file()
self.parse_header_copr()
self.parse_header_gedc()
self.parse_header_char()
self.parse_header_lang()
self.parse_header_plac()
self.parse_header_note()
#--------------------------------------------------------------------- #---------------------------------------------------------------------
# #
@ -376,11 +320,6 @@ class GedcomParser:
self.nmap[matches[2]] = noteobj self.nmap[matches[2]] = noteobj
self.source.setNoteObj(noteobj) self.source.setNoteObj(noteobj)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_record(self): def parse_record(self):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
@ -434,33 +373,19 @@ class GedcomParser:
else: else:
self.barf(1) self.barf(1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_note_data(self,level): def parse_note_data(self,level):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
if int(matches[0]) < level: if int(matches[0]) < level:
self.backup() self.backup()
return return
elif matches[1] == "SOUR": elif matches[1] in ["SOUR","CHAN","REFN"]:
self.ignore_sub_junk(level+1)
elif matches[1] == "CHAN":
self.ignore_sub_junk(level+1)
elif matches[1] == "REFN":
self.ignore_sub_junk(level+1) self.ignore_sub_junk(level+1)
elif matches[1] == "RIN": elif matches[1] == "RIN":
pass pass
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_ftw_relations(self,level): def parse_ftw_relations(self,level):
mrel = "Birth" mrel = "Birth"
frel = "Birth" frel = "Birth"
@ -482,11 +407,6 @@ class GedcomParser:
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_family(self): def parse_family(self):
self.addr = None self.addr = None
while 1: while 1:
@ -523,9 +443,7 @@ class GedcomParser:
self.family.addAttribute(a) self.family.addAttribute(a)
elif matches[1] == "RIN" or matches[1] == "SUBM": elif matches[1] == "RIN" or matches[1] == "SUBM":
pass pass
elif matches[1] == "REFN" or matches[1] == "CHAN": elif matches[1] in ["REFN","CHAN","SOUR"]:
self.ignore_sub_junk(2)
elif matches[1] == "SOUR":
self.ignore_sub_junk(2) self.ignore_sub_junk(2)
elif matches[1] == "OBJE": elif matches[1] == "OBJE":
if matches[2] and matches[2][0] == '@': if matches[2] and matches[2][0] == '@':
@ -555,11 +473,6 @@ class GedcomParser:
self.family.addEvent(event) self.family.addEvent(event)
self.parse_family_event(event,2) self.parse_family_event(event,2)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_individual(self): def parse_individual(self):
name_cnt = 0 name_cnt = 0
while 1: while 1:
@ -586,20 +499,12 @@ class GedcomParser:
self.person.addAlternateName(name) self.person.addAlternateName(name)
name_cnt = name_cnt + 1 name_cnt = name_cnt + 1
self.parse_name(name,2) self.parse_name(name,2)
elif matches[1] == "RIN" or matches[1] == "RFN":
pass
elif matches[1] == "_UID": elif matches[1] == "_UID":
self.person.setPafUid(matches[2]) self.person.setPafUid(matches[2])
elif matches[1] == "AFN" or matches[1] == "CHAN": elif matches[1] in ["AFN","CHAN","REFN","SOUR"]:
self.ignore_sub_junk(2) self.ignore_sub_junk(2)
elif matches[1] == "ALIA": elif matches[1] in ["ALIA", "ANCI","DESI","RIN","RFN"]:
pass pass
elif matches[1] == "ANCI" or matches[1] == "DESI":
pass
elif matches[1] == "REFN":
self.ignore_sub_junk(2)
elif matches[1] == "SOUR":
self.ignore_sub_junk(2)
elif matches[1] == "OBJE": elif matches[1] == "OBJE":
if matches[2] and matches[2][0] == '@': if matches[2] and matches[2][0] == '@':
self.barf(2) self.barf(2)
@ -695,11 +600,6 @@ class GedcomParser:
self.person.addEvent(event) self.person.addEvent(event)
self.parse_person_event(event,2) self.parse_person_event(event,2)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_optional_note(self,level): def parse_optional_note(self,level):
note = "" note = ""
while 1: while 1:
@ -717,11 +617,6 @@ class GedcomParser:
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_famc_type(self,level): def parse_famc_type(self,level):
type = "" type = ""
note = "" note = ""
@ -744,11 +639,6 @@ class GedcomParser:
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_person_object(self,level): def parse_person_object(self,level):
form = "" form = ""
file = "" file = ""
@ -795,11 +685,6 @@ class GedcomParser:
self.warn(_("Could not import %s: currently an unknown file type") % \ self.warn(_("Could not import %s: currently an unknown file type") % \
file + "\n") file + "\n")
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_source_object(self,source,level): def parse_source_object(self,source,level):
form = "" form = ""
file = "" file = ""
@ -839,11 +724,6 @@ class GedcomParser:
self.warn(_("Could not import %s: currently an unknown file type") % \ self.warn(_("Could not import %s: currently an unknown file type") % \
file + "\n") file + "\n")
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_family_object(self,level): def parse_family_object(self,level):
form = "" form = ""
file = "" file = ""
@ -881,36 +761,25 @@ class GedcomParser:
else: else:
self.warn("Could not import %s: current an unknown file type\n" % file) self.warn("Could not import %s: current an unknown file type\n" % file)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_residence(self,address,level): def parse_residence(self,address,level):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
if int(matches[0]) < level: if int(matches[0]) < level:
self.backup() self.backup()
break return
elif matches[1] == "DATE": elif matches[1] == "DATE":
address.setDate(matches[2]) address.setDate(matches[2])
elif matches[1] == "AGE" or matches[1] == "AGNC": elif matches[1] == "ADDR":
self.ignore_sub_junk(level+1) address.setStreet(matches[2] + self.parse_continue_data(2))
elif matches[1] == "CAUS" or matches[1] == "ADDR": self.parse_address(address,level+1)
self.ignore_sub_junk(level+1) elif matches[1] in ["AGE","AGNC","CAUS","STAT","TEMP","OBJE","TYPE"]:
elif matches[1] == "STAT" or matches[1] == "TEMP":
self.ignore_sub_junk(level+1)
elif matches[1] == "OBJE" or matches[1] == "TYPE":
self.ignore_sub_junk(level+1) self.ignore_sub_junk(level+1)
elif matches[1] == "SOUR": elif matches[1] == "SOUR":
source_ref = SourceRef() source_ref = SourceRef()
source_ref.setBase(self.db.findSource(matches[2],self.smap)) source_ref.setBase(self.db.findSource(matches[2],self.smap))
address.addSourceRef(source_ref) address.addSourceRef(source_ref)
self.parse_source_reference(source_ref,level+1) self.parse_source_reference(source_ref,level+1)
elif matches[1] == "ADDR":
self.addr = Address()
self.addr.setStreet(matches[2] + self.parse_continue_data(2))
self.parse_address(self.addr,2)
elif matches[1] == "PLAC": elif matches[1] == "PLAC":
address.setStreet(matches[2]) address.setStreet(matches[2])
self.parse_address(address,level+1) self.parse_address(address,level+1)
@ -931,16 +800,10 @@ class GedcomParser:
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_address(self,address,level): def parse_address(self,address,level):
first = 0 first = 0
while 1: while 1:
matches = self.get_next() matches = self.get_next()
if int(matches[0]) < level: if int(matches[0]) < level:
self.backup() self.backup()
return return
@ -964,11 +827,6 @@ class GedcomParser:
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_person_event(self,event,level): def parse_person_event(self,event,level):
note = "" note = ""
while 1: while 1:
@ -987,13 +845,7 @@ class GedcomParser:
event.setName(name) event.setName(name)
elif matches[1] == "DATE": elif matches[1] == "DATE":
event.setDate(matches[2]) event.setDate(matches[2])
elif matches[1] == "TIME" or matches[1] == "ADDR": elif matches[1] == ["TIME","ADDR","AGE","AGNC","STAT","TEMP","OBJE","QUAY"]:
self.ignore_sub_junk(level+1)
elif matches[1] == "AGE" or matches[1] == "AGNC":
self.ignore_sub_junk(level+1)
elif matches[1] == "STAT" or matches[1] == "TEMP":
self.ignore_sub_junk(level+1)
elif matches[1] == "OBJE" or matches[1] == "QUAY":
self.ignore_sub_junk(level+1) self.ignore_sub_junk(level+1)
elif matches[1] == "SOUR": elif matches[1] == "SOUR":
source_ref = SourceRef() source_ref = SourceRef()
@ -1049,11 +901,6 @@ class GedcomParser:
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_family_event(self,event,level): def parse_family_event(self,event,level):
global ged2fam global ged2fam
global ged2gramps global ged2gramps
@ -1071,17 +918,7 @@ class GedcomParser:
event.setName(matches[2]) event.setName(matches[2])
elif matches[1] == "DATE": elif matches[1] == "DATE":
event.setDate(matches[2]) event.setDate(matches[2])
elif matches[1] == "TIME": elif matches[1] == ["TIME","AGE","AGNC","CAUS","ADDR","STAT","TEMP","HUSB","WIFE","OBJE","QUAY"]:
self.ignore_sub_junk(level+1)
elif matches[1] == "AGE" or matches[1] == "AGNC":
self.ignore_sub_junk(level+1)
elif matches[1] == "CAUS" or matches[1] == "ADDR":
self.ignore_sub_junk(level+1)
elif matches[1] == "STAT" or matches[1] == "TEMP":
self.ignore_sub_junk(level+1)
elif matches[1] == "HUSB" or matches[1] == "WIFE":
self.ignore_sub_junk(level+1)
elif matches[1] == "OBJE" or matches[1] == "QUAY":
self.ignore_sub_junk(level+1) self.ignore_sub_junk(level+1)
elif matches[1] == "SOUR": elif matches[1] == "SOUR":
source_ref = SourceRef() source_ref = SourceRef()
@ -1239,11 +1076,6 @@ class GedcomParser:
raise GedcomParser.BadFile, line raise GedcomParser.BadFile, line
self.index = self.index + 1 self.index = self.index + 1
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_source(self): def parse_header_source(self):
global is_ftw global is_ftw
global _cnv global _cnv
@ -1266,7 +1098,7 @@ class GedcomParser:
elif matches[1] == "CORP": elif matches[1] == "CORP":
self.ignore_sub_junk(2) self.ignore_sub_junk(2)
elif matches[1] == "DATA": elif matches[1] == "DATA":
self.parse_sub_data(3) self.ignore_sub_junk(2)
elif matches[1] == "SUBM": elif matches[1] == "SUBM":
pass pass
elif matches[1] == "SUBN": elif matches[1] == "SUBN":
@ -1305,11 +1137,6 @@ class GedcomParser:
else: else:
self.barf(2) self.barf(2)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_ftw_schema(self,level): def parse_ftw_schema(self,level):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
@ -1324,11 +1151,6 @@ class GedcomParser:
else: else:
self.barf(2) self.barf(2)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_ftw_indi_schema(self,level): def parse_ftw_indi_schema(self,level):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
@ -1340,11 +1162,6 @@ class GedcomParser:
label = self.parse_label(level+1) label = self.parse_label(level+1)
ged2gramps[matches[1]] = label ged2gramps[matches[1]] = label
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_label(self,level): def parse_label(self,level):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
@ -1357,11 +1174,6 @@ class GedcomParser:
else: else:
self.barf(2) self.barf(2)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_ftw_fam_schema(self,level): def parse_ftw_fam_schema(self,level):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
@ -1373,11 +1185,6 @@ class GedcomParser:
label = self.parse_label(level+1) label = self.parse_label(level+1)
ged2fam[matches[1]] = label ged2fam[matches[1]] = label
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def ignore_sub_junk(self,level): def ignore_sub_junk(self,level):
while 1: while 1:
@ -1387,11 +1194,6 @@ class GedcomParser:
self.backup() self.backup()
return return
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def ignore_change_data(self,level): def ignore_change_data(self,level):
matches = self.get_next() matches = self.get_next()
@ -1405,11 +1207,6 @@ class GedcomParser:
else: else:
self.backup() self.backup()
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_place_form(self,level): def parse_place_form(self,level):
while 1: while 1:
matches = self.get_next() matches = self.get_next()
@ -1420,11 +1217,6 @@ class GedcomParser:
elif matches[1] != "FORM": elif matches[1] != "FORM":
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_continue_data(self,level): def parse_continue_data(self,level):
data = "" data = ""
while 1: while 1:
@ -1438,11 +1230,6 @@ class GedcomParser:
self.backup() self.backup()
return data return data
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_date(self,level): def parse_date(self,level):
date = DateStruct() date = DateStruct()
while 1: while 1:
@ -1456,164 +1243,6 @@ class GedcomParser:
else: else:
self.barf(level+1) self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_addr_struct(self,level):
addr = AddrStruct()
while 1:
matches = self.get_next()
if int(matches[0]) < level:
self.backup()
return
elif matches[1] == "ADDR":
addr.label = matches[2] + self.parse_continue_data(level+1)
self.parse_sub_addr(level+1, addr)
elif matches[1] == "PHON":
addr.phone = matches[2]
else:
self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_sub_addr(self,level,addr):
while 1:
matches = self.get_next()
if int(matches[0]) < level:
self.backup()
return
elif matches[1] == "CONT":
addr.label = "%s\n%s" %(addr.label,matches[2])
elif matches[1] == "ADR1":
addr.addr1 = matches[2]
elif matches[1] == "ADR2":
addr.addr2 = matches[2]
elif matches[1] == "CITY":
addr.city = matches[2]
elif matches[1] == "STAE":
addr.state = matches[2]
elif matches[1] == "POST":
addr.postal = matches[2]
elif matches[1] == "CTRY":
addr.country = matches[2]
else:
self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_sub_data(self,level):
while 1:
matches = self.get_next()
if int(matches[0]) < level:
self.backup()
return
elif matches[1] == "DATE":
pass
elif matches[1] == "COPR":
pass
else:
self.barf(level+1)
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_dest(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_date(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_subm(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_subn(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_file(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_copr(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_gedc(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_char(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_lang(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_plac(self):
pass
#---------------------------------------------------------------------
#
#
#
#---------------------------------------------------------------------
def parse_header_note(self):
pass
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# #

View File

@ -467,6 +467,9 @@ def write_person(g,person):
if private and addr.getPrivacy(): if private and addr.getPrivacy():
continue continue
g.write("1 RESI\n") g.write("1 RESI\n")
datestr = addr.getDateObj().getSaveDate()
if datestr != "":
g.write("2 DATE %s\n" % cnvtxt(datestr))
write_long_text(g,"ADDR",2,addr.getStreet()) write_long_text(g,"ADDR",2,addr.getStreet())
if addr.getCity() != "": if addr.getCity() != "":
g.write("3 CITY %s\n" % addr.getCity()) g.write("3 CITY %s\n" % addr.getCity())