5746: Use the new User classes for Importers and Exporters

svn: r19567
This commit is contained in:
Doug Blank 2012-05-18 01:21:30 +00:00
parent 525da42eec
commit de196aea96
16 changed files with 180 additions and 167 deletions

View File

@ -61,6 +61,7 @@ from gui.pluginmanager import GuiPluginManager
import Utils
import ManagedWindow
from QuestionDialog import ErrorDialog
from gui.user import User
#-------------------------------------------------------------------------
#
@ -631,9 +632,8 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
export_function = self.map_exporters[ix].get_export_function()
success = export_function(self.dbstate.db,
filename,
ErrorDialog,
self.option_box_instance,
self.callback)
User(error=ErrorDialog, callback=self.callback),
self.option_box_instance)
return success
def pre_save(self,page):

View File

@ -562,7 +562,7 @@ class ArgHandler(object):
for plugin in pmgr.get_export_plugins():
if family_tree_format == plugin.get_extension():
export_function = plugin.get_export_function()
export_function(self.dbstate.db, filename, self.__error)
export_function(self.dbstate.db, filename, User(error=self.__error))
#-------------------------------------------------------------------------
#

View File

@ -55,10 +55,11 @@ class User(gen.user.User):
This class provides a means to interact with the user via CLI.
It implements the interface in gen.user.User()
"""
def __init__(self, callback=None):
def __init__(self, callback=None, error=None):
self.steps = 0;
self.current_step = 0;
self.callback_function = callback
self.error_function = error
def begin_progress(self, title, message, steps):
"""
@ -94,15 +95,25 @@ class User(gen.user.User):
percent = int((float(self.current_step) / self.steps) * 100)
sys.stdout.write("\r%02d%%" % percent)
def callback(self, percent):
def callback(self, *args):
"""
Display progress meter.
"""
def callback(self, percentage, text=None):
"""
Display the precentage.
"""
if self.callback_function:
self.callback_function(percent)
if text:
self.callback_function(percentage, text)
else:
self.callback_function(percentage)
else:
sys.stdout.write("\r%02d%%" % percent)
if text is None:
sys.stdout.write("\r%02d%%" % percentage)
else:
sys.stdout.write("\r%02d%% %s" % (percentage, text))
def end_progress(self):
"""
Stop showing the progress indicator to the user.
@ -145,7 +156,10 @@ class User(gen.user.User):
@type error: str
@returns: none
"""
print "%s %s" % (title, error)
if self.error_function:
self.error_function(title, error)
else:
print "%s %s" % (title, error)
def notify_db_error(self, error):
"""

View File

@ -40,13 +40,11 @@ class ExportPlugin(Plugin):
@type description: string
@param export_function: A function to call to perform the export.
The function must take the form:
def export_function(database, filename, option_box, callback):
def export_function(database, filename, user, option_box):
where:
"db" is a Gramps database to import the data into
"filename" is the file that the data will be exported to
"callback" is a callable object that takes two parameters.
The first parameter is a progress indicator.
The second parameter is a text string.
"user" provides UI output (callback, errors, etc)
@type export_function: callable
@param extension: The extension for the output file.
Example: "ged"
@ -82,4 +80,4 @@ class ExportPlugin(Plugin):
@return: (??,??)
"""
return self.__config
return self.__config

View File

@ -493,7 +493,7 @@ class DbManager(CLIDbManager):
else:
base_path = self.dbstate.db.get_save_path()
archive = os.path.join(base_path, ARCHIVE)
check_in(self.dbstate.db, archive, None, self.__start_cursor)
check_in(self.dbstate.db, archive, User(), self.__start_cursor)
self.__end_cursor()
self.__populate()
@ -837,7 +837,7 @@ def check_out(dbase, rev, path, user):
rdr(dbase, xml_file, user)
os.unlink(xml_file)
def check_in(dbase, filename, callback, cursor_func = None):
def check_in(dbase, filename, user, cursor_func = None):
"""
Checks in the specified file into RCS
"""
@ -875,7 +875,7 @@ def check_in(dbase, filename, callback, cursor_func = None):
for plugin in plugin_manager.get_export_plugins():
if plugin.get_extension() == "gramps":
export_function = plugin.get_export_function()
export_function(dbase, filename, None, callback)
export_function(dbase, filename, user)
if cursor_func:
cursor_func(_("Saving archive..."))

