diff --git a/src/gen/db/read.py b/src/gen/db/read.py index 665f5449d..44316fa21 100644 --- a/src/gen/db/read.py +++ b/src/gen/db/read.py @@ -43,6 +43,7 @@ if config.get('preferences.use-bsddb3'): else: from bsddb import db from gen.ggettext import gettext as _ +import re import logging @@ -371,14 +372,15 @@ class DbBsddbRead(DbReadBase, Callback): def set_prefixes(self, person, media, family, source, place, event, repository, note): - self.person_prefix = self._validated_id_prefix(person, 'I') - self.mediaobject_prefix = self._validated_id_prefix(media, 'M') - self.family_prefix = self._validated_id_prefix(family, 'F') - self.source_prefix = self._validated_id_prefix(source, 'S') - self.place_prefix = self._validated_id_prefix(place, 'P') - self.event_prefix = self._validated_id_prefix(event, 'E') - self.repository_prefix = self._validated_id_prefix(repository, 'R') - self.note_prefix = self._validated_id_prefix(note, 'N') + self.set_person_id_prefix(person) + self.set_object_id_prefix(media) + self.set_family_id_prefix(family) + self.set_source_id_prefix(source) + self.set_place_id_prefix(place) + self.set_event_id_prefix(event) + self.set_repository_id_prefix(repository) + self.set_note_id_prefix(note) + #self.set_tag_id_prefix(tag) def version_supported(self): """Return True when the file has a supported version.""" @@ -1063,6 +1065,38 @@ class DbBsddbRead(DbReadBase, Callback): prefix_var = default+"%04d" # not a string or empty string return prefix_var + @staticmethod + def __id2user_format(id_pattern): + """ + Return a method that accepts a Gramps ID and adjusts it to the users + format. + """ + pattern_match = re.match(r"(.*)%[0 ](\d+)[diu]$", id_pattern) + if pattern_match: + str_prefix = pattern_match.group(1) + nr_width = pattern_match.group(2) + def closure_func(gramps_id): + if gramps_id.startswith(str_prefix): + id_number = gramps_id[len(str_prefix):] + if id_number.isdigit(): + id_value = int(id_number, 10) + if len(str(id_value)) > nr_width: + # The ID to be imported is too large to fit in the + # users format. For now just create a new ID, + # because that is also what happens with IDs that + # are identical to IDs already in the database. If + # the problem of colliding import and already + # present IDs is solved the code here also needs + # some solution. + gramps_id = id_pattern % 1 + else: + gramps_id = id_pattern % id_value + return gramps_id + else: + def closure_func(gramps_id): + return gramps_id + return closure_func + def set_person_id_prefix(self, val): """ Set the naming template for GRAMPS Person ID values. @@ -1072,6 +1106,7 @@ class DbBsddbRead(DbReadBase, Callback): such as I%d or I%04d. """ self.person_prefix = self._validated_id_prefix(val, "I") + self.id2user_format = self.__id2user_format(self.person_prefix) def set_source_id_prefix(self, val): """ @@ -1082,6 +1117,7 @@ class DbBsddbRead(DbReadBase, Callback): such as S%d or S%04d. """ self.source_prefix = self._validated_id_prefix(val, "S") + self.sid2user_format = self.__id2user_format(self.source_prefix) def set_object_id_prefix(self, val): """ @@ -1092,6 +1128,7 @@ class DbBsddbRead(DbReadBase, Callback): such as O%d or O%04d. """ self.mediaobject_prefix = self._validated_id_prefix(val, "O") + self.oid2user_format = self.__id2user_format(self.mediaobject_prefix) def set_place_id_prefix(self, val): """ @@ -1102,6 +1139,7 @@ class DbBsddbRead(DbReadBase, Callback): such as P%d or P%04d. """ self.place_prefix = self._validated_id_prefix(val, "P") + self.pid2user_format = self.__id2user_format(self.place_prefix) def set_family_id_prefix(self, val): """ @@ -1111,6 +1149,7 @@ class DbBsddbRead(DbReadBase, Callback): or F%04d. """ self.family_prefix = self._validated_id_prefix(val, "F") + self.fid2user_format = self.__id2user_format(self.family_prefix) def set_event_id_prefix(self, val): """ @@ -1121,6 +1160,7 @@ class DbBsddbRead(DbReadBase, Callback): such as E%d or E%04d. """ self.event_prefix = self._validated_id_prefix(val, "E") + self.eid2user_format = self.__id2user_format(self.event_prefix) def set_repository_id_prefix(self, val): """ @@ -1131,6 +1171,7 @@ class DbBsddbRead(DbReadBase, Callback): such as R%d or R%04d. """ self.repository_prefix = self._validated_id_prefix(val, "R") + self.rid2user_format = self.__id2user_format(self.repository_prefix) def set_note_id_prefix(self, val): """ @@ -1141,6 +1182,7 @@ class DbBsddbRead(DbReadBase, Callback): such as N%d or N%04d. """ self.note_prefix = self._validated_id_prefix(val, "N") + self.nid2user_format = self.__id2user_format(self.note_prefix) def set_undo_callback(self, callback): """ diff --git a/src/plugins/import/ImportCsv.py b/src/plugins/import/ImportCsv.py index 6e2d5c9bb..a701ea6d1 100644 --- a/src/plugins/import/ImportCsv.py +++ b/src/plugins/import/ImportCsv.py @@ -397,7 +397,7 @@ class CSVParser(object): if id is None: return None if type == "family": if id.startswith("[") and id.endswith("]"): - id = id[1:-1] + id = self.db.fid2user_format(id[1:-1]) db_lookup = self.db.get_family_from_gramps_id(id) if db_lookup is None: return self.lookup(type, id) @@ -409,7 +409,7 @@ class CSVParser(object): return None elif type == "person": if id.startswith("[") and id.endswith("]"): - id = id[1:-1] + id = self.db.id2user_format(id[1:-1]) db_lookup = self.db.get_person_from_gramps_id(id) if db_lookup is None: return self.lookup(type, id) @@ -428,8 +428,10 @@ class CSVParser(object): id = id[1:-1] #return # do not store gramps people; go look them up if type == "person": + id = self.db.id2user_format(id) self.pref[id.lower()] = object elif type == "family": + id = self.db.fid2user_format(id) self.fref[id.lower()] = object else: LOG.warn("invalid storeup type in CSV import: '%s'" % type) @@ -701,7 +703,7 @@ class CSVParser(object): person.gramps_id = grampsid elif person_ref is not None: if person_ref.startswith("[") and person_ref.endswith("]"): - person.gramps_id = person_ref[1:-1] + person.gramps_id = self.db.id2user_format(person_ref[1:-1]) if person.get_gender() == gen.lib.Person.UNKNOWN and gender is not None: gender = gender.lower() if gender == gender_map[gen.lib.Person.MALE].lower(): @@ -814,7 +816,8 @@ class CSVParser(object): # if a gramps_id and exists: LOG.debug("get_or_create_family") if family_ref.startswith("[") and family_ref.endswith("]"): - family = self.db.get_family_from_gramps_id(family_ref[1:-1]) + id = self.db.fid2user_format(family_ref[1:-1]) + family = self.db.get_family_from_gramps_id(id) if family: # don't delete, only add fam_husband_handle = family.get_father_handle() @@ -833,7 +836,8 @@ class CSVParser(object): family = gen.lib.Family() # was marked with a gramps_id, but didn't exist, so we'll use it: if family_ref.startswith("[") and family_ref.endswith("]"): - family.set_gramps_id(family_ref[1:-1]) + id = self.db.fid2user_format(family_ref[1:-1]) + family.set_gramps_id(id) # add it: family.set_handle(self.db.create_id()) if husband: diff --git a/src/plugins/import/ImportXml.py b/src/plugins/import/ImportXml.py index 0d969fa41..0cd2d1b10 100644 --- a/src/plugins/import/ImportXml.py +++ b/src/plugins/import/ImportXml.py @@ -744,6 +744,7 @@ class GrampsParser(UpdateCallback): return note, new def map_gid(self, gramps_id): + gramps_id = self.db.id2user_format(gramps_id) if not self.idswap.get(gramps_id): if self.db.has_gramps_id(PERSON_KEY, gramps_id): self.idswap[gramps_id] = self.db.find_next_person_gramps_id() @@ -752,6 +753,7 @@ class GrampsParser(UpdateCallback): return self.idswap[gramps_id] def map_fid(self, gramps_id): + gramps_id = self.db.fid2user_format(gramps_id) if not self.fidswap.get(gramps_id): if self.db.has_gramps_id(FAMILY_KEY, gramps_id): self.fidswap[gramps_id] = self.db.find_next_family_gramps_id() @@ -760,6 +762,7 @@ class GrampsParser(UpdateCallback): return self.fidswap[gramps_id] def map_eid(self, gramps_id): + gramps_id = self.db.eid2user_format(gramps_id) if not self.eidswap.get(gramps_id): if self.db.has_gramps_id(EVENT_KEY, gramps_id): self.eidswap[gramps_id] = self.db.find_next_event_gramps_id() @@ -768,6 +771,7 @@ class GrampsParser(UpdateCallback): return self.eidswap[gramps_id] def map_pid(self, gramps_id): + gramps_id = self.db.pid2user_format(gramps_id) if not self.pidswap.get(gramps_id): if self.db.has_gramps_id(PLACE_KEY, gramps_id): self.pidswap[gramps_id] = self.db.find_next_place_gramps_id() @@ -776,6 +780,7 @@ class GrampsParser(UpdateCallback): return self.pidswap[gramps_id] def map_sid(self, gramps_id): + gramps_id = self.db.sid2user_format(gramps_id) if not self.sidswap.get(gramps_id): if self.db.has_gramps_id(SOURCE_KEY, gramps_id): self.sidswap[gramps_id] = self.db.find_next_source_gramps_id() @@ -784,6 +789,7 @@ class GrampsParser(UpdateCallback): return self.sidswap[gramps_id] def map_oid(self, gramps_id): + gramps_id = self.db.oid2user_format(gramps_id) if not self.oidswap.get(gramps_id): if self.db.has_gramps_id(MEDIA_KEY, gramps_id): self.oidswap[gramps_id] = self.db.find_next_object_gramps_id() @@ -792,6 +798,7 @@ class GrampsParser(UpdateCallback): return self.oidswap[gramps_id] def map_rid(self, gramps_id): + gramps_id = self.db.rid2user_format(gramps_id) if not self.ridswap.get(gramps_id): if self.db.has_gramps_id(REPOSITORY_KEY, gramps_id): self.ridswap[gramps_id] = self.db.find_next_repository_gramps_id() @@ -800,6 +807,7 @@ class GrampsParser(UpdateCallback): return self.ridswap[gramps_id] def map_nid(self, gramps_id): + gramps_id = self.db.nid2user_format(gramps_id) if not self.nidswap.get(gramps_id): if self.db.has_gramps_id(NOTE_KEY, gramps_id): self.nidswap[gramps_id] = self.db.find_next_note_gramps_id() diff --git a/src/plugins/lib/libgedcom.py b/src/plugins/lib/libgedcom.py index 0c29aa464..08e6add6c 100644 --- a/src/plugins/lib/libgedcom.py +++ b/src/plugins/lib/libgedcom.py @@ -1619,10 +1619,11 @@ class IdFinder(object): #------------------------------------------------------------------------- class IdMapper(object): - def __init__(self, trans, find_next, translate): + def __init__(self, trans, find_next, id2user_format, translate): self.translate = translate self.trans = trans self.find_next = find_next + self.id2user_format = id2user_format self.swap = {} def __getitem__(self, gid): @@ -1635,6 +1636,7 @@ class IdMapper(object): temp = gid.strip() if len(temp) > 1 and temp[0] == '@' and temp[-1] == '@': temp = temp[1:-1] + temp = self.id2user_format(temp) return temp def no_translate(self, gid): @@ -1746,26 +1748,32 @@ class GedcomParser(UpdateCallback): self.pid_map = IdMapper( self.dbase.id_trans, self.dbase.find_next_person_gramps_id, + self.dbase.id2user_format, self.dbase.get_number_of_people()) self.fid_map = IdMapper( self.dbase.fid_trans, self.dbase.find_next_family_gramps_id, + self.dbase.fid2user_format, self.dbase.get_number_of_families()) self.sid_map = IdMapper( self.dbase.sid_trans, self.dbase.find_next_source_gramps_id, + self.dbase.sid2user_format, self.dbase.get_number_of_sources()) self.oid_map = IdMapper( self.dbase.oid_trans, self.dbase.find_next_object_gramps_id, + self.dbase.oid2user_format, self.dbase.get_number_of_media_objects()) self.rid_map = IdMapper( self.dbase.rid_trans, self.dbase.find_next_repository_gramps_id, + self.dbase.rid2user_format, self.dbase.get_number_of_repositories()) self.nid_map = IdMapper( self.dbase.nid_trans, self.dbase.find_next_note_gramps_id, + self.dbase.nid2user_format, self.dbase.get_number_of_notes()) self.gid2id = {}