759: regular expression not working in family filter/sidebar filters

svn: r17555
This commit is contained in:
Michiel Nauta 2011-05-24 20:31:54 +00:00
parent 0936618091
commit 380a515a80
13 changed files with 120 additions and 51 deletions

View File

@ -49,10 +49,18 @@ class HasRelType(Rule):
"of a particular value")
category = _('General filters')
def apply(self, db, family):
if not self.list[0]:
return False
def prepare(self, dbase):
if self.list[0]:
self.rtype = FamilyRelType()
self.rtype.set_from_xml_str(self.list[0])
else:
specified_type = FamilyRelType()
specified_type.set_from_xml_str(self.list[0])
return family.get_relationship() == specified_type
self.rtype = None
def apply(self, db, family):
if self.rtype:
if self.rtype.is_custom() and self.use_regex:
if self.regex[0].search(str(family.get_relationship())) is None:
return False
elif self.rtype != family.get_relationship():
return False
return True

View File

@ -51,14 +51,22 @@ class HasNote(Rule):
description = _("Matches Notes with particular parameters")
category = _('General filters')
def prepare(self, dbase):
if self.list[1]:
self.ntype = NoteType()
self.ntype.set_from_xml_str(self.list[1])
else:
self.ntype = None
def apply(self,db, note):
if not self.match_substring(0, note.get()):
return False
if self.list[1]:
specified_type = NoteType()
specified_type.set_from_xml_str(self.list[1])
if note.type != specified_type:
if self.ntype:
if self.ntype.is_custom() and self.use_regex:
if self.regex[1].search(str(note.type)) is None:
return False
elif note.type != self.ntype:
return False
return True

View File

@ -53,23 +53,29 @@ class HasRepo(Rule):
description = _("Matches Repositories with particular parameters")
category = _('General filters')
def apply(self,db,repo):
if not self.match_substring(0,repo.get_name()):
def prepare(self, dummy_db):
if self.list[1]:
self.rtype = RepositoryType()
self.rtype.set_from_xml_str(self.list[1])
else:
self.rtype = None
def apply(self, db, repo):
if not self.match_substring(0, repo.get_name()):
return False
if self.list[1]:
specified_type = RepositoryType()
specified_type.set_from_xml_str(self.list[1])
if repo.type != specified_type:
if self.rtype:
if self.rtype.is_custom() and self.use_regex:
if self.regex[1].search(str(repo.type)) is None:
return False
elif repo.type != self.rtype:
return False
if self.list[2]:
addr_match = False
for addr in repo.address_list:
addr_text = addr.city + addr.state + addr.country \
+ addr.postal + addr.phone + addr.street
if self.match_substring(2,addr_text):
addr_text = ', '.join(addr.get_text_data_list())
if self.match_substring(2, addr_text):
addr_match = True
break
if not addr_match:
@ -78,8 +84,8 @@ class HasRepo(Rule):
if self.list[3]:
url_match = False
for url in repo.urls:
url_text = url.path + url.desc
if self.match_substring(3,url_text):
url_text = ', '.join(url.get_text_data_list())
if self.match_substring(3, url_text):
url_match = True
break
if not url_match:

View File

@ -65,14 +65,18 @@ class HasEventBase(Rule):
try:
if self.list[1]:
self.date = DateHandler.parser.parse(self.list[1])
except: pass
except:
pass
def apply(self, db, event):
if self.etype:
if event.type != self.etype:
if self.etype.is_custom() and self.use_regex:
if self.regex[0].search(str(event.type)) is None:
return False
elif event.type != self.etype:
return False
if self.list[3] and event.get_description().upper().find(
self.list[3].upper())==-1:
if not self.match_substring(3, event.get_description()):
return False
if self.date:
@ -84,13 +88,13 @@ class HasEventBase(Rule):
if place_id:
place = db.get_place_from_handle(place_id)
place_name = place.get_title()
if place_name.upper().find(self.list[2].upper()) == -1:
if not self.match_substring(2, place_name):
return False
else:
return False
if self.list[4] and get_participant_from_event(db, event.get_handle(),
all_=True).upper().find(self.list[4].upper()) == -1:
if not self.match_substring(4,
get_participant_from_event(db, event.get_handle(), all_=True)):
return False
return True

View File