View File

@ -51,9 +51,10 @@ class User(gen.user.User):
This class provides a means to interact with the user via GTK.
It implements the interface in gen.user.User()
"""
def __init__(self, callback=None):
def __init__(self, callback=None, error=None):
self.progress = None
self.callback_function = callback
self.error_function = error
def begin_progress(self, title, message, steps):
"""
@ -82,14 +83,20 @@ class User(gen.user.User):
if self.progress:
self.progress.step()
def callback(self, percentage):
def callback(self, percentage, text=None):
"""
Display the precentage.
"""
if self.callback_function:
self.callback_function(percentage)
if text:
self.callback_function(percentage, text)
else:
self.callback_function(percentage)
else:
sys.stdout.write("\r%02d%%" % percent)
if text is None:
sys.stdout.write("\r%02d%%" % percentage)
else:
sys.stdout.write("\r%02d%% %s" % (percentage, text))
def end_progress(self):
"""
@ -135,7 +142,10 @@ class User(gen.user.User):
@type error: str
@returns: none
"""
ErrorDialog(title, error)
if self.error_function:
self.error_function(title, error)
else:
ErrorDialog(title, error)
def notify_db_error(self, error):
"""

View File

@ -43,6 +43,7 @@ from gen.ggettext import sgettext as _
from gen.ggettext import ngettext
from cStringIO import StringIO
from collections import defaultdict
from gui.user import User
import sys
import posixpath
@ -1575,15 +1576,15 @@ class ViewManager(CLIManager):
if include.get_active():
from ExportPkg import PackageWriter
writer = PackageWriter(self.dbstate.db, filename,
msg_callback=lambda m1, m2: ErrorDialog(m1, m2),
callback=self.pulse_progressbar)
User(error=ErrorDialog,
callback=self.pulse_progressbar))
writer.export()
else:
from ExportXml import XmlWriter
writer = XmlWriter(self.dbstate.db,
msg_callback=lambda m1, m2: ErrorDialog(m1, m2),
callback=self.pulse_progressbar,
strip_photos=0, compress=1)
User(error=ErrorDialog,
callback=self.pulse_progressbar),
strip_photos=0, compress=1)
writer.write(filename)
self.uistate.set_busy_cursor(0)
self.uistate.progress.hide()

View File

@ -62,8 +62,8 @@ from glade import Glade
# The function that does the exporting
#
#-------------------------------------------------------------------------
def exportData(database, filename, msg_callback, option_box=None, callback=None):
gw = CSVWriter(database, filename, msg_callback, option_box, callback)
def exportData(database, filename, user, option_box=None):
gw = CSVWriter(database, filename, user, option_box)
return gw.export_data()
#-------------------------------------------------------------------------
@ -224,13 +224,12 @@ class CSVWriterOptionBox(WriterOptionBox):
#
#-------------------------------------------------------------------------
class CSVWriter(object):
def __init__(self, database, filename, msg_callback, option_box=None, callback=None):
def __init__(self, database, filename, user, option_box=None):
self.db = database
self.option_box = option_box
self.filename = filename
self.callback = callback
self.msg_callback = msg_callback
if callable(self.callback): # callback is really callable
self.user = user
if callable(self.user.callback): # callback is really callable
self.update = self.update_real
else:
self.update = self.update_empty
@ -281,7 +280,7 @@ class CSVWriter(object):
self.count += 1
newval = int(100*self.count/self.total)
if newval != self.oldval:
self.callback(newval)
self.user.callback(newval)
self.oldval = newval
def writeln(self):
@ -298,10 +297,10 @@ class CSVWriter(object):
self.g = UnicodeWriter(self.fp)
except IOError,msg:
msg2 = _("Could not create %s") % self.filename
self.msg_callback(msg2,str(msg))
self.user.notify_error(msg2,str(msg))
return False
except:
self.msg_callback(_("Could not create %s") % self.filename)
self.user.notify_error(_("Could not create %s") % self.filename)
return False
######################### initialize progress bar
self.count = 0

View File

@ -56,8 +56,8 @@ from glade import Glade
# writeData
#
#-------------------------------------------------------------------------
def writeData(database, filename, msg_callback, option_box=None, callback=None):
writer = FtreeWriter(database, filename, msg_callback, option_box, callback)
def writeData(database, filename, user, option_box=None):
writer = FtreeWriter(database, filename, user, option_box)
return writer.export_data()
#-------------------------------------------------------------------------
@ -67,14 +67,12 @@ def writeData(database, filename, msg_callback, option_box=None, callback=None):
#-------------------------------------------------------------------------
class FtreeWriter(object):
def __init__(self, database, filename, msg_callback, option_box=None,
callback = None):
def __init__(self, database, filename, user, option_box=None):
self.db = database
self.filename = filename
self.msg_callback = msg_callback
self.user = user
self.option_box = option_box
self.callback = callback
if callable(self.callback): # callback is really callable
if callable(self.user.callback): # callback is really callable
self.update = self.update_real
else:
self.update = self.update_empty
@ -92,7 +90,7 @@ class FtreeWriter(object):
self.count += 1
newval = int(100*self.count/self.total)
if newval != self.oldval:
self.callback(newval)
self.user.callback(newval)
self.oldval = newval
def export_data(self):

View File

@ -213,12 +213,10 @@ class GedcomWriter(UpdateCallback):
so that it can provide visual feedback via a progress bar if needed.
"""
def __init__(self, database, cmd_line=0,
option_box=None, callback=None):
UpdateCallback.__init__(self, callback)
def __init__(self, database, user, option_box=None):
UpdateCallback.__init__(self, user.callback)
self.total = 100
self.dbase = database
self.cmd_line = cmd_line
self.dirname = None
self.gedcom_file = None
@ -1435,17 +1433,17 @@ class GedcomWriter(UpdateCallback):
#
#
#-------------------------------------------------------------------------
def export_data(database, filename, msg_callback, option_box=None, callback=None):
def export_data(database, filename, user, option_box=None):
"""
External interface used to register with the plugin system.
"""
ret = False
try:
ged_write = GedcomWriter(database, 0, option_box, callback)
ged_write = GedcomWriter(database, user, option_box)
ret = ged_write.write_gedcom_file(filename)
except IOError, msg:
msg2 = _("Could not create %s") % filename
msg_callback(msg2, str(msg))
user.notify_error(msg2, str(msg))
except Errors.DatabaseError, msg:
msg_callback(_("Export failed"), str(msg))
user.notify_db_error(_("Export failed"), str(msg))
return ret

View File

@ -55,14 +55,12 @@ from glade import Glade
import config
class GeneWebWriter(object):
def __init__(self, database, filename, msg_callback, option_box=None,
callback=None):
def __init__(self, database, filename, user, option_box=None):
self.db = database
self.filename = filename
self.msg_callback = msg_callback
self.user = user
self.option_box = option_box
self.callback = callback
if callable(self.callback): # callback is really callable
if callable(self.user.callback): # callback is really callable
self.update = self.update_real
else:
self.update = self.update_empty
@ -82,7 +80,7 @@ class GeneWebWriter(object):
self.count += 1
newval = int(100*self.count/self.total)
if newval != self.oldval:
self.callback(newval)
self.user.callback(newval)
self.oldval = newval
def writeln(self, text):
@ -95,15 +93,15 @@ class GeneWebWriter(object):
self.g = open(self.filename, "w")
except IOError,msg:
msg2 = _("Could not create %s") % self.filename
self.msg_callback(msg2, str(msg))
self.user.notify_error(msg2, str(msg))
return False
except:
self.msg_callback(_("Could not create %s") % self.filename)
self.user.notify_error(_("Could not create %s") % self.filename)
return False
self.flist = [x for x in self.db.iter_family_handles()]
if len(self.flist) < 1:
self.msg_callback(_("No families matched by selected filter"))
self.notify_error(_("No families matched by selected filter"))
return False
self.count = 0
@ -491,6 +489,6 @@ class GeneWebWriter(object):
#
#
#-------------------------------------------------------------------------
def exportData(database, filename, msg_callback, option_box=None, callback=None):
gw = GeneWebWriter(database, filename, msg_callback, option_box, callback)
def exportData(database, filename, user, option_box=None):
gw = GeneWebWriter(database, filename, user, option_box)
return gw.export_data()

