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") "of a particular value")
category = _('General filters') category = _('General filters')
def apply(self, db, family): def prepare(self, dbase):
if not self.list[0]: if self.list[0]:
return False self.rtype = FamilyRelType()
self.rtype.set_from_xml_str(self.list[0])
else: else:
specified_type = FamilyRelType() self.rtype = None
specified_type.set_from_xml_str(self.list[0])
return family.get_relationship() == specified_type 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") description = _("Matches Notes with particular parameters")
category = _('General filters') 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): def apply(self,db, note):
if not self.match_substring(0, note.get()): if not self.match_substring(0, note.get()):
return False return False
if self.list[1]: if self.ntype:
specified_type = NoteType() if self.ntype.is_custom() and self.use_regex:
specified_type.set_from_xml_str(self.list[1]) if self.regex[1].search(str(note.type)) is None:
if note.type != specified_type: return False
elif note.type != self.ntype:
return False return False
return True return True

View File

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

View File

@@ -65,14 +65,18 @@ class HasEventBase(Rule):
try: try:
if self.list[1]: if self.list[1]:
self.date = DateHandler.parser.parse(self.list[1]) self.date = DateHandler.parser.parse(self.list[1])
except: pass except:
pass
def apply(self, db, event): def apply(self, db, event):
if self.etype: 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 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 return False
if self.date: if self.date:
@@ -84,13 +88,13 @@ class HasEventBase(Rule):
if place_id: if place_id:
place = db.get_place_from_handle(place_id) place = db.get_place_from_handle(place_id)
place_name = place.get_title() 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 return False
else: else:
return False return False
if self.list[4] and get_participant_from_event(db, event.get_handle(), if not self.match_substring(4,
all_=True).upper().find(self.list[4].upper()) == -1: get_participant_from_event(db, event.get_handle(), all_=True)):
return False return False
return True return True

View File

@@ -21,12 +21,17 @@
# $Id$ # $Id$
"""
Base class for filter rules.
"""
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Standard Python modules # Standard Python modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gen.ggettext import gettext as _ from gen.ggettext import gettext as _
import re
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -34,7 +39,7 @@ from gen.ggettext import gettext as _
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import logging import logging
log = logging.getLogger(".") LOG = logging.getLogger(".")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -49,14 +54,18 @@ class Rule(object):
category = _('Miscellaneous filters') category = _('Miscellaneous filters')
description = _('No description') 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.set_list(arg)
self.use_regex = use_regex
self.nrprepare = 0 self.nrprepare = 0
def is_empty(self): def is_empty(self):
return False return False
def requestprepare(self, db): def requestprepare(self, dbase):
""" """
Request that the prepare method of the rule is executed if needed Request that the prepare method of the rule is executed if needed
@@ -68,10 +77,20 @@ class Rule(object):
called called
""" """
if self.nrprepare == 0: 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 self.nrprepare += 1
def prepare(self, db): def prepare(self, dummy_db):
"""prepare so the rule can be executed efficiently""" """prepare so the rule can be executed efficiently"""
pass pass
@@ -95,29 +114,39 @@ class Rule(object):
pass pass
def set_list(self, arg): def set_list(self, arg):
"""Store the values of this rule."""
assert isinstance(arg, list) or arg is None, "Argument is not a list" assert isinstance(arg, list) or arg is None, "Argument is not a list"
if len(arg) != len(self.labels): if len(arg) != len(self.labels):
log.warning(("Number of arguments does not match number of labels.\n" + LOG.warning(("Number of arguments does not match number of " +
" list: %s\n" + "labels.\n list: %s\n labels: %s") % (arg,
" labels: %s") % (arg,self.labels)) self.labels))
self.list = arg self.list = arg
def values(self): def values(self):
"""Return the values used by this rule."""
return self.list return self.list
def check(self): def check(self):
"""Verify the number of rule values versus the number of rule labels."""
return len(self.list) == len(self.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 return True
def display_values(self): def display_values(self):
v = ( '%s="%s"' % (_(self.labels[ix]), self.list[ix]) """Return the labels and values of this rule."""
for ix in xrange(len(self.list)) if self.list[ix] ) 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 # make str_var unicode so that search for ü works
# see issue 3188 # see issue 3188
str_var = unicode(str_var) str_var = unicode(str_var)
@@ -126,3 +155,16 @@ class Rule(object):
return False return False
else: else:
return True 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]) rule = HasIdOf([gid])
generic_filter.add_rule(rule) 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) generic_filter.add_rule(rule)
if note: if note:

View File

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

View File

@@ -129,7 +129,7 @@ class MediaSidebarFilter(SidebarFilter):
rule = HasIdOf([gid]) rule = HasIdOf([gid])
generic_filter.add_rule(rule) 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) generic_filter.add_rule(rule)
if note: if note:

View File

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

View File

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

View File

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

View File

@@ -128,7 +128,7 @@ class RepoSidebarFilter(SidebarFilter):
rule = HasIdOf([gid]) rule = HasIdOf([gid])
generic_filter.add_rule(rule) 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) generic_filter.add_rule(rule)
if note: if note:

View File

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