Improved GEDCOM

svn: r569
This commit is contained in:
Don Allingham 2001-11-18 04:52:59 +00:00
parent cdaedface8
commit 12bb6c1623
4 changed files with 151 additions and 46 deletions

View File

@ -1,3 +1,9 @@
Version 0.6.2pre
* Fixed SuSE 7.3/lib-imlib problem.
* Improved GEDCOM import/export. Gramps now passes the GEDCHK program
and can now properly handle the quirks in names, notes, and parent/child
relationships from PAF, Legacy, FTW, Brother's Keeper, and Family Origins.
Version 0.6.1 Version 0.6.1
* Fixed Family View/Pedigree View button swap * Fixed Family View/Pedigree View button swap
* Updated Spanish translation * Updated Spanish translation

View File

@ -97,7 +97,7 @@ gtkrcFile = "%s/gtkrc" % rootDir
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
progName = "gramps" progName = "gramps"
version = "0.6.1" version = "0.6.2pre"
copyright = "© 2001 Donald N. Allingham" copyright = "© 2001 Donald N. Allingham"
authors = ["Donald N. Allingham", "David Hampton"] authors = ["Donald N. Allingham", "David Hampton"]
comments = _("Gramps (Genealogical Research and Analysis Management Programming System) is a personal genealogy program.") comments = _("Gramps (Genealogical Research and Analysis Management Programming System) is a personal genealogy program.")

View File

