From 954d093c0f4f7a741730631e0acb1b2ac8702879 Mon Sep 17 00:00:00 2001 From: Alex Roitman Date: Fri, 27 Jan 2006 06:54:35 +0000 Subject: [PATCH] * src/GrampsDb/_ConstXML.py: More XML export fixes. * src/GrampsDb/_GrampsBSDDB.py: More XML export fixes. * src/GrampsDb/_GrampsDbBase.py: More XML export fixes. * src/GrampsDb/_GrampsInMemDB.py: More XML export fixes. * src/GrampsDb/_WriteXML.py: More XML export fixes. svn: r5842 --- ChangeLog | 6 + src/GrampsDb/_ConstXML.py | 9 ++ src/GrampsDb/_GrampsBSDDB.py | 28 ++++- src/GrampsDb/_GrampsDbBase.py | 17 +++ src/GrampsDb/_GrampsInMemDB.py | 30 ++++- src/GrampsDb/_WriteXML.py | 219 ++++++++++++++++++++------------- 6 files changed, 216 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index e2c29bc15..61f6ffd7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,12 @@ relations from integer to tuple on upgrade. * src/GrampsDb/_WriteGedcom.py: Convert from tuple to string. * src/GrampsDb/_WriteXML.py: Handle some of new XML. + + * src/GrampsDb/_ConstXML.py: More XML export fixes. + * src/GrampsDb/_GrampsBSDDB.py: More XML export fixes. + * src/GrampsDb/_GrampsDbBase.py: More XML export fixes. + * src/GrampsDb/_GrampsInMemDB.py: More XML export fixes. + * src/GrampsDb/_WriteXML.py: More XML export fixes. 2006-01-25 Don Allingham * src/DisplayTabs.py: use idle_loop to load data for source diff --git a/src/GrampsDb/_ConstXML.py b/src/GrampsDb/_ConstXML.py index f735f1dd0..abb358366 100644 --- a/src/GrampsDb/_ConstXML.py +++ b/src/GrampsDb/_ConstXML.py @@ -165,6 +165,14 @@ marker_types = ( (RelLib.PrimaryObject.MARKER_TODO , "todo"), ) +url_types = ( + (RelLib.Url.UNKNOWN , "Unknown"), + (RelLib.Url.EMAIL , "Email"), + (RelLib.Url.WEB_HOME , "Home"), + (RelLib.Url.WEB_SEARCH , "Search"), + (RelLib.Url.WEB_FTP , "FTP"), + ) + # mapping from the tuple collection to the appropriate CUSTOM integer custom_types = { child_relations : RelLib.Person.CHILD_CUSTOM, @@ -176,6 +184,7 @@ custom_types = { event_roles : RelLib.EventRef.CUSTOM, repository_types : RelLib.Repository.CUSTOM, marker_types : RelLib.PrimaryObject.MARKER_CUSTOM, + url_types : RelLib.Url.CUSTOM, } def str_for_xml(tuples,the_tuple): diff --git a/src/GrampsDb/_GrampsBSDDB.py b/src/GrampsDb/_GrampsBSDDB.py index 4a1b499ce..1fb80ddaa 100644 --- a/src/GrampsDb/_GrampsBSDDB.py +++ b/src/GrampsDb/_GrampsBSDDB.py @@ -841,11 +841,26 @@ class GrampsBSDDB(GrampsDbBase): else: self.name_group.put(name,group,txn=self.txn) self.emit('person-rebuild') - + + def get_gramps_ids(self,obj_key): + key2table = { + PERSON_KEY: self.id_trans, + FAMILY_KEY: self.fid_trans, + SOURCE_KEY: self.sid_trans, + EVENT_KEY: self.eid_trans, + MEDIA_KEY: self.oid_trans, + PLACE_KEY: self.pid_trans, + REPOSITORY_KEY: self.rid_trans, + } + + table = key2table[obj_key] + return table.keys() + def get_surname_list(self): - vals = [ unicode(val) for val in set(self.surnames.keys()) ] - vals.sort(locale.strcoll) - return vals + vals = [ (strxfrm(unicode(val)),unicode(val)) + for val in set(self.surnames.keys()) ] + vals.sort() + return [item[0] for item in vals] def get_person_event_type_list(self): vals = [ unicode(val) for val in set(self.eventnames.keys()) ] @@ -876,6 +891,11 @@ class GrampsBSDDB(GrampsDbBase): If no such Family exists, a new Person is added to the database.""" return self._get_obj_from_gramps_id(val,self.fid_trans,Family) + def get_event_from_gramps_id(self,val): + """finds a Family in the database from the passed gramps' ID. + If no such Family exists, a new Person is added to the database.""" + return self._get_obj_from_gramps_id(val,self.eid_trans,Event) + def get_place_from_gramps_id(self,val): """finds a Place in the database from the passed gramps' ID. If no such Place exists, a new Person is added to the database.""" diff --git a/src/GrampsDb/_GrampsDbBase.py b/src/GrampsDb/_GrampsDbBase.py index 03efffd50..491b40ccb 100644 --- a/src/GrampsDb/_GrampsDbBase.py +++ b/src/GrampsDb/_GrampsDbBase.py @@ -706,6 +706,15 @@ class GrampsDbBase(GrampsDBCallback): """ assert False, "Needs to be overridden in the derived class" + def get_event_from_gramps_id(self,val): + """ + Finds an Event in the database from the passed GRAMPS ID. + If no such Event exists, None is returned. + + Needs to be overridden by the derrived class. + """ + assert False, "Needs to be overridden in the derived class" + def get_place_from_gramps_id(self,val): """finds a Place in the database from the passed gramps' ID. If no such Place exists, a new Person is added to the database. @@ -972,6 +981,14 @@ class GrampsDbBase(GrampsDBCallback): return self._all_handles(self.repository_map) return [] + def get_gramps_ids(self,obj_key): + """ + Returns the list of gramps IDs contained within the database + for the objects of the obj_key type. + The function must be overridden in the derived class. + """ + assert False, "Needs to be overridden in the derived class" + def _validated_id_prefix(self, val, default): if val: try: diff --git a/src/GrampsDb/_GrampsInMemDB.py b/src/GrampsDb/_GrampsInMemDB.py index 0e91b8e8c..2cd7df6e4 100644 --- a/src/GrampsDb/_GrampsInMemDB.py +++ b/src/GrampsDb/_GrampsInMemDB.py @@ -1,7 +1,7 @@ # # Gramps - a GTK+/GNOME based genealogy program # -# Copyright (C) 2000-2005 Donald N. Allingham +# Copyright (C) 2000-2006 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 @@ -25,7 +25,13 @@ Provides the common infrastructure for database formats that must hold all of their data in memory. """ +#------------------------------------------------------------------------- +# +# Python modules +# +#------------------------------------------------------------------------- from bsddb import dbshelve, db +import sets #------------------------------------------------------------------------- # @@ -34,7 +40,6 @@ from bsddb import dbshelve, db #------------------------------------------------------------------------- from RelLib import * from _GrampsDbBase import * -import sets class GrampsInMemCursor(GrampsCursor): """ @@ -141,6 +146,27 @@ class GrampsInMemDB(GrampsDbBase): else: self.name_group[name] = group + def get_gramps_ids(self,obj_key): + """ + Returns the list of gramps IDs contained within the database + for the objects of the obj_key type. + The function must be overridden in the derived class. + """ + + key2table_getfun = { + PERSON_KEY: (self.person_map, self.get_person_from_handle), + FAMILY_KEY: (self.family_map, self.get_family_from_handle), + SOURCE_KEY: (self.source_map, self.get_source_from_handle), + EVENT_KEY: (self.event_map, self.get_event_from_handle), + MEDIA_KEY: (self.media_map, self.get_object_from_handle), + PLACE_KEY: (self.place_map, self.get_place_from_handle), + REPOSITORY_KEY: (self.repository_map, + self.get_repository_from_handle), + } + + table,getfun = key2table_getfun[obj_key] + return [getfun(handle).gramps_id for handle in iter(table)] + def get_surname_list(self): a = {} for person_id in iter(self.person_map): diff --git a/src/GrampsDb/_WriteXML.py b/src/GrampsDb/_WriteXML.py index 09a1c5d06..b00ab1198 100644 --- a/src/GrampsDb/_WriteXML.py +++ b/src/GrampsDb/_WriteXML.py @@ -53,6 +53,9 @@ import RelLib import Date from QuestionDialog import ErrorDialog import _ConstXML +from _GrampsDbBase import \ + PERSON_KEY,FAMILY_KEY,SOURCE_KEY,EVENT_KEY,\ + MEDIA_KEY,PLACE_KEY,REPOSITORY_KEY #------------------------------------------------------------------------- # @@ -67,7 +70,7 @@ except: _gzip_ok = 0 -_xml_version = "1.0.0" +_xml_version = "1.1.0" #------------------------------------------------------------------------- # @@ -143,8 +146,8 @@ class XmlWriter: if os.path.isdir(base): if not os.access(base,os.W_OK) or not os.access(base,os.R_OK): ErrorDialog(_('Failure writing %s') % filename, - _("The database cannot be saved because you do not " - "have permission to write to the directory. " + _("The database cannot be saved because you do " + "not have permission to write to the directory. " "Please make sure you have write access to the " "directory and try again.")) return 0 @@ -152,8 +155,8 @@ class XmlWriter: if os.path.exists(filename): if not os.access(filename,os.W_OK): ErrorDialog(_('Failure writing %s') % filename, - _("The database cannot be saved because you do not " - "have permission to write to the file. " + _("The database cannot be saved because you do " + "not have permission to write to the file. " "Please make sure you have write access to the " "file and try again.")) return 0 @@ -243,14 +246,17 @@ class XmlWriter: self.g.write(' default="%s" home="_%s">\n' % (person.gramps_id,person.handle)) - keys = self.db.get_person_handles(sort_handles=False) - sorted_keys = [] - for key in keys: - person = self.db.get_person_from_handle (key) - sorted_keys.append ((person.gramps_id, person)) - sorted_keys.sort () + # keys = self.db.get_person_handles(sort_handles=False) + # sorted_keys = [] + # for key in keys: + # person = self.db.get_person_from_handle (key) + # sorted_keys.append ((person.gramps_id, person)) + # sorted_keys.sort () + sorted_keys = self.db.get_gramps_ids(PERSON_KEY) + sorted_keys.sort() - for (gramps_id, person) in sorted_keys: + for gramps_id in sorted_keys: + person = self.db.get_person_from_gramps_id(gramps_id) if self.callback and count % delta == 0: self.callback(float(count)/float(total)) count += 1 @@ -274,13 +280,15 @@ class XmlWriter: self.dump_ordinance("baptism",person.get_lds_baptism(),3) self.dump_ordinance("endowment",person.get_lds_endowment(),3) - self.dump_ordinance("sealed_to_parents",person.get_lds_sealing(),3) + self.dump_ordinance("sealed_to_parents", + person.get_lds_sealing(),3) self.write_media_list(person.get_media_list()) if len(person.get_address_list()) > 0: for address in person.get_address_list(): - self.g.write(' \n' % conf_priv(address)) + self.g.write(' \n' + % conf_priv(address)) self.write_date(address.get_date_object(),4) self.write_line("street",address.get_street(),4) self.write_line("city",address.get_city(),4) @@ -301,17 +309,15 @@ class XmlWriter: if alt[1][0] != RelLib.Person.CHILD_BIRTH: mrel=' mrel="%s"' % _ConstXML.str_for_xml( _ConstXML.child_relations,alt[1]) - # const.child_rel_notrans[alt[1]] else: mrel='' if alt[2][0] != RelLib.Person.CHILD_BIRTH: frel=' frel="%s"' % _ConstXML.str_for_xml( _ConstXML.child_relations,alt[2]) - # const.child_rel_notrans[alt[2]] else: frel='' - self.g.write(" \n" % \ - ("_"+alt[0], mrel, frel)) + self.g.write(' \n' % \ + (alt[0], mrel, frel)) for family_handle in person.get_family_handle_list(): self.write_ref("parentin",family_handle,3) @@ -326,15 +332,17 @@ class XmlWriter: if family_len > 0: self.g.write(" \n") - keys = self.db.get_family_handles() - sorted_keys = [] - for key in keys: - family = self.db.get_family_from_handle(key) - value = (family.get_gramps_id (), family) - sorted_keys.append (value) +## keys = self.db.get_family_handles() +## sorted_keys = [] +## for key in keys: +## family = self.db.get_family_from_handle(key) +## value = (family.get_gramps_id (), family) +## sorted_keys.append (value) + sorted_keys = self.db.get_gramps_ids(FAMILY_KEY) sorted_keys.sort () - for (gramps_id, family) in sorted_keys: + for gramps_id in sorted_keys: + family = self.db.get_family_from_gramps_id(gramps_id) if self.callback and count % delta == 0: self.callback(float(count)/float(total)) count = count + 1 @@ -348,7 +356,8 @@ class XmlWriter: self.write_ref("mother",mhandle,3) for event_ref in family.get_event_ref_list(): self.dump_event_ref(event_ref,3) - self.dump_ordinance("sealed_to_spouse",family.get_lds_sealing(),3) + self.dump_ordinance("sealed_to_spouse", + family.get_lds_sealing(),3) self.write_media_list(family.get_media_list()) @@ -364,14 +373,16 @@ class XmlWriter: if event_len > 0: self.g.write(" \n") - keys = self.db.get_event_handles() - sorted_keys = [] - for key in keys: - event = self.db.get_event_from_handle(key) - sorted_keys.append((event.gramps_id, event)) +## keys = self.db.get_event_handles() +## sorted_keys = [] +## for key in keys: +## event = self.db.get_event_from_handle(key) +## sorted_keys.append((event.gramps_id, event)) + sorted_keys = self.db.get_gramps_ids(EVENT_KEY) sorted_keys.sort () - for (gramps_id, event) in sorted_keys: + for gramps_id in sorted_keys: + event = self.db.get_event_from_gramps_id(gramps_id) if self.callback and count % delta == 0: self.callback(float(count)/float(total)) count = count + 1 @@ -380,16 +391,15 @@ class XmlWriter: if source_len > 0: self.g.write(" \n") - keys = self.db.get_source_handles () + #keys = self.db.get_source_handles () + keys = self.db.get_gramps_ids(SOURCE_KEY) keys.sort () for key in keys: - source = self.db.get_source_from_handle(key) + source = self.db.get_source_from_gramps_id(key) if self.callback and count % delta == 0: self.callback(float(count)/float(total)) count = count + 1 - self.g.write(" \n" % - (source.get_gramps_id(), "_"+source.get_handle(), - source.get_change_time())) + self.write_primary_tag("source",source,2) self.write_force_line("stitle",source.get_title(),3) self.write_line("sauthor",source.get_author(),3) self.write_line("spubinfo",source.get_publication_info(),3) @@ -397,17 +407,19 @@ class XmlWriter: if source.get_note() != "": self.write_note("note",source.get_note_object(),3) self.write_media_list(source.get_media_list()) + self.write_reporef_list(source.get_reporef_list()) self.write_data_map(source.get_data_map()) self.g.write(" \n") self.g.write(" \n") if place_len > 0: self.g.write(" \n") - keys = self.db.get_place_handles() + #keys = self.db.get_place_handles() + keys = self.db.get_gramps_ids(PLACE_KEY) keys.sort () for key in keys: try: - place = self.db.get_place_from_handle(key) + place = self.db.get_place_from_gramps_id(key) if self.callback and count % delta == 0: self.callback(float(count)/float(total)) self.write_place_obj(place) @@ -419,22 +431,24 @@ class XmlWriter: if len(objList) > 0: self.g.write(" \n") - keys = self.db.get_media_object_handles() - sorted_keys = [] - for key in keys: - obj = self.db.get_object_from_handle (key) - value = (obj.get_gramps_id (), obj) - sorted_keys.append (value) + #keys = self.db.get_media_object_handles() + sorted_keys = self.db.get_gramps_ids(MEDIA_KEY) +## sorted_keys = [] +## for key in keys: +## obj = self.db.get_object_from_handle (key) +## value = (obj.get_gramps_id (), obj) +## sorted_keys.append (value) sorted_keys.sort () - for (gramps_id, obj) in sorted_keys: + for gramps_id in sorted_keys: + obj = self.db.get_object_from_gramps_id(gramps_id) self.write_object(obj) self.g.write(" \n") if len(self.db.get_bookmarks()) > 0: self.g.write(" \n") for person_handle in self.db.get_bookmarks(): - self.g.write(' \n' % ("_"+person_handle)) + self.g.write(' \n' % person_handle) self.g.write(" \n") if len(self.db.name_group) > 0: @@ -509,11 +523,11 @@ class XmlWriter: role_text = '' if eventref.get_note() == "": - started = self.write_ref('eventref',eventref.ref,index, - close=True,extra_text=priv_text+role_text) + self.write_ref('eventref',eventref.ref,index, + close=True,extra_text=priv_text+role_text) else: - started = self.write_ref('eventref',eventref.ref,index, - close=False,extra_text=priv_text+role_text) + self.write_ref('eventref',eventref.ref,index, + close=False,extra_text=priv_text+role_text) self.write_note("note",eventref.get_note_object(),index+1) self.g.write('%s\n' % (" "*index)) @@ -769,6 +783,8 @@ class XmlWriter: def dump_location(self,loc): "Writes the location information to the output file" + if loc.is_empty(): + return city = self.fix(loc.get_city()) parish = self.fix(loc.get_parish()) state = self.fix(loc.get_state()) @@ -843,41 +859,73 @@ class XmlWriter: self.g.write('%s' % (sp,key,datamap[key])) + def write_reporef_list(self,rrlist): + for reporef in rrlist: + if not reporef or not reporef.ref: + continue + + if reporef.call_number == "": + callno_text = '' + else: + callno_text = ' callno="%s"' % reporef.call_number + + mtype = _ConstXML.str_for_xml(_ConstXML.source_media_types, + reporef.media_type) + if mtype: + type_text = ' type="%s"' % mtype + else: + type_text = '' + + if reporef.get_note() == "": + self.write_ref('reporef',reporef.ref,3, + close=True,extra_text=callno_text+type_text) + else: + self.write_ref('reporef',reporef.ref,index, + close=False,extra_text=callno_text+type_text) + self.write_note("note",reporef.get_note_object(),4) + self.g.write('%s\n' % (" "*index)) + def write_url_list(self,list): for url in list: - self.g.write(' \n') + desc_text = ' description="%s"' % self.fix( + url.get_description()) + else: + desc_text = '' + path_text = ' href="%s"' % self.fix(url.get_path()) + self.g.write(' \n' % \ + (priv_text,path_text,type_text,desc_text)) def write_place_obj(self,place): + self.write_primary_tag("placeobj",place,2) + title = self.fix(place.get_title()) longitude = self.fix(place.get_longitude()) lat = self.fix(place.get_latitude()) handle = place.get_gramps_id() main_loc = place.get_main_location() - llen = len(place.get_alternate_locations()) + len(place.get_url_list()) + \ - len(place.get_media_list()) + len(place.get_source_references()) + llen = len(place.get_alternate_locations()) \ + + len(place.get_url_list()) + \ + len(place.get_media_list()) + \ + len(place.get_source_references()) ml_empty = main_loc.is_empty() note = place.get_note() if title == "": title = self.fix(self.build_place_title(place.get_main_location())) - - self.g.write(' 0 or note: - self.g.write('>\n') - else: - self.g.write('/>\n') - return + self.write_line("title",title,3) if longitude or lat: - self.g.write(' \n' % (longitude,lat)) - + self.g.write(' \n' + % (longitude,lat)) self.dump_location(main_loc) for loc in place.get_alternate_locations(): self.dump_location(loc) @@ -890,31 +938,28 @@ class XmlWriter: self.g.write(" \n") def write_object(self,obj): + self.write_primary_tag("object",obj,2) handle = obj.get_gramps_id() mime_type = obj.get_mime_type() path = obj.get_path() + desc = obj.get_description() + if desc: + desc_text = ' description="%s"' % self.fix(desc) + else: + desc_text = '' if self.strip_photos: path = os.path.basename(path) - self.g.write(' \n' + % (path,mime_type,desc_text)) + self.write_attribute_list(obj.get_attribute_list()) + if obj.get_note() != "": + self.write_note("note",obj.get_note_object(),3) dval = obj.get_date_object() - slist = obj.get_source_references() - if len(alist) == 0 and len(slist) == 0 and note == "" \ - and not dval.is_empty(): - self.g.write('/>\n') - else: - self.g.write('>\n') - self.write_attribute_list(alist) - if note != "": - self.write_note("note",obj.get_note_object(),3) - if not dval.is_empty(): - self.write_date(dval,3) - for s in slist: - self.dump_source_ref(s,3) - self.g.write(" \n") + if not dval.is_empty(): + self.write_date(dval,3) + for s in obj.get_source_references(): + self.dump_source_ref(s,3) + self.g.write(" \n") #------------------------------------------------------------------------- #