@ -21,12 +21,17 @@
# $Id$
"""
Base class for filter rules.
"""
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
from gen.ggettext import gettext as _
import re
#-------------------------------------------------------------------------
#
@ -34,7 +39,7 @@ from gen.ggettext import gettext as _
#
#-------------------------------------------------------------------------
import logging
log = logging.getLogger(".")
LOG = logging.getLogger(".")
#-------------------------------------------------------------------------
#
@ -49,14 +54,18 @@ class Rule(object):
category = _('Miscellaneous filters')
description = _('No description')
def __init__(self, arg):
def __init__(self, arg, use_regex=False):
self.list = []
self.regex = []
self.match_substring = self.__match_substring
self.set_list(arg)
self.use_regex = use_regex
self.nrprepare = 0
def is_empty(self):
return False
def requestprepare(self, db):
def requestprepare(self, dbase):
"""
Request that the prepare method of the rule is executed if needed
@ -68,10 +77,20 @@ class Rule(object):
called
"""
if self.nrprepare == 0:
self.prepare(db)
if self.use_regex:
self.regex = [None]*len(self.labels)
for i in xrange(len(self.labels)):
if self.list[i]:
try:
self.regex[i] = re.compile(unicode(self.list[i]),
re.I|re.U|re.L)
except re.error:
self.regex[i] = re.compile('')
self.match_substring = self.match_regex
self.prepare(dbase)
self.nrprepare += 1
def prepare(self, db):
def prepare(self, dummy_db):
"""prepare so the rule can be executed efficiently"""
pass
@ -95,29 +114,39 @@ class Rule(object):
pass
def set_list(self, arg):
"""Store the values of this rule."""
assert isinstance(arg, list) or arg is None, "Argument is not a list"
if len(arg) != len(self.labels):
log.warning(("Number of arguments does not match number of labels.\n" +
" list: %s\n" +
" labels: %s") % (arg,self.labels))
LOG.warning(("Number of arguments does not match number of " +
"labels.\n list: %s\n labels: %s") % (arg,
self.labels))
self.list = arg
def values(self):
"""Return the values used by this rule."""
return self.list
def check(self):
"""Verify the number of rule values versus the number of rule labels."""
return len(self.list) == len(self.labels)
def apply(self, db, person):
def apply(self, dummy_db, dummy_person):
"""Apply the rule to some database entry; must be overwritten."""
return True
def display_values(self):
v = ( '%s="%s"' % (_(self.labels[ix]), self.list[ix])
for ix in xrange(len(self.list)) if self.list[ix] )
"""Return the labels and values of this rule."""
l_v = ( '%s="%s"' % (_(self.labels[ix]), self.list[ix])
for ix in xrange(len(self.list)) if self.list[ix] )
return ';'.join(v)
return ';'.join(l_v)
def match_substring(self, param_index, str_var):
def __match_substring(self, param_index, str_var):
"""
Return boolean indicating if database element represented by str_var
matches filter element indicated by param_index using case insensitive
string matching.
"""
# make str_var unicode so that search for ü works
# see issue 3188
str_var = unicode(str_var)
@ -126,3 +155,16 @@ class Rule(object):
return False
else:
return True
def match_regex(self, param_index, str_var):
"""
Return boolean indicating if database element represented by str_var
matches filter element indicated by param_index using a regular
expression search.
"""
str_var = unicode(str_var)
if (self.list[param_index] and self.regex[param_index].search(str_var)
is None):
return False
else:
return True

View File

@ -132,7 +132,8 @@ class EventSidebarFilter(SidebarFilter):
rule = HasIdOf([gid])
generic_filter.add_rule(rule)
rule = HasEvent([etype, date, place, desc, mainparts])
rule = HasEvent([etype, date, place, desc, mainparts],
use_regex=regex)
generic_filter.add_rule(rule)
if note:

View File

@ -177,11 +177,11 @@ class FamilySidebarFilter(SidebarFilter):
generic_filter.add_rule(rule)
if etype:
rule = HasEvent([etype, u'', u'', u'', u''])
rule = HasEvent([etype, u'', u'', u'', u''], use_regex=regex)
generic_filter.add_rule(rule)
if rtype:
rule = HasRelType([rtype])
rule = HasRelType([rtype], use_regex=regex)
generic_filter.add_rule(rule)
if note:

View File

@ -129,7 +129,7 @@ class MediaSidebarFilter(SidebarFilter):
rule = HasIdOf([gid])
generic_filter.add_rule(rule)
rule = HasMedia([title, mime, path, date])
rule = HasMedia([title, mime, path, date], use_regex=regex)
generic_filter.add_rule(rule)
if note:

View File

@ -124,7 +124,7 @@ class NoteSidebarFilter(SidebarFilter):
rule = HasIdOf([gid])
generic_filter.add_rule(rule)
rule = HasNote([text, ntype])
rule = HasNote([text, ntype], use_regex=regex)
generic_filter.add_rule(rule)
# check the Tag

View File

@ -206,7 +206,7 @@ class PersonSidebarFilter(SidebarFilter):
# Build an event filter if needed
if etype:
rule = HasEvent([etype, u'', u'', u'', u''])
rule = HasEvent([etype, u'', u'', u'', u''], use_regex=regex)
generic_filter.add_rule(rule)
# Build birth event filter if needed

View File

@ -139,7 +139,7 @@ class PlaceSidebarFilter(SidebarFilter):
generic_filter.add_rule(rule)
rule = HasPlace([title, street, locality, city, county, state,
country, zipc, parish])
country, zipc, parish], use_regex=regex)
generic_filter.add_rule(rule)
if note:

View File

@ -128,7 +128,7 @@ class RepoSidebarFilter(SidebarFilter):
rule = HasIdOf([gid])
generic_filter.add_rule(rule)
rule = HasRepo([title, rtype, address, url])
rule = HasRepo([title, rtype, address, url], use_regex=regex)
generic_filter.add_rule(rule)
if note:

View File

@ -112,7 +112,7 @@ class SourceSidebarFilter(SidebarFilter):
rule = HasIdOf([gid])
generic_filter.add_rule(rule)
rule = HasSource([title, author, pub])
rule = HasSource([title, author, pub], use_regex=regex)
generic_filter.add_rule(rule)
if note: