Removed Django import/export and CalcEstimateDates (moved to addons)

svn: r14685
This commit is contained in:
Doug Blank 2010-03-07 21:42:03 +00:00
parent d1d83106ec
commit 3ae0224e1a
11 changed files with 67 additions and 1100 deletions

View File

@ -381,7 +381,6 @@ src/plugins/drawreport/TimeLine.py
# plugins/export directory
src/plugins/export/export.gpr.py
src/plugins/export/ExportCsv.py
src/plugins/export/ExportDjango.py
src/plugins/export/ExportFtree.py
src/plugins/export/ExportGedcom.py
src/plugins/export/ExportGeneWeb.py
@ -420,8 +419,6 @@ src/plugins/graph/GVRelGraph.py
# plugins/import directory
src/plugins/import/import.gpr.py
src/plugins/import/ImportCsv.py
src/plugins/import/ImportDjango.py
src/plugins/import/ImportDjango.py
src/plugins/import/ImportGedcom.py
src/plugins/import/ImportGeneWeb.py
src/plugins/import/ImportGrdb.py
@ -506,7 +503,6 @@ src/plugins/textreport/Summary.py
src/plugins/textreport/textplugins.gpr.py
# plugins/tool directory
src/plugins/tool/CalculateEstimatedDates.py
src/plugins/tool/ChangeNames.py
src/plugins/tool/ChangeTypes.py
src/plugins/tool/Check.py

View File

@ -1,37 +0,0 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 - 2009 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2009 B. Malengier <benny.malengier@gmail.com>
#
# 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
#
# $Id$
#
register(EXPORT,
id = "export_django",
name = _('Django Export'),
description = _('Django is a web framework working on a '
'configured database'),
version = '1.0',
gramps_target_version= '3.3',
status = UNSTABLE,
export_options_title = _('Django options'),
export_options = 'NoFilenameOptions',
export_function = 'export_all',
extension = "django",
fname = "ExportDjango.py",
)

View File

@ -1,193 +0,0 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 - 2009 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2009 B. Malengier <benny.malengier@gmail.com>
#
# 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
#
# $Id$
#
"""
Export to the Django Models on the configured database backend
"""
#------------------------------------------------------------------------
#
# Standard Python Modules
#
#------------------------------------------------------------------------
import sys
import os
import time
#------------------------------------------------------------------------
#
# Set up logging
#
#------------------------------------------------------------------------
import logging
LOG = logging.getLogger(".ExportDjango")
#------------------------------------------------------------------------
#
# GRAMPS modules
#
#------------------------------------------------------------------------
import ExportOptions
from Utils import create_id, probably_alive
import const
import gen.lib
from TransUtils import get_addon_translator
translator = get_addon_translator(__file__)
_ = translator.gettext
ngettext = translator.ngettext
from django.conf import settings
import web.settings as default_settings
try:
settings.configure(default_settings)
except RuntimeError:
# already configured; ignore
pass
from web.libdjango import DjangoInterface
def export_all(database, filename, option_box=None, callback=None):
if not callable(callback):
callback = lambda (percent): None # dummy
start = time.time()
total = (database.get_number_of_notes() +
database.get_number_of_people() +
database.get_number_of_events() +
database.get_number_of_families() +
database.get_number_of_repositories() +
database.get_number_of_places() +
database.get_number_of_media_objects() +
database.get_number_of_sources()) * 2 # steps
count = 0.0
dji = DjangoInterface()
dji.clear_tables("primary", "secondary", "ref")
for step in [0, 1]:
LOG.debug("Exporting Step %d..." % (step + 1))
# ---------------------------------
# Person
# ---------------------------------
for person_handle in database.person_map.keys():
data = database.person_map[person_handle]
if step == 0:
dji.add_person(data)
elif step == 1:
djperson = dji.add_person_detail(data)
djperson.probably_alive = not bool(djperson.death)
djperson.save()
count += 1
callback(100 * count/total)
# ---------------------------------
# Notes
# ---------------------------------
for note_handle in database.note_map.keys():
data = database.note_map[note_handle]
if step == 0:
dji.add_note(data)
count += 1
callback(100 * count/total)
# ---------------------------------
# Family
# ---------------------------------
for family_handle in database.family_map.keys():
data = database.family_map[family_handle]
if step == 0:
dji.add_family(data)
elif step == 1:
dji.add_family_detail(data)
count += 1
callback(100 * count/total)
# ---------------------------------
# Source
# ---------------------------------
for source_handle in database.source_map.keys():
data = database.source_map[source_handle]
if step == 0:
dji.add_source(data)
elif step == 1:
dji.add_source_detail(data)
count += 1
callback(100 * count/total)
# ---------------------------------
# Event
# ---------------------------------
for event_handle in database.event_map.keys():
data = database.event_map[event_handle]
if step == 0:
dji.add_event(data)
elif step == 1:
dji.add_event_detail(data)
count += 1
callback(100 * count/total)
# ---------------------------------
# Repository
# ---------------------------------
for repository_handle in database.repository_map.keys():
data = database.repository_map[repository_handle]
if step == 0:
dji.add_repository(data)
elif step == 1:
dji.add_repository_detail(data)
count += 1
callback(100 * count/total)
# ---------------------------------
# Place
# ---------------------------------
for place_handle in database.place_map.keys():
data = database.place_map[place_handle]
if step == 0:
dji.add_place(data)
elif step == 1:
dji.add_place_detail(data)
count += 1
callback(100 * count/total)
# ---------------------------------
# Media
# ---------------------------------
for media_handle in database.media_map.keys():
data = database.media_map[media_handle]
if step == 0:
dji.add_media(data)
elif step == 1:
dji.add_media_detail(data)
count += 1
callback(100 * count/total)
total_time = time.time() - start
msg = ngettext('Export Complete: %d second','Export Complete: %d seconds', total_time ) % total_time
LOG.debug(msg)
return True
class NoFilenameOptions(ExportOptions.WriterOptionBox):
no_fileselect = True