View File

@ -69,7 +69,7 @@ import constfunc
# writeData
#
#-------------------------------------------------------------------------
def writeData(database, filename, msg_callback, option_box=None, callback=None):
def writeData(database, filename, user, option_box=None):
# Rename file, if it exists already, with <filename>.bak
# as it it for normal XML export.
@ -85,7 +85,7 @@ def writeData(database, filename, msg_callback, option_box=None, callback=None):
option_box.parse_options()
database = option_box.get_filtered_database(database)
writer = PackageWriter(database, filename, msg_callback, callback)
writer = PackageWriter(database, filename, user)
return writer.export()
#-------------------------------------------------------------------------
@ -95,91 +95,90 @@ def writeData(database, filename, msg_callback, option_box=None, callback=None):
#-------------------------------------------------------------------------
class PackageWriter(object):
def __init__(self, database, filename, msg_callback, callback=None):
def __init__(self, database, filename, user):
self.db = database
self.callback = callback
self.msg_callback = msg_callback
self.user = user
self.filename = filename
def export(self):
# missmedia_action = 0
#--------------------------------------------------------------
def remove_clicked():
# File is lost => remove all references and the object itself
for p_id in self.db.iter_family_handles():
p = self.db.get_family_from_handle(p_id)
nl = p.get_media_list()
for o in nl:
if o.get_reference_handle() == m_id:
nl.remove(o)
p.set_media_list(nl)
self.db.commit_family(p,None)
for key in self.db.iter_person_handles():
p = self.db.get_person_from_handle(key)
nl = p.get_media_list()
for o in nl:
if o.get_reference_handle() == m_id:
nl.remove(o)
p.set_media_list(nl)
self.db.commit_person(p,None)
for key in self.db.get_source_handles():
p = self.db.get_source_from_handle(key)
nl = p.get_media_list()
for o in nl:
if o.get_reference_handle() == m_id:
nl.remove(o)
p.set_media_list(nl)
self.db.commit_source(p,None)
for key in self.db.get_place_handles():
p = self.db.get_place_from_handle(key)
nl = p.get_media_list()
for o in nl:
if o.get_reference_handle() == m_id:
nl.remove(o)
p.set_media_list(nl)
self.db.commit_place(p,None)
for key in self.db.get_event_handles():
p = self.db.get_event_from_handle(key)
nl = p.get_media_list()
for o in nl:
if o.get_reference_handle() == m_id:
nl.remove(o)
p.set_media_list(nl)
self.db.commit_event(p,None)
self.db.remove_object(m_id,None)
# def remove_clicked():
# # File is lost => remove all references and the object itself
# for p_id in self.db.iter_family_handles():
# p = self.db.get_family_from_handle(p_id)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference_handle() == m_id:
# nl.remove(o)
# p.set_media_list(nl)
# self.db.commit_family(p,None)
# for key in self.db.iter_person_handles():
# p = self.db.get_person_from_handle(key)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference_handle() == m_id:
# nl.remove(o)
# p.set_media_list(nl)
# self.db.commit_person(p,None)
# for key in self.db.get_source_handles():
# p = self.db.get_source_from_handle(key)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference_handle() == m_id:
# nl.remove(o)
# p.set_media_list(nl)
# self.db.commit_source(p,None)
# for key in self.db.get_place_handles():
# p = self.db.get_place_from_handle(key)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference_handle() == m_id:
# nl.remove(o)
# p.set_media_list(nl)
# self.db.commit_place(p,None)
# for key in self.db.get_event_handles():
# p = self.db.get_event_from_handle(key)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference_handle() == m_id:
# nl.remove(o)
# p.set_media_list(nl)
# self.db.commit_event(p,None)
# self.db.remove_object(m_id,None)
def leave_clicked():
# File is lost => do nothing, leave as is
pass
# def leave_clicked():
# # File is lost => do nothing, leave as is
# pass
def select_clicked():
# File is lost => select a file to replace the lost one
def fs_close_window(obj):
pass
# def select_clicked():
# # File is lost => select a file to replace the lost one
# def fs_close_window(obj):
# pass
def fs_ok_clicked(obj):
name = Utils.get_unicode_path_from_file_chooser(fs_top.get_filename())
if os.path.isfile(name):
archive.add(name)
# def fs_ok_clicked(obj):
# name = Utils.get_unicode_path_from_file_chooser(fs_top.get_filename())
# if os.path.isfile(name):
# archive.add(name)
fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"),
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OK, gtk.RESPONSE_OK)
)
response = fs_top.run()
if response == gtk.RESPONSE_OK:
fs_ok_clicked(fs_top)
elif response == gtk.RESPONSE_CANCEL:
fs_close_window(fs_top)
# fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"),
# buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
# gtk.STOCK_OK, gtk.RESPONSE_OK)
# )
# response = fs_top.run()
# if response == gtk.RESPONSE_OK:
# fs_ok_clicked(fs_top)
# elif response == gtk.RESPONSE_CANCEL:
# fs_close_window(fs_top)
fs_top.destroy()
# fs_top.destroy()
#---------------------------------------------------------------
try:
archive = tarfile.open(self.filename,'w:gz')
except EnvironmentError, msg:
log.warn(str(msg))
self.msg_callback(_('Failure writing %s') % self.filename, str(msg))
self.user.notify_error(_('Failure writing %s') % self.filename, str(msg))
return 0
# Write media files first, since the database may be modified
@ -213,7 +212,7 @@ class PackageWriter(object):
# Write XML now
g = StringIO()
gfile = XmlWriter(self.db, self.msg_callback, self.callback, 2)
gfile = XmlWriter(self.db, self.user, 2)
gfile.write_handle(g)
tarinfo = tarfile.TarInfo('data.gramps')
tarinfo.size = len(g.getvalue())

