def __execute(self, family_merger, trans): """ Merges two persons into a single person; trans is compulsory. """ new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() self.phoenix.merge(self.titanic) self.database.commit_person(self.phoenix, trans) for (dummy, person_handle) in self.database.find_backlink_handles( old_handle, ['Person']): person = self.database.get_person_from_handle(person_handle) assert person.has_handle_reference('Person', old_handle) person.replace_handle_reference('Person', old_handle, new_handle) if person_handle != old_handle: self.database.commit_person(person, trans) for family_handle in self.phoenix.get_parent_family_handle_list(): family = self.database.get_family_from_handle(family_handle) if family.has_handle_reference('Person', old_handle): family.replace_handle_reference('Person', old_handle, new_handle) self.database.commit_family(family, trans) family_merge_guard = False parent_list = [] parent_list_orig = [] family_handle_list = self.phoenix.get_family_handle_list()[:] for family_handle in family_handle_list: family = self.database.get_family_from_handle(family_handle) parents = (family.get_father_handle(), family.get_mother_handle()) parent_list_orig.append(parents) if family.has_handle_reference('Person', old_handle): if family_merger and parent_list_orig.count(parents) > 1: raise MergeError( _("A person with multiple relations with " "the same spouse is about to be merged. This is beyond " "the capabilities of the merge routine. The merge is " "aborted.")) family.replace_handle_reference('Person', old_handle, new_handle) parents = (family.get_father_handle(), family.get_mother_handle()) # prune means merging families in this case. if family_merger and parents in parent_list: # also merge when father_handle or mother_handle == None! if family_merge_guard: raise MergeError( _("Multiple families get merged. " "This is unusual, the merge is aborted.")) idx = parent_list.index(parents) main_family_handle = family_handle_list[idx] self.merge_families(main_family_handle, family, trans) family_merge_guard = True continue self.database.commit_family(family, trans) parent_list.append(parents) self.database.remove_person(old_handle, trans)
def merge_person(self, phoenix_person, titanic_person, parent, trans): """ Merge two persons even if they are None; no families are merged! """ new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() if parent == 'father': swapped = self.father_swapped family_add_person_handle = ( (self.phoenix if swapped else self.titanic).set_father_handle) elif parent == 'mother': swapped = self.mother_swapped family_add_person_handle = ( (self.phoenix if swapped else self.titanic).set_mother_handle) else: raise ValueError(_("A parent should be a father or mother.")) if phoenix_person is None: if titanic_person is not None: raise MergeError("""When merging people where one person """ """doesn't exist, that "person" must be the person that """ """will be deleted from the database.""") return elif titanic_person is None: if swapped: if any(childref.get_reference_handle() == phoenix_person.get_handle() for childref in self.phoenix.get_child_ref_list()): raise MergeError(_("A parent and child cannot be merged. " "To merge these people, you must first break the " "relationship between them.")) phoenix_person.add_family_handle(new_handle) family_add_person_handle(phoenix_person.get_handle()) self.database.commit_family(self.phoenix, trans) else: if any(childref.get_reference_handle() == phoenix_person.get_handle() for childref in self.titanic.get_child_ref_list()): raise MergeError(_("A parent and child cannot be merged. " "To merge these people, you must first break the " "relationship between them.")) phoenix_person.add_family_handle(old_handle) family_add_person_handle(phoenix_person.get_handle()) self.database.commit_family(self.titanic, trans) self.database.commit_person(phoenix_person, trans) else: query = MergePersonQuery(self.database, phoenix_person, titanic_person) query.execute(family_merger=False, trans=trans)
def __init__(self, database, phoenix, titanic): self.database = database self.phoenix = phoenix self.titanic = titanic if self.check_for_spouse(self.phoenix, self.titanic): raise MergeError( _("Spouses cannot be merged. To merge these " "people, you must first break the relationship between them." )) if self.check_for_child(self.phoenix, self.titanic): raise MergeError( _("A parent and child cannot be merged. To merge " "these people, you must first break the relationship between " "them."))
def execute(self): """ Merges to places into a single place. """ new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() self.phoenix.merge(self.titanic) with DbTxn(_("Merge Places"), self.database) as trans: self.database.commit_place(self.phoenix, trans) for (class_name, handle) in self.database.find_backlink_handles(old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) assert (person.has_handle_reference('Place', old_handle)) person.replace_handle_reference('Place', old_handle, new_handle) self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) assert (family.has_handle_reference('Place', old_handle)) family.replace_handle_reference('Place', old_handle, new_handle) self.database.commit_family(family, trans) elif class_name == Event.__name__: event = self.database.get_event_from_handle(handle) assert (event.has_handle_reference('Place', old_handle)) event.replace_handle_reference('Place', old_handle, new_handle) self.database.commit_event(event, trans) else: raise MergeError("Encounter an object of type %s that has " "a place reference." % class_name) self.database.remove_place(old_handle, trans)
def execute(self): """ Merges to citations into a single citation. """ new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() self.phoenix.merge(self.titanic) with DbTxn(_("Merge Citation"), self.database) as trans: self.database.commit_citation(self.phoenix, trans) for (class_name, handle) in self.database.find_backlink_handles( old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) assert(person.has_citation_reference(old_handle)) person.replace_citation_references(old_handle, new_handle) self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) assert(family.has_citation_reference(old_handle)) family.replace_citation_references(old_handle, new_handle) self.database.commit_family(family, trans) elif class_name == Event.__name__: event = self.database.get_event_from_handle(handle) assert(event.has_citation_reference(old_handle)) event.replace_citation_references(old_handle, new_handle) self.database.commit_event(event, trans) elif class_name == Place.__name__: place = self.database.get_place_from_handle(handle) assert(place.has_citation_reference(old_handle)) place.replace_citation_references(old_handle, new_handle) self.database.commit_place(place, trans) elif class_name == MediaObject.__name__: obj = self.database.get_object_from_handle(handle) assert(obj.has_citation_reference(old_handle)) obj.replace_citation_references(old_handle, new_handle) self.database.commit_media_object(obj, trans) elif class_name == Repository.__name__: repository = self.database.get_repository_from_handle(handle) assert(repository.has_citation_reference(old_handle)) repository.replace_citation_references(old_handle, new_handle) self.database.commit_repository(repository, trans) elif class_name == Citation.__name__: citation = self.database.get_citation_from_handle(handle) assert(citation.has_citation_reference(old_handle)) citation.replace_citation_references(old_handle, new_handle) self.database.commit_citation(citation, trans) elif class_name == Source.__name__: source = self.database.get_source_from_handle(handle) assert(source.has_citation_reference(old_handle)) source.replace_citation_references(old_handle, new_handle) self.database.commit_source(source, trans) else: raise MergeError("Encounter an object of type %s that has " "a citation reference." % class_name) self.database.remove_citation(old_handle, trans)
def execute(self): """ Merges two events into a single event. """ new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() self.phoenix.merge(self.titanic) with DbTxn(_("Merge Event Objects"), self.database) as trans: self.database.commit_event(self.phoenix, trans) for (class_name, handle) in self.database.find_backlink_handles(old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) assert (person.has_handle_reference("Event", old_handle)) bri = person.birth_ref_index dri = person.death_ref_index person.replace_handle_reference("Event", old_handle, new_handle) if person.birth_ref_index != bri and \ person.birth_ref_index == -1: for index, ref in enumerate( person.get_event_ref_list()): event = self.database.get_event_from_handle( ref.ref) if event.type.is_birth() and ref.role.is_primary(): person.birth_ref_index = index break if person.death_ref_index != dri and \ person.death_ref_index == -1: for index, ref in enumerate( person.get_event_ref_list()): event = self.database.get_event_from_handle( ref.ref) if event.type.is_death() and ref.role.is_primary(): person.death_ref_index = index break self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) assert (family.has_handle_reference("Event", old_handle)) family.replace_handle_reference("Event", old_handle, new_handle) self.database.commit_family(family, trans) else: raise MergeError("Encounter an object of type %s that has " "an event reference." % class_name) self.database.remove_event(old_handle, trans)
def execute(self): """ Merges two repositories into a single repository. """ new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() self.phoenix.merge(self.titanic) with DbTxn(_("Merge Repositories"), self.database) as trans: self.database.commit_repository(self.phoenix, trans) for (class_name, handle) in self.database.find_backlink_handles( old_handle): if class_name == Source.__name__: source = self.database.get_source_from_handle(handle) assert source.has_handle_reference('Repository', old_handle) source.replace_repo_references(old_handle, new_handle) self.database.commit_source(source, trans) else: raise MergeError("Encounter an object of type %s that has " "a repository reference." % class_name) self.database.remove_repository(old_handle, trans)
def execute(self): """ Merges to sources into a single source. """ new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() self.phoenix.merge(self.titanic) with DbTxn(_("Merge Source"), self.database) as trans: self.database.commit_source(self.phoenix, trans) for (class_name, handle) in self.database.find_backlink_handles(old_handle): if class_name == Citation.__name__: citation = self.database.get_citation_from_handle(handle) assert (citation.get_reference_handle() == old_handle) citation.set_reference_handle(new_handle) self.database.commit_citation(citation, trans) else: raise MergeError("Encounter an object of type %s that has " "a source reference." % class_name) self.database.remove_source(old_handle, trans)
def on_merge_ok_clicked(self, obj): """ Performs the actual merge of citations (Derived from ExtractCity) """ fields = self.menu.get_model()[self.menu.get_active()][1] dont_merge_notes = int(self.notes_obj.get_active()) LOG.debug("fields %d dont_merge_notes %d" % (fields, dont_merge_notes)) self.options.handler.options_dict['fields'] = fields self.options.handler.options_dict['dont_merge_notes'] = dont_merge_notes # Save options self.options.handler.save_options() self.progress = ProgressMeter(_('Checking Sources'), '') self.progress.set_pass(_('Looking for citation fields'), self.db.get_number_of_citations()) db = self.dbstate.db db.disable_signals() num_merges = 0 for handle in db.iter_source_handles(): dict = {} citation_handle_list = list(db.find_backlink_handles(handle)) for (class_name, citation_handle) in citation_handle_list: if class_name <> Citation.__name__: raise MergeError("Encountered an object of type %s " "that has a citation reference." % class_name) citation = db.get_citation_from_handle(citation_handle) key = citation.get_page() if fields <> IGNORE_DATE and fields <> IGNORE_BOTH: key += "\n" + DateHandler.get_date(citation) if fields <> IGNORE_CONFIDENCE and fields <> IGNORE_BOTH: key += "\n" + \ confidence[citation.get_confidence_level()] if key in dict and \ (not dont_merge_notes or len(citation.note_list) == 0): citation_match_handle = dict[key] citation_match = \ db.get_citation_from_handle(citation_match_handle) try: query = MergeCitationQuery( self.dbstate, citation_match, citation) query.execute() except AssertionError: print "Tool/Family Tree processing/MergeCitations", \ "citation1 gramps_id", citation_match.get_gramps_id(), \ "citation2 gramps_id", citation.get_gramps_id() , \ "citation backlink handles", \ list(db.find_backlink_handles(citation.get_handle())) num_merges += 1 elif (not dont_merge_notes or len(citation.note_list) == 0): dict[key] = citation_handle self.progress.step() db.enable_signals() db.request_rebuild() self.progress.close() OkDialog( _("Number of merges done"), ngettext("%(num)d citation merged", "%(num)d citations merged", num_merges) % {'num': num_merges}) self.close(obj)