View File

@ -8,7 +8,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/plugins/export
pkgdata_PYTHON = \
export.gpr.py \
ExportCsv.py \
ExportDjango.py \
ExportFtree.py \
ExportGedcom.py \
ExportGeneWeb.py \

View File

@ -16,7 +16,7 @@ pkgdata_PYTHON = \
GivenNameGramplet.py \
gramplet.gpr.py \
PedigreeGramplet.py \
PluginManagerGramplet.py\
PluginManagerGramplet.py\
QuickViewGramplet.py \
RelativeGramplet.py \
SessionLogGramplet.py \

View File

@ -1,35 +0,0 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 - 2009 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2009 B. Malengier <benny.malengier@gmail.com>
#
# 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
#
# $Id$
#
register(IMPORT,
id = "import_django",
name = _('Django Import'),
description = _('Django is a web framework working on a '
'configured database'),
version = '1.0',
gramps_target_version = '3.3',
status = UNSTABLE,
import_function = 'import_data',
extension = "django",
fname = "ImportDjango.py",
)

View File

@ -1,195 +0,0 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 - 2009 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2009 B. Malengier <benny.malengier@gmail.com>
#
# 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
#
# $Id$
#
"""
Import from the Django dji on the configured database backend
"""
#-------------------------------------------------------------------------
#
# Standard Python Modules
#
#-------------------------------------------------------------------------
import time
import sys
import os
#------------------------------------------------------------------------
#
# Set up logging
#
#------------------------------------------------------------------------
import logging
LOG = logging.getLogger(".ImportDjango")
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import gen.lib
from QuestionDialog import ErrorDialog
from Utils import create_id
import const
from TransUtils import get_addon_translator
translator = get_addon_translator(__file__)
_ = translator.gettext
ngettext = translator.ngettext
from django.conf import settings
import web.settings as default_settings
try:
settings.configure(default_settings)
except:
pass
from web.libdjango import DjangoInterface
#-------------------------------------------------------------------------
#
# Django Reader
#
#-------------------------------------------------------------------------
class DjangoReader(object):
def __init__(self, db, filename, callback):
if not callable(callback):
callback = lambda (percent): None # dummy
self.db = db
self.dji = DjangoInterface()
self.filename = filename
self.callback = callback
self.debug = 0
def process(self):
sql = None
total = (self.dji.Note.count() +
self.dji.Person.count() +
self.dji.Event.count() +
self.dji.Family.count() +
self.dji.Repository.count() +
self.dji.Place.count() +
self.dji.Media.count() +
self.dji.Source.count())
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
count = 0.0
self.t = time.time()
# ---------------------------------
# Process note
# ---------------------------------
notes = self.dji.Note.all()
for note in notes:
data = self.dji.get_note(note)
self.db.note_map[str(note.handle)] = data
count += 1
self.callback(100 * count/total)
# ---------------------------------
# Process event
# ---------------------------------
events = self.dji.Event.all()
for event in events:
data = self.dji.get_event(event)
self.db.event_map[str(event.handle)] = data
count += 1
self.callback(100 * count/total)
# ---------------------------------
# Process person
# ---------------------------------
## Do this after Events to get the birth/death data
people = self.dji.Person.all()
for person in people:
data = self.dji.get_person(person)
self.db.person_map[str(person.handle)] = data
count += 1
self.callback(100 * count/total)
# ---------------------------------
# Process family
# ---------------------------------
families = self.dji.Family.all()
for family in families:
data = self.dji.get_family(family)
self.db.family_map[str(family.handle)] = data
count += 1
self.callback(100 * count/total)
# ---------------------------------
# Process repository
# ---------------------------------
repositories = self.dji.Repository.all()
for repo in repositories:
data = self.dji.get_repository(repo)
self.db.repository_map[str(repo.handle)] = data
count += 1
self.callback(100 * count/total)
# ---------------------------------
# Process place
# ---------------------------------
places = self.dji.Place.all()
for place in places:
data = self.dji.get_place(place)
self.db.place_map[str(place.handle)] = data
count += 1
self.callback(100 * count/total)
# ---------------------------------
# Process source
# ---------------------------------
sources = self.dji.Source.all()
for source in sources:
data = self.dji.get_source(source)
self.db.source_map[str(source.handle)] = data
count += 1
self.callback(100 * count/total)
# ---------------------------------
# Process media
# ---------------------------------
media = self.dji.Media.all()
for med in media:
data = self.dji.get_media(med)
self.db.media_map[str(med.handle)] = data
count += 1
self.callback(100 * count/total)
return None
def cleanup(self):
self.t = time.time() - self.t
msg = ngettext('Import Complete: %d second','Import Complete: %d seconds', self.t ) % self.t
self.db.transaction_commit(self.trans, _("Django import"))
self.db.enable_signals()
self.db.request_rebuild()
LOG.debug(msg)
def import_data(db, filename, callback=None):
g = DjangoReader(db, filename, callback)
g.process()
g.cleanup()

View File

@ -8,7 +8,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/plugins/import
pkgdata_PYTHON = \
import.gpr.py \
ImportCsv.py \
ImportDjango.py \
ImportGedcom.py \
ImportGeneWeb.py \
ImportGpkg.py \

View File

@ -1,543 +0,0 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2007 Donald N. Allingham
# Copyright (C) 2008 Brian Matherly
#
# 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
#
# $Id$
"Calculate Estimated Dates"
#------------------------------------------------------------------------
#
# python modules
#
#------------------------------------------------------------------------
from gen.ggettext import gettext as _
import time
#------------------------------------------------------------------------
#
# GRAMPS modules
#
#------------------------------------------------------------------------
from PluginUtils import Tool, PluginWindows, MenuToolOptions
from gen.plug.menu import BooleanOption, NumberOption, StringOption, \
FilterOption, PersonOption, EnumeratedListOption
import gen.lib
import config
from gen.display.name import displayer as name_displayer
import Errors
from ReportBase import ReportUtils
from docgen import TextBufDoc
from Simple import make_basic_stylesheet, SimpleAccess, SimpleDoc, SimpleTable
from QuestionDialog import QuestionDialog
from Utils import create_id, probably_alive_range
import DateHandler
#------------------------------------------------------------------------
#
# Tool Classes
#
#------------------------------------------------------------------------
class CalcEstDateOptions(MenuToolOptions):
""" Calculate Estimated Date options """
def __init__(self, name, person_id=None, dbstate=None):
self.__db = dbstate.get_database()
self.__dbstate = dbstate
MenuToolOptions.__init__(self, name, person_id, dbstate)
def get_dbstate(self):
return self.__dbstate
def add_menu_options(self, menu):
""" Add the options """
category_name = _("Options")
self.__filter = FilterOption(_("Filter"), 0)
self.__filter.set_help(_("Select filter to restrict people"))
menu.add_option(category_name, "filter", self.__filter)
self.__filter.connect('value-changed', self.__filter_changed)
self.__pid = PersonOption(_("Filter Person"))
self.__pid.set_help(_("The center person for the filter"))
menu.add_option(category_name, "pid", self.__pid)
self.__pid.connect('value-changed', self.__update_filters)
self.__update_filters()
source_text = StringOption(_("Source text"),
_("Calculated Date Estimates"))
source_text.set_help(_("Source to remove and/or add"))
menu.add_option(category_name, "source_text", source_text)
remove = BooleanOption(_("Remove previously added events, notes, and source"), True)
remove.set_help(_("Remove calculated events, notes, and source; occurs immediately on Execute"))
menu.add_option(category_name, "remove", remove)
birth = EnumeratedListOption(_("Birth"), 0)
birth.add_item(0, _("Do not add birth events"))
birth.add_item(1, _("Add birth events without dates"))
birth.add_item(2, _("Add birth events with dates"))
birth.set_help( _("Add a birth events with or without estimated dates"))
menu.add_option(category_name, "add_birth", birth)
death = EnumeratedListOption(_("Death"), 0)
death.add_item(0, _("Do not add death events"))
death.add_item(1, _("Add death events without dates"))
death.add_item(2, _("Add death events with dates"))
death.set_help( _("Add death events with or without estimated dates"))
menu.add_option(category_name, "add_death", death)
# -----------------------------------------------------
num = NumberOption(_("Maximum age"),
config.get('behavior.max-age-prob-alive'),
0, 200)
num.set_help(_("Maximum age that one can live to"))
menu.add_option(category_name, "MAX_AGE_PROB_ALIVE", num)
num = NumberOption(_("Maximum sibling age difference"),
config.get('behavior.max-sib-age-diff'),
0, 200)
num.set_help(_("Maximum age difference between siblings"))
menu.add_option(category_name, "MAX_SIB_AGE_DIFF", num)
num = NumberOption(_("Average years between generations"),
config.get('behavior.avg-generation-gap'),
0, 200)
num.set_help(_("Average years between two generations"))
menu.add_option(category_name, "AVG_GENERATION_GAP", num)
dates = EnumeratedListOption(_("Estimated Dates"), 0)
dates.add_item(0, _("Approximate (about)"))
dates.add_item(1, _("Extremes (after and before)"))
dates.set_help( _("Dates on events are either about or after/before"))
menu.add_option(category_name, "dates", dates)
def __update_filters(self):
"""
Update the filter list based on the selected person
"""
gid = self.__pid.get_value()
person = self.__db.get_person_from_gramps_id(gid)
filter_list = ReportUtils.get_person_filters(person, False)
self.__filter.set_filters(filter_list)
def __filter_changed(self):
"""
Handle filter change. If the filter is not specific to a person,
disable the person option
"""
filter_value = self.__filter.get_value()
if filter_value in [1, 2, 3, 4]:
# Filters 0, 2, 3, 4 and 5 rely on the center person
self.__pid.set_available(True)
else:
# The rest don't
self.__pid.set_available(False)
class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
def __init__(self, *args, **kwargs):
PluginWindows.ToolManagedWindowBatch.__init__(self, *args, **kwargs)
if self.fail: return
self.help_page = self.add_page(_("Help"))
self.write_to_page(self.help_page,
_("The Calculate Estimated Dates Tool is used to add and remove "
"birth and death events for people that are missing these "
"events.\n\n"
"To use:\n"
"1. Go to the Options tab\n"
"2. Check the [ ] Remove option to remove previous estimates\n"
"3. Select the Add date options to date events with or without dates\n"
"4. Click on Execute\n"
"5. Select the people with which to add events\n"
"6. Click on 'Add Selected Events' button to create\n\n"
"NOTES: if you decide to make an event permanent, remove it from "
"the Source. Otherwise, it will get removed the next time you "
"automatically remove these events.\n\n"
"You may have to run the tool repeatedly (without removing previous "
"events) to add all of the events possible."))
self.set_current_frame(_("Help"))
def get_title(self):
return _("Calculate Estimated Dates")
def initial_frame(self):
return _("Options")
def set_reselect(self):
self.reselect = True
def run(self):
BUTTONS = ((_("Select All"), self.select_all),
(_("Select None"), self.select_none),
(_("Toggle Selection"), self.toggle_select),
(_("Add Selected Events"), self.apply_selection),
)
if hasattr(self, "table") and self.table:
self.reselect = False
if self.options.handler.options_dict['remove']:
QuestionDialog(_("Remove Events, Notes, and Source and Reselect Data"),
_("Are you sure you want to remove previous events, notes, and source and reselect data?"),
_("Remove and Run Select Again"),
self.set_reselect,
self.window)
else:
QuestionDialog(_("Reselect Data"),
_("Are you sure you want to reselect data?"),
_("Run Select Again"),
self.set_reselect,
self.window)
if not self.reselect:
return
current_date = gen.lib.Date()
current_date.set_yr_mon_day(*time.localtime(time.time())[0:3])
self.action = {}
widget = self.add_results_frame(_("Select"))
document = TextBufDoc(make_basic_stylesheet(), None)
document.dbstate = self.dbstate
document.uistate = self.uistate
document.open("", container=widget)
self.sdb = SimpleAccess(self.db)
sdoc = SimpleDoc(document)
stab = SimpleTable(self.sdb)
self.table = stab
stab.columns(_("Select"), _("Person"), _("Action"),
_("Birth Date"), _("Death Date"),
_("Evidence"), _("Relative"))
self.results_write(_("Processing...\n"))
self.filter_option = self.options.menu.get_option_by_name('filter')
self.filter = self.filter_option.get_filter() # the actual filter
people = self.filter.apply(self.db,
self.db.iter_person_handles())
num_people = self.db.get_number_of_people()
source_text = self.options.handler.options_dict['source_text']
source = None
add_birth = self.options.handler.options_dict['add_birth']
add_death = self.options.handler.options_dict['add_death']
remove_old = self.options.handler.options_dict['remove']
self.MAX_SIB_AGE_DIFF = self.options.handler.options_dict['MAX_SIB_AGE_DIFF']
self.MAX_AGE_PROB_ALIVE = self.options.handler.options_dict['MAX_AGE_PROB_ALIVE']
self.AVG_GENERATION_GAP = self.options.handler.options_dict['AVG_GENERATION_GAP']
if remove_old:
self.trans = self.db.transaction_begin("",batch=True)
self.db.disable_signals()
self.results_write(_("Removing old estimations... "))
self.progress.set_pass((_("Removing '%s'...") % source_text),
num_people)
for person_handle in people:
self.progress.step()
pupdate = 0
person = self.db.get_person_from_handle(person_handle)
birth_ref = person.get_birth_ref()
if birth_ref:
birth = self.db.get_event_from_handle(birth_ref.ref)
source_list = birth.get_source_references()
for source_ref in source_list:
#print "birth handle:", source_ref
source = self.db.get_source_from_handle(source_ref.ref)
if source:
#print "birth source:", source, source.get_title()
if source.get_title() == source_text:
person.set_birth_ref(None)
person.remove_handle_references('Event',[birth_ref.ref])
# remove note
note_list = birth.get_referenced_note_handles()
birth.remove_handle_references('Note',
[note_handle for (obj_type, note_handle) in note_list])
for (obj_type, note_handle) in note_list:
self.db.remove_note(note_handle, self.trans)
self.db.remove_event(birth_ref.ref, self.trans)
self.db.commit_source(source, self.trans)
pupdate = 1
break
death_ref = person.get_death_ref()
if death_ref:
death = self.db.get_event_from_handle(death_ref.ref)
source_list = death.get_source_references()
for source_ref in source_list:
#print "death handle:", source_ref
source = self.db.get_source_from_handle(source_ref.ref)
if source:
#print "death source:", source, source.get_title()
if source.get_title() == source_text:
person.set_death_ref(None)
person.remove_handle_references('Event',[death_ref.ref])
# remove note
note_list = death.get_referenced_note_handles()
birth.remove_handle_references('Note',
[note_handle for (obj_type, note_handle) in note_list])
for (obj_type, note_handle) in note_list:
self.db.remove_note(note_handle, self.trans)
self.db.remove_event(death_ref.ref, self.trans)
self.db.commit_source(source, self.trans)
pupdate = 1
break
if pupdate == 1:
self.db.commit_person(person, self.trans)
if source:
self.db.remove_source(source.handle, self.trans)
self.results_write(_("done!\n"))
self.db.transaction_commit(self.trans, _("Removed date estimates"))
self.db.enable_signals()
self.db.request_rebuild()
if add_birth or add_death:
self.results_write(_("Selecting... \n\n"))
self.progress.set_pass(_('Selecting...'),
num_people)
row = 0
for person_handle in people:
self.progress.step()
person = self.db.get_person_from_handle(person_handle)
birth_ref = person.get_birth_ref()
death_ref = person.get_death_ref()
add_birth_event, add_death_event = False, False
if not birth_ref or not death_ref:
date1, date2, explain, other = self.calc_estimates(person)
if birth_ref:
ev = self.db.get_event_from_handle(birth_ref.ref)
date1 = ev.get_date_object()
elif not birth_ref and add_birth and date1:
if date1.match( current_date, "<"):
add_birth_event = True
date1.make_vague()
else:
date1 = gen.lib.Date()
else:
date1 = gen.lib.Date()
if death_ref:
ev = self.db.get_event_from_handle(death_ref.ref)
date2 = ev.get_date_object()
elif not death_ref and add_death and date2:
if date2.match( current_date, "<"):
add_death_event = True
date2.make_vague()
else:
date2 = gen.lib.Date()
else:
date2 = gen.lib.Date()
# Describe
if add_birth_event and add_death_event:
action = _("Add birth and death events")
elif add_birth_event:
action = _("Add birth event")
elif add_death_event:
action = _("Add death event")
else:
continue
#stab.columns(_("Select"), _("Person"), _("Action"),
# _("Birth Date"), _("Death Date"), _("Evidence"), _("Relative"))
if add_birth == 1 and not birth_ref: # no date
date1 = gen.lib.Date()
if add_death == 1 and not death_ref: # no date
date2 = gen.lib.Date()
if person == other:
other = None
stab.row("checkbox",
person,
action,
date1,
date2,
explain or "",
other or "")
if add_birth_event:
stab.set_cell_markup(3, row, "<b>%s</b>" % DateHandler.displayer.display(date1))
if add_death_event:
stab.set_cell_markup(4, row, "<b>%s</b>" % DateHandler.displayer.display(date2))
self.action[person.handle] = (add_birth_event, add_death_event)
row += 1
if row > 0:
self.results_write(" ")
for text, function in BUTTONS:
self.make_button(text, function, widget)
self.results_write("\n")
stab.write(sdoc)
self.results_write(" ")
for text, function in BUTTONS:
self.make_button(text, function, widget)
self.results_write("\n")
else:
self.results_write(_("No events to be added."))
self.results_write("\n")
self.results_write("\n")
self.progress.close()
self.set_current_frame(_("Select"))
def make_button(self, text, function, widget):
import gtk
button = gtk.Button(text)
buffer = widget.get_buffer()
iter = buffer.get_end_iter()
anchor = buffer.create_child_anchor(iter)
widget.add_child_at_anchor(button, anchor)
button.connect("clicked", function)
button.show()
self.results_write(" ")
def select_all(self, obj):
select_col = self.table.model_index_of_column[_("Select")]
for row in self.table.treeview.get_model():
row[select_col] = True
def select_none(self, obj):
select_col = self.table.model_index_of_column[_("Select")]
for row in self.table.treeview.get_model():
row[select_col] = False
def toggle_select(self, obj):
select_col = self.table.model_index_of_column[_("Select")]
for row in self.table.treeview.get_model():
row[select_col] = not row[select_col]
def apply_selection(self, *args, **kwargs):
# Do not add birth or death event if one exists, no matter what
if self.table.treeview.get_model() is None:
return
self.trans = self.db.transaction_begin("",batch=True)
self.pre_run()
source_text = self.options.handler.options_dict['source_text']
select_col = self.table.model_index_of_column[_("Select")]
source = self.get_or_create_source(source_text)
self.db.disable_signals()
self.results_write(_("Selecting... "))
self.progress.set_pass((_("Adding events '%s'...") % source_text),
len(self.table.treeview.get_model()))
count = 0
for row in self.table.treeview.get_model():
self.progress.step()
select = row[select_col] # live select value
if not select:
continue
pupdate = False
index = row[0] # order put in
row_data = self.table.get_raw_data(index)
person = row_data[1] # check, person, action, date1, date2
date1 = row_data[3] # date
date2 = row_data[4] # date
evidence = row_data[5] # evidence
other = row_data[6] # other person
add_birth_event, add_death_event = self.action[person.handle]
birth_ref = person.get_birth_ref()
death_ref = person.get_death_ref()
if not birth_ref and add_birth_event:
other_name = self.sdb.name(other)
if other_name:
explanation = _("Added birth event based on %(evidence)s, from %(name)s") % {
'evidence' : evidence, 'name' : other_name }
else:
explanation = _("Added birth event based on %s") % evidence
modifier = self.get_modifier("birth")
birth = self.create_event(_("Estimated birth date"),
gen.lib.EventType.BIRTH,
date1, source, explanation, modifier)
event_ref = gen.lib.EventRef()
event_ref.set_reference_handle(birth.get_handle())
person.set_birth_ref(event_ref)
pupdate = True
count += 1
if not death_ref and add_death_event:
other_name = self.sdb.name(other)
if other_name:
explanation = _("Added death event based on %(evidence)s, from %(person)s") % {
'evidence' : evidence, 'person' : other_name }
else:
explanation = _("Added death event based on %s") % evidence
modifier = self.get_modifier("death")
death = self.create_event(_("Estimated death date"),
gen.lib.EventType.DEATH,
date2, source, explanation, modifier)
event_ref = gen.lib.EventRef()
event_ref.set_reference_handle(death.get_handle())
person.set_death_ref(event_ref)
pupdate = True
count += 1
if pupdate:
self.db.commit_person(person, self.trans)
self.results_write(_(" Done! Committing..."))
self.results_write("\n")
self.db.transaction_commit(self.trans, _("Add date estimates"))
self.db.enable_signals()
self.db.request_rebuild()
self.results_write(_("Added %d events.") % count)
self.results_write("\n\n")
self.progress.close()
def get_modifier(self, event_type):
setting = self.options.handler.options_dict['dates']
if event_type == "birth":
if setting == 0:
return gen.lib.Date.MOD_ABOUT
else:
return gen.lib.Date.MOD_AFTER
else:
if setting == 0:
return gen.lib.Date.MOD_ABOUT
else:
return gen.lib.Date.MOD_BEFORE
def get_or_create_source(self, source_text):
source_list = self.db.get_source_handles()
for source_handle in source_list:
source = self.db.get_source_from_handle(source_handle)
if source.get_title() == source_text:
return source
source = gen.lib.Source()
source.set_title(source_text)
self.db.add_source(source, self.trans)
return source
def create_event(self, description=_("Estimated date"),
type=None, date=None, source=None,
note_text="", modifier=None):
event = gen.lib.Event()
event.set_description(description)
note = gen.lib.Note()
note.handle = create_id()
note.type.set(gen.lib.NoteType.EVENT)
note.set(note_text)
self.db.add_note(note, self.trans)
event.add_note(note.handle)
if type:
event.set_type(gen.lib.EventType(type))
if date:
if modifier:
date.set_modifier(modifier)
date.set_quality(gen.lib.Date.QUAL_ESTIMATED)
date.set_yr_mon_day(date.get_year(), 0, 0)
event.set_date_object(date)
if source:
sref = gen.lib.SourceRef()
sref.set_reference_handle(source.get_handle())
event.add_source_reference(sref)
self.db.commit_source(source, self.trans)
self.db.add_event(event, self.trans)
return event
def calc_estimates(self, person):
return probably_alive_range(person, self.db,
self.MAX_SIB_AGE_DIFF,
self.MAX_AGE_PROB_ALIVE,
self.AVG_GENERATION_GAP)