View File

@ -55,14 +55,12 @@ import Errors
from glade import Glade
class CalendarWriter(object):
def __init__(self, database, filename, msg_callback, option_box=None,
callback=None):
def __init__(self, database, filename, user, option_box=None):
self.db = database
self.filename = filename
self.msg_callback = msg_callback
self.user = user
self.option_box = option_box
self.callback = callback
if callable(self.callback): # callback is really callable
if callable(self.user.callback): # callback is really callable
self.update = self.update_real
else:
self.update = self.update_empty
@ -88,7 +86,7 @@ class CalendarWriter(object):
self.count += 1
newval = int(100 * self.count / self.total)
if newval != self.oldval:
self.callback(newval)
self.user.callback(newval)
self.oldval = newval
def writeln(self, text):
@ -102,10 +100,10 @@ class CalendarWriter(object):
self.g = open(filename,"w")
except IOError,msg:
msg2 = _("Could not create %s") % filename
self.msg_callback(msg2, str(msg))
self.user.notify_error(msg2, str(msg))
return False
except:
self.msg_callback(_("Could not create %s") % filename)
self.user.notify_error(_("Could not create %s") % filename)
return False
self.writeln("BEGIN:VCALENDAR")
@ -252,6 +250,6 @@ class CalendarWriter(object):
#
#
#-------------------------------------------------------------------------
def exportData(database, filename, msg_callback, option_box=None, callback=None):
cw = CalendarWriter(database, 0, filename, option_box, callback)
def exportData(database, filename, user, option_box=None):
cw = CalendarWriter(database, filename, user, option_box)
return cw.export_data(filename)

View File

@ -61,17 +61,17 @@ from gen.plug.utils import OpenFileOrStdout
# Support Functions
#
#-------------------------------------------------------------------------
def exportData(database, filename, msg_callback, option_box=None, callback=None):
def exportData(database, filename, user, option_box=None):
"""Function called by Gramps to export data on persons in VCard format."""
cardw = VCardWriter(database, filename, option_box, callback)
cardw = VCardWriter(database, filename, option_box, user)
try:
cardw.export_data()
except EnvironmentError, msg:
msg_callback(_("Could not create %s") % filename, str(msg))
user.notify_error(_("Could not create %s") % filename, str(msg))
return False
except:
# Export shouldn't bring Gramps down.
msg_callback(_("Could not create %s") % filename)
user.notify_error(_("Could not create %s") % filename)
return False
return True
@ -102,13 +102,13 @@ class VCardWriter(object):
raise TypeError("VCard escaping is not implemented for "
"data type %s." % str(type(data)))
def __init__(self, database, filename, option_box=None, callback=None):
def __init__(self, database, filename, option_box=None, user=None):
self.db = database
self.filename = filename
self.user = user
self.filehandle = None
self.option_box = option_box
self.callback = callback
if callable(self.callback): # callback is really callable
if callable(self.user.callback): # callback is really callable
self.update = self.update_real
else:
self.update = self.update_empty
@ -134,7 +134,7 @@ class VCardWriter(object):
self.count += 1
newval = int(100*self.count/self.total)
if newval != self.oldval:
self.callback(newval)
self.user.callback(newval)
self.oldval = newval
def writeln(self, text):

View File

@ -62,7 +62,6 @@ from gen.updatecallback import UpdateCallback
from gen.db.exceptions import DbWriteFailure
import const
import constfunc
#from QuestionDialog import ErrorDialog
from ExportOptions import WriterOptionBox
import libgrampsxml
@ -99,7 +98,7 @@ class GrampsXmlWriter(UpdateCallback):
"""
def __init__(self, db, strip_photos=0, compress=1, version="unknown",
callback=None):
user=None):
"""
Initialize, but does not write, an XML file.
@ -110,7 +109,8 @@ class GrampsXmlWriter(UpdateCallback):
> 2: remove leading slash (quick write)
compress - attempt to compress the database
"""
UpdateCallback.__init__(self, callback)
UpdateCallback.__init__(self, user.callback)
self.user = user
self.compress = compress
if not _gzip_ok:
self.compress = False
@ -1247,7 +1247,7 @@ def conf_priv(obj):
# export_data
#
#-------------------------------------------------------------------------
def export_data(database, filename, msg_callback, option_box=None, callback=None):
def export_data(database, filename, user, option_box=None):
"""
Call the XML writer with the syntax expected by the export plugin.
"""
@ -1264,7 +1264,7 @@ def export_data(database, filename, msg_callback, option_box=None, callback=None
option_box.parse_options()
database = option_box.get_filtered_database(database)
g = XmlWriter(database, msg_callback, callback, 0, compress)
g = XmlWriter(database, user, 0, compress)
return g.write(filename)
#-------------------------------------------------------------------------
@ -1277,11 +1277,11 @@ class XmlWriter(GrampsXmlWriter):
Writes a database to the XML file.
"""
def __init__(self, dbase, msg_callback, callback, strip_photos, compress=1):
def __init__(self, dbase, user, strip_photos, compress=1):
GrampsXmlWriter.__init__(
self, dbase, strip_photos, compress, const.VERSION, callback)
self.msg_callback = msg_callback
self, dbase, strip_photos, compress, const.VERSION, user)
self.user = user
def write(self, filename):
"""
Write the database to the specified file.
@ -1291,5 +1291,5 @@ class XmlWriter(GrampsXmlWriter):
ret = GrampsXmlWriter.write(self, filename)
except DbWriteFailure, msg:
(m1,m2) = msg.messages()
self.msg_callback(m1, m2)
self.user.notify_db_error(m1, m2)
return ret

View File

@ -102,11 +102,11 @@ def download(url, filename=None):
r.close()
return success
def export_file(db, filename, callback):
def export_file(db, filename, user):
"""
Export the db to a file (such as a GEDCOM file).
>>> export_file(DbDjango(), "/home/user/Untitled_1.ged", lambda a: a)
>>> export_file(DbDjango(), "/home/user/Untitled_1.ged", User())
"""
dbstate = DbState.DbState()
climanager = CLIManager(dbstate, False) # do not load db_loader
@ -125,7 +125,7 @@ def export_file(db, filename, callback):
print "ERROR:", name, exception
return False
export_function = getattr(mod, pdata.export_function)
export_function(db, filename, callback)
export_function(db, filename, user)
return True
return False