* src/GenericFilter.py: add a filter to return the path to the

common ancestor(s) of two people.
* src/RelLib.py: don't barf on ZODB sorting
*


svn: r2285
This commit is contained in:
Don Allingham 2003-10-23 21:53:53 +00:00
parent 1e54886508
commit 3e532ca523
2 changed files with 141 additions and 30 deletions

View File

@ -136,6 +136,115 @@ class Everyone(Rule):
def apply(self,db,p): def apply(self,db,p):
return 1 return 1
#-------------------------------------------------------------------------
#
# 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.")
def desc_list(self, p, map, first):
if not first:
map[p.getId()] = 1
for fam in p.getFamilyList():
for child in fam.getChildList():
self.desc_list(child,map,0)
def apply_filter(self,rank,person,plist,pmap):
if person == None:
return
plist.append(person)
pmap[person.getId()] = rank
family = person.getMainParents()
if family != None:
self.apply_filter(rank+1,family.getFather(),plist,pmap)
self.apply_filter(rank+1,family.getMother(),plist,pmap)
def apply(self,db,p):
if not self.init:
self.init = 1
root1 = db.getPerson(self.list[0])
root2 = db.getPerson(self.list[1])
self.init_list(root1,root2)
return self.map.has_key(p.getId())
def init_list(self,p1,p2):
firstMap = {}
firstList = []
secondMap = {}
secondList = []
common = []
rank = 9999999
self.apply_filter(0,p1,firstList,firstMap)
self.apply_filter(0,p2,secondList,secondMap)
for person in firstList:
if person in secondList:
new_rank = firstMap[person.getId()]
if new_rank < rank:
rank = new_rank
common = [ person ]
elif new_rank == rank:
common.append(person)
path1 = { p1.getId() : 1}
path2 = { p2.getId() : 1}
print common[0].getId()
print common[1].getId()
for person in common:
new_map = {}
self.desc_list(person,new_map,1)
self.get_intersection(path1,firstMap,new_map)
self.get_intersection(path2,secondMap,new_map)
print "Common Ancestor desc"
print new_map
print "p1 ancestors"
print path1
print "p2 ancestors"
print path2
for e in path1:
self.map[e] = 1
for e in path2:
self.map[e] = 1
for e in common:
self.map[e.getId()] = 1
print path1
print path2
print self.map
def get_intersection(self,target, map1, map2):
for e in map1.keys():
if map2.has_key(e):
target[e] = map2[e]
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# HasIdOf # HasIdOf
@ -1288,38 +1397,39 @@ class GenericFilter:
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
tasks = { tasks = {
_("Everyone") : Everyone, _("Everyone") : Everyone,
_("Has the Id") : HasIdOf, _("Has the Id") : HasIdOf,
_("Has a name") : HasNameOf, _("Has a name") : HasNameOf,
_("Has the relationships") : HasRelationship, _("Has the relationships") : HasRelationship,
_("Has the death") : HasDeath, _("Has the death") : HasDeath,
_("Has the birth") : HasBirth, _("Has the birth") : HasBirth,
_("Is a descendant of") : IsDescendantOf, _("Is a descendant of") : IsDescendantOf,
_("Is a descendant family member of"): IsDescendantFamilyOf, _("Is a descendant family member of") : IsDescendantFamilyOf,
_("Is a descendant of filter match") : IsDescendantOfFilterMatch, _("Is a descendant of filter match") : IsDescendantOfFilterMatch,
_("Is a descendant of person not more than N generations away") _("Is a descendant of person not more than N generations away")
: IsLessThanNthGenerationDescendantOf, : IsLessThanNthGenerationDescendantOf,
_("Is a descendant of person at least N generations away") _("Is a descendant of person at least N generations away")
: IsMoreThanNthGenerationDescendantOf, : IsMoreThanNthGenerationDescendantOf,
_("Is a child of filter match") : IsChildOfFilterMatch, _("Is a child of filter match") : IsChildOfFilterMatch,
_("Is an ancestor of") : IsAncestorOf, _("Is an ancestor of") : IsAncestorOf,
_("Is an ancestor of filter match") : IsAncestorOfFilterMatch, _("Is an ancestor of filter match") : IsAncestorOfFilterMatch,
_("Is an ancestor of person not more than N generations away") _("Is an ancestor of person not more than N generations away")
: IsLessThanNthGenerationAncestorOf, : IsLessThanNthGenerationAncestorOf,
_("Is an ancestor of person at least N generations away") _("Is an ancestor of person at least N generations away")
: IsMoreThanNthGenerationAncestorOf, : IsMoreThanNthGenerationAncestorOf,
_("Is a parent of filter match") : IsParentOfFilterMatch, _("Is a parent of filter match") : IsParentOfFilterMatch,
_("Has a common ancestor with") : HasCommonAncestorWith, _("Has a common ancestor with") : HasCommonAncestorWith,
_("Has a common ancestor with filter match") _("Has a common ancestor with filter match")
: HasCommonAncestorWithFilterMatch, : HasCommonAncestorWithFilterMatch,
_("Is a female") : IsFemale, _("Is a female") : IsFemale,
_("Is a male") : IsMale, _("Is a male") : IsMale,
_("Has the personal event") : HasEvent, _("Has the personal event") : HasEvent,
_("Has the family event") : HasFamilyEvent, _("Has the family event") : HasFamilyEvent,
_("Has the personal attribute") : HasAttribute, _("Has the personal attribute") : HasAttribute,
_("Has the family attribute") : HasFamilyAttribute, _("Has the family attribute") : HasFamilyAttribute,
_("Matches the filter named") : MatchesFilter, _("Matches the filter named") : MatchesFilter,
_("Is spouse of filter match") : IsSpouseOfFilterMatch, _("Is spouse of filter match") : IsSpouseOfFilterMatch,
_("Relationship path between two people") : RelationshipPathBetween,
} }
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -1443,7 +1553,6 @@ class FilterParser(handler.ContentHandler):
def characters(self, data): def characters(self, data):
pass pass
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# #

View File

@ -2203,7 +2203,8 @@ class GrampsDB(Persistent):
def sortPersonKeys(self): def sortPersonKeys(self):
keys = self.personTable.keys() keys = self.personTable.keys()
keys.sort(self.sortbyname) if type(keys) == type([]):
keys.sort(self.sortbyname)
return keys return keys
def getPersonDisplay(self,key): def getPersonDisplay(self,key):
@ -2730,7 +2731,8 @@ class GrampsDB(Persistent):
def sortPlaceKeys(self): def sortPlaceKeys(self):
keys = self.placeTable.keys() keys = self.placeTable.keys()
keys.sort(self.sortbyplace) if type(keys) == type([]):
keys.sort(self.sortbyplace)
return keys return keys
def getPlaceKeys(self): def getPlaceKeys(self):