2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
|
|
#
|
2007-06-28 11:11:40 +05:30
|
|
|
# Copyright (C) 2000-2007 Donald N. Allingham
|
2008-05-19 00:54:28 +05:30
|
|
|
# Copyright (C) 2008 Brian G. Matherly
|
2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
|
2004-02-06 01:07:58 +05:30
|
|
|
# $Id$
|
|
|
|
|
2008-03-02 04:17:48 +05:30
|
|
|
"""Tools/Database Processing/Find Possible Duplicate People"""
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2002-11-17 04:52:33 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
# GNOME libraries
|
2002-11-17 04:52:33 +05:30
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2008-02-19 05:18:35 +05:30
|
|
|
import gtk
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2002-11-17 04:52:33 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
# GRAMPS modules
|
2002-11-17 04:52:33 +05:30
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2009-02-26 15:38:38 +05:30
|
|
|
import const
|
2007-10-08 22:11:39 +05:30
|
|
|
import gen.lib
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
import Utils
|
|
|
|
import soundex
|
2007-06-28 11:11:40 +05:30
|
|
|
from BasicUtils import name_displayer
|
2009-02-19 18:25:06 +05:30
|
|
|
from QuestionDialog import OkDialog
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
import ListModel
|
2007-02-13 05:22:59 +05:30
|
|
|
import Errors
|
2006-07-31 02:59:25 +05:30
|
|
|
from Merge import PersonCompare
|
2006-04-10 04:23:53 +05:30
|
|
|
import GrampsDisplay
|
|
|
|
import ManagedWindow
|
2008-10-02 09:32:10 +05:30
|
|
|
from PluginUtils import Tool
|
|
|
|
from gen.plug import PluginManager
|
2008-02-18 15:39:50 +05:30
|
|
|
from QuestionDialog import ErrorDialog, RunDatabaseRepair
|
2008-04-14 21:02:52 +05:30
|
|
|
from TransUtils import sgettext as _
|
2009-05-15 01:45:59 +05:30
|
|
|
from glade import Glade
|
|
|
|
|
2005-12-06 12:08:09 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Constants
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
_val2label = {
|
|
|
|
0.25 : _("Low"),
|
|
|
|
1.0 : _("Medium"),
|
|
|
|
2.0 : _("High"),
|
|
|
|
}
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-02-26 15:38:38 +05:30
|
|
|
WIKI_HELP_PAGE = '%s_-_Tools' % const.URL_MANUAL_PAGE
|
2008-04-14 21:02:52 +05:30
|
|
|
WIKI_HELP_SEC = _('manual|Find_Possible_Duplicate_People...')
|
2009-04-16 02:21:10 +05:30
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
def is_initial(name):
|
|
|
|
if len(name) > 2:
|
|
|
|
return 0
|
|
|
|
elif len(name) == 2:
|
2002-11-08 09:12:25 +05:30
|
|
|
if name[0] == name[0].upper() and name[1] == '.':
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
else:
|
2002-11-08 09:12:25 +05:30
|
|
|
return name[0] == name[0].upper()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
2009-04-16 02:21:10 +05:30
|
|
|
# The Actual tool.
|
2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2006-04-27 04:13:18 +05:30
|
|
|
class Merge(Tool.Tool,ManagedWindow.ManagedWindow):
|
2006-04-10 04:23:53 +05:30
|
|
|
|
|
|
|
def __init__(self, dbstate, uistate, options_class, name, callback=None):
|
|
|
|
|
|
|
|
Tool.Tool.__init__(self, dbstate, options_class, name)
|
2006-04-27 04:13:18 +05:30
|
|
|
ManagedWindow.ManagedWindow.__init__(self, uistate, [],
|
|
|
|
self.__class__)
|
|
|
|
self.dbstate = dbstate
|
|
|
|
self.uistate = uistate
|
2002-10-20 19:55:16 +05:30
|
|
|
self.map = {}
|
|
|
|
self.list = []
|
|
|
|
self.index = 0
|
|
|
|
self.merger = None
|
|
|
|
self.mergee = None
|
|
|
|
self.removed = {}
|
|
|
|
self.update = callback
|
|
|
|
self.use_soundex = 1
|
|
|
|
|
2009-05-15 01:45:59 +05:30
|
|
|
top = Glade()
|
2005-12-06 12:08:09 +05:30
|
|
|
|
|
|
|
# retrieve options
|
|
|
|
threshold = self.options.handler.options_dict['threshold']
|
|
|
|
use_soundex = self.options.handler.options_dict['soundex']
|
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
my_menu = gtk.ListStore(str, object)
|
2005-12-06 12:08:09 +05:30
|
|
|
vals = _val2label.keys()
|
|
|
|
vals.sort()
|
|
|
|
for val in vals:
|
2009-04-16 02:21:10 +05:30
|
|
|
my_menu.append([_val2label[val], val])
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
self.soundex_obj = top.get_object("soundex")
|
2005-12-06 12:08:09 +05:30
|
|
|
self.soundex_obj.set_active(use_soundex)
|
|
|
|
self.soundex_obj.show()
|
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
self.menu = top.get_object("menu")
|
|
|
|
self.menu.set_model(my_menu)
|
|
|
|
self.menu.set_active(0)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-05-15 01:45:59 +05:30
|
|
|
window = top.toplevel
|
2009-04-16 02:21:10 +05:30
|
|
|
window.show()
|
|
|
|
self.set_window(window, top.get_object('title'),
|
2008-01-29 02:52:06 +05:30
|
|
|
_('Find Possible Duplicate People'))
|
2003-03-12 08:32:08 +05:30
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
top.connect_signals({
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
"on_merge_ok_clicked" : self.on_merge_ok_clicked,
|
2004-05-11 05:20:30 +05:30
|
|
|
"destroy_passed_object" : self.close,
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
"on_help_clicked" : self.on_help_clicked,
|
2006-04-27 04:13:18 +05:30
|
|
|
"on_delete_merge_event" : self.close,
|
2002-10-20 19:55:16 +05:30
|
|
|
})
|
2006-04-10 04:23:53 +05:30
|
|
|
|
|
|
|
self.show()
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def build_menu_names(self, obj):
|
2006-04-27 04:13:18 +05:30
|
|
|
return (_("Tool settings"),_("Find Duplicates tool"))
|
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def on_help_clicked(self, obj):
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
"""Display the relevant portion of GRAMPS manual"""
|
2008-04-14 21:02:52 +05:30
|
|
|
|
|
|
|
GrampsDisplay.help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
|
2004-05-11 05:20:30 +05:30
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
def ancestors_of(self,p1_id,id_list):
|
|
|
|
if (not p1_id) or (p1_id in id_list):
|
|
|
|
return
|
|
|
|
id_list.append(p1_id)
|
2004-08-07 10:46:57 +05:30
|
|
|
p1 = self.db.get_person_from_handle(p1_id)
|
2004-07-28 07:59:07 +05:30
|
|
|
f1_id = p1.get_main_parents_family_handle()
|
2004-05-09 22:02:13 +05:30
|
|
|
if f1_id:
|
2004-08-20 03:05:16 +05:30
|
|
|
f1 = self.db.get_family_from_handle(f1_id)
|
2004-07-28 07:59:07 +05:30
|
|
|
self.ancestors_of(f1.get_father_handle(),id_list)
|
|
|
|
self.ancestors_of(f1.get_mother_handle(),id_list)
|
2004-05-09 22:02:13 +05:30
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def on_merge_ok_clicked(self, obj):
|
2009-04-16 02:21:10 +05:30
|
|
|
threshold = self.menu.get_model()[self.menu.get_active()][1]
|
2005-12-06 12:08:09 +05:30
|
|
|
self.use_soundex = int(self.soundex_obj.get_active())
|
2007-05-15 09:47:12 +05:30
|
|
|
try:
|
|
|
|
self.find_potentials(threshold)
|
|
|
|
except AttributeError, msg:
|
2008-02-18 15:39:50 +05:30
|
|
|
RunDatabaseRepair(str(msg))
|
2007-05-15 09:47:12 +05:30
|
|
|
return
|
2005-12-06 12:08:09 +05:30
|
|
|
|
|
|
|
self.options.handler.options_dict['threshold'] = threshold
|
|
|
|
self.options.handler.options_dict['soundex'] = self.use_soundex
|
|
|
|
# Save options
|
|
|
|
self.options.handler.save_options()
|
|
|
|
|
2004-06-12 10:09:45 +05:30
|
|
|
if len(self.map) == 0:
|
2009-02-19 18:25:06 +05:30
|
|
|
OkDialog(
|
2005-03-31 10:00:44 +05:30
|
|
|
_("No matches found"),
|
|
|
|
_("No potential duplicate people were found"))
|
2004-06-12 10:09:45 +05:30
|
|
|
else:
|
2008-01-06 01:40:26 +05:30
|
|
|
try:
|
|
|
|
ShowMatches(self.dbstate,self.uistate,self.track,
|
|
|
|
self.list,self.map,self.update)
|
|
|
|
except Errors.WindowActiveError:
|
|
|
|
pass
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def find_potentials(self,thresh):
|
2008-01-29 02:52:06 +05:30
|
|
|
self.progress = Utils.ProgressMeter(_('Find Duplicates'),
|
2005-12-06 12:08:09 +05:30
|
|
|
_('Looking for duplicate people'))
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
index = 0
|
|
|
|
males = {}
|
|
|
|
females = {}
|
2005-08-18 11:28:28 +05:30
|
|
|
|
2006-12-23 00:54:46 +05:30
|
|
|
self.person_list = self.db.get_person_handles(sort_handles=False)
|
2005-08-18 11:28:28 +05:30
|
|
|
length = len(self.person_list)
|
|
|
|
|
|
|
|
self.progress.set_pass(_('Pass 1: Building preliminary lists'),
|
|
|
|
length)
|
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
for p1_id in self.person_list:
|
2005-08-18 11:28:28 +05:30
|
|
|
self.progress.step()
|
2004-08-07 10:46:57 +05:30
|
|
|
p1 = self.db.get_person_from_handle(p1_id)
|
2004-02-14 11:10:30 +05:30
|
|
|
key = self.gen_key(p1.get_primary_name().get_surname())
|
2007-10-08 22:11:39 +05:30
|
|
|
if p1.get_gender() == gen.lib.Person.MALE:
|
2008-07-17 23:40:32 +05:30
|
|
|
if key in males:
|
2004-05-09 22:02:13 +05:30
|
|
|
males[key].append(p1_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
2004-05-09 22:02:13 +05:30
|
|
|
males[key] = [p1_id]
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
2008-07-17 23:40:32 +05:30
|
|
|
if key in females:
|
2004-05-09 22:02:13 +05:30
|
|
|
females[key].append(p1_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
2004-05-09 22:02:13 +05:30
|
|
|
females[key] = [p1_id]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2005-08-18 11:28:28 +05:30
|
|
|
self.progress.set_pass(_('Pass 2: Calculating potential matches'),
|
|
|
|
length)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
for p1key in self.person_list:
|
2005-08-18 11:28:28 +05:30
|
|
|
self.progress.step()
|
2004-08-07 10:46:57 +05:30
|
|
|
p1 = self.db.get_person_from_handle(p1key)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2004-02-14 11:10:30 +05:30
|
|
|
key = self.gen_key(p1.get_primary_name().get_surname())
|
2007-10-08 22:11:39 +05:30
|
|
|
if p1.get_gender() == gen.lib.Person.MALE:
|
2002-10-20 19:55:16 +05:30
|
|
|
remaining = males[key]
|
|
|
|
else:
|
|
|
|
remaining = females[key]
|
|
|
|
|
|
|
|
index = 0
|
2002-11-08 09:12:25 +05:30
|
|
|
for p2key in remaining:
|
2009-04-16 02:21:10 +05:30
|
|
|
index += 1
|
2002-11-08 09:12:25 +05:30
|
|
|
if p1key == p2key:
|
2002-10-20 19:55:16 +05:30
|
|
|
continue
|
2004-08-07 10:46:57 +05:30
|
|
|
p2 = self.db.get_person_from_handle(p2key)
|
2008-07-17 23:40:32 +05:30
|
|
|
if p2key in self.map:
|
2002-11-08 09:12:25 +05:30
|
|
|
(v,c) = self.map[p2key]
|
2004-05-09 22:02:13 +05:30
|
|
|
if v == p1key:
|
2002-10-20 19:55:16 +05:30
|
|
|
continue
|
|
|
|
|
|
|
|
chance = self.compare_people(p1,p2)
|
|
|
|
if chance >= thresh:
|
2008-07-17 23:40:32 +05:30
|
|
|
if p1key in self.map:
|
2002-11-08 09:12:25 +05:30
|
|
|
val = self.map[p1key]
|
2002-10-20 19:55:16 +05:30
|
|
|
if val[1] > chance:
|
2004-05-09 22:02:13 +05:30
|
|
|
self.map[p1key] = (p2key,chance)
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
2004-05-09 22:02:13 +05:30
|
|
|
self.map[p1key] = (p2key,chance)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2002-11-08 09:12:25 +05:30
|
|
|
self.list = self.map.keys()
|
|
|
|
self.list.sort()
|
2002-10-20 19:55:16 +05:30
|
|
|
self.length = len(self.list)
|
2005-08-18 11:28:28 +05:30
|
|
|
self.progress.close()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
def gen_key(self,val):
|
|
|
|
if self.use_soundex:
|
|
|
|
try:
|
|
|
|
return soundex.soundex(val)
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
return val
|
|
|
|
else:
|
|
|
|
return val
|
2006-04-10 04:23:53 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
def compare_people(self,p1,p2):
|
2003-03-12 08:32:08 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
name1 = p1.get_primary_name()
|
|
|
|
name2 = p2.get_primary_name()
|
2002-11-08 09:12:25 +05:30
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
chance = self.name_match(name1, name2)
|
2006-04-27 04:13:18 +05:30
|
|
|
if chance == -1 :
|
|
|
|
return -1
|
2004-05-11 05:20:30 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
birth1_ref = p1.get_birth_ref()
|
|
|
|
if birth1_ref:
|
|
|
|
birth1 = self.db.get_event_from_handle(birth1_ref.ref)
|
|
|
|
else:
|
2007-10-08 22:11:39 +05:30
|
|
|
birth1 = gen.lib.Event()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
death1_ref = p1.get_death_ref()
|
|
|
|
if death1_ref:
|
|
|
|
death1 = self.db.get_event_from_handle(death1_ref.ref)
|
|
|
|
else:
|
2007-10-08 22:11:39 +05:30
|
|
|
death1 = gen.lib.Event()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
birth2_ref = p2.get_birth_ref()
|
|
|
|
if birth2_ref:
|
|
|
|
birth2 = self.db.get_event_from_handle(birth2_ref.ref)
|
|
|
|
else:
|
2007-10-08 22:11:39 +05:30
|
|
|
birth2 = gen.lib.Event()
|
2002-11-08 09:12:25 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
death2_ref = p2.get_death_ref()
|
|
|
|
if death2_ref:
|
|
|
|
death2 = self.db.get_event_from_handle(death2_ref.ref)
|
|
|
|
else:
|
2007-10-08 22:11:39 +05:30
|
|
|
death2 = gen.lib.Event()
|
2005-03-31 10:00:44 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
value = self.date_match(birth1.get_date_object(),
|
|
|
|
birth2.get_date_object())
|
|
|
|
if value == -1 :
|
|
|
|
return -1
|
2009-04-16 02:21:10 +05:30
|
|
|
chance =+ value
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
value = self.date_match(death1.get_date_object(),
|
|
|
|
death2.get_date_object())
|
|
|
|
if value == -1 :
|
|
|
|
return -1
|
2009-04-16 02:21:10 +05:30
|
|
|
chance =+ value
|
2006-04-27 04:13:18 +05:30
|
|
|
|
|
|
|
value = self.place_match(birth1.get_place_handle(),
|
|
|
|
birth2.get_place_handle())
|
|
|
|
if value == -1 :
|
|
|
|
return -1
|
2009-04-16 02:21:10 +05:30
|
|
|
chance =+ value
|
2006-04-27 04:13:18 +05:30
|
|
|
|
|
|
|
value = self.place_match(death1.get_place_handle(),
|
|
|
|
death2.get_place_handle())
|
|
|
|
if value == -1 :
|
|
|
|
return -1
|
2009-04-16 02:21:10 +05:30
|
|
|
chance =+ value
|
2006-04-27 04:13:18 +05:30
|
|
|
|
|
|
|
ancestors = []
|
|
|
|
self.ancestors_of(p1.get_handle(),ancestors)
|
|
|
|
if p2.get_handle() in ancestors:
|
|
|
|
return -1
|
|
|
|
|
|
|
|
ancestors = []
|
|
|
|
self.ancestors_of(p2.get_handle(),ancestors)
|
|
|
|
if p1.get_handle() in ancestors:
|
2002-10-20 19:55:16 +05:30
|
|
|
return -1
|
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
f1_id = p1.get_main_parents_family_handle()
|
|
|
|
f2_id = p2.get_main_parents_family_handle()
|
|
|
|
|
|
|
|
if f1_id and f2_id:
|
|
|
|
f1 = self.db.get_family_from_handle(f1_id)
|
|
|
|
f2 = self.db.get_family_from_handle(f2_id)
|
|
|
|
dad1_id = f1.get_father_handle()
|
|
|
|
if dad1_id:
|
2008-01-06 01:40:26 +05:30
|
|
|
dad1 = get_name_obj(self.db.get_person_from_handle(dad1_id))
|
2006-04-27 04:13:18 +05:30
|
|
|
else:
|
|
|
|
dad1 = None
|
|
|
|
dad2_id = f2.get_father_handle()
|
|
|
|
if dad2_id:
|
2008-01-06 01:40:26 +05:30
|
|
|
dad2 = get_name_obj(self.db.get_person_from_handle(dad2_id))
|
2006-04-27 04:13:18 +05:30
|
|
|
else:
|
|
|
|
dad2 = None
|
|
|
|
|
|
|
|
value = self.name_match(dad1,dad2)
|
|
|
|
|
|
|
|
if value == -1:
|
|
|
|
return -1
|
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
chance += value
|
2006-04-27 04:13:18 +05:30
|
|
|
|
|
|
|
mom1_id = f1.get_mother_handle()
|
|
|
|
if mom1_id:
|
2008-01-06 01:40:26 +05:30
|
|
|
mom1 = get_name_obj(self.db.get_person_from_handle(mom1_id))
|
2006-04-27 04:13:18 +05:30
|
|
|
else:
|
|
|
|
mom1 = None
|
|
|
|
mom2_id = f2.get_mother_handle()
|
|
|
|
if mom2_id:
|
2008-01-06 01:40:26 +05:30
|
|
|
mom2 = get_name_obj(self.db.get_person_from_handle(mom2_id))
|
2006-04-27 04:13:18 +05:30
|
|
|
else:
|
|
|
|
mom2 = None
|
|
|
|
|
|
|
|
value = self.name_match(mom1,mom2)
|
|
|
|
if value == -1:
|
|
|
|
return -1
|
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
chance += value
|
2006-04-27 04:13:18 +05:30
|
|
|
|
|
|
|
for f1_id in p1.get_family_handle_list():
|
|
|
|
f1 = self.db.get_family_from_handle(f1_id)
|
|
|
|
for f2_id in p2.get_family_handle_list():
|
|
|
|
f2 = self.db.get_family_from_handle(f2_id)
|
2007-10-08 22:11:39 +05:30
|
|
|
if p1.get_gender() == gen.lib.Person.FEMALE:
|
2006-04-27 04:13:18 +05:30
|
|
|
father1_id = f1.get_father_handle()
|
|
|
|
father2_id = f2.get_father_handle()
|
|
|
|
if father1_id and father2_id:
|
|
|
|
if father1_id == father2_id:
|
2009-04-16 02:21:10 +05:30
|
|
|
chance += 1
|
2006-04-27 04:13:18 +05:30
|
|
|
else:
|
|
|
|
father1 = self.db.get_person_from_handle(father1_id)
|
|
|
|
father2 = self.db.get_person_from_handle(father2_id)
|
|
|
|
fname1 = get_name_obj(father1)
|
|
|
|
fname2 = get_name_obj(father2)
|
|
|
|
value = self.name_match(fname1,fname2)
|
|
|
|
if value != -1:
|
2009-04-16 02:21:10 +05:30
|
|
|
chance += value
|
2006-04-27 04:13:18 +05:30
|
|
|
else:
|
|
|
|
mother1_id = f1.get_mother_handle()
|
|
|
|
mother2_id = f2.get_mother_handle()
|
|
|
|
if mother1_id and mother2_id:
|
|
|
|
if mother1_id == mother2_id:
|
2009-04-16 02:21:10 +05:30
|
|
|
chance += 1
|
2006-04-27 04:13:18 +05:30
|
|
|
else:
|
|
|
|
mother1 = self.db.get_person_from_handle(mother1_id)
|
|
|
|
mother2 = self.db.get_person_from_handle(mother2_id)
|
|
|
|
mname1 = get_name_obj(mother1)
|
|
|
|
mname2 = get_name_obj(mother2)
|
|
|
|
value = self.name_match(mname1,mname2)
|
|
|
|
if value != -1:
|
2009-04-16 02:21:10 +05:30
|
|
|
chance += value
|
2006-04-27 04:13:18 +05:30
|
|
|
return chance
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def name_compare(self,s1,s2):
|
|
|
|
if self.use_soundex:
|
2004-02-06 01:07:58 +05:30
|
|
|
try:
|
|
|
|
return soundex.compare(s1,s2)
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
return s1 == s2
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
|
|
|
return s1 == s2
|
|
|
|
|
|
|
|
def date_match(self,date1,date2):
|
2005-12-13 07:37:16 +05:30
|
|
|
if date1.is_empty() or date2.is_empty():
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
2004-10-03 04:37:43 +05:30
|
|
|
if date1.is_equal(date2):
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
|
2004-10-03 04:37:43 +05:30
|
|
|
if date1.is_compound() or date2.is_compound():
|
2002-10-20 19:55:16 +05:30
|
|
|
return self.range_compare(date1,date2)
|
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
if date1.get_year() == date2.get_year():
|
|
|
|
if date1.get_month() == date2.get_month():
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0.75
|
2004-05-09 22:02:13 +05:30
|
|
|
if not date1.get_month_valid() or not date2.get_month_valid():
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0.75
|
|
|
|
else:
|
|
|
|
return -1
|
|
|
|
else:
|
|
|
|
return -1
|
|
|
|
|
|
|
|
def range_compare(self,date1,date2):
|
2004-10-03 04:37:43 +05:30
|
|
|
start_date_1 = date1.get_start_date()[0:3]
|
|
|
|
start_date_2 = date2.get_start_date()[0:3]
|
|
|
|
stop_date_1 = date1.get_stop_date()[0:3]
|
|
|
|
stop_date_2 = date2.get_stop_date()[0:3]
|
|
|
|
if date1.is_compound() and date2.is_compound():
|
2009-04-16 02:21:10 +05:30
|
|
|
if start_date_2 <= start_date_1 <= stop_date_2 or \
|
|
|
|
start_date_1 <= start_date_2 <= stop_date_1 or \
|
|
|
|
start_date_2 <= stop_date_1 <= stop_date_2 or \
|
|
|
|
start-date_1 <= stop_date_2 <= stop_date_1:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0.5
|
|
|
|
else:
|
|
|
|
return -1
|
2004-10-03 04:37:43 +05:30
|
|
|
elif date2.is_compound():
|
2009-04-16 02:21:10 +05:30
|
|
|
if start_date_2 <= start_date_1 <= stop_date_2:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0.5
|
|
|
|
else:
|
|
|
|
return -1
|
|
|
|
else:
|
2009-04-16 02:21:10 +05:30
|
|
|
if start_date_1 <= start_date_2 <= stop_date_1:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0.5
|
|
|
|
else:
|
|
|
|
return -1
|
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def name_match(self, name, name1):
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
if not name1 or not name:
|
|
|
|
return 0
|
|
|
|
|
2004-02-14 11:10:30 +05:30
|
|
|
srn1 = name.get_surname()
|
|
|
|
sfx1 = name.get_suffix()
|
|
|
|
srn2 = name1.get_surname()
|
|
|
|
sfx2 = name1.get_suffix()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
if not self.name_compare(srn1,srn2):
|
|
|
|
return -1
|
|
|
|
if sfx1 != sfx2:
|
|
|
|
if sfx1 != "" and sfx2 != "":
|
|
|
|
return -1
|
|
|
|
|
2004-02-14 11:10:30 +05:30
|
|
|
if name.get_first_name() == name1.get_first_name():
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
else:
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
list1 = name.get_first_name().split()
|
|
|
|
list2 = name1.get_first_name().split()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
if len(list1) < len(list2):
|
|
|
|
return self.list_reduce(list1,list2)
|
|
|
|
else:
|
|
|
|
return self.list_reduce(list2,list1)
|
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
def place_match(self,p1_id,p2_id):
|
|
|
|
if p1_id == p2_id:
|
2002-10-20 19:55:16 +05:30
|
|
|
return 1
|
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
if not p1_id:
|
2002-10-20 19:55:16 +05:30
|
|
|
name1 = ""
|
|
|
|
else:
|
2004-08-07 10:46:57 +05:30
|
|
|
p1 = self.db.get_place_from_handle(p1_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
name1 = p1.get_title()
|
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
if not p2_id:
|
2002-10-20 19:55:16 +05:30
|
|
|
name2 = ""
|
|
|
|
else:
|
2004-08-07 10:46:57 +05:30
|
|
|
p2 = self.db.get_place_from_handle(p2_id)
|
2002-10-20 19:55:16 +05:30
|
|
|
name2 = p2.get_title()
|
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
if not (name1 and name2):
|
2002-10-20 19:55:16 +05:30
|
|
|
return 0
|
|
|
|
if name1 == name2:
|
|
|
|
return 1
|
|
|
|
|
* src/gramps_main.py (tool_callback): Typo.
* src/QuestionDialog.py: Use gramps icon.
* src/plugins/EventCmp.py: HIG; single instance; help.
* src/plugins/eventcmp.glade: HIG; help.
* src/plugins/Desbrowser.py: HIG, help, rebuild model after edit.
* src/plugins/desbrowse.glade: help, info label.
* src/plugins/PatchNames.py: HIG, help, single instance.
* src/plugins/patchnames.glade: HIG, help.
* src/plugins/Merge.py: HIG, help, single instance.
* src/plugins/merge.glade: HIG, help.
* src/plugins/ChangeNames.py: HIG, help, single instance.
svn: r4230
2005-03-24 11:52:25 +05:30
|
|
|
list1 = name1.replace(","," ").split()
|
|
|
|
list2 = name2.replace(","," ").split()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
value = 0
|
|
|
|
for name in list1:
|
|
|
|
for name2 in list2:
|
|
|
|
if name == name2:
|
2009-04-16 02:21:10 +05:30
|
|
|
value += 0.5
|
|
|
|
elif name[0] == name2[0] and self.name_compare(name, name2):
|
|
|
|
value += 0.25
|
|
|
|
return min(value,1) if value else -1
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
def list_reduce(self,list1,list2):
|
|
|
|
value = 0
|
|
|
|
for name in list1:
|
|
|
|
for name2 in list2:
|
|
|
|
if is_initial(name) and name[0] == name2[0]:
|
2009-04-16 02:21:10 +05:30
|
|
|
value += 0.25
|
|
|
|
elif is_initial(name2) and name2[0] == name[0]:
|
|
|
|
value += 0.25
|
|
|
|
elif name == name2:
|
|
|
|
value += 0.5
|
|
|
|
elif name[0] == name2[0] and self.name_compare(name, name2):
|
|
|
|
value += 0.25
|
|
|
|
return min(value,1) if value else -1
|
2006-04-27 04:13:18 +05:30
|
|
|
|
2004-05-09 22:02:13 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
class ShowMatches(ManagedWindow.ManagedWindow):
|
2004-05-09 22:02:13 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
def __init__(self,dbstate,uistate,track,the_list,the_map,callback):
|
|
|
|
ManagedWindow.ManagedWindow.__init__(self,uistate,track,self.__class__)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
self.dellist = {}
|
|
|
|
self.list = the_list
|
|
|
|
self.map = the_map
|
|
|
|
self.length = len(self.list)
|
|
|
|
self.update = callback
|
|
|
|
self.db = dbstate.db
|
2006-04-27 05:08:32 +05:30
|
|
|
self.dbstate = dbstate
|
|
|
|
self.uistate = uistate
|
2006-04-27 04:13:18 +05:30
|
|
|
|
2009-05-15 01:45:59 +05:30
|
|
|
top = Glade(toplevel="mergelist")
|
|
|
|
window = top.toplevel
|
2009-04-16 02:21:10 +05:30
|
|
|
window.show()
|
|
|
|
self.set_window(window, top.get_object('title'),
|
2006-04-27 04:13:18 +05:30
|
|
|
_('Potential Merges'))
|
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
self.mlist = top.get_object("mlist")
|
|
|
|
top.connect_signals({
|
2006-04-27 04:13:18 +05:30
|
|
|
"destroy_passed_object" : self.close,
|
|
|
|
"on_do_merge_clicked" : self.on_do_merge_clicked,
|
|
|
|
"on_help_show_clicked" : self.on_help_clicked,
|
|
|
|
"on_delete_show_event" : self.close,
|
|
|
|
})
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-04-16 02:21:10 +05:30
|
|
|
mtitles = [
|
|
|
|
(_('Rating'),3,75),
|
|
|
|
(_('First Person'),1,200),
|
|
|
|
(_('Second Person'),2,200),
|
|
|
|
('',-1,0)
|
|
|
|
]
|
2006-04-27 04:13:18 +05:30
|
|
|
self.list = ListModel.ListModel(self.mlist,mtitles,
|
|
|
|
event_func=self.on_do_merge_clicked)
|
|
|
|
|
|
|
|
self.redraw()
|
|
|
|
self.show()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def build_menu_names(self, obj):
|
2006-04-27 04:13:18 +05:30
|
|
|
return (_("Merge candidates"),None)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def on_help_clicked(self, obj):
|
2006-04-27 04:13:18 +05:30
|
|
|
"""Display the relevant portion of GRAMPS manual"""
|
2008-04-14 21:02:52 +05:30
|
|
|
|
|
|
|
GrampsDisplay.help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
|
2006-04-27 04:13:18 +05:30
|
|
|
def redraw(self):
|
|
|
|
list = []
|
|
|
|
for p1key in self.map.keys():
|
2008-07-17 23:40:32 +05:30
|
|
|
if p1key in self.dellist:
|
2006-04-27 04:13:18 +05:30
|
|
|
continue
|
|
|
|
(p2key,c) = self.map[p1key]
|
|
|
|
if p1key == p2key:
|
|
|
|
continue
|
|
|
|
list.append((c,p1key,p2key))
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
self.list.clear()
|
|
|
|
for (c,p1key,p2key) in list:
|
|
|
|
c1 = "%5.2f" % c
|
|
|
|
c2 = "%5.2f" % (100-c)
|
|
|
|
p1 = self.db.get_person_from_handle(p1key)
|
|
|
|
p2 = self.db.get_person_from_handle(p2key)
|
|
|
|
if not p1 or not p2:
|
|
|
|
continue
|
2007-06-28 11:11:40 +05:30
|
|
|
pn1 = name_displayer.display(p1)
|
|
|
|
pn2 = name_displayer.display(p2)
|
2008-01-08 20:57:28 +05:30
|
|
|
self.list.add([c1, pn1, pn2,c2],(p1key,p2key))
|
2004-05-09 22:02:13 +05:30
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def on_do_merge_clicked(self, obj):
|
2006-04-27 04:13:18 +05:30
|
|
|
store,iter = self.list.selection.get_selected()
|
|
|
|
if not iter:
|
|
|
|
return
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
(self.p1,self.p2) = self.list.get_object(iter)
|
|
|
|
pn1 = self.db.get_person_from_handle(self.p1)
|
|
|
|
pn2 = self.db.get_person_from_handle(self.p2)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-07-31 02:59:25 +05:30
|
|
|
PersonCompare(self.dbstate,self.uistate,pn1,pn2,self.on_update)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2006-04-27 04:13:18 +05:30
|
|
|
def on_update(self):
|
|
|
|
self.dellist[self.p2] = self.p1
|
|
|
|
for key in self.dellist.keys():
|
|
|
|
if self.dellist[key] == self.p2:
|
|
|
|
self.dellist[key] = self.p1
|
2006-04-27 05:08:32 +05:30
|
|
|
self.update()
|
2006-04-27 04:13:18 +05:30
|
|
|
self.redraw()
|
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def update_and_destroy(self, obj):
|
2006-04-27 04:13:18 +05:30
|
|
|
self.update(1)
|
|
|
|
self.close()
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2004-05-11 05:20:30 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2002-10-20 19:55:16 +05:30
|
|
|
def name_of(p):
|
|
|
|
if not p:
|
|
|
|
return ""
|
2007-06-28 11:11:40 +05:30
|
|
|
return "%s (%s)" % (name_displayer.display(p),p.get_handle())
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def get_name_obj(person):
|
|
|
|
if person:
|
2004-02-14 11:10:30 +05:30
|
|
|
return person.get_primary_name()
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2005-12-06 12:08:09 +05:30
|
|
|
def by_id(p1,p2):
|
|
|
|
return cmp(p1.get_handle(),p2.get_handle())
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2005-12-06 12:08:09 +05:30
|
|
|
|
|
|
|
#------------------------------------------------------------------------
|
2002-10-20 19:55:16 +05:30
|
|
|
#
|
2005-12-06 12:08:09 +05:30
|
|
|
#
|
2002-10-20 19:55:16 +05:30
|
|
|
#
|
2005-12-06 12:08:09 +05:30
|
|
|
#------------------------------------------------------------------------
|
|
|
|
class MergeOptions(Tool.ToolOptions):
|
|
|
|
"""
|
|
|
|
Defines options and provides handling interface.
|
|
|
|
"""
|
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def __init__(self, name,person_id=None):
|
|
|
|
Tool.ToolOptions.__init__(self, name,person_id)
|
2005-12-06 12:08:09 +05:30
|
|
|
|
|
|
|
# Options specific for this report
|
|
|
|
self.options_dict = {
|
|
|
|
'soundex' : 1,
|
|
|
|
'threshold' : 0.25,
|
|
|
|
}
|
|
|
|
self.options_help = {
|
|
|
|
'soundex' : ("=0/1","Whether to use SoundEx codes",
|
|
|
|
["Do not use SoundEx","Use SoundEx"],
|
|
|
|
True),
|
|
|
|
'threshold' : ("=num","Threshold for tolerance",
|
|
|
|
"Floating point number")
|
|
|
|
}
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2008-05-19 00:54:28 +05:30
|
|
|
pmgr = PluginManager.get_instance()
|
|
|
|
pmgr.register_tool(
|
2005-12-06 12:08:09 +05:30
|
|
|
name = 'dupfind',
|
|
|
|
category = Tool.TOOL_DBPROC,
|
|
|
|
tool_class = Merge,
|
|
|
|
options_class = MergeOptions,
|
2008-10-02 09:32:10 +05:30
|
|
|
modes = PluginManager.TOOL_MODE_GUI,
|
2008-03-02 04:17:48 +05:30
|
|
|
translated_name = _("Find Possible Duplicate People"),
|
2005-12-06 12:08:09 +05:30
|
|
|
status = _("Stable"),
|
|
|
|
author_name = "Donald N. Allingham",
|
|
|
|
author_email = "don@gramps-project.org",
|
2008-03-02 04:17:48 +05:30
|
|
|
description = _("Searches the entire database, looking for "
|
|
|
|
"individual entries that may represent the same person.")
|
2002-10-20 19:55:16 +05:30
|
|
|
)
|