# # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2000-2004 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 # # $Id$ from RelLib import * _UNDO_SIZE = 1000 #------------------------------------------------------------------------- # # ID regular expression # #------------------------------------------------------------------------- _id_reg = compile("%\d+d") #------------------------------------------------------------------------- # # GrampsBSDDB # #------------------------------------------------------------------------- class GrampsBSDDB: """GRAMPS database object. This object is a base class for other objects.""" def __init__(self): """creates a new GrampsDB""" self.iprefix = "I%04d" self.sprefix = "S%04d" self.oprefix = "O%04d" self.pprefix = "P%04d" self.fprefix = "F%04d" self.eprefix = "E%04d" self.open = 0 self.new() self.added_files = [] self.genderStats = GenderStats() self.env = None self.person_map = None self.family_map = None self.place_map = None self.source_map = None self.media_map = None self.event_map = None self.surnames = None self.eventnames = None self.metadata = None self.undolabel = None self.redolabel = None self.undodb = None def set_undo_label(self,label): self.undolabel = label self.undolabel.set_sensitive(0) def set_redo_label(self,label): self.redolabel = label self.redolabel.set_sensitive(0) def load(self,name,callback): if self.person_map: self.close() self.env = db.DBEnv() self.env.set_cachesize(0,4*1024*1024) # 2MB flags = db.DB_CREATE|db.DB_INIT_MPOOL|db.DB_PRIVATE self.undolog = "%s.log" % name self.env.open(os.path.dirname(name), flags) name = os.path.basename(name) self.person_map = dbshelve.open(name, dbname="person", dbenv=self.env) self.family_map = dbshelve.open(name, dbname="family", dbenv=self.env) self.place_map = dbshelve.open(name, dbname="places", dbenv=self.env) self.source_map = dbshelve.open(name, dbname="sources",dbenv=self.env) self.media_map = dbshelve.open(name, dbname="media", dbenv=self.env) self.event_map = dbshelve.open(name, dbname="events", dbenv=self.env) self.metadata = dbshelve.open(name, dbname="meta", dbenv=self.env) self.surnames = db.DB(self.env) self.surnames.set_flags(db.DB_DUP) self.surnames.open(name, "surnames", db.DB_HASH, flags=db.DB_CREATE) self.id_trans = db.DB(self.env) self.id_trans.set_flags(db.DB_DUP) self.id_trans.open(name, "idtrans", db.DB_HASH, flags=db.DB_CREATE) self.eventnames = db.DB(self.env) self.eventnames.set_flags(db.DB_DUP) self.eventnames.open(name, "eventnames", db.DB_HASH, flags=db.DB_CREATE) self.person_map.associate(self.surnames, find_surname, db.DB_CREATE) self.person_map.associate(self.id_trans, find_idmap, db.DB_CREATE) self.event_map.associate(self.eventnames, find_eventname, db.DB_CREATE) self.undodb = db.DB() self.undodb.open(self.undolog, db.DB_RECNO, db.DB_CREATE) self.bookmarks = self.metadata.get('bookmarks') if self.bookmarks == None: self.bookmarks = [] return 1 def find_next_gramps_id(self): index = self.iprefix % self.pmap_index while self.id_trans.get(str(index)): self.pmap_index += 1 index = self.iprefix % self.pmap_index self.pmap_index += 1 return index def get_people_view_maps(self): if self.metadata: return (self.metadata.get('tp_iter'), self.metadata.get('tp_path'), self.metadata.get('p_iter'), self.metadata.get('p_path'), self.metadata.get('sname')) else: return (None,None,None,None,None) def set_people_view_maps(self,maps): if self.metadata: self.metadata['tp_iter'] = maps[0] self.metadata['tp_path'] = maps[1] self.metadata['p_iter'] = maps[2] self.metadata['p_path'] = maps[3] self.metadata['sname'] = maps[4] def close(self): self.person_map.close() self.family_map.close() self.place_map.close() self.source_map.close() self.media_map.close() self.event_map.close() self.metadata['bookmarks'] = self.bookmarks self.metadata.close() self.surnames.close() self.eventnames.close() self.id_trans.close() self.env.close() self.undodb.close() try: os.remove(self.undolog) except: pass self.person_map = None self.family_map = None self.place_map = None self.source_map = None self.media_map = None self.event_map = None self.surnames = None self.env = None self.metadata = None def is_open(self): return self.person_map != None def get_added_media_objects(self): return self.added_files def clear_added_media_objects(self): self.added_files = [] def get_number_of_people(self): return len(self.person_map) def get_person_keys(self): if self.person_map: return self.person_map.keys() else: return [] def get_family_keys(self): if self.family_map: return self.family_map.keys() else: return [] def sort_by_name(self,f,s): n1 = self.person_map.get(f)[2].sname n2 = self.person_map.get(s)[2].sname return cmp(n1,n2) def sort_person_keys(self): if self.person_map: keys = self.person_map.keys() keys.sort(self.sort_by_name) return keys else: return [] def get_person_display(self,key): data = self.person_map.get(key) if data[2] == Person.male: gender = const.male elif data[2] == Person.female: gender = const.female else: gender = const.unknown return [ data[3].get_name(), data[1], gender, data[7], data[6], data[3].get_sort_name(), data[7], data[6], GrampsCfg.get_display_surname()(data[3])] def commit_person(self,person,transaction): handle = person.get_handle() if transaction != None: old_data = self.person_map.get(handle) transaction.add(PERSON_KEY,handle,old_data) self.person_map.put(handle,person.serialize()) def commit_media_object(self,object,transaction): handle = str(object.get_handle()) if transaction != None: old_data = self.media_map.get(handle) transaction.add(MEDIA_KEY,handle,old_data) self.media_map.put(str(object.get_handle()),object.serialize()) def commit_source(self,source,transaction): handle = str(source.get_handle()) if transaction != None: old_data = self.source_map.get(handle) transaction.add(SOURCE_KEY,handle,old_data) self.source_map.put(str(source.get_handle()),source.serialize()) def commit_place(self,place,transaction): handle = str(place.get_handle()) if transaction != None: old_data = self.place_map.get(handle) transaction.add(PLACE_KEY,handle,old_data) self.place_map.put(str(place.get_handle()),place.serialize()) def commit_event(self,event,transaction): handle = str(event.get_handle()) if transaction != None: old_data = self.event_map.get(handle) transaction.add(EVENT_KEY,handle,old_data) self.event_map.put(str(event.get_handle()),event.serialize()) def commit_family(self,family,transaction): handle = str(family.get_handle()) if transaction != None: old_data = self.family_map.get(handle) transaction.add(FAMILY_KEY,handle,old_data) self.family_map.put(str(family.get_handle()),family.serialize()) def set_iprefix(self,val): if val: if _id_reg.search(val): self.iprefix = val else: self.iprefix = val + "%d" else: self.iprefix = "I%04d" def set_sprefix(self,val): if val: if _id_reg.search(val): self.sprefix = val else: self.sprefix = val + "%d" else: self.sprefix = "S%04d" def set_oprefix(self,val): if val: if _id_reg.search(val): self.oprefix = val else: self.oprefix = val + "%d" else: self.oprefix = "O%04d" def set_pprefix(self,val): if val: if _id_reg.search(val): self.pprefix = val else: self.pprefix = val + "%d" else: self.pprefix = "P%04d" def set_fprefix(self,val): if val: if _id_reg.search(val): self.fprefix = val else: self.fprefix = val + "%d" else: self.fprefix = "F%04d" def set_eprefix(self,val): if val: if _id_reg.search(val): self.eprefix = val else: self.eprefix = val + "%d" else: self.eprefix = "E%04d" def new(self): """initializes the GrampsDB to empty values""" self.undoindex = -1 self.translist = [None] * _UNDO_SIZE self.smap_index = 0 self.emap_index = 0 self.pmap_index = 0 self.fmap_index = 0 self.lmap_index = 0 self.omap_index = 0 self.default = None self.owner = Researcher() self.bookmarks = [] self.path = "" self.place2title = {} self.genderStats = GenderStats() def start_transaction(self,msg=""): return Transaction(msg,self.undodb) def add_transaction(self,transaction,msg): if not len(transaction): return transaction.set_description(msg) self.undoindex += 1 if self.undoindex == _UNDO_SIZE: self.translist = transaction[0:-1] + [ transaction ] else: self.translist[self.undoindex] = transaction if self.undolabel: self.undolabel.set_sensitive(1) label = self.undolabel.get_children()[0] label.set_text(_("_Undo %s") % transaction.get_description()) label.set_use_underline(1) def undo(self): if self.undoindex == -1: return transaction = self.translist[self.undoindex] self.undoindex -= 1 subitems = transaction.get_recnos() subitems.reverse() for record_id in subitems: (key, handle, data) = transaction.get_record(record_id) if key == PERSON_KEY: if data == None: del self.person_map[handle] else: self.person_map.put(handle,data) elif key == FAMILY_KEY: if data == None: del self.family_map[handle] else: self.family_map.put(handle,data) elif key == SOURCE_KEY: if data == None: del self.source_map[handle] else: self.source_map.put(handle,data) elif key == EVENT_KEY: if data == None: del self.event_map[handle] else: self.event_map.put(handle,data) elif key == PLACE_KEY: if data == None: del self.place_map[handle] else: self.place_map.put(handle,data) elif key == MEDIA_KEY: if data == None: del self.media_map[handle] else: self.media_map.put(handle,data) if self.undolabel: label = self.undolabel.get_children()[0] if self.undoindex == -1: label.set_text(_("_Undo")) self.undolabel.set_sensitive(0) else: transaction = self.translist[self.undoindex] label.set_text(_("_Undo %s") % transaction.get_description()) self.undolabel.set_sensitive(1) label.set_use_underline(1) def get_surnames(self): names = self.surnames.keys() a = {} for name in names: a[unicode(name)] = 1 vals = a.keys() vals.sort() return vals def get_eventnames(self): names = self.eventnames.keys() a = {} for name in names: a[unicode(name)] = 1 vals = a.keys() vals.sort() return vals def get_bookmarks(self): """returns the list of Person instances in the bookmarks""" return self.bookmarks def clean_bookmarks(self): """cleans up the bookmark list, removing empty slots""" new_bookmarks = [] for person_handle in self.bookmarks: new_bookmarks.append(person_handle) self.bookmarks = new_bookmarks def set_researcher(self,owner): """sets the information about the owner of the database""" self.owner.set(owner.get_name(),owner.get_address(),owner.get_city(), owner.get_state(),owner.get_country(), owner.get_postal_code(),owner.get_phone(),owner.get_email()) def get_researcher(self): """returns the Researcher instance, providing information about the owner of the database""" return self.owner def set_default_person(self,person): """sets the default Person to the passed instance""" # if (self.default): # self.default.set_ancestor(0) self.metadata['default'] = person.get_handle() # if person: # self.default.set_ancestor(1) def set_default_person_handle(self,handle): """sets the default Person to the passed instance""" self.metadata['default'] = handle def get_default_person(self): """returns the default Person of the database""" if self.metadata and self.metadata.has_key('default'): person = Person() handle = self.metadata['default'] data = self.person_map.get(handle) person.unserialize(data) return person return None def get_person(self,handle): """returns a Person from a GRAMPS's ID""" p = Person() data = self.person_map.get(handle) p.unserialize(data) return p def get_place_handle_map(self): """returns a map of gramps's IDs to Place instances""" return self.place_map def set_place_handle_map(self,map): """sets the map of gramps's IDs to Place instances""" self.place_map = map def get_family_handle(self,handle): """returns a map of gramps's IDs to Family instances""" return self.family_map.get(str(handle)) def get_save_path(self): """returns the save path of the file, or "" if one does not exist""" return self.path def set_save_path(self,path): """sets the save path for the database""" self.path = path def get_person_event_types(self): """returns a list of all Event types assocated with Person instances in the database""" return [] def get_person_attribute_types(self): """returns a list of all Attribute types assocated with Person instances in the database""" return [] def get_family_attribute_types(self): """returns a list of all Attribute types assocated with Family instances in the database""" return [] def get_family_event_types(self): """returns a list of all Event types assocated with Family instances in the database""" return [] def get_media_attribute_types(self): """returns a list of all Attribute types assocated with Media instances in the database""" return [] def get_place_handles(self): """returns a list of Place instances""" return self.place_map.keys() def get_family_relation_types(self): """returns a list of all relationship types assocated with Family instances in the database""" return [] def remove_person_handle(self,handle,transaction): # self.genderStats.uncount_person (self.person_map[handle]) if transaction != None: old_data = self.person_map.get(handle) transaction.add(PERSON_KEY,handle,old_data) self.person_map.delete(handle) def remove_source_handle(self,handle,transaction): if transaction != None: old_data = self.source_map.get(str(handle)) transaction.add(SOURCE_KEY,handle,old_data) self.source_map.delete(str(handle)) def remove_event_handle(self,handle,transaction): if transaction != None: old_data = self.event_map.get(str(handle)) transaction.add(EVENT_KEY,handle,old_data) self.event_map.delete(str(handle)) def add_person_as(self,person,trans): if trans != None: trans.add(PERSON_KEY, person.get_handle(),None) self.person_map.put(person.get_handle(),person.serialize()) # self.genderStats.count_person (person, self) return person.get_handle() def add_person(self,person,trans): """adds a Person to the database, assigning a gramps' ID""" person.set_gramps_id(self.find_next_gramps_id()) person.set_handle(Utils.create_id()) if trans != None: trans.add(PERSON_KEY, person.get_handle(),None) self.person_map.put(person.get_handle(),person.serialize()) self.genderStats.count_person (person, self) return person.get_handle() def has_person_handle(self,val): return self.person_map.get(val) def has_family_handle(self,val): return self.family_map.get(str(val)) def try_to_find_person_from_handle(self,val): """finds a Person in the database from the passed gramps' ID. If no such Person exists, a new Person is added to the database.""" data = self.person_map.get(val) if data: person = Person() person.unserialize(data) return person else: return None def try_to_find_person_from_gramps_id(self,val): """finds a Person in the database from the passed gramps' ID. If no such Person exists, a new Person is added to the database.""" data = self.id_trans.get(str(val)) if data: person = Person() person.unserialize(cPickle.loads(data)) return person else: return None def find_person_from_gramps_id(self,val,trans): """finds a Person in the database from the passed gramps' ID. If no such Person exists, a new Person is added to the database.""" person = Person() data = self.id_trans.get(str(val)) if data: person.unserialize(cPickle.loads(data)) else: intid = Utils.create_id() person.set_handle(intid) person.set_gramps_id(val) self.add_person_as(person,trans) return person def find_person_from_handle(self,val,trans): """finds a Person in the database from the passed gramps' ID. If no such Person exists, a new Person is added to the database.""" person = Person() data = self.person_map.get(val) if data: person.unserialize(data) else: person.set_handle(val) if trans != None: trans.add(PERSON_KEY, val, None) self.person_map.put(val, person.serialize()) # self.genderStats.count_person (person, self) return person def add_person_no_map(self,person,handle,trans): """adds a Person to the database if the gramps' ID is known""" person.set_handle(handle) if trans != None: trans.add(PERSON_KEY, handle, None) self.person_map.set(handle,person.serialize()) # self.genderStats.count_person (person, self) return handle def add_source(self,source,trans): """adds a Source instance to the database, assigning it a gramps' ID number""" index = self.sprefix % self.smap_index while self.source_map.get(str(index)): self.smap_index = self.smap_index + 1 index = self.sprefix % self.smap_index source.set_handle(index) if trans != None: trans.add(SOURCE_KEY,index,None) self.source_map.put(str(index),source.serialize()) self.smap_index = self.smap_index + 1 return index def add_event(self,event,trans): """adds a Event instance to the database, assigning it a gramps' ID number""" index = self.eprefix % self.emap_index while self.event_map.get(str(index)): self.emap_index += 1 index = self.eprefix % self.emap_index event.set_handle(index) if trans != None: trans.add(EVENT_KEY,index,None) self.event_map.put(str(index),event.serialize()) self.emap_index += 1 return index def add_source_no_map(self,source,index,trans): """adds a Source to the database if the gramps' ID is known""" source.set_handle(index) if trans != None: trans.add(SOURCE_KEY,index,None) self.source_map.put(str(index),source.serialize()) self.smap_index = self.smap_index + 1 return index def add_event_no_map(self,event,index,trans): """adds a Source to the database if the gramps' ID is known""" event.set_handle(index) if trans != None: trans.add(EVENT_KEY,index,None) self.event_map.put(str(index),event.serialize()) self.emap_index += 1 return index def find_source(self,handle,map,trans): """finds a Source in the database using the handle and map variables to translate between the external ID and gramps' internal ID. If no such Source exists, a new Source instance is created. handle - external ID number map - map build by find_source of external to gramp's IDs""" if map.has_key(handle): data = self.source_map.get(str(map[handle])) source = Source() source.unserialize(data) else: source = Source() map[handle] = self.add_source(source,trans) return source def find_event(self,handle,map,trans): """finds a Event in the database using the handle and map variables to translate between the external ID and gramps' internal ID. If no such Event exists, a new Event instance is created. handle - external ID number map - map build by find_source of external to gramp's IDs""" event = Event() if map.has_key(handle): data = self.event_map.get(str(map[handle])) event.unserialize(data) else: map[handle] = self.add_event(event,trans) return event def try_to_find_source_from_handle(self,val): """finds a Source in the database from the passed gramps' ID. If no such Source exists, None is returned.""" data = self.source_map.get(str(val)) if data: source = Source() source.unserialize(data) return source else: return None def find_source_from_handle(self,val,trans): """finds a Source in the database from the passed gramps' ID. If no such Source exists, a new Source is added to the database.""" source = Source() if self.source_map.get(str(val)): source.unserialize(self.source_map.get(str(val))) else: self.add_source_no_map(source,val,trans) return source def find_event_from_handle(self,val): """finds a Family in the database from the passed gramps' ID. If no such Family exists, a new Family is added to the database.""" data = self.event_map.get(str(val)) if data: event = Event() event.unserialize(data) return event else: return None def add_object(self,object,trans): """adds an Object instance to the database, assigning it a gramps' ID number""" index = self.oprefix % self.omap_index while self.media_map.get(str(index)): self.omap_index = self.omap_index + 1 index = self.oprefix % self.omap_index object.set_handle(index) if trans != None: trans.add(MEDIA_KEY,index,None) self.media_map.put(str(index),object.serialize()) self.omap_index = self.omap_index + 1 self.added_files.append(object) return index def find_object_no_conflicts(self,handle,map,trans): """finds an Object in the database using the handle and map variables to translate between the external ID and gramps' internal ID. If no such Object exists, a new Object instance is created. handle - external ID number map - map build by find_object of external to gramp's IDs""" handle = str(handle) object = MediaObject() if map.has_key(handle): object.unserialize(self.media_map.get(str(map[handle]))) else: if self.media_map.get(str(handle)): map[handle] = self.add_object(object,trans) else: map[handle] = self.add_object_no_map(object,handle,trans) return object def add_object_no_map(self,object,index,trans): """adds an Object to the database if the gramps' ID is known""" index = str(index) object.set_handle(index) if trans != None: trans.add(MEDIA_KEY,index,None) self.media_map.put(str(index),object.serialize()) self.omap_index = self.omap_index + 1 self.added_files.append(object) return index def try_to_find_object_from_handle(self,handle): """finds an Object in the database from the passed gramps' ID. If no such Object exists, None is returned.""" data = self.media_map.get(str(handle)) if data: mobject = MediaObject() mobject.unserialize(data) return mobject else: return None def find_object_from_handle(self,handle,trans): """finds an Object in the database from the passed gramps' ID. If no such Object exists, a new Object is added to the database.""" object = MediaObject() if self.media_map.get(str(handle)): object.unserialize(self.media_map.get(str(handle))) else: self.add_object_no_map(object,handle,trans) return object def has_object_handle(self,handle): """finds an Object in the database from the passed gramps' ID. If no such Source exists, a new Source is added to the database.""" return self.media_map.get(str(handle)) != None def add_place(self,place,trans): """adds a Place instance to the database, assigning it a gramps' ID number""" index = self.pprefix % self.lmap_index while self.place_map.get(str(index)): self.lmap_index = self.lmap_index + 1 index = self.pprefix % self.lmap_index place.set_handle(index) if trans != None: trans.add(PLACE_KEY,index,None) self.place_map.put(str(index),place.serialize()) self.lmap_index = self.lmap_index + 1 return index def remove_object(self,handle,transaction): if transaction != None: old_data = self.media_map.get(str(handle)) transaction.add(MEDIA_KEY,handle,old_data) self.media_map.delete(str(handle)) def remove_place(self,handle,transaction): if transaction != None: old_data = self.place_map.get(str(handle)) transaction.add(PLACE_KEY,handle,old_data) self.place_map.delete(str(handle)) def add_place_as(self,place,trans): if trans != None: trans.add(PLACE_KEY,place.get_handle(),None) self.place_map.put(str(place.get_handle()),place.serialize()) return place.get_handle() def find_place_no_conflicts(self,handle,map,trans): """finds a Place in the database using the handle and map variables to translate between the external ID and gramps' internal ID. If no such Place exists, a new Place instance is created. handle - external ID number map - map build by findPlace of external to gramp's IDs""" if map.has_key(str(handle)): place = Place() data = self.place_map[str(map[handle])] place.unserialize(data) else: place = Place() if self.place_map.has_key(str(handle)): map[handle] = self.add_place(place,trans) else: place.set_handle(str(handle)) map[str(handle)] = self.add_place_as(place,trans) self.place_map.put(str(handle),place.serialize()) return place def add_place_no_map(self,place,index,trans): """adds a Place to the database if the gramps' ID is known""" index = str(index) place.set_handle(index) if trans != None: trans.add(PLACE_KEY,index,None) self.place_map.put(str(index), place.serialize()) self.lmap_index = self.lmap_index + 1 return index def find_place_from_handle(self,handle,trans): """finds a Place in the database from the passed gramps' ID. If no such Place exists, a new Place is added to the database.""" data = self.place_map.get(str(handle)) place = Place() if not data: place.handle = handle if trans != None: trans.add(PLACE_KEY,handle,None) self.place_map.put(str(handle),place.serialize()) self.lmap_index = self.lmap_index + 1 else: place.unserialize(data) return place def try_to_find_place_from_handle(self,handle): """finds a Place in the database from the passed gramps' ID. If no such Place exists, None is returned.""" data = self.place_map.get(str(handle)) if data: place = Place() place.unserialize(data) return place else: return None def sortbyplace(self,f,s): return cmp(self.placesortmap[f], self.placesortmap[s]) def sortbysource(self,f,s): fp = self.source_map[f][1].upper() sp = self.source_map[s][1].upper() return cmp(fp,sp) def sortbymedia(self,f,s): fp = self.media_map[f][3].upper() sp = self.media_map[s][3].upper() return cmp(fp,sp) def sort_place_keys(self): if self.place_map: self.placesortmap = {} for key in self.place_map.keys(): self.placesortmap[key] = self.place_map[key][1].upper() keys = self.placesortmap.keys() keys.sort(self.sortbyplace) del self.placesortmap return keys return [] def sort_media_keys(self): if self.media_map: keys = self.media_map.keys() keys.sort(self.sortbymedia) return keys else: return [] def sort_source_keys(self): if self.source_map: keys = self.source_map.keys() keys.sort(self.sortbysource) return keys else: return [] def get_place_handle_keys(self): if self.place_map: return self.place_map.keys() else: return [] def get_place_handle(self,key): place = Place() place.unserialize(self.place_map.get(str(key))) return place def get_place_display(self,key): # fix this up better place = Place() place.unserialize(self.place_map[str(key)]) return place.get_display_info() def get_source_keys(self): if self.source_map: return self.source_map.keys() return [] def get_object_keys(self): if self.media_map: return self.media_map.keys() return [] def get_event_keys(self): if self.event_map: return self.event_map.keys() return [] def sortbysource(self,f,s): f1 = self.source_map[f][1].upper() s1 = self.source_map[s][1].upper() return cmp(f1,s1) def set_source_keys(self): keys = self.source_map.keys() if type(keys) == type([]): keys.sort(self.sortbyplace) return keys def get_source_display(self,key): source = Source() source.unserialize(self.source_map.get(str(key))) return source.get_display_info() def get_source(self,key): source = Source() source.unserialize(self.source_map[key]) return source def build_source_display(self,nkey,okey=None): pass def new_family(self,trans): """adds a Family to the database, assigning a gramps' ID""" index = self.fprefix % self.fmap_index while self.family_map.get(str(index)): self.fmap_index = self.fmap_index + 1 index = self.fprefix % self.fmap_index self.fmap_index = self.fmap_index + 1 family = Family() family.set_handle(unicode(index)) if trans != None: trans.add(FAMILY_KEY, index, None) self.family_map.put(str(index),family.serialize()) return family def new_family_no_map(self,handle,trans): """finds a Family in the database from the passed gramps' ID. If no such Family exists, a new Family is added to the database.""" family = Family() family.set_handle(handle) if trans != None: trans.add(FAMILY_KEY, handle, None) self.family_map.put(str(handle),family.serialize()) self.fmap_index = self.fmap_index + 1 return family def find_family_with_map(self,handle,map,trans): """finds a Family in the database using the handle and map variables to translate between the external ID and gramps' internal ID. If no such Family exists, a new Family instance is created. handle - external ID number map - map build by find_family_with_map of external to gramp's IDs""" if map.has_key(handle): family = Family() data = self.family_map.get(str(map[handle])) family.unserialize(data) else: family = self.new_family(trans) map[handle] = family.get_handle() return family def find_family_no_map(self,val,trans): """finds a Family in the database from the passed gramps' ID. If no such Family exists, a new Family is added to the database.""" family = Family() data = self.family_map.get(str(val)) if data: family.unserialize(data) else: family.handle = val if trans: trans.add(FAMILY_KEY,val,None) self.family_map.put(str(val),family.serialize()) self.fmap_index = self.fmap_index + 1 return family def find_family_from_handle(self,val): """finds a Family in the database from the passed gramps' ID. If no such Family exists, a new Family is added to the database.""" data = self.family_map.get(str(val)) if data: family = Family() family.unserialize(data) return family else: return None def delete_family(self,family_handle,trans): """deletes the Family instance from the database""" if self.family_map.get(str(family_handle)): if trans != None: old_data = self.family_map.get(str(family_handle)) trans.add(FAMILY_KEY,family_handle,old_data) self.family_map.delete(str(family_handle)) def find_family_no_conflicts(self,handle,map,trans): """finds a Family in the database using the handle and map variables to translate between the external ID and gramps' internal ID. If no such Family exists, a new Family instance is created. handle - external ID number map - map build by findFamily of external to gramp's IDs""" if map.has_key(str(handle)): family = Family() family.unserialize(self.family_map.get(str(map[str(handle)]))) else: if self.family_map.has_key(str(handle)): family = self.new_family(trans) else: family = self.new_family_no_map(str(handle),trans) map[handle] = family.get_handle() return family def find_source_no_conflicts(self,handle,map,trans): """finds a Source in the database using the handle and map variables to translate between the external ID and gramps' internal ID. If no such Source exists, a new Source instance is created. handle - external ID number map - map build by findSource of external to gramp's IDs""" source = Source() if map.has_key(handle): source.unserialize(self.source_map.get(str(map[handle]))) else: if self.source_map.get(str(handle)): map[handle] = self.add_source(source,trans) else: map[handle] = self.add_source(source,trans) return source def set_column_order(self,list): if self.metadata != None: self.metadata['columns'] = list def set_place_column_order(self,list): if self.metadata != None: self.metadata['place_columns'] = list def set_source_column_order(self,list): if self.metadata != None: self.metadata['source_columns'] = list def set_media_column_order(self,list): if self.metadata != None: self.metadata['media_columns'] = list def get_column_order(self): default = [(1,1),(1,2),(1,3),(0,4),(1,5),(0,6),(0,7)] if self.metadata == None: return default else: cols = self.metadata.get('columns',default) if len(cols) != len(default): return cols + default[len(cols):] else: return cols def get_place_column_order(self): default = [(1,1),(1,2),(0,3),(1,4),(0,5),(1,6),(0,7),(0,8)] if self.metadata == None: return default else: cols = self.metadata.get('place_columns',default) if len(cols) != len(default): return cols + default[len(cols):] else: return cols def get_source_column_order(self): default = [(1,1),(1,2),(1,3),(0,4)] if self.metadata == None: return default else: cols = self.metadata.get('source_columns',default) if len(cols) != len(default): return cols + default[len(cols):] else: return cols def get_media_column_order(self): default = [(1,1),(1,2),(1,3)] if self.metadata == None: return default else: cols = self.metadata.get('meda_columns',default) if len(cols) != len(default): return cols + default[len(cols):] else: return cols #------------------------------------------------------------------------- # # Transaction # #------------------------------------------------------------------------- class Transaction: def __init__(self,msg,db): self.db = db self.first = None self.last = None def get_description(self): return self.msg def set_description(self,msg): self.msg = msg def add(self, type, handle, data): self.last = self.db.append(cPickle.dumps((type,handle,data),1)) if self.first == None: self.first = self.last def get_recnos(self): return range (self.first, self.last+1) def get_record(self,id): return cPickle.loads(self.db[id]) def __len__(self): if self.last and self.first: return self.last - self.first + 1 return 0 def display(self): for record in self.get_recnos(): (key,handle,val) = self.get_record(record) if key == PERSON_KEY: if val: print "PERSON %s change" % handle else: print "PERSON %s remove" % handle elif key == FAMILY_KEY: if val: print "FAMILY %s change" % handle else: print "FAMILY %s remove" % handle elif key == EVENT_KEY: if val: print "EVENT %s change" % handle else: print "EVENT %s remove" % handle elif key == SOURCE_KEY: if val: print "SOURCE %s change" % handle else: print "SOURCE %s remove" % handle elif key == MEDIA_KEY: if val: print "MEDIA %s change" % handle else: print "MEDIA %s remove" % handle elif key == PLACE_KEY: if val: print "PLACE %s change" % handle else: print "PLACE %s remove" % handle