From 4169661302a827f30f5ed118a5065b4420070a85 Mon Sep 17 00:00:00 2001 From: Tim G L Lyons Date: Tue, 1 Nov 2011 11:10:18 +0000 Subject: [PATCH] Update uses of get_source_referents to handle citations: * implement new Utils get_source_and_citation_referents * Update sourceview.py and citationtreeview.py to use it * Fix editsource.py, where deletion of a source object was not properly dealing with all possible citations * Update mediaobj.py which still had a remnant of a source_list * fix _HasTextMatchingSubstringOf filter to deal with text in both sources and citations svn: r18394 --- .../Person/_HasTextMatchingSubstringOf.py | 27 +++- src/Utils.py | 59 ++++++++- src/gen/lib/mediaobj.py | 4 +- src/gui/editors/editsource.py | 118 ++++++------------ src/plugins/view/citationtreeview.py | 20 +-- src/plugins/view/sourceview.py | 33 +---- 6 files changed, 124 insertions(+), 137 deletions(-) diff --git a/src/Filters/Rules/Person/_HasTextMatchingSubstringOf.py b/src/Filters/Rules/Person/_HasTextMatchingSubstringOf.py index c09c677a4..963fd969d 100644 --- a/src/Filters/Rules/Person/_HasTextMatchingSubstringOf.py +++ b/src/Filters/Rules/Person/_HasTextMatchingSubstringOf.py @@ -26,13 +26,15 @@ # #------------------------------------------------------------------------- from gen.ggettext import gettext as _ +import logging +LOG = logging.getLogger(".citationfilter") #------------------------------------------------------------------------- # # GRAMPS modules # #------------------------------------------------------------------------- -from Utils import get_source_referents +from Utils import get_source_and_citation_referents from Filters.Rules._Rule import Rule #------------------------------------------------------------------------- @@ -179,15 +181,30 @@ class HasTextMatchingSubstringOf(Rule): # search all sources and match all referents of a matching source for source in self.db.iter_sources(): match = self.match_object(source) + LOG.debug("cache_sources match %s string %s source %s" % + (match, self.list[0], source.gramps_id)) if not match: if any(reporef.get_reference_handle() in self.repo_map for reporef in source.get_reporef_list() ): - + match = True + LOG.debug("cache_sources repomatch %s string %s source %s" % + (match, self.list[0], source.gramps_id)) + (citation_list, citation_referents_list) = \ + get_source_and_citation_referents(source.handle, self.db) + LOG.debug("the_lists %s %s" % + (citation_list, citation_referents_list)) + for (citation_handle, refs) in citation_referents_list: + citation = self.db.get_citation_from_handle(citation_handle) + LOG.debug("cache_sources match %s matchcitation %s string %s" + " source %s citation %s" % + (match, self.match_object(citation), + self.list[0], source.gramps_id, + citation.gramps_id)) + if match or self.match_object(citation): # Update the maps to reflect the reference - (person_list, family_list, event_list, place_list, - source_list, media_list, repo_list - ) = get_source_referents(source.handle,self.db) + (person_list, family_list, event_list, place_list, + source_list, media_list, repo_list) = refs self.person_map.update(person_list) self.family_map.update(family_list) self.event_map.update(event_list) diff --git a/src/Utils.py b/src/Utils.py index abea44f98..d01b619ee 100644 --- a/src/Utils.py +++ b/src/Utils.py @@ -973,9 +973,9 @@ def get_source_referents(source_handle, db): This function finds all primary objects that refer (directly or through secondary child-objects) to a given source handle in a given database. + Only Citations can refer to sources, so that is all we need to check """ - _primaries = ('Person', 'Family', 'Event', 'Place', - 'Source', 'MediaObject', 'Repository', 'Citation') + _primaries = ('Citation',) return (get_referents(source_handle, db, _primaries)) @@ -991,6 +991,61 @@ def get_citation_referents(citation_handle, db): return (get_referents(citation_handle, db, _primaries)) +def get_source_and_citation_referents(source_handle, db): + """ + Find all citations that refer to the sources, and recursively, all objects + that refer to the sources. + + This function finds all primary objects that refer (directly or through + secondary child-objects) to a given source handle in a given database. + + Objects -> Citations -> Source + e.g. + Media object M1 -> Citation C1 -> Source S1 + Media object M2 -> Citation C1 -> Source S1 + Person object P1 -> Citation C2 -> Source S1 + + The returned structure is rather ugly, but provides all the information in + a way that is consistent with the other Util functions. + ( + tuple of objects that refer to the source - only first element is present + ([C1, C2],), + list of citations with objects that refer to them + [ + (C1, + tuple of reference lists + P, F, E, Pl, S, M, R + ([], [], [], [], [], [M1, M2]. []) + ) + (C2, + tuple of reference lists + P, F, E, Pl, S, M, R + ([P1], [], [], [], [], []. []) + ) + ] + ) +#47738: DEBUG: citationtreeview.py: line 428: source referents [(['bfe59e90dbb555d0d87'],)] +#47743: DEBUG: citationtreeview.py: line 432: citation bfe59e90dbb555d0d87 +#47825: DEBUG: citationtreeview.py: line 435: citation_referents_list [[('bfe59e90dbb555d0d87', ([], [], ['ba77932bf0b2d59eccb'], [], [], [], []))]] +#47827: DEBUG: citationtreeview.py: line 440: the_lists [((['bfe59e90dbb555d0d87'],), [('bfe59e90dbb555d0d87', ([], [], ['ba77932bf0b2d59eccb'], [], [], [], []))])] + + """ + the_lists = get_source_referents(source_handle, db) + LOG.debug('source referents %s' % [the_lists]) + # now, for each citation, get the objects that refer to that citation + citation_referents_list = [] + for citation in the_lists[0]: + LOG.debug('citation %s' % citation) + refs = get_citation_referents(citation, db) + citation_referents_list += [(citation, refs)] + LOG.debug('citation_referents_list %s' % [citation_referents_list]) + + (citation_list) = the_lists + the_lists = (citation_list, citation_referents_list) + + LOG.debug('the_lists %s' % [the_lists]) + return the_lists + def get_media_referents(media_handle, db): """ Find objects that refer the media object. diff --git a/src/gen/lib/mediaobj.py b/src/gen/lib/mediaobj.py index a425f8dd1..94a3423ea 100644 --- a/src/gen/lib/mediaobj.py +++ b/src/gen/lib/mediaobj.py @@ -149,7 +149,7 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase, :returns: Returns the list of child objects that may carry textual data. :rtype: list """ - return self.attribute_list + self.source_list + return self.attribute_list def get_citation_child_list(self): """ @@ -169,7 +169,7 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase, refer notes. :rtype: list """ - return self.attribute_list + self.source_list + self.citation_list + return self.attribute_list + self.citation_list def get_referenced_handles(self): """ diff --git a/src/gui/editors/editsource.py b/src/gui/editors/editsource.py index 80d5bb48e..e1c5101c1 100644 --- a/src/gui/editors/editsource.py +++ b/src/gui/editors/editsource.py @@ -224,15 +224,16 @@ class DeleteSrcQuery(object): self.db.disable_signals() # we can have: - # object(CitationBase) -> Citation(RefBase) -> Source + # object(CitationBase) -> Citation(source_handle) -> Source # We first have to remove the CitationBase references to the # Citation. Then we remove the Citations. (We don't need to - # remove the RefBase references to the Source, because we are - # removing the whole Citation). Then we can emove the Source + # remove the source_handle references to the Source, because we are + # removing the whole Citation). Then we can remove the Source - (person_list, family_list, event_list, place_list, source_list, - media_list, repo_list, citation_list, - citation_referents_list) = self.the_lists + (citation_list, citation_referents_list) = self.the_lists + # citation_list is a tuple of lists. Only the first, for Citations, + # exists. + citation_list = citation_list[0] # (1) delete the references to the citation for (citation_handle, refs) in citation_referents_list: @@ -241,88 +242,47 @@ class DeleteSrcQuery(object): (person_list, family_list, event_list, place_list, source_list, media_list, repo_list) = refs -# for handle in person_list: -# person = self.db.get_person_from_handle(handle) -# person.remove_citation(citation_handle) -# self.db.commit_person(person, trans) -# -# for handle in family_list: -# family = self.db.get_family_from_handle(handle) -# family.remove_citation(citation_handle) -# self.db.commit_family(family, trans) -# -# for handle in event_list: -# event = self.db.get_event_from_handle(handle) -# event.remove_citation(citation_handle) -# self.db.commit_event(event, trans) -# -# for handle in place_list: -# place = self.db.get_place_from_handle(handle) -# place.remove_citation(citation_handle) -# self.db.commit_place(place, trans) -# -# for handle in source_list: -# source = self.db.get_source_from_handle(handle) -# source.remove_citation(citation_handle) -# self.db.commit_source(source, trans) -# + for handle in person_list: + person = self.db.get_person_from_handle(handle) + person.remove_citation(citation_handle) + self.db.commit_person(person, trans) + + for handle in family_list: + family = self.db.get_family_from_handle(handle) + family.remove_citation(citation_handle) + self.db.commit_family(family, trans) + + for handle in event_list: + event = self.db.get_event_from_handle(handle) + event.remove_citation(citation_handle) + self.db.commit_event(event, trans) + + for handle in place_list: + place = self.db.get_place_from_handle(handle) + place.remove_citation(citation_handle) + self.db.commit_place(place, trans) + + for handle in source_list: + source = self.db.get_source_from_handle(handle) + source.remove_citation(citation_handle) + self.db.commit_source(source, trans) + for handle in media_list: media = self.db.get_object_from_handle(handle) media.remove_citation(citation_handle) self.db.commit_media_object(media, trans) -# for handle in repo_list: -# repo = self.db.get_repository_from_handle(handle) -# repo.remove_citation(citation_handle) -# self.db.commit_repository(repo, trans) + for handle in repo_list: + repo = self.db.get_repository_from_handle(handle) + repo.remove_citation(citation_handle) + self.db.commit_repository(repo, trans) - # (2) delete the actual citation + # (2) delete the actual citations LOG.debug('remove the actual citations %s' % citation_list) for citation_handle in citation_list: + LOG.debug("remove_citation %s" % citation_handle) self.db.remove_citation(citation_handle, trans) - # (3) delete the references to the source - src_handle_list = [self.source.get_handle()] - LOG.debug('remove the source references to %s' % src_handle_list) - - for handle in person_list: - person = self.db.get_person_from_handle(handle) - person.remove_source_references(src_handle_list) - self.db.commit_person(person, trans) - - for handle in family_list: - family = self.db.get_family_from_handle(handle) - family.remove_source_references(src_handle_list) - self.db.commit_family(family, trans) - - for handle in event_list: - event = self.db.get_event_from_handle(handle) - event.remove_source_references(src_handle_list) - self.db.commit_event(event, trans) - - for handle in place_list: - place = self.db.get_place_from_handle(handle) - place.remove_source_references(src_handle_list) - self.db.commit_place(place, trans) - - for handle in source_list: - source = self.db.get_source_from_handle(handle) - source.remove_source_references(src_handle_list) - self.db.commit_source(source, trans) - - for handle in media_list: - media = self.db.get_object_from_handle(handle) - media.remove_source_references(src_handle_list) - self.db.commit_media_object(media, trans) - - for handle in repo_list: - repo = self.db.get_repository_from_handle(handle) - repo.remove_source_references(src_handle_list) - self.db.commit_repository(repo, trans) - -# FIXME: we need to remove all the citations that point to this source object, -# and before that, all the CitationBase pointers in all objects that point to -# this source. - + # (3) delete the source self.db.enable_signals() self.db.remove_source(self.source.get_handle(), trans) diff --git a/src/plugins/view/citationtreeview.py b/src/plugins/view/citationtreeview.py index 4a709f77b..04dda78ba 100644 --- a/src/plugins/view/citationtreeview.py +++ b/src/plugins/view/citationtreeview.py @@ -420,24 +420,8 @@ class CitationTreeView(ListView): is_used = any(the_lists) return (query, is_used, object) else: - # FIXME: this is copied from SourceView, because import with - # from plugins.view.sourceview import SourceView - # doesn't seem to work! - the_lists = Utils.get_source_referents(handle, self.dbstate.db) - LOG.debug('source referents %s' % [the_lists]) - citation_referents_list = [] - for citation in the_lists[7]: - LOG.debug('citation %s' % citation) - refs = Utils.get_citation_referents(citation, self.dbstate.db) - citation_referents_list += [(citation, refs)] - LOG.debug('citation_referents_list %s' % [citation_referents_list]) - - (person_list, family_list, event_list, place_list, source_list, - media_list, repo_list, citation_list) = the_lists - the_lists = (person_list, family_list, event_list, place_list, - source_list, media_list, repo_list, citation_list, - citation_referents_list) - + the_lists = Utils.get_source_and_citation_referents(handle, + self.dbstate.db) LOG.debug('the_lists %s' % [the_lists]) object = self.dbstate.db.get_source_from_handle(handle) diff --git a/src/plugins/view/sourceview.py b/src/plugins/view/sourceview.py index fd7957706..543bd58ca 100644 --- a/src/plugins/view/sourceview.py +++ b/src/plugins/view/sourceview.py @@ -213,37 +213,8 @@ class SourceView(ListView): self.remove_selected_objects() def remove_object_from_handle(self, handle): - the_lists = Utils.get_source_referents(handle, self.dbstate.db) - LOG.debug('source referents %s' % [the_lists]) -# per = [] -# fam = [] -# eve = [] -# pla = [] -# sou = [] -# med = [] -# rep = [] - citation_referents_list = [] - for citation in the_lists[7]: - LOG.debug('citation %s' % citation) - refs = Utils.get_citation_referents(citation, self.dbstate.db) - citation_referents_list += [(citation, refs)] -# (per2 , fam2, eve2, pla2, sou2, med2, rep2) = refs -# per += per2 -# fam += fam2 -# eve += eve2 -# pla += pla2 -# sou += sou2 -# med += med2 -# rep += rep2 -# citation_referents_list = (per , fam, eve, pla, sou, med, rep) - LOG.debug('citation_referents_list %s' % [citation_referents_list]) - - (person_list, family_list, event_list, place_list, source_list, - media_list, repo_list, citation_list) = the_lists - the_lists = (person_list, family_list, event_list, place_list, - source_list, media_list, repo_list, citation_list, - citation_referents_list) - + the_lists = Utils.get_source_and_citation_referents(handle, + self.dbstate.db) LOG.debug('the_lists %s' % [the_lists]) object = self.dbstate.db.get_source_from_handle(handle)