View File

@ -1,68 +1,66 @@
# This is the src/plugins/tool level Makefile for Gramps
# We could use GNU make's ':=' syntax for nice wildcard use,
# but that is not necessarily portable.
# If not using GNU make, then list all .py files individually
pkgdatadir = $(datadir)/@PACKAGE@/plugins/tool
pkgdata_PYTHON = \
CalculateEstimatedDates.py \
ChangeNames.py \
ChangeTypes.py \
Check.py \
Desbrowser.py \
Eval.py \
EventCmp.py \
EventNames.py \
ExtractCity.py \
FindDupes.py \
Leak.py \
MediaManager.py \
NotRelated.py \
OwnerEditor.py \
PatchNames.py \
Rebuild.py \
RebuildRefMap.py \
RelCalc.py \
RemoveUnused.py \
ReorderIds.py \
SortEvents.py \
SoundGen.py \
tools.gpr.py \
Verify.py
# DumpGenderStats.py \
# PHPGedViewConnector.py \
# TestcaseGenerator.py
pkgpyexecdir = @pkgpyexecdir@/plugins/tool
pkgpythondir = @pkgpythondir@/plugins/tool
GLADEFILES = \
changenames.glade \
changetypes.glade \
check.glade \
desbrowser.glade \
eval.glade \
eventcmp.glade \
finddupes.glade \
leak.glade \
notrelated.glade \
ownereditor.glade \
patchnames.glade \
phpgedview.glade \
relcalc.glade \
removeunused.glade \
soundgen.glade \
verify.glade
dist_pkgdata_DATA = $(GLADEFILES)
# Clean up all the byte-compiled files
MOSTLYCLEANFILES = *pyc *pyo
GRAMPS_PY_MODPATH = "../../"
pycheck:
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
pychecker $(pkgdata_PYTHON));
# This is the src/plugins/tool level Makefile for Gramps
# We could use GNU make's ':=' syntax for nice wildcard use,
# but that is not necessarily portable.
# If not using GNU make, then list all .py files individually
pkgdatadir = $(datadir)/@PACKAGE@/plugins/tool
pkgdata_PYTHON = \
ChangeNames.py \
ChangeTypes.py \
Check.py \
Desbrowser.py \
Eval.py \
EventCmp.py \
EventNames.py \
ExtractCity.py \
FindDupes.py \
Leak.py \
MediaManager.py \
NotRelated.py \
OwnerEditor.py \
PatchNames.py \
Rebuild.py \
RebuildRefMap.py \
RelCalc.py \
RemoveUnused.py \
ReorderIds.py \
SortEvents.py \
SoundGen.py \
tools.gpr.py \
Verify.py
# DumpGenderStats.py \
# PHPGedViewConnector.py \
# TestcaseGenerator.py
pkgpyexecdir = @pkgpyexecdir@/plugins/tool
pkgpythondir = @pkgpythondir@/plugins/tool
GLADEFILES = \
changenames.glade \
changetypes.glade \
check.glade \
desbrowser.glade \
eval.glade \
eventcmp.glade \
finddupes.glade \
leak.glade \
notrelated.glade \
ownereditor.glade \
patchnames.glade \
phpgedview.glade \
relcalc.glade \
removeunused.glade \
soundgen.glade \
verify.glade
dist_pkgdata_DATA = $(GLADEFILES)
# Clean up all the byte-compiled files
MOSTLYCLEANFILES = *pyc *pyo
GRAMPS_PY_MODPATH = "../../"
pycheck:
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
pychecker $(pkgdata_PYTHON));

View File

@ -24,28 +24,6 @@
GRAMPS registration file
"""
#------------------------------------------------------------------------
#
# Calculate Estimated Dates
#
#------------------------------------------------------------------------
register(TOOL,
id = 'calculateestimateddates',
name = _("Calculate Estimated Dates"),
description = _("Calculates estimated dates for birth and death."),
version = '0.90',
gramps_target_version = '3.3',
status = UNSTABLE,
fname = 'CalculateEstimatedDates.py',
authors = ["Douglas S. Blank"],
authors_email = ["dblank@cs.brynmawr.edu"],
category = TOOL_DBPROC,
toolclass = 'CalcToolManagedWindow',
optionclass = 'CalcEstDateOptions',
tool_modes = [TOOL_MODE_GUI]
)
#------------------------------------------------------------------------
#
# Fix Capitalization of Family Names