Export Web Family Tree; error on file write is now a message, not exception. (#524)

* Fix Export Web Family Tree for errors on file write

Fixes #10364

* Pylint on Web Family Tree export
This commit is contained in:
Paul Culley
2018-01-19 23:58:13 -06:00
committed by Sam Manzi
parent 10e0e64ff4
commit d081b75993

View File

@@ -27,7 +27,6 @@
# standard python modules # standard python modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import os
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@@ -43,9 +42,12 @@ log = logging.getLogger(".WriteFtree")
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.utils.alive import probably_alive # keep the following line even though not obviously used (works on import)
from gramps.gui.plug.export import WriterOptionBox from gramps.gui.plug.export import WriterOptionBox
from gramps.gui.glade import Glade from gramps.gui.dialog import ErrorDialog
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -53,22 +55,25 @@ from gramps.gui.glade import Glade
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def writeData(database, filename, user, option_box=None): def writeData(database, filename, user, option_box=None):
""" function to export Web Family Tree file """
writer = FtreeWriter(database, filename, user, option_box) writer = FtreeWriter(database, filename, user, option_box)
return writer.export_data() return writer.export_data()
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# FtreeWriter # FtreeWriter
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class FtreeWriter: class FtreeWriter:
""" Export a Web Family Tree format file """
def __init__(self, database, filename, user, option_box=None): def __init__(self, database, filename, user, option_box=None):
self.db = database self.db = database
self.filename = filename self.filename = filename
self.user = user self.user = user
self.option_box = option_box self.option_box = option_box
if isinstance(self.user.callback, collections.Callable): # callback is really callable # is callback is really callable?
if isinstance(self.user.callback, collections.Callable):
self.update = self.update_real self.update = self.update_real
else: else:
self.update = self.update_empty self.update = self.update_empty
@@ -78,121 +83,132 @@ class FtreeWriter:
self.db = option_box.get_filtered_database(self.db) self.db = option_box.get_filtered_database(self.db)
self.plist = [x for x in self.db.iter_person_handles()] self.plist = [x for x in self.db.iter_person_handles()]
# the following are used to update the progress meter
self.total = 2 * len(self.plist)
self.count = 0
self.oldval = 0 # we only update when percentage changes
def update_empty(self): def update_empty(self):
""" used when no callback is present """
pass pass
def update_real(self): def update_real(self):
""" Progress update """
self.count += 1 self.count += 1
newval = int(100*self.count/self.total) newval = int(100 * self.count / self.total)
if newval != self.oldval: if newval != self.oldval:
self.user.callback(newval) self.user.callback(newval)
self.oldval = newval self.oldval = newval
def export_data(self): def export_data(self):
""" main export processing """
name_map = {} name_map = {}
id_map = {} id_map = {}
id_name = {} id_name = {}
self.count = 0
self.oldval = 0
self.total = 2*len(self.plist)
for key in self.plist: for key in self.plist:
self.update() self.update()
pn = self.db.get_person_from_handle(key).get_primary_name() pnam = self.db.get_person_from_handle(key).get_primary_name()
sn = pn.get_surname() snam = pnam.get_surname()
items = pn.get_first_name().split() items = pnam.get_first_name().split()
n = ("%s %s" % (items[0], sn)) if items else sn nam = ("%s %s" % (items[0], snam)) if items else snam
count = -1 count = -1
if n in name_map: if nam in name_map:
count = 0 count = 0
while 1: while 1:
nn = "%s%d" % (n, count) nam_num = "%s%d" % (nam, count)
if nn not in name_map: if nam_num not in name_map:
break; break
count += 1 count += 1
name_map[nn] = key name_map[nam_num] = key
id_map[key] = nn id_map[key] = nam_num
else: else:
name_map[n] = key name_map[nam] = key
id_map[key] = n id_map[key] = nam
id_name[key] = get_name(pn, sn, count) id_name[key] = get_name(pnam, snam, count)
with open(self.filename, "w", encoding='utf_8') as f: try:
with open(self.filename, "w", encoding='utf_8') as file:
return self._export_data(file, id_name, id_map)
except IOError as msg:
msg2 = _("Could not create %s") % self.filename
ErrorDialog(msg2, str(msg), parent=self.option_box.window)
return False
for key in self.plist: def _export_data(self, file, id_name, id_map):
self.update() """ file export processing """
p = self.db.get_person_from_handle(key) for key in self.plist:
name = id_name[key] self.update()
father = mother = email = web = "" pers = self.db.get_person_from_handle(key)
name = id_name[key]
father = mother = email = web = ""
family_handle = p.get_main_parents_family_handle() family_handle = pers.get_main_parents_family_handle()
if family_handle: if family_handle:
family = self.db.get_family_from_handle(family_handle) family = self.db.get_family_from_handle(family_handle)
if family.get_father_handle() and \ if family.get_father_handle() and \
family.get_father_handle() in id_map: family.get_father_handle() in id_map:
father = id_map[family.get_father_handle()] father = id_map[family.get_father_handle()]
if family.get_mother_handle() and \ if family.get_mother_handle() and \
family.get_mother_handle() in id_map: family.get_mother_handle() in id_map:
mother = id_map[family.get_mother_handle()] mother = id_map[family.get_mother_handle()]
# #
# Calculate Date # Calculate Date
# #
birth_ref = p.get_birth_ref() birth_ref = pers.get_birth_ref()
death_ref = p.get_death_ref() death_ref = pers.get_death_ref()
if birth_ref: if birth_ref:
birth_event = self.db.get_event_from_handle(birth_ref.ref) birth_event = self.db.get_event_from_handle(birth_ref.ref)
birth = birth_event.get_date_object() birth = birth_event.get_date_object()
else:
birth = None
if death_ref:
death_event = self.db.get_event_from_handle(death_ref.ref)
death = death_event.get_date_object()
else:
death = None
#if self.restrict:
# alive = probably_alive(pers, self.db)
#else:
# alive = 0
if birth:
if death:
dates = "%s-%s" % (fdate(birth), fdate(death))
else: else:
birth = None dates = fdate(birth)
if death_ref: else:
death_event = self.db.get_event_from_handle(death_ref.ref) if death:
death = death_event.get_date_object() dates = fdate(death)
else: else:
death = None dates = ""
#if self.restrict: file.write('%s;%s;%s;%s;%s;%s\n' %
# alive = probably_alive(p, self.db) (name, father, mother, email, web, dates))
#else:
# alive = 0
if birth: return True
if death:
dates = "%s-%s" % (fdate(birth), fdate(death))
else:
dates = fdate(birth)
else:
if death:
dates = fdate(death)
else:
dates = ""
f.write('%s;%s;%s;%s;%s;%s\n' % (name, father, mother, email, web,
dates))
return True
def fdate(val): def fdate(val):
""" return properly formatted date """
if val.get_year_valid(): if val.get_year_valid():
if val.get_month_valid(): if val.get_month_valid():
if val.get_day_valid(): if val.get_day_valid():
return "%d/%d/%d" % (val.get_day(), val.get_month(), return "%d/%d/%d" % (val.get_day(), val.get_month(),
val.get_year()) val.get_year())
else: return "%d/%d" % (val.get_month(), val.get_year())
return "%d/%d" % (val.get_month(), val.get_year()) return "%d" % val.get_year()
else: return ""
return "%d" % val.get_year()
else:
return ""
def get_name(name, surname, count): def get_name(name, surname, count):
"""returns a name string built from the components of the Name """returns a name string built from the components of the Name
instance, in the form of Firstname Surname""" instance, in the form of Firstname Surname"""
return (name.first_name + ' ' + return (name.first_name + ' ' +
surname + surname +
(str(count) if count != -1 else '') + (str(count) if count != -1 else '') +
(', ' +name.suffix if name.suffix else '') (', ' + name.suffix if name.suffix else ''))
)