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
This commit is contained in:
Tim G L Lyons 2011-11-01 11:10:18 +00:00
parent 9c046f38a0
commit 4169661302
6 changed files with 124 additions and 137 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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):
"""

View File

@ -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)

View File

@ -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)

View File

@ -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)