# # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2000-2003 Donald N. Allingham # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # "Export to GEDCOM" #------------------------------------------------------------------------- # # Standard Python Modules # #------------------------------------------------------------------------- import os import string import time import re #------------------------------------------------------------------------- # # GNOME/GTK modules # #------------------------------------------------------------------------- import gtk import gtk.glade #------------------------------------------------------------------------- # # GRAMPS modules # #------------------------------------------------------------------------- import RelLib import GenericFilter import const import Utils import Date import Calendar import Julian import Hebrew import FrenchRepublic import GedcomInfo import ansel_utf8 from intl import gettext as _ from QuestionDialog import ErrorDialog def keep_utf8(s): return s #------------------------------------------------------------------------- # # Calendar month names # #------------------------------------------------------------------------- _hmonth = [ "", "ELUL", "TSH", "CSH", "KSL", "TVT", "SHV", "ADR", "ADS", "NSN", "IYR", "SVN", "TMZ", "AAV", "ELL" ] _fmonth = [ "", "VEND", "BRUM", "FRIM", "NIVO", "PLUV", "VENT", "GERM", "FLOR", "PRAI", "MESS", "THER", "FRUC", "COMP"] _month = [ "", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" ] _calmap = { Hebrew.Hebrew.NAME : (_hmonth, '@#HEBREW@'), FrenchRepublic.FrenchRepublic.NAME : (_fmonth, '@#FRENCH R@'), Julian.Julian.NAME : (_month, '@#JULIAN@'), } _caldef = { Calendar.ABOUT : "ABT", Calendar.BEFORE : "BEF", Calendar.AFTER : "AFT", } #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- _get_int = re.compile('([0-9]+)') #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def add_familys_sources(family,slist,private): for event in family.getEventList(): if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and not slist.has_key(sbase.getId()): slist[sbase.getId()] = 1 for attr in family.getAttributeList(): if private and attr.getPrivacy(): continue for source_ref in attr.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and not slist.has_key(sbase.getId()): slist[sbase.getId()] = 1 #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def add_persons_sources(person,slist,private): elist = person.getEventList()[:] elist.append(person.getBirth()) elist.append(person.getDeath()) for event in elist: if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and not slist.has_key(sbase.getId()): slist[sbase.getId()] = 1 for event in person.getAddressList(): if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and not slist.has_key(sbase.getId()): slist[sbase.getId()] = 1 for event in person.getAttributeList(): if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and not slist.has_key(sbase.getId()): slist[sbase.getId()] = 1 for name in person.getAlternateNames() + [person.getPrimaryName()]: if private and name.getPrivacy(): continue for source_ref in name.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and not slist.has_key(sbase.getId()): slist[sbase.getId()] = 1 #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def addr_append(text,data): if data: return "%s, %s" % (text,data) else: return text #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def sortById(first,second): fid = first.getId() sid = second.getId() if fid == sid: return 0 elif fid < sid: return -1 else: return 1 #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def make_date(subdate): retval = "" day = subdate.getDay() mon = subdate.getMonth() year = subdate.getYear() mode = subdate.getModeVal() day_valid = subdate.getDayValid() mon_valid = subdate.getMonthValid() year_valid = subdate.getYearValid() if _calmap.has_key(subdate.calendar.NAME): (mmap,prefix) = _calmap[subdate.calendar.NAME] else: mmap = _month prefix = "" if not day_valid: try: if not mon_valid: retval = '%d' % year elif not year_valid: retval = '(%s)' % mmap[mon] else: retval = "%s %d" % (mmap[mon],year) except IndexError: print "Month index error - %d" % mon retval = '%d' % year elif not mon_valid: retval = '%d' % year else: try: month = mmap[mon] if not year_valid: retval = "(%d %s)" % (day,month) else: retval = "%d %s %d" % (day,month,year) except IndexError: print "Month index error - %d" % mon retval = str(year) if prefix: retval = "%s %s" % (prefix, retval) if _caldef.has_key(mode): retval = "%s %s" % (_caldef[mode],retval) return retval #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def fmtline(text,limit,level): new_text = [] while len(text) > limit: new_text.append(text[0:limit-1]) text = text[limit:] if len(text) > 0: new_text.append(text) app = "\n%d CONC " % (level+1) return string.join(new_text,app) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def gedcom_date(date): if date.range == 1: s1 = ged_subdate(date.get_start_date()) s2 = ged_subdate(date.get_stop_date()) return "BET %s AND %s" % (s1,s2) elif date.range == -1: return "(%s)" % date.text else: return ged_subdate(date.start) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def ged_subdate(date): if not date.getValid(): return "" elif not date.getDayValid(): try: if not date.getMonthValid(): retval = str(date.year) elif not date.getYearValid(): retval = "(%s)" % Date.SingleDate.emname[date.month] else: retval = "%s %d" % (Date.SingleDate.emname[date.month],date.year) except IndexError: print "Month index error - %d" % date.month retval = str(date.year) elif not date.getMonthValid(): retval = str(date.year) else: try: month = Date.SingleDate.emname[date.month] if not date.getYearValid(): retval = "(%d %s)" % (date.day,month) else: retval = "%d %s %d" % (date.day,month,date.year) except IndexError: print "Month index error - %d" % date.month retval = str(date.year) if date.mode == Date.SingleDate.about: retval = "ABT %s" % retval if date.mode == Date.SingleDate.before: retval = "BEF %s" % retval elif date.mode == Date.SingleDate.after: retval = "AFT %s" % retval return retval #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def writeData(database,person): try: GedcomWriter(database,person) except: import DisplayTrace DisplayTrace.DisplayTrace() #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- class GedcomWriter: """Writes a GEDCOM file from the passed database""" def __init__(self,db,person,cl=0,name=""): self.db = db self.person = person self.restrict = 1 self.private = 1 self.cnvtxt = ansel_utf8.utf8_to_ansel self.plist = {} self.slist = {} self.flist = {} self.adopt = GedcomInfo.ADOPT_EVENT self.fidval = 0 self.fidmap = {} self.pidval = 0 self.pidmap = {} self.sidval = 0 self.sidmap = {} self.cl = cl self.name = name if self.cl: self.cl_setup() else: glade_file = "%s/gedcomexport.glade" % os.path.dirname(__file__) self.topDialog = gtk.glade.XML(glade_file,"gedcomExport") self.topDialog.signal_autoconnect({ "destroy_passed_object" : Utils.destroy_passed_object, "gnu_free" : self.gnu_free, "standard_copyright" : self.standard_copyright, "no_copyright" : self.no_copyright, "on_ok_clicked" : self.on_ok_clicked }) Utils.set_titles(self.topDialog.get_widget('gedcomExport'), self.topDialog.get_widget('title'), _('GEDCOM export')) filter_obj = self.topDialog.get_widget("filter") self.copy = 0 all = GenericFilter.GenericFilter() all.set_name(_("Entire Database")) all.add_rule(GenericFilter.Everyone([])) des = GenericFilter.GenericFilter() des.set_name(_("Descendants of %s") % person.getPrimaryName().getName()) des.add_rule(GenericFilter.IsDescendantOf([person.getId()])) ans = GenericFilter.GenericFilter() ans.set_name(_("Ancestors of %s") % person.getPrimaryName().getName()) ans.add_rule(GenericFilter.IsAncestorOf([person.getId()])) com = GenericFilter.GenericFilter() com.set_name(_("People with common ancestor with %s") % person.getPrimaryName().getName()) com.add_rule(GenericFilter.HasCommonAncestorWith([person.getId()])) self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com]) filter_obj.set_menu(self.filter_menu) gedmap = GedcomInfo.GedcomInfoDB() target_obj = self.topDialog.get_widget("target") myMenu = gtk.Menu() for name in gedmap.get_name_list(): menuitem = gtk.MenuItem(name) myMenu.append(menuitem) data = gedmap.get_description(name) menuitem.set_data("data",data) menuitem.show() target_obj.set_menu(myMenu) self.target_menu = myMenu pathname = "%s.ged" % os.path.dirname(db.getSavePath()) filetgt = self.topDialog.get_widget('fileentry1') filetgt.set_filename(pathname) self.topDialog.get_widget("gedcomExport").show() def gnu_free(self,obj): self.copy = 1 def standard_copyright(self,obj): self.copy = 0 def no_copyright(self,obj): self.copy = 2 def on_ok_clicked(self,obj): self.restrict = self.topDialog.get_widget("restrict").get_active() self.private = self.topDialog.get_widget("private").get_active() cfilter = self.filter_menu.get_active().get_data("filter") act_tgt = self.target_menu.get_active() self.target_ged = act_tgt.get_data("data") self.dest = self.target_ged.get_dest() self.adopt = self.target_ged.get_adopt() self.conc = self.target_ged.get_conc() self.altname = self.target_ged.get_alt_name() self.cal = self.target_ged.get_alt_calendar() self.obje = self.target_ged.get_obje() self.resi = self.target_ged.get_resi() self.prefix = self.target_ged.get_prefix() self.source_refs = self.target_ged.get_source_refs() if self.topDialog.get_widget("ansel").get_active(): self.cnvtxt = ansel_utf8.utf8_to_ansel else: self.cnvtxt = keep_utf8 name = self.topDialog.get_widget("filename").get_text() if cfilter == None: for p in self.db.getPersonKeys(): self.plist[p] = 1 else: for p in cfilter.apply(self.db, self.db.getPersonMap().values()): self.plist[p.getId()] = 1 self.flist = {} self.slist = {} for key in self.plist.keys(): p = self.db.getPerson(key) add_persons_sources(p,self.slist,self.private) for family in p.getFamilyList(): add_familys_sources(family,self.slist,self.private) self.flist[family.getId()] = 1 Utils.destroy_passed_object(obj) glade_file = "%s/gedcomexport.glade" % os.path.dirname(__file__) self.exprogress = gtk.glade.XML(glade_file,"exportprogress") self.exprogress.signal_autoconnect({ "on_close_clicked" : Utils.destroy_passed_object }) Utils.set_titles(self.exprogress.get_widget('exportprogress'), self.exprogress.get_widget('title'), _('GEDCOM export')) self.fbar = self.exprogress.get_widget("fbar") self.pbar = self.exprogress.get_widget("pbar") self.sbar = self.exprogress.get_widget("sbar") self.progress = self.exprogress.get_widget('exportprogress') closebtn = self.exprogress.get_widget("close") closebtn.connect("clicked",Utils.destroy_passed_object) closebtn.set_sensitive(0) self.export_data(name) closebtn.set_sensitive(1) def cl_setup(self): self.restrict = 0 self.private = 0 self.copy = 0 for p in self.db.getPersonKeys(): self.plist[p] = 1 gedmap = GedcomInfo.GedcomInfoDB() self.target_ged = gedmap.standard self.dest = self.target_ged.get_dest() self.adopt = self.target_ged.get_adopt() self.conc = self.target_ged.get_conc() self.altname = self.target_ged.get_alt_name() self.cal = self.target_ged.get_alt_calendar() self.obje = self.target_ged.get_obje() self.resi = self.target_ged.get_resi() self.prefix = self.target_ged.get_prefix() self.source_refs = self.target_ged.get_source_refs() self.cnvtxt = keep_utf8 self.flist = {} self.slist = {} for key in self.plist.keys(): p = self.db.getPerson(key) add_persons_sources(p,self.slist,self.private) for family in p.getFamilyList(): add_familys_sources(family,self.slist,self.private) self.flist[family.getId()] = 1 self.export_data(self.name) def export_data(self,filename): try: self.g = open(filename,"w") except IOError,msg: msg2 = _("Could not create %s") % filename ErrorDialog(msg2,str(msg)) self.progress.destroy() return except: ErrorDialog(_("Could not create %s") % filename) self.progress.destroy() return date = string.split(time.ctime(time.time())) self.g.write("0 HEAD\n") self.g.write("1 SOUR GRAMPS\n") self.g.write("2 VERS %s\n" % const.version) self.g.write("2 NAME GRAMPS\n") if self.dest: self.g.write("1 DEST %s\n" % self.dest) self.g.write("1 DATE %s %s %s\n" % (date[2],string.upper(date[1]),date[4])) if self.cnvtxt == ansel_utf8.utf8_to_ansel: self.g.write("1 CHAR ANSEL\n") else: self.g.write("1 CHAR UTF-8\n") self.g.write("1 SUBM @SUBM@\n") self.g.write("1 FILE %s\n" % filename) self.write_copy() self.g.write("1 GEDC\n") self.g.write("2 VERS 5.5\n") self.g.write('2 FORM LINEAGE-LINKED\n') self.gnu_fdl() self.g.write("0 @SUBM@ SUBM\n") owner = self.db.getResearcher() if owner.getName(): self.g.write("1 NAME %s\n" % self.cnvtxt(owner.getName())) else: self.g.write('1 NAME Not Provided\n') if owner.getAddress(): cnt = 0 self.g.write("1 ADDR %s\n" % self.cnvtxt(owner.getAddress())) if owner.getCity(): self.g.write("2 CONT %s\n" % self.cnvtxt(owner.getCity())) cnt = 1 if owner.getState(): self.g.write("2 CONT %s\n" % self.cnvtxt(owner.getState())) cnt = 1 if owner.getPostalCode(): self.g.write("2 CONT %s\n" % self.cnvtxt(owner.getPostalCode())) cnt = 1 if owner.getCountry(): self.g.write("2 CONT %s\n" % self.cnvtxt(owner.getCountry())) cnt = 1 if owner.getPhone(): self.g.write("2 PHON %s\n" % self.cnvtxt(owner.getPhone())) cnt = 1 if cnt == 0: self.g.write('2 CONT Not Provided\n') else: self.g.write('1 ADDR Not Provided\n') self.g.write('2 CONT Not Provided\n') pkeys = self.plist.keys() pkeys.sort() nump = float(len(self.plist)) index = 0.0 for key in pkeys: self.write_person(self.db.getPerson(key)) index = index + 1 if index%100 == 0 and not self.cl: self.pbar.set_fraction(index/nump) while(gtk.events_pending()): gtk.mainiteration() if not self.cl: self.pbar.set_fraction(1.0) self.write_families() if self.source_refs: self.write_sources() else: if not self.cl: self.sbar.set_fraction(1.0) self.g.write("0 TRLR\n") self.g.close() def write_copy(self): import time t = time.localtime(time.time()) y = t[0] if self.copy == 0: o = self.db.getResearcher().getName() self.g.write('1 COPR Copyright (c) %d %s.\n' % (y,o)) elif self.copy == 1: o = self.db.getResearcher().getName() self.g.write('1 COPR Copyright (c) %d %s. See additional copyright NOTE below.\n' % (y,o)) def gnu_fdl(self): import time if self.copy != 1: return t = time.localtime(time.time()) y = t[0] o = self.db.getResearcher().getName() self.g.write('1 NOTE Copyright (c) %d %s.\n' % (y,o)) try: f = open(const.fdl,"r") for line in f.readlines(): self.g.write('2 CONT %s' % line) f.close() except: pass def write_families(self): nump = float(len(self.flist)) index = 0.0 for key in self.flist.keys(): family = self.db.getFamily(key) father_alive = mother_alive = 0 self.g.write("0 @%s@ FAM\n" % self.fid(family.getId())) self.prefn(family) person = family.getFather() if person != None and self.plist.has_key(person.getId()): self.g.write("1 HUSB @%s@\n" % self.pid(person.getId())) father_alive = person.probablyAlive() person = family.getMother() if person != None and self.plist.has_key(person.getId()): self.g.write("1 WIFE @%s@\n" % self.pid(person.getId())) mother_alive = person.probablyAlive() if not self.restrict or ( not father_alive and not mother_alive ): self.write_ord("SLGS",family.getLdsSeal(),1,const.lds_ssealing) for event in family.getEventList(): if self.private and event.getPrivacy(): continue name = event.getName() val = "" if const.familyConstantEvents.has_key(name): val = const.familyConstantEvents[name] if val == "": val = self.target_ged.gramps2tag(name) if val: self.g.write("1 %s %s\n" % (self.cnvtxt(val), self.cnvtxt(event.getDescription()))) else: self.g.write("1 EVEN %s\n" % self.cnvtxt(event.getDescription())) self.g.write("2 TYPE %s\n" % self.cnvtxt(name)) self.dump_event_stats(event) for person in family.getChildList(): if not self.plist.has_key(person.getId()): continue self.g.write("1 CHIL @%s@\n" % self.pid(person.getId())) if self.adopt == GedcomInfo.ADOPT_FTW: if person.getMainParents() == family: self.g.write('2 _FREL Natural\n') self.g.write('2 _MREL Natural\n') else: for f in person.getParentList(): if f[0] == family: self.g.write('2 _FREL %s\n' % f[2]) self.g.write('2 _MREL %s\n' % f[1]) break if self.adopt == GedcomInfo.ADOPT_LEGACY: for f in person.getAltParentList(): if f[0] == family: self.g.write('2 _STAT %s\n' % f[2]) break index = index + 1 if index % 100 == 0 and not self.cl: self.fbar.set_fraction(index/nump) while(gtk.events_pending()): gtk.mainiteration() if not self.cl: self.fbar.set_fraction(1.0) def write_sources(self): nump = float(len(self.slist)) index = 0.0 for key in self.slist.keys(): source = self.db.getSource(key) self.g.write("0 @%s@ SOUR\n" % self.sid(source.getId())) if source.getTitle(): self.g.write("1 TITL %s\n" % fmtline(self.cnvtxt(source.getTitle()),248,1)) if source.getAuthor(): self.g.write("1 AUTH %s\n" % self.cnvtxt(source.getAuthor())) if source.getPubInfo(): self.g.write("1 PUBL %s\n" % self.cnvtxt(source.getPubInfo())) if source.getTitle(): self.g.write("1 ABBR %s\n" % self.cnvtxt(source.getTitle())) if source.getCallNumber(): self.g.write("1 CALN %s\n" % self.cnvtxt(source.getCallNumber())) if source.getNote(): self.write_long_text("NOTE",1,self.cnvtxt(source.getNote())) index = index + 1 if index % 100 == 0 and not self.cl: self.sbar.set_fraction(index/nump) while(gtk.events_pending()): gtk.mainiteration() if not self.cl: self.sbar.set_fraction(1.0) def write_person(self,person): self.g.write("0 @%s@ INDI\n" % self.pid(person.getId())) self.prefn(person) self.write_person_name(person.getPrimaryName(),person.getNickName()) if self.altname == GedcomInfo.ALT_NAME_STD: for name in person.getAlternateNames(): self.write_person_name(name,"") if person.getGender() == RelLib.Person.male: self.g.write("1 SEX M\n") elif person.getGender() == RelLib.Person.female: self.g.write("1 SEX F\n") if not self.restrict or not person.probablyAlive(): birth = person.getBirth() if not (self.private and birth.getPrivacy()): if not birth.getDateObj().isEmpty() or birth.getPlaceName(): self.g.write("1 BIRT\n") self.dump_event_stats(birth) death = person.getDeath() if not (self.private and death.getPrivacy()): if not death.getDateObj().isEmpty() or death.getPlaceName(): self.g.write("1 DEAT\n") self.dump_event_stats(death) uid = person.getPafUid() if uid: self.g.write("1 _UID %s\n" % uid) ad = 0 self.write_ord("BAPL",person.getLdsBaptism(),1,const.lds_baptism) self.write_ord("ENDL",person.getLdsEndowment(),1,const.lds_baptism) self.write_ord("SLGC",person.getLdsSeal(),1,const.lds_csealing) for event in person.getEventList(): if self.private and event.getPrivacy(): continue name = event.getName() val = "" if const.personalConstantEvents.has_key(name): val = const.personalConstantEvents[name] if val == "": val = self.target_ged.gramps2tag(name) if self.adopt == GedcomInfo.ADOPT_EVENT and val == "ADOP": ad = 1 self.g.write('1 ADOP\n') fam = None for f in person.getParentList(): mrel = string.lower(f[1]) frel = string.lower(f[2]) if mrel=="adopted" or frel=="adopted": fam = f[0] break if fam: self.g.write('2 FAMC @%s@\n' % self.fid(fam.getId())) if mrel == frel: self.g.write('3 ADOP BOTH\n') elif mrel == "adopted": self.g.write('3 ADOP WIFE\n') else: self.g.write('3 ADOP HUSB\n') elif val : self.g.write("1 %s %s\n" % (self.cnvtxt(val),\ self.cnvtxt(event.getDescription()))) else: self.g.write("1 EVEN %s\n" % self.cnvtxt(event.getDescription())) self.g.write("2 TYPE %s\n" % self.cnvtxt(event.getName())) self.dump_event_stats(event) if self.adopt == GedcomInfo.ADOPT_EVENT and ad == 0 and len(person.getParentList()) != 0: self.g.write('1 ADOP\n') fam = None for f in person.getParentList(): mrel = string.lower(f[1]) frel = string.lower(f[2]) if mrel=="adopted" or frel=="adopted": fam = f[0] break if fam: self.g.write('2 FAMC @%s@\n' % self.fid(fam.getId())) if mrel == frel: self.g.write('3 ADOP BOTH\n') elif mrel == "adopted": self.g.write('3 ADOP WIFE\n') else: self.g.write('3 ADOP HUSB\n') for attr in person.getAttributeList(): if self.private and attr.getPrivacy(): continue name = attr.getType() if const.personalConstantAttributes.has_key(name): val = const.personalConstantAttributes[name] else: val = "" if val : self.g.write("1 %s\n" % val) else: self.g.write("1 EVEN\n") self.g.write("2 TYPE %s\n" % self.cnvtxt(name)) self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(attr.getValue()),'\r',' ')) if attr.getNote(): self.write_long_text("NOTE",2,self.cnvtxt(attr.getNote())) for srcref in attr.getSourceRefList(): self.write_source_ref(2,srcref) for addr in person.getAddressList(): if self.private and addr.getPrivacy(): continue self.g.write("1 RESI\n") self.print_date("2 DATE",addr.getDateObj()) if self.resi == 0: self.write_long_text("ADDR",2,self.cnvtxt(addr.getStreet())) if addr.getCity(): self.g.write("3 CITY %s\n" % self.cnvtxt(addr.getCity())) if addr.getState(): self.g.write("3 STAE %s\n" % self.cnvtxt(addr.getState())) if addr.getPostal(): self.g.write("3 POST %s\n" % self.cnvtxt(addr.getPostal())) if addr.getCountry(): self.g.write("3 CTRY %s\n" % self.cnvtxt(addr.getCountry())) else: text = addr.getStreet() text = addr_append(text,addr.getCity()) text = addr_append(text,addr.getState()) text = addr_append(text,addr.getPostal()) text = addr_append(text,addr.getCountry()) if text: self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(text),'\r',' ')) if addr.getNote(): self.write_long_text("NOTE",2,self.cnvtxt(addr.getNote())) for srcref in addr.getSourceRefList(): self.write_source_ref(2,srcref) for family in person.getParentList(): if self.flist.has_key(family[0].getId()): self.g.write("1 FAMC @%s@\n" % self.fid(family[0].getId())) if self.adopt == GedcomInfo.ADOPT_PEDI: if string.lower(family[1]) == "adopted": self.g.write("2 PEDI Adopted\n") for family in person.getFamilyList(): if family != None and self.flist.has_key(family.getId()): self.g.write("1 FAMS @%s@\n" % self.fid(family.getId())) if self.obje: for url in person.getUrlList(): self.g.write('1 OBJE\n') self.g.write('2 FORM URL\n') if url.get_description(): self.g.write('2 TITL %s\n' % url.get_description()) if url.get_path(): self.g.write('2 FILE %s\n' % url.get_path()) if person.getNote(): self.write_long_text("NOTE",1,self.cnvtxt(person.getNote())) def write_long_text(self,tag,level,note): if self.conc == GedcomInfo.CONC_OK: self.write_conc_ok(tag,level,note) else: self.write_conc_broken(tag,level,note) def write_conc_ok(self,tag,level,note): prefix = "%d %s" % (level,tag) textlines = string.split(note,'\n') if len(note) == 0: self.g.write("%s\n" % prefix) else: for line in textlines: ll = len(line) while ll > 0: brkpt = 70 if ll > brkpt: while (ll > brkpt and line[brkpt] in string.whitespace): brkpt = brkpt+1 if ll == brkpt: self.g.write("%s %s\n" % (prefix,line)) line = '' break else: self.g.write("%s %s\n" % (prefix,line[0:brkpt+1])) line = line[brkpt+1:] else: self.g.write("%s %s\n" % (prefix,line)) line = "" if len(line) > 0: prefix = "%d CONC" % (level+1) else: prefix = "%d CONT" % (level+1) ll = len(line) def write_conc_broken(self,tag,level,note): prefix = "%d %s" % (level,tag) textlines = string.split(note,'\n') if len(note) == 0: self.g.write("%s\n" % prefix) else: for line in textlines: ll = len(line) while ll > 0: brkpt = 70 if ll > brkpt: while (ll > brkpt and line[brkpt] not in string.whitespace): brkpt = brkpt+1 if ll == brkpt: self.g.write("%s %s\n" % (prefix,line)) line = '' break else: self.g.write("%s %s\n" % (prefix,line[0:brkpt+1])) line = line[brkpt+1:] else: self.g.write("%s %s\n" % (prefix,line)) line = "" if len(line) > 0: prefix = "%d CONC" % (level+1) else: prefix = "%d CONT" % (level+1) ll = len(line) def dump_event_stats(self,event): dateobj = event.getDateObj() self.print_date("2 DATE",dateobj) if event.getPlaceName(): self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(event.getPlaceName()),'\r',' ')) if event.getCause(): self.g.write("2 CAUS %s\n" % self.cnvtxt(event.getCause())) if event.getNote(): self.write_long_text("NOTE",2,self.cnvtxt(event.getNote())) for srcref in event.getSourceRefList(): self.write_source_ref(2,srcref) def write_ord(self,name,ord,index,statlist): if ord == None: return self.g.write('%d %s\n' % (index,name)) self.print_date("%d DATE" % (index + 1), ord.getDateObj()) if ord.getFamily(): self.g.write('%d FAMC @%s@\n' % (index+1,self.fid(ord.getFamily().getId()))) if ord.getTemple(): self.g.write('%d TEMP %s\n' % (index+1,ord.getTemple())) if ord.getPlaceName(): self.g.write("2 PLAC %s\n" % string.replace(self.cnvtxt(ord.getPlaceName()),'\r',' ')) if ord.getStatus() != 0: self.g.write("2 STAT %s\n" % self.cnvtxt(statlist[ord.getStatus()])) if ord.getNote(): self.write_long_text("NOTE",index+1,self.cnvtxt(ord.getNote())) for srcref in ord.getSourceRefList(): self.write_source_ref(index+1,srcref) def print_date(self,prefix,date): start = date.get_start_date() if date.isEmpty(): val = date.getText() if val: self.g.write("%s %s\n" % (prefix,self.cnvtxt(val))) else: if date.isRange(): val = "FROM %s TO %s" % (make_date(start), make_date(date.get_stop_date())) else: val = make_date(start) self.g.write("%s %s\n" % (prefix,val)) def write_person_name(self,name,nick): firstName = self.cnvtxt(name.getFirstName()) surName = self.cnvtxt(name.getSurname()) surPref = self.cnvtxt(name.getSurnamePrefix()) suffix = self.cnvtxt(name.getSuffix()) title = self.cnvtxt(name.getTitle()) if suffix == "": if not surPref: self.g.write("1 NAME %s /%s/\n" % (firstName,surName)) else: self.g.write("1 NAME %s /%s %s/\n" % (firstName,surPref,surName)) else: if not surPref: self.g.write("1 NAME %s /%s %s/, %s\n" % (firstName,surPref,surName,suffix)) else: self.g.write("1 NAME %s /%s/, %s\n" % (firstName,surName,suffix)) if name.getFirstName(): self.g.write("2 GIVN %s\n" % firstName) if self.prefix: if surPref: self.g.write('2 SPFX %s\n' % surPref) if surName: self.g.write("2 SURN %s\n" % surName) else: if surPref: self.g.write("2 SURN %s %s\n" % (surPref,surName)) elif surName: self.g.write("2 SURN %s\n" % surName) if name.getSuffix(): self.g.write("2 NSFX %s\n" % suffix) if name.getTitle(): self.g.write("2 NPFX %s\n" % title) if nick: self.g.write('2 NICK %s\n' % nick) if name.getNote(): self.write_long_text("NOTE",2,self.cnvtxt(name.getNote())) for srcref in name.getSourceRefList(): self.write_source_ref(2,srcref) def write_source_ref(self,level,ref): if ref.getBase() == None: return if self.source_refs: self.g.write("%d SOUR @%s@\n" % (level,self.sid(ref.getBase().getId()))) if ref.getPage() != "": self.g.write("%d PAGE %s\n" % (level+1,ref.getPage())) ref_text = ref.getText() if ref_text != "" or not ref.getDate().isEmpty(): self.g.write('%d DATA\n' % (level+1)) if ref_text != "": self.write_long_text("TEXT",level+2,self.cnvtxt(ref_text)) pfx = "%d DATE" % (level+2) self.print_date(pfx,ref.getDate()) else: # We put title, page, and date on the SOUR line. # Not using CONC and CONT because GeneWeb does not support these. # TEXT and NOTE will be ignored by GeneWeb, but we can't # output paragaphs in SOUR without CONT. sbase = ref.getBase() if sbase and sbase.getTitle(): txt = sbase.getTitle() + ". " else: txt = "" if ref.getPage(): txt = txt + ref.getPage() + ". " self.g.write("%d SOUR %s" % (level,self.cnvtxt(txt))) if not ref.getDate().isEmpty(): self.print_date("", ref.getDate()) else: self.g.write("\n") if ref.getText(): self.write_long_text("TEXT",level+1,self.cnvtxt(ref_text)) if ref.getComments(): self.write_long_text("NOTE",level+1,self.cnvtxt(ref.getComments())) def fid(self,id): return id def prefn(self,person): match = _get_int.search(person.getId()) if match: self.g.write('1 REFN %d\n' % int(match.groups()[0])) def frefn(self,family): match = _get_int.search(family.getId()) if match: self.g.write('1 REFN %d\n' % int(match.groups()[0])) def pid(self,id): return id def sid(self,id): if self.sidmap.has_key(id): return self.sidmap[id] else: val = "S%05d" % self.sidval self.sidval = self.sidval + 1 self.sidmap[id] = val return val #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- from Plugins import register_export register_export(writeData,_("Export to GEDCOM"))