From ec6343e00c47ce0f3f3c04a6c52bdeeb0f96701d Mon Sep 17 00:00:00 2001 From: prculley Date: Wed, 1 Feb 2017 16:37:08 -0600 Subject: [PATCH 1/2] A new Soundex filter for matching 'name' with people using Soundex --- gramps/gen/filters/rules/person/__init__.py | 2 + .../filters/rules/person/_hassoundexname.py | 86 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 gramps/gen/filters/rules/person/_hassoundexname.py diff --git a/gramps/gen/filters/rules/person/__init__.py b/gramps/gen/filters/rules/person/__init__.py index 7deba8f10..903fb1a46 100644 --- a/gramps/gen/filters/rules/person/__init__.py +++ b/gramps/gen/filters/rules/person/__init__.py @@ -109,6 +109,7 @@ from ._matchidof import MatchIdOf from ._regexpidof import RegExpIdOf from ._changedsince import ChangedSince from ._isrelatedwith import IsRelatedWith +from ._hassoundexname import HasSoundexName #------------------------------------------------------------------------- # @@ -189,5 +190,6 @@ editor_rule_list = [ Disconnected, ChangedSince, IsRelatedWith, + HasSoundexName, ] diff --git a/gramps/gen/filters/rules/person/_hassoundexname.py b/gramps/gen/filters/rules/person/_hassoundexname.py new file mode 100644 index 000000000..ae280dbda --- /dev/null +++ b/gramps/gen/filters/rules/person/_hassoundexname.py @@ -0,0 +1,86 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2017 Paul Culley +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from ....const import GRAMPS_LOCALE as glocale +_ = glocale.translation.sgettext + +#------------------------------------------------------------------------- +# +# Gramps modules +# +#------------------------------------------------------------------------- +from .. import Rule +from ....lib.nameorigintype import NameOriginType +from gramps.gen.soundex import soundex + + +#------------------------------------------------------------------------- +# +# HasNameOf +# +#------------------------------------------------------------------------- +class HasSoundexName(Rule): + """Rule that checks for full or partial name matches""" + + labels = [_('Name:')] + name = _('Soundex match of People with the ') + description = _("Soundex Match of people with a specified name. First " + "name, Surname, Call name, and Nickname are searched in " + "primary and alternate names.") + category = _('General filters') + allow_regex = False + + def apply(self, db, person): + self.sndx = soundex(self.list[0]) + for name in [person.get_primary_name()] + person.get_alternate_names(): + if self._match_name(name): + return True + return False + + def _match_name(self, name): + if self.list[0]: + if soundex(str(name.get_first_name())) == self.sndx: + return True + elif soundex(str(name.get_surname())) == self.sndx: + return True + elif soundex(str(name.get_call_name())) == self.sndx: + return True + elif soundex(str(name.get_nick_name())) == self.sndx: + return True + elif soundex(str(name.get_family_nick_name())) == self.sndx: + return True + else: + for surn in name.get_surname_list(): + if self._match_surname(surn): + return True + return False + + def _match_surname(self, surn): + if soundex(str(surn.get_surname())) == self.sndx: + return True + if surn.get_origintype().value == NameOriginType.PATRONYMIC: + if soundex(str(surn.get_surname())) == self.sndx: + return True + return False From 5ca82248d30238152ae353b8068b96aa291c4bef Mon Sep 17 00:00:00 2001 From: prculley Date: Wed, 1 Feb 2017 18:32:19 -0600 Subject: [PATCH 2/2] Add tests for new Person HasSoundexName, and old HasNameOf rules --- .../filters/rules/test/person_rules_test.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/gramps/gen/filters/rules/test/person_rules_test.py b/gramps/gen/filters/rules/test/person_rules_test.py index 463f5baca..f97d5bcca 100644 --- a/gramps/gen/filters/rules/test/person_rules_test.py +++ b/gramps/gen/filters/rules/test/person_rules_test.py @@ -36,7 +36,7 @@ from gramps.gen.filters.rules.person import ( IsDuplicatedAncestorOf, IsRelatedWith, HasIdOf, IsDefaultPerson, IsFemale, IsMale, MissingParent, MultipleMarriages, NeverMarried, NoBirthdate, NoDeathdate, PeoplePrivate, PeoplePublic, PersonWithIncompleteEvent, - RelationshipPathBetweenBookmarks) + RelationshipPathBetweenBookmarks, HasNameOf, HasSoundexName) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") @@ -564,6 +564,22 @@ class BaseTest(unittest.TestCase): b'D3WJQCCGV58IP8PNHZ', b'Q8HKQC3VMRM1M6M7ES', ])) + def test_hassoundexname(self): + """ + Test HasSoundexName rule. + """ + rule = HasSoundexName(['garner']) + self.assertEqual(len(self.filter_with_rule(rule)), 73) + + def test_hasnameof(self): + """ + Test HasNameOf rule. + """ + rule = HasNameOf(['Lewis', 'Garner', 'Dr.', 'Sr', 'Anderson', + 'Big Louie', 'von', 'ZieliƄski', None, None, None]) + self.assertEqual(self.filter_with_rule(rule), set([ + b'GNUJQCL9MD64AM56OH'])) + if __name__ == "__main__": unittest.main()