@ -164,6 +164,8 @@ class GedcomParser:
self.dir_path = os.path.dirname(file) self.dir_path = os.path.dirname(file)
self.localref = 0 self.localref = 0
self.placemap = {} self.placemap = {}
self.broken_conc_list = [ 'FamilyOrigins', 'FTW' ]
self.broken_conc = 0
self.f = open(file,"r") self.f = open(file,"r")
self.index = 0 self.index = 0
@ -555,8 +557,8 @@ class GedcomParser:
addr.setStreet(matches[2] + self.parse_continue_data(2)) addr.setStreet(matches[2] + self.parse_continue_data(2))
self.parse_address(addr,2) self.parse_address(addr,2)
self.person.addAddress(addr) self.person.addAddress(addr)
elif matches[1] == "TITL": # elif matches[1] == "TITL":
self.person.getPrimaryName().setTitle(matches[2]) # self.person.getPrimaryName().setTitle(matches[2])
elif matches[1] == "BIRT": elif matches[1] == "BIRT":
event = Event() event = Event()
if self.person.getBirth().getDate() != "" or \ if self.person.getBirth().getDate() != "" or \
@ -694,7 +696,7 @@ class GedcomParser:
photo.setPath(path) photo.setPath(path)
photo.setDescription(title) photo.setDescription(title)
photo.setMimeType(utils.get_mime_type(path)) photo.setMimeType(utils.get_mime_type(path))
db.addObject(photo) self.db.addObject(photo)
oref = ObjectRef() oref = ObjectRef()
oref.setReference(photo) oref.setReference(photo)
self.person.addPhoto(oref) self.person.addPhoto(oref)
@ -733,7 +735,7 @@ class GedcomParser:
photo.setPath(path) photo.setPath(path)
photo.setDescription(title) photo.setDescription(title)
photo.setMimeType(utils.get_mime_type(path)) photo.setMimeType(utils.get_mime_type(path))
db.addObject(photo) self.db.addObject(photo)
oref = ObjectRef() oref = ObjectRef()
oref.setReference(photo) oref.setReference(photo)
source.addPhoto(oref) source.addPhoto(oref)
@ -771,7 +773,7 @@ class GedcomParser:
photo.setPath(path) photo.setPath(path)
photo.setDescription(title) photo.setDescription(title)
photo.setMimeType(utils.get_mime_type(path)) photo.setMimeType(utils.get_mime_type(path))
db.addObject(photo) self.db.addObject(photo)
oref = ObjectRef() oref = ObjectRef()
oref.setReference(photo) oref.setReference(photo)
self.family.addPhoto(photo) self.family.addPhoto(photo)
@ -904,7 +906,11 @@ class GedcomParser:
else: else:
note = "\n%s" % info note = "\n%s" % info
elif matches[1] == "CONC": elif matches[1] == "CONC":
event.setDescription( "%s %s" % (event.getDescription(), matches[2])) d = event.getDescription()
if self.broken_conc:
event.setDescription("%s %s" % (d, matches[2]))
else:
event.setDescription("%s%s" % (d, matches[2]))
elif matches[1] == "CONT": elif matches[1] == "CONT":
event.setDescription("%s\n%s" % (event.getDescription(),matches[2])) event.setDescription("%s\n%s" % (event.getDescription(),matches[2]))
else: else:
@ -969,9 +975,14 @@ class GedcomParser:
else: else:
note = "\n%s" % info note = "\n%s" % info
elif matches[1] == "CONC": elif matches[1] == "CONC":
event.setDescription( "%s %s" % (event.getDescription(), matches[2])) d = event.getDescription()
if self.broken_conc:
event.setDescription("%s %s" % (d,matches[2]))
else:
event.setDescription("%s%s" % (d,matches[2]))
elif matches[1] == "CONT": elif matches[1] == "CONT":
event.setDescription("%s\n%s" % (event.getDescription(),matches[2])) d = event.getDescription()
event.setDescription("%s\n%s" % (d,matches[2]))
else: else:
self.barf(level+1) self.barf(level+1)
@ -1033,7 +1044,10 @@ class GedcomParser:
else: else:
note = "\n%s" % info note = "\n%s" % info
elif matches[1] == "CONC": elif matches[1] == "CONC":
attr.setValue( "%s %s" % (attr.getValue(), matches[2])) if self.broken_conc:
attr.setValue("%s %s" % (attr.getValue(), matches[2]))
else:
attr.setValue("%s %s" % (attr.getValue(), matches[2]))
elif matches[1] == "CONT": elif matches[1] == "CONT":
attr.setValue("%s\n%s" % (attr.getValue(),matches[2])) attr.setValue("%s\n%s" % (attr.getValue(),matches[2]))
else: else:
@ -1182,8 +1196,11 @@ class GedcomParser:
pass pass
elif matches[1] == "SURN": elif matches[1] == "SURN":
name.setSurname(matches[2]) name.setSurname(matches[2])
elif matches[1] == "NSFX": elif matches[1] == "TITL":
name.setSuffix(matches[2]) name.setSuffix(matches[2])
elif matches[1] == "NSFX":
if name.getSuffix() == "":
name.setSuffix(matches[2])
elif matches[1] == "NICK": elif matches[1] == "NICK":
self.person.setNickName(matches[2]) self.person.setNickName(matches[2])
elif matches[1] == "_AKA": elif matches[1] == "_AKA":
@ -1235,6 +1252,10 @@ class GedcomParser:
elif matches[1] == "SOUR": elif matches[1] == "SOUR":
if self.created_obj.get_text() == "": if self.created_obj.get_text() == "":
self.update(self.created_obj,matches[2]) self.update(self.created_obj,matches[2])
if matches[2] in self.broken_conc_list:
self.broken_conc = 1
else:
self.broken_conc = 0
if matches[2] == "FTW": if matches[2] == "FTW":
self.is_ftw = 1 self.is_ftw = 1
elif matches[1] == "NAME": elif matches[1] == "NAME":
@ -1363,9 +1384,12 @@ class GedcomParser:
matches = self.get_next() matches = self.get_next()
if matches[1] == "CONC": if matches[1] == "CONC":
data = "%s%s" % (data,matches[2]) if self.broken_conc:
data = "%s %s" % (data,matches[2])
else:
data = "%s%s" % (data,matches[2])
elif matches[1] == "CONT": elif matches[1] == "CONT":
data = "%s\n%s" % (data,matches[2]) data = "%s\n%s" % (data,matches[2])
else: else:
self.backup() self.backup()
return data return data
@ -1389,8 +1413,6 @@ class GedcomParser:
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def on_ok_clicked(obj): def on_ok_clicked(obj):
global db
global topDialog
global clear_data global clear_data
name = topDialog.get_widget("filename").get_text() name = topDialog.get_widget("filename").get_text()
@ -1439,12 +1461,3 @@ from Plugins import register_import
register_import(readData,_("Import from GEDCOM")) register_import(readData,_("Import from GEDCOM"))
if __name__ == "__main__":
import profile
import sys
global db
glade_file = "plugins/gedcomimport.glade"
db = RelDataBase()
profile.run('importData(db,sys.argv[1])')

