* src/GenericFilter.py: rewrote IsAncestorOf and IsDescendantOf rules

to be more efficient and to properly handle loop detection.
* src/RelLib.py: Added the getValidDeath and getValidBirth methods to
the Person class


svn: r1710
This commit is contained in:
Don Allingham 2003-06-12 02:04:42 +00:00
parent 91b3c84bee
commit 57bd52fd17
4 changed files with 85 additions and 54 deletions

View File

@ -38,7 +38,7 @@ except:
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import os import os
from string import find,join,strip,replace from string import find,join
import gtk import gtk
@ -167,31 +167,31 @@ class IsDescendantOf(Rule):
labels = [ _('ID:') ] labels = [ _('ID:') ]
def __init__(self,list):
Rule.__init__(self,list)
self.init = 0
self.map = {}
def name(self): def name(self):
return 'Is a descendant of' return 'Is a descendant of'
def apply(self,db,p): def apply(self,db,p):
self.map = {}
self.orig = p self.orig = p
return self.search(p)
def search(self,p): if not self.init:
self.init = 1
root = db.getPerson(self.list[0])
self.init_list(root)
return self.map.has_key(p.getId())
def init_list(self,p):
if self.map.has_key(p.getId()) == 1: if self.map.has_key(p.getId()) == 1:
raise Errors.FilterError(_("Loop detected while applying filter"), loop_error(self.orig,p)
_("A relationship loop was detected between %s [%s] "
"and %s [%s]. This is probably due to an error in the "
"database.") % (self.orig.getPrimaryName().getName(),
self.orig.getId(),
p.getPrimaryName().getName(),p.getId()))
self.map[p.getId()] = 1 self.map[p.getId()] = 1
if p.getId() == self.list[0]:
return 1 for fam in p.getFamilyList():
for (f,r1,r2) in p.getParentList(): for child in fam.getChildList():
for p1 in [f.getMother(),f.getFather()]: self.init_list(child)
if p1:
if self.search(p1):
return 1
return 0
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -214,12 +214,7 @@ class IsDescendantFamilyOf(Rule):
def search(self,p,val): def search(self,p,val):
if self.map.has_key(p.getId()): if self.map.has_key(p.getId()):
Errors.FilterError(_("Loop detected while applying filter"), loop_error(self.orig,p)
_("A relationship loop was detected between %s [%s] "
"and %s [%s]. This is probably due to an error in the "
"database.") % (self.orig.getPrimaryName().getName(),
self.orig.getId(),
p.getPrimaryName().getName(),p.getId()))
if p.getId() == self.list[0]: if p.getId() == self.list[0]:
self.map[p.getId()] = 1 self.map[p.getId()] = 1
return 1 return 1
@ -252,6 +247,7 @@ class IsAncestorOf(Rule):
def __init__(self,list): def __init__(self,list):
Rule.__init__(self,list) Rule.__init__(self,list)
self.init = 0
self.map = {} self.map = {}
def name(self): def name(self):
@ -259,27 +255,26 @@ class IsAncestorOf(Rule):
def apply(self,db,p): def apply(self,db,p):
self.orig = p self.orig = p
return self.search(p) if not self.init:
self.init = 1
root = db.getPerson(self.list[0])
self.init_ancestor_list(root)
return self.map.has_key(p.getId())
def search(self,p): def init_ancestor_list(self,p):
if self.map.has_key(p.getId()) == 1: if self.map.has_key(p.getId()) == 1:
raise Errors.FilterError(_("Loop detected while applying filter"), loop_error(self.orig,p)
_("A relationship loop was detected between %s [%s] "
"and %s [%s]. This is probably due to an error in the "
"database.") % (self.orig.getPrimaryName().getName(),
self.orig.getId(),
p.getPrimaryName().getName(),p.getId()))
self.map[p.getId()] = 1 self.map[p.getId()] = 1
if p.getId() == self.list[0]: fam = p.getMainParents()
return 1 if fam:
f = fam.getFather()
for f in p.getFamilyList(): m = fam.getMother()
for p1 in f.getChildList():
if p1: if f:
if self.search(p1): self.init_ancestor_list(f)
return 1 if m:
return 0 self.init_ancestor_list(m)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -636,6 +631,21 @@ class MatchesFilter(Rule):
if filter.get_name() == self.list[0]: if filter.get_name() == self.list[0]:
return filter.check(db,p) return filter.check(db,p)
return 0 return 0
#-------------------------------------------------------------------------
#
# loop_error
#
#-------------------------------------------------------------------------
def loop_error(p1,p2):
p1name = p1.getPrimaryName().getName()
p2name = p2.getPrimaryName().getName()
p1id = p1.getId()
p2id = p2.getId()
raise Errors.FilterError(_("Loop detected while applying filter"),
_("A relationship loop was detected between %s [%s] "
"and %s [%s]. This is probably due to an error in the "
"database.") % (p1name,p1id,p2name,p2id))
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -817,11 +827,11 @@ class GenericFilterList:
pass pass
def fix(self,line): def fix(self,line):
l = strip(line) l = line.strip()
l = replace(l,'&','&') l = l.replace('&','&')
l = replace(l,'>','>') l = l.replace('>','>')
l = replace(l,'<','&lt;') l = l.replace('<','&lt;')
return replace(l,'"','&quot;') return l.replace('"','&quot;')
def save(self): def save(self):
# try: # try:

View File

@ -1121,6 +1121,26 @@ class Person(Persistent):
self.death.name = "Death" self.death.name = "Death"
return self.death return self.death
def getValidDeath(self):
e = self.death
if e == None:
return None
if e.place == None and (e.date == None or not e.date.getValid()) and \
e.description == "" and e.cause == "" and e.witness == None:
return None
else:
return e
def getValidBirth(self):
e = self.birth
if e == None:
return None
if e.place == None and (e.date == None or not e.date.getValid()) and \
e.description == "" and e.cause == "" and e.witness == None:
return None
else:
return e
def addPhoto(self,photo): def addPhoto(self,photo):
"""adds a Photo instance to the image list""" """adds a Photo instance to the image list"""
self.photoList.append(photo) self.photoList.append(photo)

View File

@ -319,14 +319,14 @@ class OpenOfficeDoc(TextDoc.TextDoc):
def _write_zip(self): def _write_zip(self):
file = zipfile.ZipFile(self.filename,"w",zipfile.ZIP_DEFLATED) file = zipfile.ZipFile(self.filename,"w",zipfile.ZIP_DEFLATED)
file.write(self.manifest_xml,"META-INF/manifest.xml") file.write(self.manifest_xml,str("META-INF/manifest.xml"))
file.write(self.content_xml,"content.xml") file.write(self.content_xml,str("content.xml"))
file.write(self.meta_xml,"meta.xml") file.write(self.meta_xml,str("meta.xml"))
file.write(self.styles_xml,"styles.xml") file.write(self.styles_xml,str("styles.xml"))
for image in self.photo_list: for image in self.photo_list:
base = os.path.basename(image[0]) base = os.path.basename(image[0])
file.write(image[0],"Pictures/%s" % base) file.write(image[0], str("Pictures/%s" % base))
file.close() file.close()
os.unlink(self.manifest_xml) os.unlink(self.manifest_xml)
@ -595,4 +595,4 @@ class OpenOfficeDoc(TextDoc.TextDoc):
self.f.write('</office:document-meta>\n') self.f.write('</office:document-meta>\n')
self.f.close() self.f.close()
Plugins.register_text_doc(_("OpenOffice.org/StarOffice 6"),OpenOfficeDoc,1,1,1,".sxw") Plugins.register_text_doc(_("OpenOffice.org Writer"),OpenOfficeDoc,1,1,1,".sxw")

View File

@ -52,6 +52,7 @@ import GenericFilter
import Date import Date
import sort import sort
import Report import Report
import Errors
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from intl import gettext as _ from intl import gettext as _
@ -1162,11 +1163,11 @@ class WebReportDialog(Report.ReportDialog):
self.img_dir_text,self.template_name, self.img_dir_text,self.template_name,
self.use_id,self.id_link,self.use_gendex, self.use_id,self.id_link,self.use_gendex,
self.html_ext) self.html_ext)
MyReport.write_report()
except Errors.FilterError, msg: except Errors.FilterError, msg:
(m1,m2) = msg.messages() (m1,m2) = msg.messages()
ErrorDialog(m1,m2) ErrorDialog(m1,m2)
MyReport.write_report()
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #