2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
|
|
#
|
2004-03-11 09:01:35 +05:30
|
|
|
# Copyright (C) 2002-2004 Donald N. Allingham
|
2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
|
2003-12-08 07:53:53 +05:30
|
|
|
# $Id$
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
"""Generic Filtering Routines"""
|
|
|
|
|
|
|
|
__author__ = "Don Allingham"
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Try to abstract SAX1 from SAX2
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2004-04-30 08:31:51 +05:30
|
|
|
from xml.sax import make_parser,handler,SAXParseException
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Standard Python modules
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
import os
|
2004-04-30 08:31:51 +05:30
|
|
|
import string
|
2002-10-20 19:55:16 +05:30
|
|
|
import gtk
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GRAMPS modules
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
import const
|
2003-01-10 10:51:32 +05:30
|
|
|
import RelLib
|
2002-10-20 19:55:16 +05:30
|
|
|
import Date
|
2003-03-12 08:32:08 +05:30
|
|
|
import Calendar
|
2004-01-21 04:58:44 +05:30
|
|
|
from TransTable import TransTable
|
2003-08-17 07:44:33 +05:30
|
|
|
from gettext import gettext as _
|
2003-01-10 10:51:32 +05:30
|
|
|
from Utils import for_each_ancestor
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# date_cmp
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
def date_cmp(rule,value):
|
|
|
|
sd = rule.get_start_date()
|
|
|
|
s = sd.mode
|
2003-03-12 08:32:08 +05:30
|
|
|
if s == Calendar.BEFORE:
|
2002-10-20 19:55:16 +05:30
|
|
|
return Date.compare_dates(rule,value) == 1
|
2003-03-12 08:32:08 +05:30
|
|
|
elif s == Calendar.AFTER:
|
2002-10-20 19:55:16 +05:30
|
|
|
return Date.compare_dates(rule,value) == -1
|
|
|
|
elif sd.month == Date.UNDEF and sd.year != Date.UNDEF:
|
|
|
|
return sd.year == value.get_start_date().year
|
|
|
|
else:
|
|
|
|
return Date.compare_dates(rule,value) == 0
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Rule
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class Rule:
|
|
|
|
"""Base rule class"""
|
|
|
|
|
|
|
|
labels = []
|
|
|
|
|
|
|
|
def __init__(self,list):
|
2004-04-30 08:31:51 +05:30
|
|
|
self.set_list(list)
|
|
|
|
|
|
|
|
def set_list(self,list):
|
2004-01-21 08:26:53 +05:30
|
|
|
assert type(list) == type([]) or list == None, "Argument is not a list"
|
2002-10-20 19:55:16 +05:30
|
|
|
self.list = list
|
|
|
|
|
|
|
|
def values(self):
|
|
|
|
return self.list
|
|
|
|
|
|
|
|
def trans_name(self):
|
|
|
|
return _(self.name())
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'None'
|
2003-08-10 10:58:11 +05:30
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Miscellaneous filters')
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def description(self):
|
|
|
|
return _('No description')
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
def check(self):
|
|
|
|
return len(self.list) == len(self.labels)
|
|
|
|
|
2003-01-06 10:44:49 +05:30
|
|
|
def apply(self,db,p):
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
|
|
|
|
def display_values(self):
|
|
|
|
v = []
|
|
|
|
for i in range(0,len(self.list)):
|
|
|
|
if self.list[i]:
|
2004-01-21 08:26:53 +05:30
|
|
|
v.append('%s="%s"' % (_(self.labels[i]),_(self.list[i])))
|
2004-05-07 09:28:26 +05:30
|
|
|
return string.join(v,'; ')
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Everyone
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class Everyone(Rule):
|
|
|
|
"""Matches Everyone"""
|
|
|
|
|
|
|
|
labels = []
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Everyone'
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def category(self):
|
|
|
|
return _('General filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _('Matches everyone in the database')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
|
2003-10-24 03:23:53 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# RelationshipPathBetween
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class RelationshipPathBetween(Rule):
|
|
|
|
"""Rule that checks for a person that is a descendant of a specified person
|
|
|
|
not more than N generations away"""
|
|
|
|
|
|
|
|
labels = [ _('ID:'), _('ID:') ]
|
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return "Relationship path between two people"
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Relationship filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _("Matches the ancestors of two people back to a common ancestor, producing "
|
|
|
|
"the relationship path between two people.")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def desc_list(self, p_id, map, first):
|
2003-10-24 03:23:53 +05:30
|
|
|
if not first:
|
2004-03-11 09:01:35 +05:30
|
|
|
map[p_id] = 1
|
2003-10-24 03:23:53 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
for fam_id in p.get_family_id_list():
|
|
|
|
if fam_id:
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
for child_id in fam.get_child_id_list():
|
|
|
|
if child_id:
|
|
|
|
self.desc_list(child_id,map,0)
|
2003-10-24 03:23:53 +05:30
|
|
|
|
|
|
|
def apply_filter(self,rank,person,plist,pmap):
|
|
|
|
if person == None:
|
|
|
|
return
|
|
|
|
plist.append(person)
|
2004-02-14 11:10:30 +05:30
|
|
|
pmap[person.get_id()] = rank
|
2003-10-24 03:23:53 +05:30
|
|
|
|
2004-02-14 11:10:30 +05:30
|
|
|
family = person.get_main_parents_family_id()
|
2003-10-24 03:23:53 +05:30
|
|
|
if family != None:
|
2004-02-14 11:10:30 +05:30
|
|
|
self.apply_filter(rank+1,family.get_father_id(),plist,pmap)
|
|
|
|
self.apply_filter(rank+1,family.get_mother_id(),plist,pmap)
|
2003-10-24 03:23:53 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.db = db
|
2003-10-24 03:23:53 +05:30
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
root1 = self.list[0]
|
|
|
|
root2 = self.list[1]
|
2003-10-24 03:23:53 +05:30
|
|
|
self.init_list(root1,root2)
|
2004-03-11 09:01:35 +05:30
|
|
|
return self.map.has_key(p_id)
|
2003-10-24 03:23:53 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_list(self,p1_id,p2_id):
|
2003-10-24 03:23:53 +05:30
|
|
|
|
|
|
|
firstMap = {}
|
|
|
|
firstList = []
|
|
|
|
secondMap = {}
|
|
|
|
secondList = []
|
|
|
|
common = []
|
|
|
|
rank = 9999999
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
self.apply_filter(0,p1_id,firstList,firstMap)
|
|
|
|
self.apply_filter(0,p2_id,secondList,secondMap)
|
2003-10-24 03:23:53 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
for person_id in firstList:
|
|
|
|
if person_id in secondList:
|
|
|
|
new_rank = firstMap[person_id]
|
2003-10-24 03:23:53 +05:30
|
|
|
if new_rank < rank:
|
|
|
|
rank = new_rank
|
2004-03-11 09:01:35 +05:30
|
|
|
common = [ person_id ]
|
2003-10-24 03:23:53 +05:30
|
|
|
elif new_rank == rank:
|
2004-03-11 09:01:35 +05:30
|
|
|
common.append(person_id)
|
2003-10-24 03:23:53 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
path1 = { p1_id : 1}
|
|
|
|
path2 = { p2_id : 1}
|
2003-10-24 03:23:53 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
for person_id in common:
|
2003-10-24 03:23:53 +05:30
|
|
|
new_map = {}
|
2004-03-11 09:01:35 +05:30
|
|
|
self.desc_list(person_id,new_map,1)
|
2003-10-24 03:23:53 +05:30
|
|
|
self.get_intersection(path1,firstMap,new_map)
|
|
|
|
self.get_intersection(path2,secondMap,new_map)
|
|
|
|
|
|
|
|
for e in path1:
|
|
|
|
self.map[e] = 1
|
|
|
|
for e in path2:
|
|
|
|
self.map[e] = 1
|
|
|
|
for e in common:
|
2004-03-11 09:01:35 +05:30
|
|
|
self.map[e] = 1
|
2003-10-24 03:23:53 +05:30
|
|
|
|
|
|
|
def get_intersection(self,target, map1, map2):
|
|
|
|
for e in map1.keys():
|
|
|
|
if map2.has_key(e):
|
|
|
|
target[e] = map2[e]
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasIdOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasIdOf(Rule):
|
2003-08-10 10:58:11 +05:30
|
|
|
"""Rule that checks for a person with a specific GRAMPS ID"""
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('ID:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the Id'
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person with a specified GRAMPS ID")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('General filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
return p_id == self.list[0]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-12-08 07:53:53 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasCompleteRecord
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasCompleteRecord(Rule):
|
|
|
|
"""Rule that checks for a person whose record is complete"""
|
|
|
|
|
|
|
|
labels = []
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has complete record'
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('General filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _('Matches all people whose records are complete')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
return db.find_person_from_id(p_id).get_complete() == 1
|
2003-12-08 07:53:53 +05:30
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsFemale
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsFemale(Rule):
|
|
|
|
"""Rule that checks for a person that is a female"""
|
|
|
|
|
|
|
|
labels = []
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is a female'
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def category(self):
|
|
|
|
return _('General filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _('Matches all females')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
return db.find_person_from_id(p_id).get_gender() == RelLib.Person.female
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsDescendantOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsDescendantOf(Rule):
|
|
|
|
"""Rule that checks for a person that is a descendant
|
|
|
|
of a specified person"""
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
labels = [ _('ID:'), _('Inclusive:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-06-12 07:34:42 +05:30
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
def name(self):
|
|
|
|
return 'Is a descendant of'
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def category(self):
|
|
|
|
return _('Descendant filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _('Matches all descendants for the specified person')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-09-09 07:18:30 +05:30
|
|
|
try:
|
|
|
|
if int(self.list[1]):
|
|
|
|
first = 0
|
|
|
|
else:
|
|
|
|
first = 1
|
|
|
|
except IndexError:
|
2003-09-05 10:08:43 +05:30
|
|
|
first = 1
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-06-12 07:34:42 +05:30
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
root_id = self.list[0]
|
|
|
|
self.init_list(root_id,first)
|
|
|
|
return self.map.has_key(p_id)
|
2003-06-12 07:34:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_list(self,p_id,first):
|
2003-08-05 09:05:42 +05:30
|
|
|
if not first:
|
2004-03-11 09:01:35 +05:30
|
|
|
self.map[p_id] = 1
|
2003-06-12 07:34:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
for fam_id in p.get_family_id_list():
|
|
|
|
if fam_id:
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
for child_id in fam.get_child_id_list():
|
|
|
|
self.init_list(child_id,0)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsDescendantOfFilterMatch
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsDescendantOfFilterMatch(IsDescendantOf):
|
|
|
|
"""Rule that checks for a person that is a descendant
|
|
|
|
of someone matched by a filter"""
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
labels = [ _('Filter name:'), _('Inclusive:') ]
|
2003-07-24 22:17:36 +05:30
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
IsDescendantOf.__init__(self,list)
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is a descendant of filter match'
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def category(self):
|
|
|
|
return _('Descendant filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _("Matches people that are descendants of someone matched by a filter")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-09-09 07:18:30 +05:30
|
|
|
try:
|
|
|
|
if int(self.list[1]):
|
|
|
|
first = 0
|
|
|
|
else:
|
|
|
|
first = 1
|
|
|
|
except IndexError:
|
2003-09-05 10:08:43 +05:30
|
|
|
first = 1
|
2003-07-24 22:17:36 +05:30
|
|
|
|
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
|
|
|
filter = MatchesFilter(self.list)
|
2004-03-11 09:01:35 +05:30
|
|
|
for person_id in db.get_person_keys():
|
|
|
|
if filter.apply (db, person_id):
|
|
|
|
self.init_list (person_id, first)
|
|
|
|
return self.map.has_key(p_id)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsLessThanNthGenerationDescendantOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsLessThanNthGenerationDescendantOf(Rule):
|
|
|
|
"""Rule that checks for a person that is a descendant of a specified person
|
|
|
|
not more than N generations away"""
|
|
|
|
|
|
|
|
labels = [ _('ID:'), _('Number of generations:') ]
|
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is a descendant of person not more than N generations away'
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def category(self):
|
|
|
|
return _('Descendant filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _("Matches people that are descendants of a specified person "
|
|
|
|
"not more than N generations away")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-08-05 09:05:42 +05:30
|
|
|
|
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
root_id = self.list[0]
|
|
|
|
self.init_list(root_id,0)
|
|
|
|
return self.map.has_key(p_id)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_list(self,p_id,gen):
|
2003-08-05 09:05:42 +05:30
|
|
|
if gen:
|
2004-03-11 09:01:35 +05:30
|
|
|
self.map[p_id] = 1
|
2003-08-05 09:05:42 +05:30
|
|
|
if gen >= int(self.list[1]):
|
|
|
|
return
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
for fam_id in p.get_family_id_list():
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
for child_id in fam.get_child_id_list():
|
|
|
|
self.init_list(child_id,gen+1)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsMoreThanNthGenerationDescendantOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsMoreThanNthGenerationDescendantOf(Rule):
|
|
|
|
"""Rule that checks for a person that is a descendant of a specified person
|
|
|
|
at least N generations away"""
|
|
|
|
|
|
|
|
labels = [ _('ID:'), _('Number of generations:') ]
|
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is a descendant of person at least N generations away'
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches people that are descendants of a specified "
|
|
|
|
"person at least N generations away")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _("Descendant filters")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-08-05 09:05:42 +05:30
|
|
|
|
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
root_id = self.list[0]
|
|
|
|
self.init_list(root_id,0)
|
|
|
|
return self.map.has_key(p_id)
|
2003-07-24 22:17:36 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_list(self,p_id,gen):
|
2003-08-05 09:05:42 +05:30
|
|
|
if gen >= int(self.list[1]):
|
2004-03-11 09:01:35 +05:30
|
|
|
self.map[p_id] = 1
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
for fam_id in p.get_family_id_list():
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
for child_id in fam.get_child_id_list():
|
|
|
|
self.init_list(child_id,gen+1)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsChildOfFilterMatch
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsChildOfFilterMatch(Rule):
|
|
|
|
"""Rule that checks for a person that is a child
|
|
|
|
of someone matched by a filter"""
|
|
|
|
|
|
|
|
labels = [ _('Filter name:') ]
|
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is a child of filter match'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person that is a child of someone matched by a filter")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Family filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-07-24 22:17:36 +05:30
|
|
|
|
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
|
|
|
filter = MatchesFilter(self.list)
|
2004-03-11 09:01:35 +05:30
|
|
|
for person_id in db.get_person_keys():
|
|
|
|
if filter.apply (db, person_id):
|
|
|
|
self.init_list (person_id)
|
|
|
|
return self.map.has_key(p_id)
|
2003-07-24 22:17:36 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_list(self,p_id):
|
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
for fam_id in p.get_family_id_list():
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
for child_id in fam.get_child_id_list():
|
|
|
|
self.map[child_id] = 1
|
2003-07-24 22:17:36 +05:30
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsDescendantFamilyOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsDescendantFamilyOf(Rule):
|
|
|
|
"""Rule that checks for a person that is a descendant or the spouse
|
|
|
|
of a descendant of a specified person"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('ID:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return "Is a descendant family member of"
|
|
|
|
|
2003-08-10 10:58:11 +05:30
|
|
|
def category(self):
|
|
|
|
return _('Descendant filters')
|
|
|
|
|
|
|
|
def description(self):
|
2003-09-05 10:08:43 +05:30
|
|
|
return _("Matches people that are descendants or the spouse "
|
2003-08-10 10:58:11 +05:30
|
|
|
"of a descendant of a specified person")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2003-05-23 09:38:03 +05:30
|
|
|
self.map = {}
|
2004-03-11 09:01:35 +05:30
|
|
|
self.orig_id = p_id
|
2004-02-14 11:10:30 +05:30
|
|
|
self.db = db
|
2004-03-11 09:01:35 +05:30
|
|
|
return self.search(p_id,1)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def search(self,p_id,val):
|
|
|
|
if p_id == self.list[0]:
|
|
|
|
self.map[p_id] = 1
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
2004-03-11 09:01:35 +05:30
|
|
|
|
|
|
|
p = self.db.find_person_from_id(p_id)
|
2004-02-14 11:10:30 +05:30
|
|
|
for (f,r1,r2) in p.get_parent_family_id_list():
|
|
|
|
family = self.db.find_family_from_id(f)
|
|
|
|
for person_id in [family.get_mother_id(),family.get_father_id()]:
|
|
|
|
if person_id:
|
2004-03-11 09:01:35 +05:30
|
|
|
if self.search(person_id,0):
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
if val:
|
2004-02-14 11:10:30 +05:30
|
|
|
for family_id in p.get_family_id_list():
|
|
|
|
family = self.db.find_family_from_id(family_id)
|
2004-03-11 09:01:35 +05:30
|
|
|
if p_id == family.get_father_id():
|
2004-02-14 11:10:30 +05:30
|
|
|
spouse_id = family.get_mother_id()
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
2004-02-14 11:10:30 +05:30
|
|
|
spouse_id = family.get_father_id()
|
|
|
|
if spouse_id:
|
2004-03-11 09:01:35 +05:30
|
|
|
if self.search(spouse_id,0):
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsAncestorOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsAncestorOf(Rule):
|
|
|
|
"""Rule that checks for a person that is an ancestor of a specified person"""
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
labels = [ _('ID:'), _('Inclusive:') ]
|
2003-05-23 09:38:03 +05:30
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
2003-06-12 07:34:42 +05:30
|
|
|
self.init = 0
|
2003-05-23 09:38:03 +05:30
|
|
|
self.map = {}
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is an ancestor of'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches people that are ancestors of a specified person")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _("Ancestral filters")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2003-09-09 07:18:30 +05:30
|
|
|
"""Assume that if 'Inclusive' not defined, assume inclusive"""
|
2004-03-11 09:01:35 +05:30
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-09-09 07:18:30 +05:30
|
|
|
try:
|
|
|
|
if int(self.list[1]):
|
|
|
|
first = 0
|
|
|
|
else:
|
|
|
|
first = 1
|
|
|
|
except IndexError:
|
2003-09-05 10:08:43 +05:30
|
|
|
first = 1
|
2003-09-09 07:18:30 +05:30
|
|
|
|
2003-06-12 07:34:42 +05:30
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
root_id = self.list[0]
|
|
|
|
self.init_ancestor_list(root_id,first)
|
|
|
|
return self.map.has_key(p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_ancestor_list(self,p_id,first):
|
2003-08-05 09:05:42 +05:30
|
|
|
if not first:
|
2004-03-11 09:01:35 +05:30
|
|
|
self.map[p_id] = 1
|
2003-06-12 07:34:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
fam_id = p.get_main_parents_family_id()
|
|
|
|
if fam_id:
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
f_id = fam.get_father_id()
|
|
|
|
m_id = fam.get_mother_id()
|
2003-06-12 07:34:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
if f_id:
|
|
|
|
self.init_ancestor_list(f_id,0)
|
|
|
|
if m_id:
|
|
|
|
self.init_ancestor_list(m_id,0)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsAncestorOfFilterMatch
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2003-08-05 09:05:42 +05:30
|
|
|
class IsAncestorOfFilterMatch(IsAncestorOf):
|
2003-07-24 22:17:36 +05:30
|
|
|
"""Rule that checks for a person that is an ancestor of
|
|
|
|
someone matched by a filter"""
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
labels = [ _('Filter name:'), _('Inclusive:') ]
|
2003-07-24 22:17:36 +05:30
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
IsAncestorOf.__init__(self,list)
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is an ancestor of filter match'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches people that are ancestors "
|
2003-09-30 09:49:35 +05:30
|
|
|
"of someone matched by a filter")
|
2003-09-05 10:08:43 +05:30
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _("Ancestral filters")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
2003-09-09 07:18:30 +05:30
|
|
|
try:
|
|
|
|
if int(self.list[1]):
|
|
|
|
first = 0
|
|
|
|
else:
|
|
|
|
first = 1
|
|
|
|
except IndexError:
|
2003-09-05 10:08:43 +05:30
|
|
|
first = 1
|
2003-09-09 07:18:30 +05:30
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2003-09-05 10:08:43 +05:30
|
|
|
filter = MatchesFilter(self.list[0])
|
2004-03-11 09:01:35 +05:30
|
|
|
for person_id in db.get_person_keys():
|
|
|
|
if filter.apply (db, person_id):
|
|
|
|
self.init_ancestor_list (person_id,first)
|
|
|
|
return self.map.has_key(p_id)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsLessThanNthGenerationAncestorOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsLessThanNthGenerationAncestorOf(Rule):
|
|
|
|
"""Rule that checks for a person that is an ancestor of a specified person
|
|
|
|
not more than N generations away"""
|
|
|
|
|
|
|
|
labels = [ _('ID:'), _('Number of generations:') ]
|
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is an ancestor of person not more than N generations away'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches people that are ancestors "
|
|
|
|
"of a specified person not more than N generations away")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _("Ancestral filters")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-08-05 09:05:42 +05:30
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
root_id = self.list[0]
|
|
|
|
self.init_ancestor_list(root_id,0)
|
|
|
|
return self.map.has_key(p_id)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_ancestor_list(self,p_id,gen):
|
2004-02-14 11:10:30 +05:30
|
|
|
# if self.map.has_key(p.get_id()) == 1:
|
2003-08-05 09:05:42 +05:30
|
|
|
# loop_error(self.orig,p)
|
|
|
|
if gen:
|
2004-03-11 09:01:35 +05:30
|
|
|
self.map[p_id] = 1
|
2003-08-05 09:05:42 +05:30
|
|
|
if gen >= int(self.list[1]):
|
|
|
|
return
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
fam_id = p.get_main_parents_family_id()
|
|
|
|
if fam_id:
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
f_id = fam.get_father_id()
|
|
|
|
m_id = fam.get_mother_id()
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
if f_id:
|
|
|
|
self.init_ancestor_list(f_id,gen+1)
|
|
|
|
if m_id:
|
|
|
|
self.init_ancestor_list(m_id,gen+1)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsMoreThanNthGenerationAncestorOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsMoreThanNthGenerationAncestorOf(Rule):
|
|
|
|
"""Rule that checks for a person that is an ancestor of a specified person
|
|
|
|
at least N generations away"""
|
|
|
|
|
|
|
|
labels = [ _('ID:'), _('Number of generations:') ]
|
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is an ancestor of person at least N generations away'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches people that are ancestors "
|
|
|
|
"of a specified person at least N generations away")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _("Ancestral filters")
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-08-05 09:05:42 +05:30
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
root_id = self.list[0]
|
|
|
|
self.init_ancestor_list(root_id,0)
|
|
|
|
return self.map.has_key(p_id)
|
2003-07-24 22:17:36 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_ancestor_list(self,p_id,gen):
|
2004-02-14 11:10:30 +05:30
|
|
|
# if self.map.has_key(p.get_id()) == 1:
|
2003-08-05 09:05:42 +05:30
|
|
|
# loop_error(self.orig,p)
|
|
|
|
if gen >= int(self.list[1]):
|
2004-03-11 09:01:35 +05:30
|
|
|
self.map[p_id] = 1
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
fam_id = p.get_main_parents_family_id()
|
|
|
|
if fam_id:
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
f_id = fam.get_father_id()
|
|
|
|
m_id = fam.get_mother_id()
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
if f_id:
|
|
|
|
self.init_ancestor_list(f_id,gen+1)
|
|
|
|
if m_id:
|
|
|
|
self.init_ancestor_list(m_id,gen+1)
|
2003-08-05 09:05:42 +05:30
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsParentOfFilterMatch
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsParentOfFilterMatch(Rule):
|
|
|
|
"""Rule that checks for a person that is a parent
|
|
|
|
of someone matched by a filter"""
|
|
|
|
|
|
|
|
labels = [ _('Filter name:') ]
|
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
self.init = 0
|
|
|
|
self.map = {}
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is a parent of filter match'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person that is a parent of someone matched by a filter")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Family filters')
|
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
def apply(self,db,p):
|
2004-03-11 09:01:35 +05:30
|
|
|
self.orig_id = p_id
|
|
|
|
self.db = db
|
2003-07-24 22:17:36 +05:30
|
|
|
|
|
|
|
if not self.init:
|
|
|
|
self.init = 1
|
|
|
|
filter = MatchesFilter(self.list)
|
2004-03-11 09:01:35 +05:30
|
|
|
for person_id in db.get_person_keys():
|
|
|
|
if filter.apply (db, person_id):
|
|
|
|
self.init_list (person_id)
|
|
|
|
return self.map.has_key(p_id)
|
2003-07-24 22:17:36 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def init_list(self,p_id):
|
|
|
|
p = self.db.find_person_from_id(p_id)
|
|
|
|
for fam_id in p.get_main_parents_family_id():
|
|
|
|
fam = self.db.find_family_from_id(fam_id)
|
|
|
|
for parent_id in [fam.get_father_id (), fam.get_mother_id ()]:
|
|
|
|
if parent_id:
|
|
|
|
self.map[parent_id] = 1
|
2003-07-24 22:17:36 +05:30
|
|
|
|
2003-01-06 10:44:49 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasCommonAncestorWith
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasCommonAncestorWith(Rule):
|
|
|
|
"""Rule that checks for a person that has a common ancestor with a specified person"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('ID:') ]
|
2003-01-06 10:44:49 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has a common ancestor with'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches people that have a common ancestor "
|
|
|
|
"with a specified person")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _("Ancestral filters")
|
|
|
|
|
2003-01-06 10:44:49 +05:30
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
|
|
|
# Keys in `ancestor_cache' are ancestors of list[0].
|
|
|
|
# We delay the computation of ancestor_cache until the
|
|
|
|
# first use, because it's not uncommon to instantiate
|
|
|
|
# this class and not use it.
|
|
|
|
self.ancestor_cache = {}
|
|
|
|
|
|
|
|
def init_ancestor_cache(self,db):
|
|
|
|
# list[0] is an Id, but we need to pass a Person to for_each_ancestor.
|
2004-03-11 09:01:35 +05:30
|
|
|
p_id = self.list[0]
|
|
|
|
if p_id:
|
2003-01-06 10:44:49 +05:30
|
|
|
def init(self,pid): self.ancestor_cache[pid] = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
for_each_ancestor([p_id],init,self)
|
2003-01-06 10:44:49 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2003-01-06 10:44:49 +05:30
|
|
|
# On the first call, we build the ancestor cache for the
|
|
|
|
# reference person. Then, for each person to test,
|
|
|
|
# we browse his ancestors until we found one in the cache.
|
|
|
|
if len(self.ancestor_cache) == 0:
|
|
|
|
self.init_ancestor_cache(db)
|
2004-03-11 09:01:35 +05:30
|
|
|
return for_each_ancestor([p_id],
|
|
|
|
lambda self,p_id: self.ancestor_cache.has_key(p_id),
|
2003-01-06 10:44:49 +05:30
|
|
|
self);
|
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasCommonAncestorWithFilterMatch
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith):
|
|
|
|
"""Rule that checks for a person that has a common ancestor with
|
|
|
|
someone matching a filter"""
|
|
|
|
|
|
|
|
labels = [ _('Filter name:') ]
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has a common ancestor with filter match'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches people that have a common ancestor "
|
|
|
|
"with someone matched by a filter")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _("Ancestral filters")
|
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
def __init__(self,list):
|
|
|
|
HasCommonAncestorWith.__init__(self,list)
|
|
|
|
|
|
|
|
def init_ancestor_cache(self,db):
|
|
|
|
filter = MatchesFilter(self.list)
|
|
|
|
def init(self,pid): self.ancestor_cache[pid] = 1
|
2004-03-11 09:01:35 +05:30
|
|
|
for p_id in db.get_person_keys():
|
|
|
|
if (not self.ancestor_cache.has_key (p_id)
|
|
|
|
and filter.apply (db, p_id)):
|
|
|
|
for_each_ancestor([p_id],init,self)
|
2003-07-24 22:17:36 +05:30
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsMale
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsMale(Rule):
|
|
|
|
"""Rule that checks for a person that is a male"""
|
|
|
|
|
|
|
|
labels = []
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is a male'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def category(self):
|
|
|
|
return _('General filters')
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _('Matches all males')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2004-04-28 09:36:25 +05:30
|
|
|
return db.find_person_from_id(p_id).get_gender() == RelLib.Person.male
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasEvent
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasEvent(Rule):
|
|
|
|
"""Rule that checks for a person with a particular value"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('Personal event:'), _('Date:'), _('Place:'), _('Description:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
2004-01-21 08:26:53 +05:30
|
|
|
if self.list and self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
self.date = Date.Date()
|
|
|
|
self.date.set(self.list[0])
|
|
|
|
else:
|
|
|
|
self.date = None
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the personal event'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person with a personal event of a particular value")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Event filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
p = db.find_person_from_id(p_id)
|
|
|
|
for event_id in p.get_event_list():
|
|
|
|
if not event_id:
|
|
|
|
continue
|
|
|
|
event = db.find_event_from_id(event_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 1
|
2004-02-14 11:10:30 +05:30
|
|
|
if self.list[0] and event.get_name() != self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.list[3] and string.find(event.get_description().upper(),
|
|
|
|
self.list[3].upper())==-1:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
|
|
|
if self.date:
|
2004-02-14 11:10:30 +05:30
|
|
|
if date_cmp(self.date,event.get_date_object()):
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
2003-03-12 08:32:08 +05:30
|
|
|
if self.list[2]:
|
2004-03-11 09:01:35 +05:30
|
|
|
pl_id = event.get_place_id()
|
|
|
|
if pl_id:
|
|
|
|
pl = db.find_place_from_id(pl_id)
|
|
|
|
pn = pl.get_title()
|
2004-04-30 08:31:51 +05:30
|
|
|
if string.find(pn.upper(),self.list[2].upper()) == -1:
|
2004-03-11 09:01:35 +05:30
|
|
|
val = 0
|
|
|
|
if val == 1:
|
|
|
|
return 1
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasFamilyEvent
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasFamilyEvent(Rule):
|
|
|
|
"""Rule that checks for a person who has a relationship event
|
|
|
|
with a particular value"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('Family event:'), _('Date:'), _('Place:'), _('Description:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
2004-01-21 08:26:53 +05:30
|
|
|
if self.list and self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
self.date = Date.Date()
|
|
|
|
self.date.set(self.list[0])
|
|
|
|
else:
|
|
|
|
self.date = None
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the family event'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person with a family event of a particular value")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Event filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
p = db.find_person_from_id(p_id)
|
|
|
|
for f_id in p.get_family_id_list():
|
|
|
|
f = db.find_family_from_id(f_id)
|
|
|
|
for event_id in f.get_event_list():
|
|
|
|
if not event_id:
|
|
|
|
continue
|
|
|
|
event = db.find_event_from_id(event_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 1
|
2004-02-14 11:10:30 +05:30
|
|
|
if self.list[0] and event.get_name() != self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
|
|
|
v = self.list[3]
|
2004-04-30 08:31:51 +05:30
|
|
|
if v and string.find(event.get_description().upper(),v.upper())==-1:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
|
|
|
if self.date:
|
2004-02-14 11:10:30 +05:30
|
|
|
if date_cmp(self.date,event.get_date_object()):
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
2004-03-11 09:01:35 +05:30
|
|
|
pl_id = event.get_place_id()
|
|
|
|
if pl_id:
|
|
|
|
pl = db.find_place_from_id(pl_id)
|
|
|
|
pn = pl.get_title()
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.list[2] and string.find(pn,self.list[2].upper()) == -1:
|
2004-03-11 09:01:35 +05:30
|
|
|
val = 0
|
|
|
|
if val == 1:
|
|
|
|
return 1
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasRelationship
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasRelationship(Rule):
|
|
|
|
"""Rule that checks for a person who has a particular relationship"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('Number of relationships:'),
|
|
|
|
_('Relationship type:'),
|
|
|
|
_('Number of children:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the relationships'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person who has a particular relationship")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Family filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
rel_type = 0
|
|
|
|
cnt = 0
|
2004-03-11 09:01:35 +05:30
|
|
|
p = db.find_person_from_id(p_id)
|
2004-02-14 11:10:30 +05:30
|
|
|
num_rel = len(p.get_family_id_list())
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
# count children and look for a relationship type match
|
2004-03-11 09:01:35 +05:30
|
|
|
for f_id in p.get_family_id_list():
|
|
|
|
f = db.find_family_from_id(f_id)
|
2004-02-14 11:10:30 +05:30
|
|
|
cnt = cnt + len(f.get_child_id_list())
|
|
|
|
if self.list[1] and f.get_relationship() == self.list[1]:
|
2002-10-20 19:55:16 +05:30
|
|
|
rel_type = 1
|
|
|
|
|
|
|
|
# if number of relations specified
|
|
|
|
if self.list[0]:
|
|
|
|
try:
|
|
|
|
v = int(self.list[0])
|
|
|
|
except:
|
|
|
|
return 0
|
|
|
|
if v != num_rel:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
# number of childred
|
|
|
|
if self.list[2]:
|
|
|
|
try:
|
|
|
|
v = int(self.list[2])
|
|
|
|
except:
|
|
|
|
return 0
|
|
|
|
if v != cnt:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
# relation
|
|
|
|
if self.list[1]:
|
|
|
|
return rel_type == 1
|
|
|
|
else:
|
|
|
|
return 1
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasBirth
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasBirth(Rule):
|
|
|
|
"""Rule that checks for a person with a birth of a particular value"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('Date:'), _('Place:'), _('Description:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
2004-01-21 08:26:53 +05:30
|
|
|
if self.list and self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
self.date = Date.Date()
|
|
|
|
self.date.set(self.list[0])
|
|
|
|
else:
|
|
|
|
self.date = None
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the birth'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person with a birth of a particular value")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Event filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
p = db.find_person_from_id(p_id)
|
|
|
|
event_id = p.get_birth_id()
|
|
|
|
if not event_id:
|
|
|
|
return 0
|
|
|
|
event = db.find_event_from_id(event_id)
|
2004-02-14 11:10:30 +05:30
|
|
|
ed = event.get_description().upper()
|
2004-04-30 08:31:51 +05:30
|
|
|
if len(self.list) > 2 and string.find(ed,self.list[2].upper())==-1:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
|
|
|
if self.date:
|
2004-02-14 11:10:30 +05:30
|
|
|
if date_cmp(self.date,event.get_date_object()) == 0:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
2004-03-11 09:01:35 +05:30
|
|
|
pl_id = event.get_place_id()
|
|
|
|
if pl_id:
|
|
|
|
pl = db.find_place_from_id(pl_id)
|
|
|
|
pn = pl.get_title()
|
2004-04-30 08:31:51 +05:30
|
|
|
if len(self.list) > 1 and string.find(pn,self.list[1].upper()) == -1:
|
2004-03-11 09:01:35 +05:30
|
|
|
return 0
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasDeath
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasDeath(Rule):
|
|
|
|
"""Rule that checks for a person with a death of a particular value"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('Date:'), _('Place:'), _('Description:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def __init__(self,list):
|
|
|
|
Rule.__init__(self,list)
|
2004-01-21 08:26:53 +05:30
|
|
|
if self.list and self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
self.date = Date.Date()
|
|
|
|
self.date.set(self.list[0])
|
|
|
|
else:
|
|
|
|
self.date = None
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the death'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person with a death of a particular value")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Event filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
p = db.find_person_from_id(p_id)
|
|
|
|
event_id = p.get_death_id()
|
|
|
|
if not event_id:
|
|
|
|
return 0
|
|
|
|
event = db.find_event_from_id(event_id)
|
2004-02-14 11:10:30 +05:30
|
|
|
ed = event.get_description().upper()
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.list[2] and string.find(ed,self.list[2].upper())==-1:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
|
|
|
if self.date:
|
2004-02-14 11:10:30 +05:30
|
|
|
if date_cmp(self.date,event.get_date_object()) == 0:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
2004-03-11 09:01:35 +05:30
|
|
|
pl_id = event.get_place_id()
|
|
|
|
if pl_id:
|
|
|
|
pl = db.find_place_from_id(pl_id)
|
|
|
|
pn = pl.get_title()
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.list[1] and string.find(pn,self.list[1].upper()) == -1:
|
2004-03-11 09:01:35 +05:30
|
|
|
return 0
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasAttribute
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasAttribute(Rule):
|
|
|
|
"""Rule that checks for a person with a particular personal attribute"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('Personal attribute:'), _('Value:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the personal attribute'
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
p = db.find_person_from_id(p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
for event in p.getAttributes():
|
2004-02-14 11:10:30 +05:30
|
|
|
if self.list[0] and event.get_type() != self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
2004-02-14 11:10:30 +05:30
|
|
|
ev = event.get_value().upper()
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.list[1] and string.find(ev,self.list[1].upper())==-1:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
|
|
|
return 1
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasFamilyAttribute
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasFamilyAttribute(Rule):
|
|
|
|
"""Rule that checks for a person with a particular family attribute"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [ _('Family attribute:'), _('Value:') ]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has the family attribute'
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
|
|
|
p = db.find_person_from_id(p_id)
|
|
|
|
for f_id in p.get_family_id_list():
|
|
|
|
f = db.find_family_from_id(f_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
for event in f.getAttributes():
|
|
|
|
val = 1
|
2004-02-14 11:10:30 +05:30
|
|
|
if self.list[0] and event.get_type() != self.list[0]:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
2004-02-14 11:10:30 +05:30
|
|
|
ev = event.get_value().upper()
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.list[1] and string.find(ev,self.list[1].upper())==-1:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
|
|
|
if val == 1:
|
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasNameOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class HasNameOf(Rule):
|
|
|
|
"""Rule that checks for full or partial name matches"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [_('Given name:'),_('Family name:'),_('Suffix:'),_('Title:')]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Has a name'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person with a specified (partial) name")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('General filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
self.f = self.list[0]
|
|
|
|
self.l = self.list[1]
|
|
|
|
self.s = self.list[2]
|
|
|
|
self.t = self.list[3]
|
2004-03-11 09:01:35 +05:30
|
|
|
p = db.find_person_from_id(p_id)
|
2004-02-14 11:10:30 +05:30
|
|
|
for name in [p.get_primary_name()] + p.get_alternate_names():
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 1
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.f and string.find(name.get_first_name().upper(),self.f.upper()) == -1:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.l and string.find(name.get_surname().upper(),self.l.upper()) == -1:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.s and string.find(name.get_suffix().upper(),self.s.upper()) == -1:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
2004-04-30 08:31:51 +05:30
|
|
|
if self.t and string.find(name.get_title().upper(),self.t.upper()) == -1:
|
2002-10-20 19:55:16 +05:30
|
|
|
val = 0
|
|
|
|
if val == 1:
|
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
2004-04-30 08:31:51 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HasNameOf
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class SearchName(Rule):
|
|
|
|
"""Rule that checks for full or partial name matches"""
|
|
|
|
|
|
|
|
labels = [_('Substring:')]
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Matches name'
|
|
|
|
|
|
|
|
def description(self):
|
|
|
|
return _("Matches the person with a specified (partial) name")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('General filters')
|
|
|
|
|
|
|
|
def apply(self,db,p_id):
|
|
|
|
self.f = self.list[0]
|
|
|
|
p = db.find_person_from_id(p_id)
|
|
|
|
return self.f and string.find(p.get_primary_name().get_name().upper(),self.f.upper()) != -1
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-03-25 10:56:05 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# MatchesFilter
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2002-10-20 19:55:16 +05:30
|
|
|
class MatchesFilter(Rule):
|
|
|
|
"""Rule that checks against another filter"""
|
|
|
|
|
2003-03-07 07:51:18 +05:30
|
|
|
labels = [_('Filter name:')]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Matches the filter named'
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
for filter in SystemFilters.get_filters():
|
|
|
|
if filter.get_name() == self.list[0]:
|
2004-03-11 09:01:35 +05:30
|
|
|
return filter.check(p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
for filter in CustomFilters.get_filters():
|
|
|
|
if filter.get_name() == self.list[0]:
|
2004-03-11 09:01:35 +05:30
|
|
|
return filter.check(db,p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
2003-06-12 07:34:42 +05:30
|
|
|
|
2003-07-24 22:17:36 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# IsSpouseOfFilterMatch
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class IsSpouseOfFilterMatch(Rule):
|
|
|
|
"""Rule that checks for a person married to someone matching
|
|
|
|
a filter"""
|
|
|
|
|
|
|
|
labels = [_('Filter name:')]
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
return 'Is spouse of filter match'
|
|
|
|
|
2003-09-05 10:08:43 +05:30
|
|
|
def description(self):
|
|
|
|
return _("Matches the person married to someone matching a filter")
|
|
|
|
|
|
|
|
def category(self):
|
|
|
|
return _('Family filters')
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,p_id):
|
2003-07-24 22:17:36 +05:30
|
|
|
filter = MatchesFilter (self.list)
|
2004-03-11 09:01:35 +05:30
|
|
|
p = db.find_person_from_id(p_id)
|
|
|
|
for family_id in p.get_family_id_list ():
|
|
|
|
family = db.find_family_from_id(family_id)
|
|
|
|
for spouse_id in [family.get_father_id (), family.get_mother_id ()]:
|
|
|
|
if not spouse_id:
|
2003-07-24 22:17:36 +05:30
|
|
|
continue
|
2004-03-11 09:01:35 +05:30
|
|
|
if spouse_id == p_id:
|
2003-07-24 22:17:36 +05:30
|
|
|
continue
|
2004-03-11 09:01:35 +05:30
|
|
|
if filter.apply (db, spouse_id):
|
2003-07-24 22:17:36 +05:30
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GenericFilter
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class GenericFilter:
|
|
|
|
"""Filter class that consists of several rules"""
|
|
|
|
|
|
|
|
def __init__(self,source=None):
|
|
|
|
if source:
|
2004-04-30 08:31:51 +05:30
|
|
|
self.need_param = source.need_param
|
2002-10-20 19:55:16 +05:30
|
|
|
self.flist = source.flist[:]
|
|
|
|
self.name = source.name
|
|
|
|
self.comment = source.comment
|
|
|
|
self.logical_op = source.logical_op
|
|
|
|
self.invert = source.invert
|
|
|
|
else:
|
2004-04-30 08:31:51 +05:30
|
|
|
self.need_param = 0
|
2002-10-20 19:55:16 +05:30
|
|
|
self.flist = []
|
|
|
|
self.name = ''
|
|
|
|
self.comment = ''
|
|
|
|
self.logical_op = 'and'
|
|
|
|
self.invert = 0
|
|
|
|
|
|
|
|
def set_logical_op(self,val):
|
|
|
|
if val in const.logical_functions:
|
|
|
|
self.logical_op = val
|
|
|
|
else:
|
|
|
|
self.logical_op = 'and'
|
|
|
|
|
|
|
|
def get_logical_op(self):
|
|
|
|
return self.logical_op
|
|
|
|
|
|
|
|
def set_invert(self, val):
|
|
|
|
self.invert = not not val
|
|
|
|
|
|
|
|
def get_invert(self):
|
|
|
|
return self.invert
|
|
|
|
|
|
|
|
def get_name(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
def set_name(self,name):
|
|
|
|
self.name = name
|
|
|
|
|
|
|
|
def set_comment(self,comment):
|
|
|
|
self.comment = comment
|
|
|
|
|
|
|
|
def get_comment(self):
|
|
|
|
return self.comment
|
|
|
|
|
|
|
|
def add_rule(self,rule):
|
|
|
|
self.flist.append(rule)
|
|
|
|
|
2003-03-12 08:32:08 +05:30
|
|
|
def delete_rule(self,rule):
|
|
|
|
self.flist.remove(rule)
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
def set_rules(self,rules):
|
|
|
|
self.flist = rules
|
|
|
|
|
|
|
|
def get_rules(self):
|
|
|
|
return self.flist
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def check_or(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
test = 0
|
|
|
|
for rule in self.flist:
|
2004-03-11 09:01:35 +05:30
|
|
|
test = test or rule.apply(db,p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
if test:
|
|
|
|
break
|
|
|
|
if self.invert:
|
|
|
|
return not test
|
|
|
|
else:
|
|
|
|
return test
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def check_xor(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
test = 0
|
|
|
|
for rule in self.flist:
|
2004-03-11 09:01:35 +05:30
|
|
|
temp = rule.apply(db,p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
test = ((not test) and temp) or (test and (not temp))
|
|
|
|
if self.invert:
|
|
|
|
return not test
|
|
|
|
else:
|
|
|
|
return test
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def check_one(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
count = 0
|
|
|
|
for rule in self.flist:
|
2004-03-11 09:01:35 +05:30
|
|
|
if rule.apply(db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
count = count + 1
|
|
|
|
if count > 1:
|
|
|
|
break
|
|
|
|
if self.invert:
|
|
|
|
return count != 1
|
|
|
|
else:
|
|
|
|
return count == 1
|
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def check_and(self,db,p_id):
|
2002-10-20 19:55:16 +05:30
|
|
|
test = 1
|
|
|
|
for rule in self.flist:
|
2004-03-11 09:01:35 +05:30
|
|
|
test = test and rule.apply(db,p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
if not test:
|
|
|
|
break
|
|
|
|
if self.invert:
|
|
|
|
return not test
|
|
|
|
else:
|
|
|
|
return test
|
|
|
|
|
2003-01-06 10:44:49 +05:30
|
|
|
def get_check_func(self):
|
2002-10-20 19:55:16 +05:30
|
|
|
try:
|
|
|
|
m = getattr(self, 'check_' + self.logical_op)
|
|
|
|
except AttributeError:
|
|
|
|
m = self.check_and
|
2003-01-06 10:44:49 +05:30
|
|
|
return m
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def check(self,db,p_id):
|
|
|
|
return self.get_check_func()(db,p_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2004-03-11 09:01:35 +05:30
|
|
|
def apply(self,db,id_list):
|
2003-01-06 10:44:49 +05:30
|
|
|
m = self.get_check_func()
|
|
|
|
res = []
|
2004-03-11 09:01:35 +05:30
|
|
|
for p_id in id_list:
|
|
|
|
if m(db,p_id):
|
|
|
|
res.append(p_id)
|
2003-01-06 10:44:49 +05:30
|
|
|
return res
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Name to class mappings
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
tasks = {
|
2004-04-30 08:31:51 +05:30
|
|
|
unicode(_("Everyone")) : Everyone,
|
2004-01-21 04:58:44 +05:30
|
|
|
unicode(_("Has the Id")) : HasIdOf,
|
|
|
|
unicode(_("Has a name")) : HasNameOf,
|
|
|
|
unicode(_("Has the relationships")) : HasRelationship,
|
|
|
|
unicode(_("Has the death")) : HasDeath,
|
|
|
|
unicode(_("Has the birth")) : HasBirth,
|
|
|
|
unicode(_("Is a descendant of")) : IsDescendantOf,
|
|
|
|
unicode(_("Is a descendant family member of")) : IsDescendantFamilyOf,
|
|
|
|
unicode(_("Is a descendant of filter match")) : IsDescendantOfFilterMatch,
|
2004-01-20 09:27:19 +05:30
|
|
|
unicode(_("Is a descendant of person not more than N generations away"))
|
2004-04-30 08:31:51 +05:30
|
|
|
: IsLessThanNthGenerationDescendantOf,
|
2004-01-20 09:27:19 +05:30
|
|
|
unicode(_("Is a descendant of person at least N generations away"))
|
2004-04-30 08:31:51 +05:30
|
|
|
: IsMoreThanNthGenerationDescendantOf,
|
2004-01-21 04:58:44 +05:30
|
|
|
unicode(_("Is a child of filter match")) : IsChildOfFilterMatch,
|
|
|
|
unicode(_("Is an ancestor of")) : IsAncestorOf,
|
|
|
|
unicode(_("Is an ancestor of filter match")) : IsAncestorOfFilterMatch,
|
2004-01-20 09:27:19 +05:30
|
|
|
unicode(_("Is an ancestor of person not more than N generations away"))
|
2004-04-30 08:31:51 +05:30
|
|
|
: IsLessThanNthGenerationAncestorOf,
|
2004-01-20 09:27:19 +05:30
|
|
|
unicode(_("Is an ancestor of person at least N generations away"))
|
2004-04-30 08:31:51 +05:30
|
|
|
: IsMoreThanNthGenerationAncestorOf,
|
2004-01-21 04:58:44 +05:30
|
|
|
unicode(_("Is a parent of filter match")) : IsParentOfFilterMatch,
|
|
|
|
unicode(_("Has a common ancestor with")) : HasCommonAncestorWith,
|
2004-01-20 09:27:19 +05:30
|
|
|
unicode(_("Has a common ancestor with filter match"))
|
2004-04-30 08:31:51 +05:30
|
|
|
: HasCommonAncestorWithFilterMatch,
|
2004-01-21 04:58:44 +05:30
|
|
|
unicode(_("Is a female")) : IsFemale,
|
|
|
|
unicode(_("Is a male")) : IsMale,
|
|
|
|
unicode(_("Has complete record")) : HasCompleteRecord,
|
|
|
|
unicode(_("Has the personal event")) : HasEvent,
|
|
|
|
unicode(_("Has the family event")) : HasFamilyEvent,
|
|
|
|
unicode(_("Has the personal attribute")) : HasAttribute,
|
|
|
|
unicode(_("Has the family attribute")) : HasFamilyAttribute,
|
|
|
|
unicode(_("Matches the filter named")) : MatchesFilter,
|
|
|
|
unicode(_("Is spouse of filter match")) : IsSpouseOfFilterMatch,
|
|
|
|
unicode(_("Relationship path between two people")) : RelationshipPathBetween,
|
2002-10-20 19:55:16 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GenericFilterList
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class GenericFilterList:
|
|
|
|
"""Container class for the generic filters. Stores, saves, and
|
|
|
|
loads the filters."""
|
|
|
|
|
|
|
|
def __init__(self,file):
|
|
|
|
self.filter_list = []
|
|
|
|
self.file = os.path.expanduser(file)
|
|
|
|
|
|
|
|
def get_filters(self):
|
|
|
|
return self.filter_list
|
|
|
|
|
|
|
|
def add(self,filter):
|
|
|
|
self.filter_list.append(filter)
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
try:
|
|
|
|
parser = make_parser()
|
|
|
|
parser.setContentHandler(FilterParser(self))
|
2003-01-06 10:44:49 +05:30
|
|
|
if self.file[0:7] != "file://":
|
2003-03-12 08:32:08 +05:30
|
|
|
parser.parse("file://" + self.file)
|
|
|
|
else:
|
|
|
|
parser.parse(self.file)
|
2002-10-20 19:55:16 +05:30
|
|
|
except (IOError,OSError,SAXParseException):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def fix(self,line):
|
2003-06-12 07:34:42 +05:30
|
|
|
l = line.strip()
|
|
|
|
l = l.replace('&','&')
|
|
|
|
l = l.replace('>','>')
|
|
|
|
l = l.replace('<','<')
|
|
|
|
return l.replace('"','"')
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def save(self):
|
2003-03-12 08:32:08 +05:30
|
|
|
# try:
|
|
|
|
# f = open(self.file,'w')
|
|
|
|
# except:
|
|
|
|
# return
|
|
|
|
|
2003-09-14 09:51:44 +05:30
|
|
|
f = open(self.file.encode('utf-8'),'w')
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-01-29 10:13:12 +05:30
|
|
|
f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
2002-10-20 19:55:16 +05:30
|
|
|
f.write('<filters>\n')
|
|
|
|
for i in self.filter_list:
|
|
|
|
f.write(' <filter name="%s"' % self.fix(i.get_name()))
|
|
|
|
if i.get_invert():
|
|
|
|
f.write(' invert="1"')
|
|
|
|
f.write(' function="%s"' % i.get_logical_op())
|
|
|
|
comment = i.get_comment()
|
|
|
|
if comment:
|
|
|
|
f.write(' comment="%s"' % self.fix(comment))
|
|
|
|
f.write('>\n')
|
|
|
|
for rule in i.get_rules():
|
|
|
|
f.write(' <rule class="%s">\n' % self.fix(rule.name()))
|
|
|
|
for v in rule.values():
|
|
|
|
f.write(' <arg value="%s"/>\n' % self.fix(v))
|
|
|
|
f.write(' </rule>\n')
|
|
|
|
f.write(' </filter>\n')
|
|
|
|
f.write('</filters>\n')
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# FilterParser
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
class FilterParser(handler.ContentHandler):
|
|
|
|
"""Parses the XML file and builds the list of filters"""
|
|
|
|
|
|
|
|
def __init__(self,gfilter_list):
|
|
|
|
handler.ContentHandler.__init__(self)
|
|
|
|
self.gfilter_list = gfilter_list
|
|
|
|
self.f = None
|
|
|
|
self.r = None
|
|
|
|
self.a = []
|
|
|
|
self.cname = None
|
|
|
|
|
|
|
|
def setDocumentLocator(self,locator):
|
|
|
|
self.locator = locator
|
|
|
|
|
|
|
|
def startElement(self,tag,attrs):
|
|
|
|
if tag == "filter":
|
|
|
|
self.f = GenericFilter()
|
2002-11-19 09:45:02 +05:30
|
|
|
self.f.set_name(attrs['name'])
|
2002-10-20 19:55:16 +05:30
|
|
|
if attrs.has_key('function'):
|
|
|
|
try:
|
2002-11-19 09:45:02 +05:30
|
|
|
if int(attrs['function']):
|
2002-10-20 19:55:16 +05:30
|
|
|
op = 'or'
|
|
|
|
else:
|
|
|
|
op = 'and'
|
|
|
|
except ValueError:
|
2002-11-19 09:45:02 +05:30
|
|
|
op = attrs['function']
|
2002-10-20 19:55:16 +05:30
|
|
|
self.f.set_logical_op(op)
|
|
|
|
if attrs.has_key('comment'):
|
2002-11-19 09:45:02 +05:30
|
|
|
self.f.set_comment(attrs['comment'])
|
2002-10-20 19:55:16 +05:30
|
|
|
if attrs.has_key('invert'):
|
|
|
|
try:
|
2002-11-19 09:45:02 +05:30
|
|
|
self.f.set_invert(int(attrs['invert']))
|
2002-10-20 19:55:16 +05:30
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
self.gfilter_list.add(self.f)
|
|
|
|
elif tag == "rule":
|
2003-02-04 00:54:27 +05:30
|
|
|
cname = attrs['class']
|
2004-01-21 04:58:44 +05:30
|
|
|
name = unicode(_(cname))
|
2002-10-20 19:55:16 +05:30
|
|
|
self.a = []
|
|
|
|
self.cname = tasks[name]
|
|
|
|
elif tag == "arg":
|
2002-11-19 09:45:02 +05:30
|
|
|
self.a.append(attrs['value'])
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def endElement(self,tag):
|
|
|
|
if tag == "rule":
|
|
|
|
rule = self.cname(self.a)
|
|
|
|
self.f.add_rule(rule)
|
|
|
|
|
|
|
|
def characters(self, data):
|
|
|
|
pass
|
|
|
|
|
2004-04-30 08:31:51 +05:30
|
|
|
class ParamFilter(GenericFilter):
|
|
|
|
|
|
|
|
def __init__(self,source=None):
|
|
|
|
GenericFilter.__init__(self,source)
|
|
|
|
self.need_param = 1
|
|
|
|
self.param_list = []
|
|
|
|
|
|
|
|
def set_parameter(self,param):
|
|
|
|
self.param_list = [param]
|
|
|
|
|
|
|
|
def apply(self,db,id_list):
|
|
|
|
for rule in self.flist:
|
|
|
|
rule.set_list(self.param_list)
|
|
|
|
return GenericFilter.apply(self,db,id_list)
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
SystemFilters = None
|
|
|
|
CustomFilters = None
|
|
|
|
|
|
|
|
def reload_system_filters():
|
|
|
|
global SystemFilters
|
|
|
|
SystemFilters = GenericFilterList(const.system_filters)
|
|
|
|
SystemFilters.load()
|
|
|
|
|
|
|
|
def reload_custom_filters():
|
|
|
|
global CustomFilters
|
|
|
|
CustomFilters = GenericFilterList(const.custom_filters)
|
|
|
|
CustomFilters.load()
|
|
|
|
|
|
|
|
if not SystemFilters:
|
|
|
|
reload_system_filters()
|
|
|
|
|
|
|
|
if not CustomFilters:
|
|
|
|
reload_custom_filters()
|
|
|
|
|
2003-10-31 06:56:58 +05:30
|
|
|
def build_filter_menu(local_filters = [], default=""):
|
2002-10-28 19:06:39 +05:30
|
|
|
menu = gtk.Menu()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-10-31 06:56:58 +05:30
|
|
|
active = 0
|
|
|
|
cnt = 0
|
2002-10-20 19:55:16 +05:30
|
|
|
for filter in local_filters:
|
2002-10-28 19:06:39 +05:30
|
|
|
menuitem = gtk.MenuItem(filter.get_name())
|
2002-10-20 19:55:16 +05:30
|
|
|
menuitem.show()
|
|
|
|
menu.append(menuitem)
|
|
|
|
menuitem.set_data("filter", filter)
|
2003-10-31 06:56:58 +05:30
|
|
|
if default != "" and default == filter.get_name():
|
|
|
|
active = cnt
|
|
|
|
cnt += 1
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
for filter in SystemFilters.get_filters():
|
2002-10-28 19:06:39 +05:30
|
|
|
menuitem = gtk.MenuItem(_(filter.get_name()))
|
2002-10-20 19:55:16 +05:30
|
|
|
menuitem.show()
|
|
|
|
menu.append(menuitem)
|
|
|
|
menuitem.set_data("filter", filter)
|
2003-10-31 06:56:58 +05:30
|
|
|
if default != "" and default == filter.get_name():
|
|
|
|
active = cnt
|
|
|
|
cnt += 1
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
for filter in CustomFilters.get_filters():
|
2002-10-28 19:06:39 +05:30
|
|
|
menuitem = gtk.MenuItem(_(filter.get_name()))
|
2002-10-20 19:55:16 +05:30
|
|
|
menuitem.show()
|
|
|
|
menu.append(menuitem)
|
|
|
|
menuitem.set_data("filter", filter)
|
2003-10-31 06:56:58 +05:30
|
|
|
if default != "" and default == filter.get_name():
|
|
|
|
active = cnt
|
|
|
|
cnt += 1
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-10-31 06:56:58 +05:30
|
|
|
if active:
|
|
|
|
menu.set_active(active)
|
|
|
|
elif len(local_filters):
|
2002-10-20 19:55:16 +05:30
|
|
|
menu.set_active(2)
|
|
|
|
elif len(SystemFilters.get_filters()):
|
|
|
|
menu.set_active(4 + len(local_filters))
|
|
|
|
elif len(CustomFilters.get_filters()):
|
|
|
|
menu.set_active(6 + len(local_filters) + len(SystemFilters.get_filters()))
|
|
|
|
else:
|
|
|
|
menu.set_active(0)
|
|
|
|
|
|
|
|
return menu
|