View File

@ -46,6 +46,7 @@ db = None
people_list = [] people_list = []
family_list = [] family_list = []
source_list = [] source_list = []
adopt_mode = 1
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -276,10 +277,18 @@ def write_long_text(g,tag,level,note):
g.write("%s\n" % prefix) g.write("%s\n" % prefix)
else: else:
for line in textlines: for line in textlines:
while len(line) > 0: ll = len(line)
if len(line) > 70: while ll > 0:
g.write("%s %s\n" % (prefix,line[0:70])) brkpt = 70
line = line[70:] if ll > brkpt:
while (ll > brkpt and line[brkpt] in string.whitespace):
brkpt = brkpt+1
if ll == brkpt:
g.write("%s %s\n" % (prefix,line))
line = ''
else:
g.write("%s %s\n" % (prefix,line[0:brkpt+1]))
line = line[brkpt+1:]
else: else:
g.write("%s %s\n" % (prefix,line)) g.write("%s %s\n" % (prefix,line))
line = "" line = ""
@ -287,6 +296,7 @@ def write_long_text(g,tag,level,note):
prefix = "%d CONC" % (level + 1) prefix = "%d CONC" % (level + 1)
else: else:
prefix = "%d CONT" % (level + 1) prefix = "%d CONT" % (level + 1)
ll = len(line)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -364,7 +374,7 @@ def write_person_name(g,name,nick):
if name.getSuffix() != "": if name.getSuffix() != "":
g.write("2 NSFX %s\n" % suffix) g.write("2 NSFX %s\n" % suffix)
if name.getTitle() != "": if name.getTitle() != "":
g.write("2 TITL %s\n" % title) g.write("2 NPFX %s\n" % title)
if nick != "": if nick != "":
g.write('2 NICK %s\n' % nick) g.write('2 NICK %s\n' % nick)
if name.getNote() != "": if name.getNote() != "":
@ -388,9 +398,9 @@ def write_source_ref(g,level,ref):
if ref_text != "" or ref.getDate().getDate() != "": if ref_text != "" or ref.getDate().getDate() != "":
g.write('%d DATA\n' % (level+1)) g.write('%d DATA\n' % (level+1))
if ref_text != "": if ref_text != "":
write_long_text(g,"TEXT",level+1,ref_text) write_long_text(g,"TEXT",level+2,ref_text)
if ref.getDate().getDate(): if ref.getDate().getDate():
g.write("%d DATE %s\n" % (level+1,ref.getDate().getSaveDate())) g.write("%d DATE %s\n" % (level+2,ref.getDate().getSaveDate()))
if ref.getComments() != "": if ref.getComments() != "":
write_long_text(g,"NOTE",level+1,ref.getComments()) write_long_text(g,"NOTE",level+1,ref.getComments())
@ -429,6 +439,7 @@ def write_person(g,person):
if uid != "": if uid != "":
g.write("1 _UID %s\n" % uid) g.write("1 _UID %s\n" % uid)
ad = 0
for event in person.getEventList(): for event in person.getEventList():
if private and event.getPrivacy(): if private and event.getPrivacy():
continue continue
@ -437,13 +448,49 @@ def write_person(g,person):
val = const.personalConstantEvents[name] val = const.personalConstantEvents[name]
else: else:
val = "" val = ""
if val != "" : if adopt_mode == 1 and val == "ADOP":
ad = 1
g.write('1 ADOP\n')
fam = None
for f in person.getAltFamilyList():
mrel = string.lower(f[1])
frel = string.lower(f[2])
if mrel=="adopted" or mrel=="adopted":
fam = f[0]
break
if fam:
g.write('2 FAMC @F%s@\n' % fam.getId())
if mrel == frel:
g.write('3 ADOP BOTH\n')
elif mrel == "adopted":
g.write('3 ADOP WIFE\n')
else:
g.write('3 ADOP HUSB\n')
elif val != "" :
g.write("1 %s %s\n" % (cnvtxt(val),cnvtxt(event.getDescription()))) g.write("1 %s %s\n" % (cnvtxt(val),cnvtxt(event.getDescription())))
else: else:
g.write("1 EVEN %s\n" % cnvtxt(event.getDescription())) g.write("1 EVEN %s\n" % cnvtxt(event.getDescription()))
g.write("2 TYPE %s\n" % cnvtxt(event.getName())) g.write("2 TYPE %s\n" % cnvtxt(event.getName()))
dump_event_stats(g,event) dump_event_stats(g,event)
if adopt_mode == 1 and ad == 0 and len(person.getAltFamilyList()) != 0:
g.write('1 ADOP\n')
fam = None
for f in person.getAltFamilyList():
mrel = string.lower(f[1])
frel = string.lower(f[2])
if mrel=="adopted" or mrel=="adopted":
fam = f[0]
break
if fam:
g.write('2 FAMC @F%s@\n' % fam.getId())
if mrel == frel:
g.write('3 ADOP BOTH\n')
elif mrel == "adopted":
g.write('3 ADOP WIFE\n')
else:
g.write('3 ADOP HUSB\n')
for attr in person.getAttributeList(): for attr in person.getAttributeList():
if private and attr.getPrivacy(): if private and attr.getPrivacy():
continue continue
@ -487,12 +534,12 @@ def write_person(g,person):
family = person.getMainFamily() family = person.getMainFamily()
if family != None and family in family_list: if family != None and family in family_list:
g.write("1 FAMC @F%s@\n" % family.getId()) g.write("1 FAMC @F%s@\n" % family.getId())
g.write("2 PEDI birth\n")
for family in person.getAltFamilyList(): for family in person.getAltFamilyList():
g.write("1 FAMC @F%s@\n" % family[0].getId()) g.write("1 FAMC @F%s@\n" % family[0].getId())
if string.lower(family[1]) == "adopted": if adopt_mode == 0:
g.write("2 PEDI adopted\n") if string.lower(family[1]) == "adopted":
g.write("2 PEDI Adopted\n")
for family in person.getFamilyList(): for family in person.getFamilyList():
if family != None and family in family_list: if family != None and family in family_list:
@ -515,9 +562,19 @@ def write_person(g,person):
# #
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def exportData(database, filename, pbar, fbar, sbar): def exportData(database, filename, progress, pbar, fbar, sbar):
g = open(filename,"w") try:
g = open(filename,"w")
except IOError,msg:
msg = "%s\n%s" % (_("Could not open %s") % filename,str(msg))
GnomeErrorDialog(msg)
progress.destroy()
return
except:
GnomeErrorDialog(_("Could not open %s") % filename)
progress.destroy()
return
date = string.split(time.ctime(time.time())) date = string.split(time.ctime(time.time()))
@ -535,23 +592,36 @@ def exportData(database, filename, pbar, fbar, sbar):
g.write("1 FILE %s\n" % filename) g.write("1 FILE %s\n" % filename)
g.write("1 GEDC\n") g.write("1 GEDC\n")
g.write("2 VERS 5.5\n") g.write("2 VERS 5.5\n")
g.write('2 FORM LINEAGE-LINKED\n')
g.write("0 @SUBM@ SUBM\n") g.write("0 @SUBM@ SUBM\n")
owner = database.getResearcher() owner = database.getResearcher()
if owner.getName() != "": if owner.getName() != "":
g.write("1 NAME " + cnvtxt(owner.getName()) +"\n") g.write("1 NAME " + cnvtxt(owner.getName()) +"\n")
if owner.getAddress() != "": else:
g.write("1 ADDR " + cnvtxt(owner.getAddress()) + "\n") g.write('1 NAME Not Provided\n')
if owner.getAddress() != "":
cnt = 0
g.write("1 ADDR " + cnvtxt(owner.getAddress()) + "\n")
if owner.getCity() != "": if owner.getCity() != "":
g.write("2 CITY " + cnvtxt(owner.getCity()) + "\n") g.write("2 CONT " + cnvtxt(owner.getCity()) + "\n")
cnt = 1
if owner.getState() != "": if owner.getState() != "":
g.write("2 STAE " + cnvtxt(owner.getState()) + "\n") g.write("2 CONT " + cnvtxt(owner.getState()) + "\n")
cnt = 1
if owner.getPostalCode() != "": if owner.getPostalCode() != "":
g.write("2 POST " + cnvtxt(owner.getPostalCode()) + "\n") g.write("2 CONT " + cnvtxt(owner.getPostalCode()) + "\n")
cnt = 1
if owner.getCountry() != "": if owner.getCountry() != "":
g.write("2 CTRY " + cnvtxt(owner.getCountry()) + "\n") g.write("2 CONT " + cnvtxt(owner.getCountry()) + "\n")
cnt = 1
if owner.getPhone() != "": if owner.getPhone() != "":
g.write("1 PHON " + cnvtxt(owner.getPhone()) + "\n") g.write("2 PHON " + cnvtxt(owner.getPhone()) + "\n")
cnt = 1
if cnt == 0:
g.write('2 CONT Not Provided\n')
else:
g.write('1 ADDR Not Provided\n')
g.write('2 CONT Not Provided\n')
people_list.sort(sortById) people_list.sort(sortById)
nump = float(len(people_list)) nump = float(len(people_list))
index = 0.0 index = 0.0
@ -597,6 +667,22 @@ def exportData(database, filename, pbar, fbar, sbar):
for person in family.getChildList(): for person in family.getChildList():
g.write("1 CHIL @I%s@\n" % person.getId()) g.write("1 CHIL @I%s@\n" % person.getId())
if adopt_mode == 2:
if person.getMainFamily() == family:
g.write('2 _FREL Natural\n')
g.write('2 _MREL Natural\n')
else:
for f in person.getAltFamilyList():
if f[0] == family:
g.write('2 _FREL %s\n' % f[2])
g.write('2 _MREL %s\n' % f[1])
break
if adopt_mode == 3:
for f in person.getAltFamilyList():
if f[0] == family:
g.write('2 _STAT %s\n' % f[2])
break
index = index + 1 index = index + 1
fbar.set_value((100*index)/nump) fbar.set_value((100*index)/nump)
while(events_pending()): while(events_pending()):
@ -716,7 +802,7 @@ def on_ok_clicked(obj):
closebtn = progress.get_widget("close") closebtn = progress.get_widget("close")
closebtn.connect("clicked",utils.destroy_passed_object) closebtn.connect("clicked",utils.destroy_passed_object)
closebtn.set_sensitive(0) closebtn.set_sensitive(0)
exportData(db,name,pbar,fbar,sbar) exportData(db,name,progress.get_widget('exportprogress'),pbar,fbar,sbar)
closebtn.set_sensitive(1) closebtn.set_sensitive(1)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------