From 38e87b074eb7c8060ecb99e88ad9973e2b80ddbe Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Fri, 3 Sep 2010 22:54:40 +0000 Subject: [PATCH] 4196: Error by using special filter in person view svn: r15855 --- .../Person/_DeepRelationshipPathBetween.py | 6 ++-- .../_HasCommonAncestorWithFilterMatch.py | 6 ++-- .../Rules/Person/_IsAncestorOfFilterMatch.py | 6 ++-- .../Rules/Person/_IsChildOfFilterMatch.py | 7 ++-- .../Person/_IsDescendantOfFilterMatch.py | 6 ++-- .../Rules/Person/_IsParentOfFilterMatch.py | 7 ++-- .../Rules/Person/_IsSiblingOfFilterMatch.py | 7 ++-- .../Rules/Person/_IsSpouseOfFilterMatch.py | 8 +++-- src/Filters/Rules/_MatchesFilterBase.py | 5 +-- src/Filters/Rules/_Rule.py | 33 +++++++++++++++++++ src/Filters/_GenericFilter.py | 4 +-- src/Filters/_ParamFilter.py | 8 +++-- 12 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/Filters/Rules/Person/_DeepRelationshipPathBetween.py b/src/Filters/Rules/Person/_DeepRelationshipPathBetween.py index 8006afae0..bc0b95956 100644 --- a/src/Filters/Rules/Person/_DeepRelationshipPathBetween.py +++ b/src/Filters/Rules/Person/_DeepRelationshipPathBetween.py @@ -47,7 +47,7 @@ def filter_database(db, progress, filter_name): filt = MatchesFilter([filter_name]) progress.set_header('Preparing sub-filter') - filt.prepare(db) + filt.requestprepare(db) progress.set_header('Retrieving all sub-filter matches') matches = [] @@ -57,7 +57,7 @@ def filter_database(db, progress, filter_name): matches.append(handle) progress.step() - filt.reset() + filt.requestreset() return matches @@ -133,7 +133,7 @@ class DeepRelationshipPathBetween(Rule): root_person = db.get_person_from_gramps_id(root_person_id) progress = ProgressMeter(_('Finding relationship paths')) - progress.set_pass(header=_('Evaluating people'), mode=ProgressMeter.MODE_ACTIVITY) + progress.set_pass(header=_('Evaluating people'), mode=ProgressMeter.MODE_ACTIVITY) filter_name = self.list[1] target_people = filter_database(db, progress, filter_name) diff --git a/src/Filters/Rules/Person/_HasCommonAncestorWithFilterMatch.py b/src/Filters/Rules/Person/_HasCommonAncestorWithFilterMatch.py index 5982bc830..1618d4ecb 100644 --- a/src/Filters/Rules/Person/_HasCommonAncestorWithFilterMatch.py +++ b/src/Filters/Rules/Person/_HasCommonAncestorWithFilterMatch.py @@ -41,7 +41,7 @@ from _MatchesFilter import MatchesFilter # HasCommonAncestorWithFilterMatch # #------------------------------------------------------------------------- -class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith,MatchesFilter): +class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith): """Rule that checks for a person that has a common ancestor with someone matching a filter""" @@ -64,7 +64,7 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith,MatchesFilter): self.ancestor_cache = {} self.with_people = [] filt = MatchesFilter(self.list) - filt.prepare(db) + filt.requestprepare(db) for handle in db.iter_person_handles(): person = db.get_person_from_handle(handle) if person and filt.apply(db, person): @@ -73,4 +73,4 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith,MatchesFilter): #fill list of ancestor of person if not present yet if handle not in self.ancestor_cache: self.add_ancs(db, person) - filt.reset() + filt.requestreset() diff --git a/src/Filters/Rules/Person/_IsAncestorOfFilterMatch.py b/src/Filters/Rules/Person/_IsAncestorOfFilterMatch.py index 57d4715ea..4d8cb72cb 100644 --- a/src/Filters/Rules/Person/_IsAncestorOfFilterMatch.py +++ b/src/Filters/Rules/Person/_IsAncestorOfFilterMatch.py @@ -40,7 +40,7 @@ from _MatchesFilter import MatchesFilter # IsAncestorOfFilterMatch # #------------------------------------------------------------------------- -class IsAncestorOfFilterMatch(IsAncestorOf,MatchesFilter): +class IsAncestorOfFilterMatch(IsAncestorOf): """Rule that checks for a person that is an ancestor of someone matched by a filter""" @@ -66,11 +66,11 @@ class IsAncestorOfFilterMatch(IsAncestorOf,MatchesFilter): first = 1 filt = MatchesFilter(self.list[0:1]) - filt.prepare(db) + filt.requestprepare(db) for person in db.iter_people(): if filt.apply(db, person): self.init_ancestor_list(db, person, first) - filt.reset() + filt.requestreset() def reset(self): self.map.clear() diff --git a/src/Filters/Rules/Person/_IsChildOfFilterMatch.py b/src/Filters/Rules/Person/_IsChildOfFilterMatch.py index 90495ae06..9433621e1 100644 --- a/src/Filters/Rules/Person/_IsChildOfFilterMatch.py +++ b/src/Filters/Rules/Person/_IsChildOfFilterMatch.py @@ -32,6 +32,7 @@ from gen.ggettext import gettext as _ # GRAMPS modules # #------------------------------------------------------------------------- +from Filters.Rules import Rule from _MatchesFilter import MatchesFilter #------------------------------------------------------------------------- @@ -39,7 +40,7 @@ from _MatchesFilter import MatchesFilter # IsChildOfFilterMatch # #------------------------------------------------------------------------- -class IsChildOfFilterMatch(MatchesFilter): +class IsChildOfFilterMatch(Rule): """Rule that checks for a person that is a child of someone matched by a filter""" @@ -52,11 +53,11 @@ class IsChildOfFilterMatch(MatchesFilter): self.db = db self.map = set() filt = MatchesFilter(self.list) - filt.prepare(db) + filt.requestprepare(db) for person in db.iter_people(): if filt.apply(db, person): self.init_list(person) - filt.reset() + filt.requestreset() def reset(self): self.map.clear() diff --git a/src/Filters/Rules/Person/_IsDescendantOfFilterMatch.py b/src/Filters/Rules/Person/_IsDescendantOfFilterMatch.py index 01332eb3b..0c65891a3 100644 --- a/src/Filters/Rules/Person/_IsDescendantOfFilterMatch.py +++ b/src/Filters/Rules/Person/_IsDescendantOfFilterMatch.py @@ -40,7 +40,7 @@ from _MatchesFilter import MatchesFilter # IsDescendantOfFilterMatch # #------------------------------------------------------------------------- -class IsDescendantOfFilterMatch(IsDescendantOf,MatchesFilter): +class IsDescendantOfFilterMatch(IsDescendantOf): """Rule that checks for a person that is a descendant of someone matched by a filter""" @@ -66,11 +66,11 @@ class IsDescendantOfFilterMatch(IsDescendantOf,MatchesFilter): first = 1 filt = MatchesFilter(self.list[0:1]) - filt.prepare(db) + filt.requestprepare(db) for person in db.iter_people(): if filt.apply(db, person): self.init_list(person, first) - filt.reset() + filt.requestreset() def reset(self): self.map.clear() diff --git a/src/Filters/Rules/Person/_IsParentOfFilterMatch.py b/src/Filters/Rules/Person/_IsParentOfFilterMatch.py index 5e092f8ef..2ef6970e2 100644 --- a/src/Filters/Rules/Person/_IsParentOfFilterMatch.py +++ b/src/Filters/Rules/Person/_IsParentOfFilterMatch.py @@ -32,6 +32,7 @@ from gen.ggettext import gettext as _ # GRAMPS modules # #------------------------------------------------------------------------- +from Filters.Rules import Rule from _MatchesFilter import MatchesFilter #------------------------------------------------------------------------- @@ -39,7 +40,7 @@ from _MatchesFilter import MatchesFilter # IsParentOfFilterMatch # #------------------------------------------------------------------------- -class IsParentOfFilterMatch(MatchesFilter): +class IsParentOfFilterMatch(Rule): """Rule that checks for a person that is a parent of someone matched by a filter""" @@ -52,11 +53,11 @@ class IsParentOfFilterMatch(MatchesFilter): self.db = db self.map = set() filt = MatchesFilter(self.list) - filt.prepare(db) + filt.requestprepare(db) for person in db.iter_people(): if filt.apply(db, person): self.init_list(person) - filt.reset() + filt.requestreset() def reset(self): self.map.clear() diff --git a/src/Filters/Rules/Person/_IsSiblingOfFilterMatch.py b/src/Filters/Rules/Person/_IsSiblingOfFilterMatch.py index dc66dec07..86a50dc4a 100644 --- a/src/Filters/Rules/Person/_IsSiblingOfFilterMatch.py +++ b/src/Filters/Rules/Person/_IsSiblingOfFilterMatch.py @@ -32,6 +32,7 @@ from gen.ggettext import gettext as _ # GRAMPS modules # #------------------------------------------------------------------------- +from Filters.Rules import Rule from _MatchesFilter import MatchesFilter #------------------------------------------------------------------------- @@ -39,7 +40,7 @@ from _MatchesFilter import MatchesFilter # IsSiblingOfFilterMatch # #------------------------------------------------------------------------- -class IsSiblingOfFilterMatch(MatchesFilter): +class IsSiblingOfFilterMatch(Rule): """Rule that checks for siblings of someone matched by a filter""" labels = [ _('Filter name:') ] @@ -51,11 +52,11 @@ class IsSiblingOfFilterMatch(MatchesFilter): self.db = db self.map = set() filt = MatchesFilter(self.list) - filt.prepare(db) + filt.requestprepare(db) for person in db.iter_people(): if filt.apply (db, person): self.init_list (person) - filt.reset() + filt.requestreset() def reset(self): self.map.clear() diff --git a/src/Filters/Rules/Person/_IsSpouseOfFilterMatch.py b/src/Filters/Rules/Person/_IsSpouseOfFilterMatch.py index 783d1017a..1d2da9070 100644 --- a/src/Filters/Rules/Person/_IsSpouseOfFilterMatch.py +++ b/src/Filters/Rules/Person/_IsSpouseOfFilterMatch.py @@ -32,6 +32,7 @@ from gen.ggettext import gettext as _ # GRAMPS modules # #------------------------------------------------------------------------- +from Filters.Rules import Rule from _MatchesFilter import MatchesFilter #------------------------------------------------------------------------- @@ -39,7 +40,7 @@ from _MatchesFilter import MatchesFilter # IsSpouseOfFilterMatch # #------------------------------------------------------------------------- -class IsSpouseOfFilterMatch(MatchesFilter): +class IsSpouseOfFilterMatch(Rule): """Rule that checks for a person married to someone matching a filter""" @@ -50,7 +51,7 @@ class IsSpouseOfFilterMatch(MatchesFilter): def prepare(self,db): self.filt = MatchesFilter (self.list) - self.filt.prepare(db) + self.filt.requestprepare(db) def apply(self,db,person): for family_handle in person.get_family_handle_list (): @@ -65,3 +66,6 @@ class IsSpouseOfFilterMatch(MatchesFilter): if self.filt.apply (db, db.get_person_from_handle( spouse_id)): return True return False + + def reset(self): + self.filt.requestreset() diff --git a/src/Filters/Rules/_MatchesFilterBase.py b/src/Filters/Rules/_MatchesFilterBase.py index 8420c28f2..4c4c06d29 100644 --- a/src/Filters/Rules/_MatchesFilterBase.py +++ b/src/Filters/Rules/_MatchesFilterBase.py @@ -60,7 +60,8 @@ class MatchesFilterBase(Rule): if self.list[0] in filters: filt = filters[self.list[0]] for rule in filt.flist: - rule.prepare(db) + rule.requestprepare(db) + def reset(self): if Filters.CustomFilters: @@ -68,7 +69,7 @@ class MatchesFilterBase(Rule): if self.list[0] in filters: filt = filters[self.list[0]] for rule in filt.flist: - rule.reset() + rule.requestreset() def apply(self, db, obj): if Filters.CustomFilters: diff --git a/src/Filters/Rules/_Rule.py b/src/Filters/Rules/_Rule.py index ccc6e6b35..f5ff34af4 100644 --- a/src/Filters/Rules/_Rule.py +++ b/src/Filters/Rules/_Rule.py @@ -43,14 +43,47 @@ class Rule(object): def __init__(self, arg): self.set_list(arg) + self.nrprepare = 0 def is_empty(self): return False + def requestprepare(self, db): + """ + Request that the prepare method of the rule is executed if needed + + Special: Custom Filters have fixed values, so only one instance needs to + exists during a search. It is stored in a FilterStore, and initialized + once. + As filters are can be grouped in a group + filter, we request a prepare. Only the first time prepare will be + called + """ + if self.nrprepare == 0: + self.prepare(db) + self.nrprepare += 1 + def prepare(self, db): + """prepare so the rule can be executed efficiently""" pass + def requestreset(self): + """ + Request that the reset method of the rule is executed if possible + + Special: Custom Filters have fixed values, so only one instance needs to + exists during a search. It is stored in a FilterStore, and initialized + once. + As filters are can be grouped in a group + filter, we request a reset. Only the last time reset will be + called + """ + self.nrprepare -= 1 + if self.nrprepare == 0: + self.reset() + def reset(self): + """remove no longer needed memory""" pass def set_list(self, arg): diff --git a/src/Filters/_GenericFilter.py b/src/Filters/_GenericFilter.py index c34e93f9d..9acf81baa 100644 --- a/src/Filters/_GenericFilter.py +++ b/src/Filters/_GenericFilter.py @@ -227,10 +227,10 @@ class GenericFilter(object): """ m = self.get_check_func() for rule in self.flist: - rule.prepare(db) + rule.requestprepare(db) res = m(db, id_list, progress, tupleind) for rule in self.flist: - rule.reset() + rule.requestreset() return res class GenericFamilyFilter(GenericFilter): diff --git a/src/Filters/_ParamFilter.py b/src/Filters/_ParamFilter.py index 7de619804..d08f2c549 100644 --- a/src/Filters/_ParamFilter.py +++ b/src/Filters/_ParamFilter.py @@ -30,6 +30,7 @@ Package providing filtering framework for GRAMPS. # #------------------------------------------------------------------------- from Filters._GenericFilter import GenericFilter +from Errors import FilterError #------------------------------------------------------------------------- # @@ -58,8 +59,11 @@ class ParamFilter(GenericFilter): new_list[ix] = self.param_list[ix] rule.set_list(new_list) for rule in self.flist: - rule.prepare(db) + if rule.nrprepare > 0: + raise FilterError, 'Custom filters can not twice be used' \ + ' in a parameter filter' + rule.requestprepare(db) result = GenericFilter.apply(self, db, id_list) for rule in self.flist: - rule.reset() + rule.requestreset() return result