Refactor export plugin framework. All importers and exporters are now plugins.

svn: r11243
This commit is contained in:
Brian Matherly
2008-11-04 04:12:51 +00:00
parent b51caa5844
commit 2e9a488e3e
45 changed files with 746 additions and 1387 deletions

View File

@@ -204,12 +204,6 @@ src/GrampsDbUtils/_GedcomStageOne.py
#src/GrampsDbUtils/_GedcomLex.py #src/GrampsDbUtils/_GedcomLex.py
src/GrampsDbUtils/_GedcomParse.py src/GrampsDbUtils/_GedcomParse.py
src/GrampsDbUtils/_GedcomTokens.py src/GrampsDbUtils/_GedcomTokens.py
src/GrampsDbUtils/_GrampsDbWriteXML.py
src/GrampsDbUtils/_GrampsDbWRFactories.py
src/GrampsDbUtils/_ReadGedcom.py
src/GrampsDbUtils/_ReadXML.py
src/GrampsDbUtils/_WriteGedcom.py
src/GrampsDbUtils/_WriteXML.py
src/GrampsDbUtils/__init__.py src/GrampsDbUtils/__init__.py
# GrampsLocale package # GrampsLocale package
@@ -242,12 +236,11 @@ src/Selectors/_SelectorFactory.py
src/Selectors/__init__.py src/Selectors/__init__.py
# plugins directory # plugins directory
src/plugins/AgeOnDate.py
src/plugins/all_events.py src/plugins/all_events.py
src/plugins/all_relations.py src/plugins/all_relations.py
src/plugins/siblings.py
src/plugins/AgeOnDate.py
src/plugins/AncestorTree.py
src/plugins/AncestorReport.py src/plugins/AncestorReport.py
src/plugins/AncestorTree.py
src/plugins/BookReport.py src/plugins/BookReport.py
src/plugins/CalculateEstimatedDates.py src/plugins/CalculateEstimatedDates.py
src/plugins/Calendar.py src/plugins/Calendar.py
@@ -267,9 +260,15 @@ src/plugins/EndOfLineReport.py
src/plugins/Eval.py src/plugins/Eval.py
src/plugins/EventCmp.py src/plugins/EventCmp.py
src/plugins/EventNames.py src/plugins/EventNames.py
src/plugins/ExportCSV.py src/plugins/ExportCd.py
src/plugins/ExportCsv.py
src/plugins/ExportFtree.py
src/plugins/ExportGedcom.py
src/plugins/ExportGeneWeb.py
src/plugins/ExportPkg.py
src/plugins/ExportVCalendar.py src/plugins/ExportVCalendar.py
src/plugins/ExportVCard.py src/plugins/ExportVCard.py
src/plugins/ExportXml.py
src/plugins/ExtractCity.py src/plugins/ExtractCity.py
src/plugins/FamilyGroup.py src/plugins/FamilyGroup.py
src/plugins/FanChart.py src/plugins/FanChart.py
@@ -278,11 +277,14 @@ src/plugins/FindDupes.py
src/plugins/GVFamilyLines.py src/plugins/GVFamilyLines.py
src/plugins/GVHourGlass.py src/plugins/GVHourGlass.py
src/plugins/GVRelGraph.py src/plugins/GVRelGraph.py
src/plugins/ImportCSV.py src/plugins/ImportCsv.py
src/plugins/ImportGedcom.py
src/plugins/ImportGeneWeb.py src/plugins/ImportGeneWeb.py
src/plugins/ImportGpkg.py src/plugins/ImportGpkg.py
src/plugins/ImportGrdb.py src/plugins/ImportGrdb.py
src/plugins/ImportProGen.py
src/plugins/ImportvCard.py src/plugins/ImportvCard.py
src/plugins/ImportXml.py
src/plugins/IndivComplete.py src/plugins/IndivComplete.py
src/plugins/KinshipReport.py src/plugins/KinshipReport.py
src/plugins/Leak.py src/plugins/Leak.py
@@ -297,6 +299,7 @@ src/plugins/OwnerEditor.py
src/plugins/PatchNames.py src/plugins/PatchNames.py
src/plugins/PlaceReport.py src/plugins/PlaceReport.py
src/plugins/Rebuild.py src/plugins/Rebuild.py
src/plugins/RebuildRefMap.py
src/plugins/References.py src/plugins/References.py
src/plugins/RelCalc.py src/plugins/RelCalc.py
src/plugins/rel_da.py src/plugins/rel_da.py
@@ -315,6 +318,7 @@ src/plugins/rel_pl.py
src/plugins/RemoveUnused.py src/plugins/RemoveUnused.py
src/plugins/ReorderIds.py src/plugins/ReorderIds.py
src/plugins/SameSurnames.py src/plugins/SameSurnames.py
src/plugins/siblings.py
src/plugins/SimpleBookTitle.py src/plugins/SimpleBookTitle.py
src/plugins/SoundGen.py src/plugins/SoundGen.py
src/plugins/StatisticsChart.py src/plugins/StatisticsChart.py
@@ -322,11 +326,6 @@ src/plugins/Summary.py
src/plugins/TimeLine.py src/plugins/TimeLine.py
src/plugins/Verify.py src/plugins/Verify.py
src/plugins/WebCal.py src/plugins/WebCal.py
src/plugins/WriteCD.py
src/plugins/WriteFtree.py
src/plugins/WriteGeneWeb.py
src/plugins/WritePkg.py
src/plugins/RebuildRefMap.py
# PluginUtils package # PluginUtils package
src/PluginUtils/_GuiOptions.py src/PluginUtils/_GuiOptions.py
@@ -337,6 +336,7 @@ src/PluginUtils/_Tool.py
src/gen/utils/dbutils.py src/gen/utils/dbutils.py
src/gen/utils/progressmon.py src/gen/utils/progressmon.py
src/gen/plug/__init__.py src/gen/plug/__init__.py
src/gen/plug/_export.py
src/gen/plug/_import.py src/gen/plug/_import.py
src/gen/plug/_manager.py src/gen/plug/_manager.py
src/gen/plug/_plugin.py src/gen/plug/_plugin.py
@@ -693,7 +693,6 @@ src/widgets/validatedmaskedentry.py
# Glade files # Glade files
# #
src/docgen/gtkprintpreview.glade src/docgen/gtkprintpreview.glade
src/GrampsDbUtils/gedcomimport.glade
src/glade/edit_person.glade src/glade/edit_person.glade
src/glade/gramps.glade src/glade/gramps.glade
src/glade/mergedata.glade src/glade/mergedata.glade
@@ -703,14 +702,12 @@ src/glade/scratchpad.glade
src/glade/paper_settings.glade src/glade/paper_settings.glade
src/plugins/NotRelated.glade src/plugins/NotRelated.glade
src/plugins/book.glade src/plugins/book.glade
src/plugins/cdexport.glade
src/plugins/changenames.glade src/plugins/changenames.glade
src/plugins/changetype.glade src/plugins/changetype.glade
src/plugins/csvexport.glade
src/plugins/desbrowse.glade src/plugins/desbrowse.glade
src/plugins/eval.glade src/plugins/eval.glade
src/plugins/eventcmp.glade src/plugins/eventcmp.glade
src/plugins/genewebexport.glade src/plugins/ImportGedcom.glade
src/plugins/leak.glade src/plugins/leak.glade
src/plugins/merge.glade src/plugins/merge.glade
src/plugins/ownereditor.glade src/plugins/ownereditor.glade
@@ -719,10 +716,12 @@ src/plugins/relcalc.glade
src/plugins/soundex.glade src/plugins/soundex.glade
src/plugins/summary.glade src/plugins/summary.glade
src/plugins/unused.glade src/plugins/unused.glade
src/plugins/vcalendarexport.glade src/plugins/ExportCsv.glade
src/plugins/vcardexport.glade src/plugins/ExportFtree.glade
src/plugins/ExportGeneWeb.glade
src/plugins/ExportVCard.glade
src/plugins/ExportVCalendar.glade
src/plugins/verify.glade src/plugins/verify.glade
src/plugins/writeftree.glade
# #
# Files to extract from and then merge into # Files to extract from and then merge into
# #

View File

@@ -45,13 +45,9 @@ import logging
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import const import const
import GrampsDbUtils
import Mime
from QuestionDialog import ErrorDialog
import Config import Config
import RecentFiles import RecentFiles
import Utils import Utils
import gen.db.exceptions as GX
import gen import gen
from DbManager import CLIDbManager, NAME_FILE, find_locker_name from DbManager import CLIDbManager, NAME_FILE, find_locker_name
@@ -59,10 +55,6 @@ from PluginUtils import Tool
from gen.plug import PluginManager from gen.plug import PluginManager
from ReportBase import CATEGORY_BOOK, CATEGORY_CODE, cl_report from ReportBase import CATEGORY_BOOK, CATEGORY_CODE, cl_report
IMPORT_TYPES = (const.APP_GRAMPS_XML, const.APP_GEDCOM,
const.APP_GRAMPS_PKG, const.APP_GENEWEB,
const.APP_GRAMPS)
_help = """ _help = """
Usage: gramps.py [OPTION...] Usage: gramps.py [OPTION...]
--load-modules=MODULE1,MODULE2,... Dynamic modules to load --load-modules=MODULE1,MODULE2,... Dynamic modules to load
@@ -74,7 +66,7 @@ Help options
Application options Application options
-O, --open=FAMILY_TREE Open family tree -O, --open=FAMILY_TREE Open family tree
-i, --import=FILENAME Import file -i, --import=FILENAME Import file
-o, --output=FILENAME Write file -e, --export=FILENAME Export file
-f, --format=FORMAT Specify format -f, --format=FORMAT Specify format
-a, --action=ACTION Specify action -a, --action=ACTION Specify action
-p, --options=OPTIONS_STRING Specify options -p, --options=OPTIONS_STRING Specify options
@@ -96,7 +88,7 @@ class ArgHandler:
All following arguments will be ignored. All following arguments will be ignored.
-O, --open=FAMTREE : Family tree or family tree database dir to open. -O, --open=FAMTREE : Family tree or family tree database dir to open.
-i, --import=FILE : filename to import. -i, --import=FILE : filename to import.
-o, --output=FILE : filename to export. -e, --export=FILE : filename to export.
-f, --format=FORMAT : format of the file preceding this option. -f, --format=FORMAT : format of the file preceding this option.
If the filename (no flags) is specified, the interactive session is If the filename (no flags) is specified, the interactive session is
@@ -148,11 +140,9 @@ class ArgHandler:
1/ Just the family tree (name or database dir) 1/ Just the family tree (name or database dir)
2/ -O, Open of a family tree 2/ -O, Open of a family tree
3/ -i, Import of any format understood by an importer, optionally provide 3/ -i, Import of any format understood by an importer, optionally provide
-f to indicate format (possible: 'gedcom','gramps-xml','gramps-pkg', -f to indicate format
'grdb','geneweb' 4/ -e, export a family tree in required format, optionally provide
4/ -o, output a family tree in required format, optionally provide -f to indicate format
-f to indicate format (possible: 'gedcom',
'gramps-xml','gramps-pkg','iso','wft','geneweb')
5/ -a, --action: An action (possible: 'check', 'summary', 'report', 5/ -a, --action: An action (possible: 'check', 'summary', 'report',
'tool') 'tool')
6/ -u, --force-unlock: A locked database can be unlocked by given this 6/ -u, --force-unlock: A locked database can be unlocked by given this
@@ -187,84 +177,19 @@ class ArgHandler:
for opt_ix in range(len(options)): for opt_ix in range(len(options)):
option, value = options[opt_ix] option, value = options[opt_ix]
if option in ( '-O', '--open'): if option in ( '-O', '--open'):
self.handle_open_option(value) self.__handle_open_option(value)
elif option in ( '-i', '--import'): elif option in ( '-i', '--import'):
fname = value
fullpath = os.path.abspath(os.path.expanduser(fname))
format = None format = None
ftype = Mime.get_type(fullpath) if opt_ix < len(options) - 1 \
if opt_ix<len(options)-1 \ and options[opt_ix + 1][0] in ( '-f', '--format'):
and options[opt_ix+1][0] in ( '-f', '--format'): format = options[opt_ix + 1][1]
format = options[opt_ix+1][1] self.__handle_import_option(value, format)
if format not in ('gedcom', elif option in ( '-e', '--export' ):
'gramps-xml', format = None
'gramps-pkg', if opt_ix < len(options) - 1 \
'grdb', and options[opt_ix + 1][0] in ( '-f', '--format'):
'geneweb'): format = options[opt_ix + 1][1]
print "Invalid format: %s" % format self.__handle_export_option(value, format)
print "Ignoring input file: %s" % fname
continue
elif ftype == const.APP_GEDCOM:
format = 'gedcom'
elif ftype == const.APP_GRAMPS_PKG:
format = 'gramps-pkg'
elif ftype == const.APP_GRAMPS_XML:
format = 'gramps-xml'
elif ftype == const.APP_GRAMPS:
format = 'grdb'
elif ftype == const.APP_GENEWEB:
format = 'geneweb'
else:
print 'Unrecognized type: "%s" for input file: %s' \
% (ftype,fname)
print "Ignoring input file: %s" % fname
continue
self.imports.append((fname, format))
elif option in ( '-o', '--output' ):
outfname = value
fullpath = os.path.abspath(os.path.expanduser(outfname))
if os.path.exists(fullpath):
print "WARNING: Output file already exist!"
print "WARNING: It will be overwritten:\n %s" % fullpath
answer = None
while not answer:
answer = raw_input('OK to overwrite? (yes/no) ')
if answer.upper() in ('Y','YES'):
print "Will overwrite the existing file: %s" % fullpath
else:
print "Will skip the output file: %s" % fullpath
continue
if opt_ix < len(options)-1 \
and options[opt_ix+1][0] in ( '-f', '--format'):
outformat = options[opt_ix+1][1]
if outformat not in ('gedcom',
'gramps-xml',
'gramps-pkg',
'grdb',
'iso',
'wft',
'geneweb'):
print "Invalid format for output: %s" % outformat
print "Ignoring output file: %s" % outfname
continue
elif outfname[-3:].upper() == "GED":
outformat = 'gedcom'
elif outfname[-4:].upper() == "GPKG":
outformat = 'gramps-pkg'
elif outfname[-3:].upper() == "WFT":
outformat = 'wft'
elif outfname[-2:].upper() == "GW":
outformat = 'geneweb'
elif outfname[-6:].upper() == "GRAMPS":
outformat = 'gramps-xml'
elif outfname[-4:].upper() == "GRDB":
outformat = 'grdb'
else:
print "Unrecognized format for output file %s" % outfname
print "Ignoring output file: %s" % outfname
continue
self.exports.append((fullpath, outformat))
elif option in ( '-a', '--action' ): elif option in ( '-a', '--action' ):
action = value action = value
if action not in ( 'check', 'summary', 'report', 'tool' ): if action not in ( 'check', 'summary', 'report', 'tool' ):
@@ -287,26 +212,11 @@ class ArgHandler:
elif option in ('-u', '--force-unlock'): elif option in ('-u', '--force-unlock'):
self.force_unlock = True self.force_unlock = True
def handle_open_option(self, value): def __handle_open_option(self, value):
""" """
Handle the "-O" or "--open" option. Handle the "-O" or "--open" option.
""" """
db_path = None db_path = self.__deduce_db_path(value)
# First, check if this is the name of a family tree
data = self.dbman.family_tree(value)
if data is not None:
# This is a known database name. Use it.
db_path, ftype, title = data
else:
# This is not a known database name.
# Check if the user provided a db path instead.
fullpath = os.path.abspath(os.path.expanduser(value))
if os.path.isdir(fullpath):
# The user provided a directory. Check if it is a valid tree.
name_file_path = os.path.join(fullpath, NAME_FILE)
if os.path.isfile(name_file_path):
db_path = fullpath
if db_path: if db_path:
# We have a potential database path. # We have a potential database path.
@@ -319,7 +229,95 @@ class ArgHandler:
print _("If gedcom, gramps-xml or grdb, use the -i option to " print _("If gedcom, gramps-xml or grdb, use the -i option to "
"import into a family tree instead") "import into a family tree instead")
sys.exit(0) sys.exit(0)
def __handle_import_option(self, value, format):
"""
Handle the "-i" or "--import" option.
"""
fname = value
fullpath = os.path.abspath(os.path.expanduser(fname))
if not os.path.exists(fullpath):
print 'Import file not found.'
print "Ignoring import file: %s" % fname
return
if format is None:
# Guess the file format based on the file extension.
# This will get the lower case extension without a period,
# or an empty string.
format = os.path.splitext(fname)[-1][1:].lower()
pmgr = PluginManager.get_instance()
plugin_found = False
for plugin in pmgr.get_import_plugins():
if format == plugin.get_extension():
plugin_found = True
if plugin_found:
self.imports.append((fname, format))
else:
print 'Unrecognized type: "%s" for import file: %s' \
% (format, fname)
print "Ignoring import file: %s" % fname
def __handle_export_option(self, value, format):
"""
Handle the "-e" or "--export" option.
"""
fname = value
fullpath = os.path.abspath(os.path.expanduser(fname))
if os.path.exists(fullpath):
print "WARNING: Output file already exist!"
print "WARNING: It will be overwritten:\n %s" % fullpath
answer = None
while not answer:
answer = raw_input('OK to overwrite? (yes/no) ')
if answer.upper() in ('Y','YES'):
print "Will overwrite the existing file: %s" % fullpath
else:
print "Will skip the output file: %s" % fullpath
return
if format is None:
# Guess the file format based on the file extension.
# This will get the lower case extension without a period,
# or an empty string.
format = os.path.splitext(fname)[-1][1:].lower()
pmgr = PluginManager.get_instance()
plugin_found = False
for plugin in pmgr.get_export_plugins():
if format == plugin.get_extension():
plugin_found = True
if plugin_found:
self.exports.append((fullpath, format))
else:
print "Unrecognized format for export file %s" % fname
print "Ignoring export file: %s" % fname
def __deduce_db_path(self, db_name_or_path):
"""
Attempt to find a database path for the given parameter.
@return: The path to a Gramps DB
or None if a database can not be deduced.
"""
# First, check if this is the name of a family tree
db_path = self.dbman.get_family_tree_path(db_name_or_path)
if db_path is None:
# This is not a known database name.
# Check if the user provided a db path instead.
fullpath = os.path.abspath(os.path.expanduser(db_name_or_path))
if os.path.isdir(fullpath):
# The user provided a directory. Check if it is a valid tree.
name_file_path = os.path.join(fullpath, NAME_FILE)
if os.path.isfile(name_file_path):
db_path = fullpath
return db_path
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Determine the need for GUI # Determine the need for GUI
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@@ -358,80 +356,47 @@ class ArgHandler:
for name, dirname in self.dbman.family_tree_list(): for name, dirname in self.dbman.family_tree_list():
print dirname, ', with name ', name print dirname, ', with name ', name
sys.exit(0) sys.exit(0)
if self.list_more: if self.list_more:
print 'GRAMPS Family Trees:' print 'GRAMPS Family Trees:'
list = self.dbman.family_tree_summary() summary_list = self.dbman.family_tree_summary()
for dict in list: for summary in summary_list:
print "Family Tree \"%s\":" % dict["Family tree"] print "Family Tree \"%s\":" % dict["Family tree"]
for item in dict: for item in summary:
if item != "Family tree": if item != "Family tree":
print " %s: %s" % (item, dict[item]) print " %s: %s" % (item, dict[item])
sys.exit(0) sys.exit(0)
if self.help: if self.help:
print _help print _help
sys.exit(0) sys.exit(0)
if self.open_gui: if self.open_gui:
# Filename was given as gramps FILENAME. # First check if a Gramps database was provided
# Open a session with that file. Forget the rest of given arguments # (either a database path or a database name)
success = False db_path = self.__deduce_db_path(self.open_gui)
if os.path.isdir(self.open_gui):
#only accept if a name.txt is found
path_name = os.path.join(self.open_gui, NAME_FILE)
if os.path.isfile(path_name):
filetype = const.APP_FAMTREE
filename = self.open_gui
else:
filetype = 'No Fam Tree Dir'
filename = self.open_gui
else:
filename = os.path.abspath(os.path.expanduser(self.open_gui))
filetype = Mime.get_type(filename)
if filetype is const.APP_FAMTREE:
success = True
pass
elif filetype in IMPORT_TYPES:
# Say the type outloud
if filetype == const.APP_GRAMPS:
print "Type: GRAMPS 2.2.x GRDB database"
elif filetype == const.APP_GEDCOM:
print "Type: GEDCOM file"
elif filetype == const.APP_GRAMPS_XML:
print "Type: GRAMPS XML database"
elif filetype == const.APP_GRAMPS_PKG:
print "Type: GRAMPS XML package"
filename, filetype, name = self.dbman.import_new_db(filetype, if not db_path:
filename, None) # Apparently it is not a database. See if it is a file that
success = True # can be imported.
else: db_path, title = self.dbman.import_new_db(self.open_gui, None)
#see if not just a name of a database is given
data = self.dbman.family_tree(self.open_gui) if db_path:
if data is not None:
filename, filetype = data[0], data[1]
success = True
else:
ErrorDialog(
_("Could not open file: %s") % filename,
_('Not a valid Family tree given to open\n\n'
))
print "Exiting..."
sys.exit(0)
if success:
# Test if not locked or problematic # Test if not locked or problematic
if not self.__check_db(filename, self.force_unlock): if not self.__check_db(db_path, self.force_unlock):
sys.exit(0) sys.exit(0)
# Add the file to the recent items # Add the file to the recent items
path = os.path.join(filename, "name.txt") path = os.path.join(db_path, "name.txt")
try: try:
ifile = open(path) ifile = open(path)
title = ifile.readline().strip() title = ifile.readline().strip()
ifile.close() ifile.close()
except: except:
title = filename title = db_path
RecentFiles.recent_files(filename, title) RecentFiles.recent_files(db_path, title)
else: else:
sys.exit(1) sys.exit(1)
return (filename, filetype) return db_path
if self.open: if self.open:
# Family Tree to open was given. Open it # Family Tree to open was given. Open it
@@ -496,7 +461,7 @@ class ArgHandler:
os.path.isfile(os.path.join(filename, "name.txt")) and \ os.path.isfile(os.path.join(filename, "name.txt")) and \
self.__check_db(filename): self.__check_db(filename):
self.vm.db_loader.read_file(filename) self.vm.db_loader.read_file(filename)
return (filename, const.APP_FAMTREE) return filename
def __check_db(self, dbpath, force_unlock = False): def __check_db(self, dbpath, force_unlock = False):
# Test if not locked or problematic # Test if not locked or problematic
@@ -521,88 +486,12 @@ class ArgHandler:
Command-line import routine. Try to import filename using the format. Command-line import routine. Try to import filename using the format.
Any errors will cause the sys.exit(1) call. Any errors will cause the sys.exit(1) call.
""" """
if format == 'grdb': pmgr = PluginManager.get_instance()
#2.x database for plugin in pmgr.get_import_plugins():
filename = os.path.normpath(os.path.abspath(filename)) if format == plugin.get_extension():
try: import_function = plugin.get_import_function()
GrampsDbUtils.gramps_db_reader_factory(const.APP_GRAMPS)( import_function(self.state.db, filename, None)
self.state.db,filename,empty)
except GX.GrampsDbException, e:
print "%s" % e.value
sys.exit(1)
except:
print "Error importing %s" % filename
sys.exit(1)
elif format == 'gedcom':
filename = os.path.normpath(os.path.abspath(filename))
filename = Utils.get_unicode_path(filename)
try:
# Cheating here to use default encoding
from GrampsDbUtils._ReadGedcom import import2
import2(self.state.db, filename, None, "", False)
except:
print "Error importing %s" % filename
sys.exit(1)
elif format == 'gramps-xml':
try:
GrampsDbUtils.gramps_db_reader_factory(const.APP_GRAMPS_XML)(
self.state.db,filename,None,self.cl)
except:
print "Error importing %s" % filename
sys.exit(1)
elif format == 'geneweb':
import ImportGeneWeb
filename = os.path.normpath(os.path.abspath(filename))
try:
ImportGeneWeb.importData(self.state.db, filename, None)
except:
print "Error importing %s" % filename
sys.exit(1)
elif format == 'gramps-pkg':
tmpdir_path = Utils.get_empty_tempdir("imp_gpkgdir")
try:
import tarfile
archive = tarfile.open(filename)
for tarinfo in archive:
archive.extract(tarinfo, tmpdir_path)
archive.close()
except tarfile.ReadError, msg:
print "Error reading archive:", msg
sys.exit(1)
except tarfile.CompressionError, msg:
print "Error uncompressing archive:", msg
sys.exit(1)
except:
print "Error extracting into %s" % tmpdir_path
sys.exit(1)
dbname = os.path.join(tmpdir_path, const.XMLFILE)
try:
GrampsDbUtils.gramps_db_reader_factory(const.APP_GRAMPS_XML)(
self.state.db,dbname,None)
except:
print "Error importing %s" % filename
sys.exit(1)
# Clean up tempdir after ourselves
# THIS HAS BEEN CHANGED, because now we want to keep images
# stay after the import is over. Just delete the XML file.
##jgs:FIXME for how long? just for debug? or this session?
## must not be forever, since re-exec of this routine
## clears dirfiles without asking
## & expands nre tarball possibly overwriting subdirs
##
## if only debugging, could do Utils.rm_tempdir here
## in any case, no real harm (exc. space) to leave stuff here
## until next exec of this, which will discard all old stuff
os.remove(dbname)
## files = os.listdir(tmpdir_path)
## for fn in files:
## os.remove(os.path.join(tmpdir_path,fn))
## os.rmdir(tmpdir_path)
else:
print "Invalid format: %s" % format
sys.exit(1)
if not self.cl: if not self.cl:
if self.imp_db_path: if self.imp_db_path:
return self.vm.open_activate(self.imp_db_path) return self.vm.open_activate(self.imp_db_path)
@@ -620,71 +509,11 @@ class ArgHandler:
Try to write into filename using the format. Try to write into filename using the format.
Any errors will cause the sys.exit(1) call. Any errors will cause the sys.exit(1) call.
""" """
filename = os.path.abspath(os.path.expanduser(filename)) pmgr = PluginManager.get_instance()
if format == 'grdb': for plugin in pmgr.get_export_plugins():
print "GRDB format write is no longer supported!" if format == plugin.get_extension():
sys.exit(1) export_function = plugin.get_export_function()
elif format == 'gedcom': export_function(self.state.db, filename)
try:
gw = GrampsDbUtils.GedcomWriter(self.state.db, None, 1)
ret = gw.write_gedcom_file(filename)
print "... finished writing %s" % filename
except:
print "Error exporting %s" % filename
sys.exit(1)
elif format == 'gramps-xml':
filename = os.path.normpath(os.path.abspath(filename))
if filename:
try:
g = GrampsDbUtils.XmlWriter(self.state.db, None, 0, 1)
ret = g.write(filename)
print "... finished writing %s" % filename
except:
print "Error exporting %s" % filename
sys.exit(1)
else:
print "Error exporting %s" % filename
elif format == 'gramps-pkg':
try:
import WritePkg
writer = WritePkg.PackageWriter(self.state.db, filename)
ret = writer.export()
print "... finished writing %s" % filename
except:
print "Error creating %s" % filename
sys.exit(1)
elif format == 'iso':
import WriteCD
try:
writer = WriteCD.PackageWriter(self.state.db, filename, 1)
ret = writer.export()
print "... finished writing %s" % filename
except:
print "Error exporting %s" % filename
sys.exit(1)
elif format == 'wft':
import WriteFtree
try:
writer = WriteFtree.FtreeWriter(self.state.db, None, 1,
filename)
ret = writer.export_data()
print "... finished writing %s" % filename
except:
print "Error exporting %s" % filename
sys.exit(1)
elif format == 'geneweb':
import WriteGeneWeb
try:
writer = WriteGeneWeb.GeneWebWriter(self.state.db,
None, 1, filename)
ret = writer.export_data()
print "... finished writing %s" % filename
except:
print "Error exporting %s" % filename
sys.exit(1)
else:
print "Invalid format: %s" % format
sys.exit(1)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -777,5 +606,3 @@ class ArgHandler:
print "Unknown action: %s." % action print "Unknown action: %s." % action
sys.exit(1) sys.exit(1)
def empty(val):
pass

View File

@@ -56,30 +56,13 @@ import gobject
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import const import const
import Config import Config
import Mime
import gen.db import gen.db
import GrampsDbUtils
import Utils import Utils
from gen.plug import PluginManager from gen.plug import PluginManager
from QuestionDialog import (DBErrorDialog, ErrorDialog, QuestionDialog2, from QuestionDialog import (DBErrorDialog, ErrorDialog, QuestionDialog2,
WarningDialog) WarningDialog)
import Errors import Errors
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
#connection between main mime type, name, and list of alternative mime types
_KNOWN_FORMATS = {
const.APP_GRAMPS : [_('GRAMPS (grdb)'), []],
const.APP_GRAMPS_XML : [_('GRAMPS XML'), []],
const.APP_GEDCOM : [_('GEDCOM'), []],
}
OPEN_FORMATS = [const.APP_GRAMPS_XML, const.APP_GEDCOM]
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# DbLoader class # DbLoader class
@@ -110,39 +93,27 @@ class DbLoader:
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
choose_db_dialog = gtk.FileChooserDialog(_('GRAMPS: Import database'), import_dialog = gtk.FileChooserDialog(_('GRAMPS: Import database'),
self.uistate.window, self.uistate.window,
gtk.FILE_CHOOSER_ACTION_OPEN, gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
'gramps-import', gtk.RESPONSE_OK)) 'gramps-import', gtk.RESPONSE_OK))
choose_db_dialog.set_local_only(False) import_dialog.set_local_only(False)
# Always add automatic (match all files) filter # Always add automatic (match all files) filter
add_all_files_filter(choose_db_dialog) # * add_all_files_filter(import_dialog) # *
add_xml_filter(choose_db_dialog) # .gramps
add_gedcom_filter(choose_db_dialog) # .ged
format_list = OPEN_FORMATS[:] # Add more file type selections for available importers
# Add more data type selections if opening existing db
for plugin in pmgr.get_import_plugins(): for plugin in pmgr.get_import_plugins():
mime_types = plugin.get_mime_types() file_filter = gtk.FileFilter()
mime_filter = gtk.FileFilter() name = "%s (.%s)" % (plugin.get_name(), plugin.get_extension())
mime_filter.set_name(plugin.get_name()) file_filter.set_name(name)
for mime_type in mime_types: file_filter.add_pattern("*.%s" % plugin.get_extension())
mime_filter.add_mime_type(mime_type) file_filter.add_pattern(plugin.get_extension().capitalize())
format_name = plugin.get_name() import_dialog.add_filter(file_filter)
choose_db_dialog.add_filter(mime_filter) (box, type_selector) = format_maker()
# There might be multiple entries in mime_types import_dialog.set_extra_widget(box)
# Add only formats not already in list, so user don't get confused
# with multiple entries
if not mime_types[0] in format_list:
format_list.append(mime_types[0])
_KNOWN_FORMATS[mime_types[0]] = [format_name, mime_types[1:]]
(box, type_selector) = format_maker(format_list)
choose_db_dialog.set_extra_widget(box)
# Suggested folder: try last open file, import, then last export, # Suggested folder: try last open file, import, then last export,
# then home. # then home.
@@ -150,43 +121,31 @@ class DbLoader:
if len(default_dir)<=1: if len(default_dir)<=1:
default_dir = get_default_dir() default_dir = get_default_dir()
choose_db_dialog.set_current_folder(default_dir) import_dialog.set_current_folder(default_dir)
while True: while True:
response = choose_db_dialog.run() response = import_dialog.run()
if response == gtk.RESPONSE_CANCEL: if response == gtk.RESPONSE_CANCEL:
break break
elif response == gtk.RESPONSE_OK: elif response == gtk.RESPONSE_OK:
filename = Utils.get_unicode_path(choose_db_dialog.get_filename()) filename = Utils.get_unicode_path(import_dialog.get_filename())
if self.check_errors(filename): if self.check_errors(filename):
# displays errors if any # displays errors if any
continue continue
# Do not allow importing from the currently open file
if filename == self.dbstate.db.full_name:
ErrorDialog(_("Cannot import from current file"))
continue
filetype = type_selector.get_value()
if filetype == 'auto':
try:
filetype = Mime.get_type(filename)
except RuntimeError, msg:
ErrorDialog(_("Could not open file: %s") % filename,
str(msg))
continue
# First we try our best formats
if filetype in OPEN_FORMATS or filetype in _KNOWN_FORMATS:
importer = GrampsDbUtils.gramps_db_reader_factory(filetype)
self.do_import(choose_db_dialog, importer, filename)
return True
(the_path, the_file) = os.path.split(filename) (the_path, the_file) = os.path.split(filename)
Config.set(Config.RECENT_IMPORT_DIR, the_path) Config.set(Config.RECENT_IMPORT_DIR, the_path)
# Then we try all the known plugins
extension = type_selector.get_value()
if extension == 'auto':
# Guess the file format based on the file extension.
# This will get the lower case extension without a period,
# or an empty string.
extension = os.path.splitext(filename)[-1][1:].lower()
for plugin in pmgr.get_import_plugins(): for plugin in pmgr.get_import_plugins():
if filetype in plugin.get_mime(): print plugin.get_extension()
self.do_import(choose_db_dialog, if extension == plugin.get_extension():
self.do_import(import_dialog,
plugin.get_import_function(), plugin.get_import_function(),
filename) filename)
return True return True
@@ -196,9 +155,9 @@ class DbLoader:
_("Could not open file: %s") % filename, _("Could not open file: %s") % filename,
_('File type "%s" is unknown to GRAMPS.\n\n' _('File type "%s" is unknown to GRAMPS.\n\n'
'Valid types are: GRAMPS database, GRAMPS XML, ' 'Valid types are: GRAMPS database, GRAMPS XML, '
'GRAMPS package, and GEDCOM.') % filetype) 'GRAMPS package, and GEDCOM.') % extension)
choose_db_dialog.destroy() import_dialog.destroy()
return False return False
def check_errors(self, filename): def check_errors(self, filename):
@@ -218,16 +177,14 @@ class DbLoader:
return True return True
elif os.path.isdir(filename): elif os.path.isdir(filename):
ErrorDialog( ErrorDialog(
_('Cannot open database'), _('Cannot open file'),
_('The selected file is a directory, not ' _('The selected file is a directory, not a file.\n'))
'a file.\nA GRAMPS database must be a file.'))
return True return True
elif os.path.exists(filename): elif os.path.exists(filename):
if not os.access(filename, os.R_OK): if not os.access(filename, os.R_OK):
ErrorDialog( ErrorDialog(
_('Cannot open database'), _('Cannot open file'),
_('You do not have read access to the selected ' _('You do not have read access to the selected file.'))
'file.'))
return True return True
else: else:
try: try:
@@ -236,7 +193,7 @@ class DbLoader:
os.remove(filename) os.remove(filename)
except IOError: except IOError:
ErrorDialog( ErrorDialog(
_('Cannot create database'), _('Cannot create file'),
_('You do not have write access to the selected file.')) _('You do not have write access to the selected file.'))
return True return True
@@ -361,34 +318,6 @@ def add_all_files_filter(chooser):
mime_filter.add_pattern('*') mime_filter.add_pattern('*')
chooser.add_filter(mime_filter) chooser.add_filter(mime_filter)
def add_gramps_files_filter(chooser):
"""
Add an all-GRAMPS filter to the file chooser dialog.
"""
mime_filter = gtk.FileFilter()
mime_filter.set_name(_('All GRAMPS files'))
for fmt in OPEN_FORMATS:
mime_filter.add_mime_type(fmt)
chooser.add_filter(mime_filter)
def add_xml_filter(chooser):
"""
Add a GRAMPS XML filter to the file chooser dialog.
"""
mime_filter = gtk.FileFilter()
mime_filter.set_name(_('GRAMPS XML databases'))
mime_filter.add_mime_type(const.APP_GRAMPS_XML)
chooser.add_filter(mime_filter)
def add_gedcom_filter(chooser):
"""
Add a GEDCOM filter to the file chooser dialog.
"""
mime_filter = gtk.FileFilter()
mime_filter.set_name(_('GEDCOM files'))
mime_filter.add_mime_type(const.APP_GEDCOM)
chooser.add_filter(mime_filter)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Format selectors: explictly set the format of the file # Format selectors: explictly set the format of the file
@@ -417,7 +346,7 @@ class GrampsFormatWidget(gtk.ComboBox):
return None return None
return self.format_list[active][0] return self.format_list[active][0]
def format_maker(formats): def format_maker():
""" """
A factory function making format selection widgets. A factory function making format selection widgets.
@@ -425,10 +354,11 @@ def format_maker(formats):
The auto selection is always added as the first one. The auto selection is always added as the first one.
The returned box contains both the label and the selector. The returned box contains both the label and the selector.
""" """
pmgr = PluginManager.get_instance()
format_list = [ ('auto', _('Automatically detected')) ] format_list = [ ('auto', _('Automatically detected')) ]
for format in formats:
if format in _KNOWN_FORMATS: for plugin in pmgr.get_import_plugins():
format_list.append( (format, _KNOWN_FORMATS[format][0]) ) format_list.append( (plugin.get_extension(), plugin.get_name()) )
type_selector = GrampsFormatWidget() type_selector = GrampsFormatWidget()
type_selector.set(format_list) type_selector.set(format_list)

View File

@@ -69,14 +69,12 @@ import pango
import const import const
from QuestionDialog import ErrorDialog, QuestionDialog from QuestionDialog import ErrorDialog, QuestionDialog
import gen.db import gen.db
from gen.plug import PluginManager
import GrampsDbUtils import GrampsDbUtils
import Config import Config
import Mime import Mime
from DdTargets import DdTargets from DdTargets import DdTargets
import RecentFiles import RecentFiles
IMPORT_TYPES = (const.APP_GRAMPS_XML, const.APP_GEDCOM,
const.APP_GRAMPS_PKG, const.APP_GENEWEB,
const.APP_GRAMPS)
_RETURN = gtk.gdk.keyval_from_name("Return") _RETURN = gtk.gdk.keyval_from_name("Return")
_KP_ENTER = gtk.gdk.keyval_from_name("KP_Enter") _KP_ENTER = gtk.gdk.keyval_from_name("KP_Enter")
@@ -208,14 +206,14 @@ class CLIDbManager:
self.current_names.sort() self.current_names.sort()
def family_tree(self, name): def get_family_tree_path(self, name):
"""Given a name, return None if name not existing or """
filename, filetype, name Given a name, return None if name not existing or the path to the
if a known database name database if it is a known database name.
""" """
for data in self.current_names: for data in self.current_names:
if data[0] == name: if data[0] == name:
return data[1], 'x-directory/normal', name return data[1]
return None return None
def family_tree_list(self): def family_tree_list(self):
@@ -269,37 +267,39 @@ class CLIDbManager:
""" """
return self._create_new_db_cli(title) return self._create_new_db_cli(title)
def import_new_db(self, filetype, filename, callback): def import_new_db(self, filename, callback):
if filetype in IMPORT_TYPES: """
# get the name of the database from the filename of the file Attempt to import the provided file into a new database.
(name, ext) = os.path.splitext(os.path.basename(filename)) A new database will only be created if an appropriate importer was
found.
@return: A tuple of (new_path, name) for the new database
or (None, None) if no import was performed.
"""
pmgr = PluginManager.get_instance()
(name, ext) = os.path.splitext(os.path.basename(filename))
format = ext[1:].lower()
# create the database for plugin in pmgr.get_import_plugins():
new_path, name = self._create_new_db(name) if format == plugin.get_extension():
# get the import function using the filetype, but create a db new_path, name = self._create_new_db(name)
# based on the DBDir
self.__start_cursor(_("Importing data...")) # Create a new database
dbclass = gen.db.GrampsDBDir self.__start_cursor(_("Importing data..."))
dbase = dbclass() dbclass = gen.db.GrampsDBDir
dbase.load(new_path, callback) dbase = dbclass()
dbase.load(new_path, callback)
rdr = GrampsDbUtils.gramps_db_reader_factory(filetype)
rdr(dbase, filename, callback) import_function = plugin.get_import_function()
import_function(dbase, filename, callback)
# finish up
self.__end_cursor() # finish up
dbase.close() self.__end_cursor()
dbase.close()
path = os.path.join(new_path, "name.txt")
try: return new_path, name
ifile = open(path) return None, None
title = ifile.readline().strip()
ifile.close()
except:
title = new_path
return new_path, 'x-directory/normal', title
return None, None, None
def is_locked(self, dbpath): def is_locked(self, dbpath):
""" """
@@ -929,13 +929,9 @@ class DbManager(CLIDbManager):
drag_value = drag_value.strip() drag_value = drag_value.strip()
# deterimine the mime type. If it is one that we are interested in, fname, title = self.import_new_db(drag_value[7:], None)
# we process it
filetype = Mime.get_type(drag_value)
fname, type, title = self.import_new_db(filetype, drag_value[7:],
None)
return fname, type, title return fname, title
def drag_motion(wid, context, xpos, ypos, time_stamp): def drag_motion(wid, context, xpos, ypos, time_stamp):
""" """
@@ -1099,7 +1095,11 @@ def check_out(dbase, rev, path, callback):
) )
return return
rdr = GrampsDbUtils.gramps_db_reader_factory(const.APP_GRAMPS_XML) pmgr = PluginManager.get_instance()
for plugin in pmgr.get_import_plugins():
if plugin.get_extension() == "gramps":
rdr = plugin.get_import_function()
xml_file = os.path.join(path, ARCHIVE) xml_file = os.path.join(path, ARCHIVE)
rdr(dbase, xml_file, callback) rdr(dbase, xml_file, callback)
os.unlink(xml_file) os.unlink(xml_file)

View File

@@ -131,7 +131,8 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
self.logo = gtk.gdk.pixbuf_new_from_file(_gramps_png) self.logo = gtk.gdk.pixbuf_new_from_file(_gramps_png)
self.splash = gtk.gdk.pixbuf_new_from_file(_splash_jpg) self.splash = gtk.gdk.pixbuf_new_from_file(_splash_jpg)
self.obtain_export_formats() pmgr = PluginManager.get_instance()
self.__exporters = pmgr.get_export_plugins()
self.__previous_page = -1 self.__previous_page = -1
@@ -191,7 +192,7 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
box.set_border_width(12) box.set_border_width(12)
box.set_spacing(12) box.set_spacing(12)
table = gtk.Table(2*len(self.exportformats),2) table = gtk.Table(2*len(self.__exporters),2)
table.set_row_spacings(6) table.set_row_spacings(6)
table.set_col_spacings(6) table.set_col_spacings(6)
@@ -200,9 +201,9 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
group = None group = None
recent_type = Config.get(Config.RECENT_EXPORT_TYPE) recent_type = Config.get(Config.RECENT_EXPORT_TYPE)
for ix in range(len(self.exportformats)): for ix in range(len(self.__exporters)):
title = self.exportformats[ix][1] title = self.__exporters[ix].get_name()
description= self.exportformats[ix][2] description= self.__exporters[ix].get_description()
button = gtk.RadioButton(group,title) button = gtk.RadioButton(group,title)
if not group: if not group:
@@ -248,7 +249,7 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
if pagenumber == _ExportAssistant_pages['exporttypes'] : if pagenumber == _ExportAssistant_pages['exporttypes'] :
#decide if options need to be shown: #decide if options need to be shown:
ix = self.get_selected_format_index() ix = self.get_selected_format_index()
if self.exportformats[ix][3]: if self.__exporters[ix].get_config():
return pagenumber + 1 return pagenumber + 1
else : else :
# no options needed # no options needed
@@ -260,12 +261,15 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
"""This method gets the option page, and fills it with the options.""" """This method gets the option page, and fills it with the options."""
option = self.get_selected_format_index() option = self.get_selected_format_index()
vbox = self.get_nth_page(_ExportAssistant_pages['options']) vbox = self.get_nth_page(_ExportAssistant_pages['options'])
self.set_page_title(vbox, self.exportformats[option][3][0]) (config_title, config_box_class) = self.__exporters[option].get_config()
self.set_page_title(vbox, config_title)
# remove present content of the vbox # remove present content of the vbox
vbox.foreach(vbox.remove) vbox.foreach(vbox.remove)
# add new content # add new content
option_box_class = self.exportformats[option][3][1] if config_box_class:
self.option_box_instance = option_box_class(self.person) self.option_box_instance = config_box_class(self.person)
else:
self.option_box_instance = None
box = self.option_box_instance.get_option_box() box = self.option_box_instance.get_option_box()
vbox.add(box) vbox.add(box)
vbox.show_all() vbox.show_all()
@@ -430,7 +434,7 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
# The confirm page with apply button # The confirm page with apply button
# Present user with what will happen # Present user with what will happen
ix = self.get_selected_format_index() ix = self.get_selected_format_index()
format = self.exportformats[ix][1].replace('_','') format = self.__exporters[ix].get_name()
#Allow for exotic error: file is still not correct #Allow for exotic error: file is still not correct
self.check_fileselect(self.chooser, show=False) self.check_fileselect(self.chooser, show=False)
@@ -505,18 +509,7 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
#clean up ManagedWindow menu, then destroy window, bring forward parent #clean up ManagedWindow menu, then destroy window, bring forward parent
ManagedWindow.ManagedWindow.close(self,*obj) ManagedWindow.ManagedWindow.close(self,*obj)
def obtain_export_formats(self):
"""
This method builds its own list of available exports.
The list is built from the list of exporters in the PluginManager and
from the locally defined exports (i.e. native export defined here).
"""
pmgr = PluginManager.get_instance()
self.exportformats = [item for item in pmgr.get_export_list()]
def get_intro_text(self): def get_intro_text(self):
return _('Under normal circumstances, GRAMPS does not require you ' return _('Under normal circumstances, GRAMPS does not require you '
'to directly save your changes. All changes you make are ' 'to directly save your changes. All changes you make are '
@@ -546,7 +539,7 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
def suggest_filename(self): def suggest_filename(self):
"""Prepare suggested filename and set it in the file chooser.""" """Prepare suggested filename and set it in the file chooser."""
ix = self.get_selected_format_index() ix = self.get_selected_format_index()
ext = self.exportformats[ix][4] ext = self.__exporters[ix].get_extension()
# Suggested folder: try last export, then last import, then home. # Suggested folder: try last export, then last import, then home.
default_dir = Config.get(Config.RECENT_EXPORT_DIR) default_dir = Config.get(Config.RECENT_EXPORT_DIR)
@@ -575,15 +568,11 @@ class ExportAssistant(gtk.Assistant, ManagedWindow.ManagedWindow) :
Config.set(Config.RECENT_EXPORT_DIR, os.path.split(filename)[0]) Config.set(Config.RECENT_EXPORT_DIR, os.path.split(filename)[0])
ix = self.get_selected_format_index() ix = self.get_selected_format_index()
Config.set(Config.RECENT_EXPORT_TYPE, ix) Config.set(Config.RECENT_EXPORT_TYPE, ix)
if self.exportformats[ix][3]: export_function = self.__exporters[ix].get_export_function()
success = self.exportformats[ix][0](self.dbstate.db, success = export_function(self.dbstate.db,
filename,self.person, filename,
self.option_box_instance, self.option_box_instance,
self.callback) self.callback)
else:
success = self.exportformats[ix][0](self.dbstate.db,
filename,self.person,
self.callback)
return success return success
def pre_save(self,page): def pre_save(self,page):

View File

@@ -14,22 +14,11 @@ pkgdata_PYTHON = \
_GedcomStageOne.py\ _GedcomStageOne.py\
_GedcomTokens.py\ _GedcomTokens.py\
_GedcomUtils.py\ _GedcomUtils.py\
_GrampsDbWRFactories.py\ __init__.py
_GrampsDbWriteXML.py\
__init__.py\
_ReadGedcom.py\
_ReadXML.py\
_WriteGedcom.py\
_WriteXML.py
pkgpyexecdir = @pkgpyexecdir@/GrampsDbUtils pkgpyexecdir = @pkgpyexecdir@/GrampsDbUtils
pkgpythondir = @pkgpythondir@/GrampsDbUtils pkgpythondir = @pkgpythondir@/GrampsDbUtils
GLADEFILES = \
gedcomimport.glade
dist_pkgdata_DATA = $(GLADEFILES)
# Clean up all the byte-compiled files # Clean up all the byte-compiled files
MOSTLYCLEANFILES = *pyc *pyo MOSTLYCLEANFILES = *pyc *pyo

View File

@@ -79,7 +79,6 @@ def add_to_list(table, key, value):
Add the value to the table entry associated with key. If the entry Add the value to the table entry associated with key. If the entry
does not exist, it is added. does not exist, it is added.
""" """
print type(table)
if key in table: if key in table:
table[key].append(value) table[key].append(value)
else: else:

View File

@@ -1,77 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004-2007 Donald N. Allingham
# Copyright (C) 2008 Brian G. 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:_GrampsDbWRFactories.py 9912 2008-01-22 09:17:46Z acraphae $
"""
This module contains factory methods for accessing the different
GrampsDb backends. These methods should be used obtain the correct class
for a database backend.
The app_* constants in const.py can be used to indicate which backend is
required e.g.:
>
> # To get a Gedcom reader
> GrampsDb.gramps_db_reader_factory(db_type = const.APP_GEDCOM)
"""
import const
import logging
log = logging.getLogger(".GrampDb")
from gen.db import GrampsDbException
from gen.plug import PluginManager
def gramps_db_reader_factory(db_type):
"""Factory class for obtaining a Gramps database importer.
@param db_type: the type of backend required.
@type db_type: one of the app_* constants in const.py
Raises GrampsDbException if the db_type is not recognised.
"""
if db_type == const.APP_GRAMPS_XML:
import _ReadXML as ReadXML
md = ReadXML.importData
elif db_type == const.APP_GEDCOM:
import _ReadGedcom as ReadGedcom
md = ReadGedcom.importData
else:
#see if registered importer
found = False
pmgr = PluginManager.get_instance()
for plugin in pmgr.get_import_plugins():
if db_type in plugin.get_mime_types():
print "Found import plugin for %s" % plugin.get_name()
found = True
md = plugin.get_import_function()
break
if not found:
raise GrampsDbException("Attempt to create a database "
"reader for unknown format: "
"db_type = %s" % (str(db_type)))
return md

View File

@@ -1,149 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2008 Brian G. Matherly
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2008 Robert Cheramy <robert@cheramy.net>
#
# 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$
"""
Contains the interface to allow a database to get written using
GRAMPS' XML file format.
"""
#-------------------------------------------------------------------------
#
# load standard python libraries
#
#-------------------------------------------------------------------------
import shutil
import os
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# load GRAMPS libraries
#
#-------------------------------------------------------------------------
import const
from QuestionDialog import ErrorDialog
import GrampsDbUtils
import ExportOptions
from gen.db.exceptions import GrampsDbWriteFailure
import gen.proxy
#-------------------------------------------------------------------------
#
# Attempt to load the GZIP library. Some version of python do not seem
# to be compiled with this available.
#
#-------------------------------------------------------------------------
try:
import gzip
_gzip_ok = 1
except:
_gzip_ok = 0
#-------------------------------------------------------------------------
#
# export_data
#
#-------------------------------------------------------------------------
def export_data(database, filename, person, option_box, callback=None):
"""
Call the XML writer with the syntax expected by the export plugin.
"""
if os.path.isfile(filename):
try:
shutil.copyfile(filename, filename + ".bak")
shutil.copystat(filename, filename + ".bak")
except:
pass
compress = _gzip_ok == 1
option_box.parse_options()
if option_box.private:
database = gen.proxy.PrivateProxyDb(database)
if option_box.restrict:
database = gen.proxy.LivingProxyDb(
database, gen.proxy.LivingProxyDb.MODE_INCLUDE_LAST_NAME_ONLY)
# Apply the Person Filter
if not option_box.cfilter.is_empty():
database = gen.proxy.FilterProxyDb(database, option_box.cfilter)
# Apply the Note Filter
if not option_box.nfilter.is_empty():
database = gen.proxy.FilterProxyDb(
database, note_filter=option_box.nfilter)
# Apply the ReferencedProxyDb to remove any objects not referenced
# after any of the other proxies have been applied
if option_box.unlinked:
database = gen.proxy.ReferencedProxyDb(database)
g = XmlWriter(database, callback, 0, compress)
return g.write(filename)
#-------------------------------------------------------------------------
#
# XmlWriter
#
#-------------------------------------------------------------------------
class XmlWriter(GrampsDbUtils.GrampsDbXmlWriter):
"""
Writes a database to the XML file.
"""
def __init__(self, dbase, callback, strip_photos, compress=1):
GrampsDbUtils.GrampsDbXmlWriter.__init__(
self, dbase, strip_photos, compress, const.VERSION, callback)
def write(self, filename):
"""
Write the database to the specified file.
"""
ret = 0 #False
try:
ret = GrampsDbUtils.GrampsDbXmlWriter.write(self, filename)
except GrampsDbWriteFailure, msg:
(m1,m2) = msg.messages()
ErrorDialog(m1, m2)
return ret
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
TITLE = _('GRAMPS _XML database')
DESCRIPTION = _('The GRAMPS XML database is a text version of a family tree. '
'It is read-write compatible with '
'the present GRAMPS database format.')
CONFIG = (_('GRAMPS XML export options'), ExportOptions.WriterOptionBox)
FILENAME = 'gramps'
from gen.plug import PluginManager
pmgr = PluginManager.get_instance()
pmgr.register_export(export_data, TITLE, DESCRIPTION, CONFIG, FILENAME)

View File

@@ -22,28 +22,12 @@
""" """
This package implements additions to the the GrampsDb database. This package implements additions to the the GrampsDb database.
This package should be used for code that extended GrampsDb but also
depends on Gtk.
A number of importers and exporters are provided to convert between
the different backend formats.
To obtain a class that implements readers use the gramps_db_reader_factory
method. For information on using this factory see the
_GrampsDbUtilsFactories.py file comments.
""" """
from _GedcomInfo import (personalConstantEvents, familyConstantEvents, from _GedcomInfo import (personalConstantEvents, familyConstantEvents,
personalConstantAttributes) personalConstantAttributes)
from _GrampsDbWRFactories import gramps_db_reader_factory
from _GedcomParse import GedcomParser from _GedcomParse import GedcomParser
from _WriteGedcom import GedcomWriter
from _GrampsDbWriteXML import GrampsDbXmlWriter
from _WriteXML import XmlWriter
import _Backup as Backup import _Backup as Backup

View File

@@ -1,34 +0,0 @@
#!/usr/bin/env python
import unittest
from test import test_util as tu
par = tu.path_append_parent()
###
class Test1(unittest.TestCase):
"""Test imports which are buried within functions
otherwise they may not get timely test coverage
NB: if any test fails, check imports within that module
"""
def test1a_buried_imports(self):
import sys
self.assertTrue(par in sys.path,
"par %r has to be in path!" % par)
ilist = (
"_WriteXML",
"_WriteGedcom",
"_ReadXML",
"_ReadGedcom",
)
for m in ilist:
try:
mod = __import__(m)
except ImportError:
mod = None
self.assertTrue(mod, "try import of module %r" % m)
if __name__ == "__main__":
unittest.main()
#===eof===

View File

@@ -1,57 +0,0 @@
"""gedwrite_breakup_test tests the breakup function in GedcomWrite"""
import unittest as U
from test.test_util import msg, path_append_parent
path_append_parent();
import _WriteGedcom as WG
class Test1(U.TestCase):
def test1a_common(s):
#txt, limit, [split-results]
L=4
dat = (
##0123456
("a", L, ["a",]),
("abc", L, ["abc",]),
("abcd", L, ["abcd",]),
("abcde", L, ["abcd","e"]),
("1234567", L, ["1234","567"]),
("12345678", L, ["1234","5678"]),
("123456789", L, ["1234","5678", "9"]),
)
for (t,l,r) in dat:
g = WG.breakup(t,l)
s.assertEquals(g,r, msg(g,r, "breakup(%r,%d) results" % (t,l)))
def test1b_spaces(s):
#txt, limit, [split-results]
L=4
dat = (
##0123456
("a b ", L, ["a b ",]),
(" a b", L, [" a b",]),
("asdf g", L, ["asd", "f g"]),
(" z", L, [" ", "z"]),
(" z", L, [" ", " z"]),
(" A", 2, [" ", " ", " ", "A"]),
)
for (t,l,r) in dat:
g = WG.breakup(t,l)
s.assertEquals(g,r, msg(g,r, "breakup(%r,%d) results" % (t,l)))
def test1c_unusual(s):
#just documenting behavior for unlikely input
#txt, limit, [split-results]
dat = (
##0123456
("", 4, []),
("xyz", 1, ["x", "y", "z"]),
)
for (t,l,r) in dat:
g = WG.breakup(t,l)
s.assertEquals(g,r, msg(g,r, "breakup(%r,%d) results" % (t,l)))
s.assertRaises(ValueError, WG.breakup, "xy",0)
if __name__ == "__main__":
U.main()
#===eof===

View File

@@ -133,7 +133,7 @@ class PluginStatus(ManagedWindow.ManagedWindow):
data = model.get_value(node, 3) data = model.get_value(node, 3)
name = model.get_value(node, 1) name = model.get_value(node, 1)
if data: if data:
PluginTrace(self.uistate, self.track, data, name) PluginTrace(self.uistate, [], data, name)
def build_menu_names(self, obj): def build_menu_names(self, obj):
return (self.title, "") return (self.title, "")

View File

@@ -10,6 +10,7 @@ pkgdatadir = $(datadir)/@PACKAGE@/gen/plug
pkgdata_PYTHON = \ pkgdata_PYTHON = \
__init__.py \ __init__.py \
_export.py \
_import.py \ _import.py \
_manager.py \ _manager.py \
_plugin.py _plugin.py

View File

@@ -24,5 +24,6 @@ The "plug" package for handling plugins in Gramps.
from _plugin import Plugin from _plugin import Plugin
from _manager import PluginManager from _manager import PluginManager
from _import import ImportPlugin from _import import ImportPlugin
from _export import ExportPlugin
__all__ = [ "menu", Plugin, PluginManager, ImportPlugin ] __all__ = [ "menu", Plugin, PluginManager, ImportPlugin, ExportPlugin ]

102
src/gen/plug/_export.py Normal file
View File

@@ -0,0 +1,102 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2008 Brian G. 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$
"""
This module provides the Plugin class for export plugins.
"""
from gen.plug import Plugin
class ExportPlugin(Plugin):
"""
This class represents a plugin for exporting data from Gramps
"""
def __init__(self, name, description, export_function,
extension, config=None):
"""
@param name: A friendly name to call this plugin.
Example: "GEDCOM Export"
@type name: string
@param description: An short description of the plugin.
Example: "This plugin will export a GEDCOM file from database"
@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):
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.
@type export_function: callable
@param extension: The extension for the output file.
Example: "ged"
@type extension: str
@param config: Options for the exporter
@type config: tuple (??,??)
@return: nothing
"""
Plugin.__init__(self, name, description)
self.__name = name
self.__export_func = export_function
self.__extension = extension
self.__config = config
def get_module_name(self):
"""
Get the name of the module that this plugin lives in.
@return: a string representing the name of the module for this plugin
"""
return self.__export_func.__module__
def get_name(self):
"""
Get the short name for this plugins.
@return: str
"""
return self.__name
def get_export_function(self):
"""
Get the import function for this plugins.
@return: the callable import_function passed into __init__
"""
return self.__export_func
def get_extension(self):
"""
Get the file extension for the export file.
@return: str
"""
return self.__extension
def get_config(self):
"""
Get the config.
@return: (??,??)
"""
return self.__config

View File

@@ -29,7 +29,7 @@ class ImportPlugin(Plugin):
""" """
This class represents a plugin for importing data into Gramps This class represents a plugin for importing data into Gramps
""" """
def __init__(self, name, description, import_function, mime_types=None): def __init__(self, name, description, import_function, extension):
""" """
@param name: A friendly name to call this plugin. @param name: A friendly name to call this plugin.
Example: "GEDCOM Import" Example: "GEDCOM Import"
@@ -47,14 +47,14 @@ class ImportPlugin(Plugin):
The first parameter is a progress indicator. The first parameter is a progress indicator.
The second parameter is a text string. The second parameter is a text string.
@type import_function: callable @type import_function: callable
@param mime_types: A list of mime types that apply to the file type. @param extension: The extension for the files imported by this plugin.
Example: "['application/x-gramps']" Example: "ged"
@type mime_types: [str] (list of strings) @type extension: str
@return: nothing @return: nothing
""" """
Plugin.__init__(self, name, description) Plugin.__init__(self, name, description)
self.__import_func = import_function self.__import_func = import_function
self.__mime_types = mime_types self.__extension = extension
def get_module_name(self): def get_module_name(self):
""" """
@@ -72,10 +72,10 @@ class ImportPlugin(Plugin):
""" """
return self.__import_func return self.__import_func
def get_mime_types(self): def get_extension(self):
""" """
Get the list of mime types that apply to the import file. Get the extension for the files imported by this plugin.
@return: [str] (list of strings) @return: str
""" """
return self.__mime_types return self.__extension

View File

@@ -93,8 +93,8 @@ class PluginManager(gen.utils.Callback):
self.__report_list = [] self.__report_list = []
self.__quick_report_list = [] self.__quick_report_list = []
self.__tool_list = [] self.__tool_list = []
self.__export_list = []
self.__import_plugins = [] self.__import_plugins = []
self.__export_plugins = []
self.__attempt_list = [] self.__attempt_list = []
self.__loaddir_list = [] self.__loaddir_list = []
self.__textdoc_list = [] self.__textdoc_list = []
@@ -257,10 +257,6 @@ class PluginManager(gen.utils.Callback):
""" Return the list of command line tool plugins. """ """ Return the list of command line tool plugins. """
return self.__cli_tool_list return self.__cli_tool_list
def get_export_list(self):
""" Return the list of export plugins. """
return self.__export_list
def get_module_description(self, module): def get_module_description(self, module):
""" Given a module name, return the module description. """ """ Given a module name, return the module description. """
return self.__mod2text.get(module, '') return self.__mod2text.get(module, '')
@@ -274,6 +270,9 @@ class PluginManager(gen.utils.Callback):
if isinstance(plugin, gen.plug.ImportPlugin): if isinstance(plugin, gen.plug.ImportPlugin):
self.__import_plugins.append(plugin) self.__import_plugins.append(plugin)
self.__mod2text[plugin.get_module_name()] = plugin.get_description() self.__mod2text[plugin.get_module_name()] = plugin.get_description()
if isinstance(plugin, gen.plug.ExportPlugin):
self.__export_plugins.append(plugin)
self.__mod2text[plugin.get_module_name()] = plugin.get_description()
def get_import_plugins(self): def get_import_plugins(self):
""" """
@@ -282,24 +281,14 @@ class PluginManager(gen.utils.Callback):
@return: [gen.plug.ImportPlugin] (a list of ImportPlugin instances) @return: [gen.plug.ImportPlugin] (a list of ImportPlugin instances)
""" """
return self.__import_plugins return self.__import_plugins
def register_export(self, export_data, title, description='', config=None,
filename=''):
"""
Register an export filter, taking the task, file filter,
and the list of patterns for the filename matching.
"""
if description and filename:
del_index = -1
for i in range(0, len(self.__export_list)):
if self.__export_list[i][1] == title:
del_index = i
if del_index != -1:
del self.__export_list[del_index]
self.__export_list.append( def get_export_plugins(self):
(export_data, title, description, config, filename)) """
self.__mod2text[export_data.__module__] = description Get the list of export plugins.
@return: [gen.plug.ExportPlugin] (a list of ExportPlugin instances)
"""
return self.__export_plugins
def register_tool(self, name, category, tool_class, options_class, def register_tool(self, name, category, tool_class, options_class,
modes, translated_name, status=_("Unknown"), modes, translated_name, status=_("Unknown"),
@@ -545,8 +534,8 @@ class PluginManager(gen.utils.Callback):
for filename, junk in self.__failmsg_list for filename, junk in self.__failmsg_list
] ]
self.__export_list[:] = [ item for item in self.__export_list self.__export_plugins[:] = [ item for item in self.__export_plugins
if item[0].__module__ not in failed_module_names ][:] if item.get_module_name not in failed_module_names ][:]
self.__import_plugins[:] = [ item for item in self.__import_plugins self.__import_plugins[:] = [ item for item in self.__import_plugins
if item.get_module_name not in failed_module_names ][:] if item.get_module_name not in failed_module_names ][:]
self.__tool_list[:] = [ item for item in self.__tool_list self.__tool_list[:] = [ item for item in self.__tool_list

View File

@@ -275,9 +275,8 @@ class Gramps:
# we may need to change the order of operation # we may need to change the order of operation
ah = ArgHandler.ArgHandler(state, self.vm, args) ah = ArgHandler.ArgHandler(state, self.vm, args)
if ah.need_gui(): if ah.need_gui():
retval = ah.handle_args() filename = ah.handle_args()
if retval: if filename:
filename, filetype = retval
self.vm.post_init_interface(show_manager=False) self.vm.post_init_interface(show_manager=False)
self.vm.open_activate(filename) self.vm.open_activate(filename)
else: else:

View File

@@ -73,10 +73,10 @@ except:
# GRAMPS modules # GRAMPS modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from GrampsDbUtils import XmlWriter from ExportXml import XmlWriter
from Utils import media_path_full from Utils import media_path_full
from QuestionDialog import ErrorDialog, MissingMediaDialog from QuestionDialog import ErrorDialog, MissingMediaDialog
from gen.plug import PluginManager from gen.plug import PluginManager, ExportPlugin
_title_string = _("Export to CD") _title_string = _("Export to CD")
@@ -85,7 +85,7 @@ _title_string = _("Export to CD")
# writeData # writeData
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def writeData(database, filename, person, option_box=None, callback=None): def writeData(database, filename, option_box=None, callback=None):
writer = PackageWriter(database, filename, callback) writer = PackageWriter(database, filename, callback)
return writer.export() return writer.export()
@@ -299,13 +299,15 @@ class PackageWriter:
# Register the plugin # Register the plugin
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
_title = _('_Export to CD (portable XML)') _description = _('Exporting to CD copies all your data and media object files '
_description = _('Exporting to CD copies all your data and media ' 'to the CD Creator. You may later burn the CD with this data, '
'object files to the CD Creator. You may later burn the CD ' 'and that copy will be completely portable across different '
'with this data, and that copy will be completely portable ' 'machines and binary architectures.')
'across different machines and binary architectures.')
_config = None
_filename = 'burn'
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(writeData, _title, _description, _config, _filename) plugin = ExportPlugin(name = _('_Export to CD (portable XML)'),
description = _description,
export_function = writeData,
extension = "burn",
config = None )
pmgr.register_plugin(plugin)

View File

@@ -57,9 +57,9 @@ log = logging.getLogger(".ExportCSV")
import gen.lib import gen.lib
from Filters import GenericFilter, Rules, build_filter_menu from Filters import GenericFilter, Rules, build_filter_menu
import Utils import Utils
import Errors
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.plug import PluginManager from gen.plug import PluginManager, ExportPlugin
import gen.proxy
import DateHandler import DateHandler
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@@ -67,8 +67,8 @@ import DateHandler
# The function that does the exporting # The function that does the exporting
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def exportData(database,filename,person, option_box,callback=None): def exportData(database, filename, option_box=None, callback=None):
gw = CSVWriter(database,person,0,filename, option_box,callback) gw = CSVWriter(database, filename, option_box, callback)
return gw.export_data() return gw.export_data()
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@@ -166,15 +166,12 @@ class CSVWriterOptionBox:
""" """
def __init__(self,person): def __init__(self,person):
self.person = person self.person = person
def get_option_box(self):
self.include_individuals = 1 self.include_individuals = 1
self.include_marriages = 1 self.include_marriages = 1
self.include_children = 1 self.include_children = 1
glade_file = "%s/csvexport.glade" % os.path.dirname(__file__) def get_option_box(self):
if not os.path.isfile(glade_file): glade_file = os.path.join(os.path.dirname(__file__), "ExportCsv.glade")
glade_file = "plugins/csvexport.glade"
self.topDialog = glade.XML(glade_file,"csvExport","gramps") self.topDialog = glade.XML(glade_file,"csvExport","gramps")
filter_obj = self.topDialog.get_widget("filter") filter_obj = self.topDialog.get_widget("filter")
@@ -229,12 +226,9 @@ class CSVWriterOptionBox:
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class CSVWriter: class CSVWriter:
def __init__(self,database,person,cl=0,filename="", def __init__(self, database, filename, option_box=None, callback=None):
option_box=None,callback=None):
self.db = database self.db = database
self.person = person
self.option_box = option_box self.option_box = option_box
self.cl = cl
self.filename = filename self.filename = filename
self.callback = callback self.callback = callback
if callable(self.callback): # callback is really callable if callable(self.callback): # callback is really callable
@@ -250,7 +244,9 @@ class CSVWriter:
self.person_ids = {} self.person_ids = {}
if not option_box: if not option_box:
self.cl_setup() self.include_individuals = 1
self.include_marriages = 1
self.include_children = 1
else: else:
self.option_box.parse_options() self.option_box.parse_options()
@@ -258,48 +254,9 @@ class CSVWriter:
self.include_marriages = self.option_box.include_marriages self.include_marriages = self.option_box.include_marriages
self.include_children = self.option_box.include_children self.include_children = self.option_box.include_children
if self.option_box.cfilter is None: if not option_box.cfilter.is_empty():
for p in self.db.get_person_handles(sort_handles=False): self.db = gen.proxy.FilterProxyDb(self.db, option_box.cfilter)
self.plist[p] = 1
else:
try:
for p in self.option_box.cfilter.apply(self.db,
self.db.get_person_handles(sort_handles=False)):
self.plist[p] = 1
except Errors.FilterError, msg:
(m1,m2) = msg.messages()
ErrorDialog(m1,m2)
return
# get the families for which these people are spouses:
self.flist = {}
for key in self.plist:
p = self.db.get_person_from_handle(key)
for family_handle in p.get_family_handle_list():
self.flist[family_handle] = 1
# now add the families for which these people are a child:
family_handles = self.db.get_family_handles()
for family_handle in family_handles:
family = self.db.get_family_from_handle(family_handle)
for child_ref in family.get_child_ref_list():
child_handle = child_ref.ref
if child_handle in self.plist.keys():
self.flist[family_handle] = 1
def update_empty(self):
pass
def update_real(self):
self.count += 1
newval = int(100*self.count/self.total)
if newval != self.oldval:
self.callback(newval)
self.oldval = newval
def cl_setup(self):
self.include_individuals = 0
self.include_marriages = 0
self.include_children = 0
for p in self.db.get_person_handles(sort_handles=False): for p in self.db.get_person_handles(sort_handles=False):
self.plist[p] = 1 self.plist[p] = 1
# get the families for which these people are spouses: # get the families for which these people are spouses:
@@ -316,6 +273,16 @@ class CSVWriter:
child_handle = child_ref.ref child_handle = child_ref.ref
if child_handle in self.plist.keys(): if child_handle in self.plist.keys():
self.flist[family_handle] = 1 self.flist[family_handle] = 1
def update_empty(self):
pass
def update_real(self):
self.count += 1
newval = int(100*self.count/self.total)
if newval != self.oldval:
self.callback(newval)
self.oldval = newval
def writeln(self): def writeln(self):
self.g.writerow([]) self.g.writerow([])
@@ -497,13 +464,17 @@ class CSVWriter:
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Register all of the plugins # Register the plugin
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
_title = _('Comma _Separated Values Spreadsheet (CSV)') _name = _('Comma _Separated Values Spreadsheet (CSV)')
_description = _('CSV is a common spreadsheet format.') _description = _('CSV is a common spreadsheet format.')
_config = (_('CSV spreadsheet options'),CSVWriterOptionBox) _config = (_('CSV spreadsheet options'),CSVWriterOptionBox)
_filename = 'csv'
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(exportData,_title,_description,_config,_filename) plugin = ExportPlugin(name = _name,
description = _description,
export_function = exportData,
extension = "csv",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -29,7 +29,6 @@
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import os import os
from cStringIO import StringIO
from gettext import gettext as _ from gettext import gettext as _
#------------------------------------------------------------------------ #------------------------------------------------------------------------
@@ -56,15 +55,15 @@ import Utils
from Filters import GenericFilter, Rules, build_filter_menu from Filters import GenericFilter, Rules, build_filter_menu
import Errors import Errors
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.plug import PluginManager from gen.plug import PluginManager, ExportPlugin
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# writeData # writeData
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def writeData(database, filename, person, option_box, callback=None): def writeData(database, filename, option_box=None, callback=None):
writer = FtreeWriter(database, person, 0, filename, option_box, callback) writer = FtreeWriter(database, filename, option_box, callback)
return writer.export_data() return writer.export_data()
class FtreeWriterOptionBox: class FtreeWriterOptionBox:
@@ -74,11 +73,11 @@ class FtreeWriterOptionBox:
""" """
def __init__(self, person): def __init__(self, person):
self.person = person self.person = person
self.restrict = True
def get_option_box(self): def get_option_box(self):
self.restrict = True glade_file = os.path.join(os.path.dirname(__file__),
base = os.path.dirname(__file__) "ExportFtree.glade")
glade_file = "%s/%s" % (base,"writeftree.glade")
self.top = glade.XML(glade_file, "top", "gramps") self.top = glade.XML(glade_file, "top", "gramps")
@@ -133,12 +132,10 @@ class FtreeWriterOptionBox:
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class FtreeWriter: class FtreeWriter:
def __init__(self, database, person, cl=0, filename="", option_box=None, def __init__(self, database, filename="", option_box=None,
callback = None): callback = None):
self.db = database self.db = database
self.person = person
self.option_box = option_box self.option_box = option_box
self.cl = cl
self.filename = filename self.filename = filename
self.callback = callback self.callback = callback
if callable(self.callback): # callback is really callable if callable(self.callback): # callback is really callable
@@ -303,15 +300,17 @@ def get_name(name, count):
else: else:
return "%s %s%s, %s" % (name.first_name, name.surname, val, name.suffix) return "%s %s%s, %s" % (name.first_name, name.surname, val, name.suffix)
#------------------------------------------------------------------------- #------------------------------------------------------------------------
# #
# Register the plugin # Register with the plugin system
# #
#------------------------------------------------------------------------- #------------------------------------------------------------------------
_title = _('_Web Family Tree')
_description = _('Web Family Tree format.')
_config = (_('Web Family Tree export options'), FtreeWriterOptionBox) _config = (_('Web Family Tree export options'), FtreeWriterOptionBox)
_filename = 'wft'
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(writeData, _title, _description, _config,_filename) plugin = ExportPlugin(name = _('_Web Family Tree'),
description = _('Web Family Tree format.'),
export_function = writeData,
extension = "wft",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -40,13 +40,14 @@ import time
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
import const import const
import _GedcomInfo as GedcomInfo import GrampsDbUtils._GedcomInfo as GedcomInfo
import Errors import Errors
import ExportOptions import ExportOptions
import BasicUtils import BasicUtils
from Utils import media_path_full from Utils import media_path_full
import gen.proxy import gen.proxy
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.plug import PluginManager, ExportPlugin
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -306,12 +307,11 @@ class GedcomWriter(BasicUtils.UpdateCallback):
so that it can provide visual feedback via a progress bar if needed. so that it can provide visual feedback via a progress bar if needed.
""" """
def __init__(self, database, person, cmd_line=0, def __init__(self, database, cmd_line=0,
option_box=None, callback=None): option_box=None, callback=None):
BasicUtils.UpdateCallback.__init__(self, callback) BasicUtils.UpdateCallback.__init__(self, callback)
self.dbase = database self.dbase = database
self.person = person
self.cmd_line = cmd_line self.cmd_line = cmd_line
self.dirname = None self.dirname = None
self.gedcom_file = None self.gedcom_file = None
@@ -1502,14 +1502,13 @@ class GedcomWriter(BasicUtils.UpdateCallback):
# #
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def export_data(database, filename, person, option_box, callback=None): def export_data(database, filename, option_box=None, callback=None):
""" """
External interface used to register with the plugin system. External interface used to register with the plugin system.
""" """
ret = False ret = False
try: try:
ged_write = GedcomWriter(database, person, 0, ged_write = GedcomWriter(database, 0, option_box, callback)
option_box, callback)
ret = ged_write.write_gedcom_file(filename) ret = ged_write.write_gedcom_file(filename)
except IOError, msg: except IOError, msg:
msg2 = _("Could not create %s") % filename msg2 = _("Could not create %s") % filename
@@ -1520,17 +1519,19 @@ def export_data(database, filename, person, option_box, callback=None):
ErrorDialog(_("Could not create %s") % filename) ErrorDialog(_("Could not create %s") % filename)
return ret return ret
#------------------------------------------------------------------------- #------------------------------------------------------------------------
# #
# Register with the plugin system
# #
# #------------------------------------------------------------------------
#------------------------------------------------------------------------- _description = _('GEDCOM is used to transfer data between genealogy programs. '
TITLE = _('GE_DCOM')
DESCRIPTION = _('GEDCOM is used to transfer data between genealogy programs. '
'Most genealogy software will accept a GEDCOM file as input.') 'Most genealogy software will accept a GEDCOM file as input.')
CONFIG = (_('GEDCOM export options'), ExportOptions.WriterOptionBox) _config = (_('GEDCOM export options'), ExportOptions.WriterOptionBox)
FILENAME = 'ged'
from gen.plug import PluginManager
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(export_data, TITLE, DESCRIPTION, CONFIG, FILENAME) plugin = ExportPlugin(name = _('GE_DCOM'),
description = _description,
export_function = export_data,
extension = "ged",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -55,9 +55,8 @@ import gen.lib
from Filters import GenericFilter, Rules, build_filter_menu from Filters import GenericFilter, Rules, build_filter_menu
#import const #import const
import Utils import Utils
import Errors
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.plug import PluginManager from gen.plug import PluginManager, ExportPlugin
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -77,9 +76,8 @@ class GeneWebWriterOptionBox:
self.restrict = 1 self.restrict = 1
self.private = 1 self.private = 1
glade_file = "%s/genewebexport.glade" % os.path.dirname(__file__) glade_file = os.path.join(os.path.dirname(__file__),
if not os.path.isfile(glade_file): "ExportGeneWeb.glade")
glade_file = "plugins/genewebexport.glade"
self.topDialog = glade.XML(glade_file, "genewebExport", "gramps") self.topDialog = glade.XML(glade_file, "genewebExport", "gramps")
self.topDialog.signal_autoconnect({ self.topDialog.signal_autoconnect({
@@ -154,12 +152,10 @@ class GeneWebWriterOptionBox:
self.images_path = "" self.images_path = ""
class GeneWebWriter: class GeneWebWriter:
def __init__(self, database, person, cl=0, filename="", option_box=None, def __init__(self, database, filename="", option_box=None,
callback=None): callback=None):
self.db = database self.db = database
self.person = person
self.option_box = option_box self.option_box = option_box
self.cl = cl
self.filename = filename self.filename = filename
self.callback = callback self.callback = callback
if callable(self.callback): # callback is really callable if callable(self.callback): # callback is really callable
@@ -175,7 +171,10 @@ class GeneWebWriter:
self.person_ids = {} self.person_ids = {}
if not option_box: if not option_box:
self.cl_setup() self.restrict = 0
self.private = 0
self.copy = 0
self.images = 0
else: else:
self.option_box.parse_options() self.option_box.parse_options()
@@ -188,23 +187,17 @@ class GeneWebWriter:
self.images = self.option_box.images self.images = self.option_box.images
self.images_path = self.option_box.images_path self.images_path = self.option_box.images_path
if self.option_box.cfilter is None: if not option_box.cfilter.is_empty():
for p in self.db.get_person_handles(sort_handles=False): self.db = gen.proxy.FilterProxyDb(self.db, option_box.cfilter)
self.plist[p] = 1
else:
try:
for p in self.option_box.cfilter.apply(self.db, self.db.get_person_handles(sort_handles=False)):
self.plist[p] = 1
except Errors.FilterError, msg:
(m1, m2) = msg.messages()
ErrorDialog(m1, m2)
return
self.flist = {} for p in self.db.get_person_handles(sort_handles=False):
for key in self.plist: self.plist[p] = 1
p = self.db.get_person_from_handle(key)
for family_handle in p.get_family_handle_list(): self.flist = {}
self.flist[family_handle] = 1 for key in self.plist:
p = self.db.get_person_from_handle(key)
for family_handle in p.get_family_handle_list():
self.flist[family_handle] = 1
# remove families that dont contain father AND mother # remove families that dont contain father AND mother
# because GeneWeb requires both to be present # because GeneWeb requires both to be present
@@ -229,22 +222,6 @@ class GeneWebWriter:
self.callback(newval) self.callback(newval)
self.oldval = newval self.oldval = newval
def cl_setup(self):
self.restrict = 0
self.private = 0
self.copy = 0
self.images = 0
for p in self.db.get_person_handles(sort_handles=False):
self.plist[p] = 1
self.flist = {}
for key in self.plist:
p = self.db.get_person_from_handle(key)
for family_handle in p.get_family_handle_list():
self.flist[family_handle] = 1
def writeln(self, text): def writeln(self, text):
self.g.write(self.iso8859('%s\n' % (text))) self.g.write(self.iso8859('%s\n' % (text)))
@@ -389,7 +366,7 @@ class GeneWebWriter:
note = "" note = ""
for notehandle in notelist: for notehandle in notelist:
noteobj = self.db.get_note_from_handle(notehandle) noteobj = self.db.get_note_from_handle(notehandle)
note += noteobj.get(False) note += noteobj.get()
note += " " note += " "
if note and note != "": if note and note != "":
@@ -629,19 +606,22 @@ class GeneWebWriter:
# #
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def exportData(database,filename,person, option_box,callback=None): def exportData(database, filename, option_box=None, callback=None):
gw = GeneWebWriter(database,person,0,filename, option_box,callback) gw = GeneWebWriter(database, filename, option_box, callback)
return gw.export_data() return gw.export_data()
#------------------------------------------------------------------------- #------------------------------------------------------------------------
# #
# Register with the plugin system
# #
# #------------------------------------------------------------------------
#-------------------------------------------------------------------------
_title = _('_GeneWeb')
_description = _('GeneWeb is a web based genealogy program.') _description = _('GeneWeb is a web based genealogy program.')
_config = (_('GeneWeb export options'), GeneWebWriterOptionBox) _config = (_('GeneWeb export options'), GeneWebWriterOptionBox)
_filename = 'gw'
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(exportData, _title, _description, _config, _filename) plugin = ExportPlugin(name = _('_GeneWeb'),
description = _description,
export_function = exportData,
extension = "gw",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -60,8 +60,8 @@ import gtk
# GRAMPS modules # GRAMPS modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from GrampsDbUtils import XmlWriter from ExportXml import XmlWriter
from gen.plug import PluginManager from gen.plug import PluginManager, ExportPlugin
import Utils import Utils
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@@ -69,29 +69,30 @@ import Utils
# writeData # writeData
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def writeData(database, filename, person, option_box, callback=None): def writeData(database, filename, option_box=None, callback=None):
option_box.parse_options() if option_box:
option_box.parse_options()
if option_box.private:
database = gen.proxy.PrivateProxyDb(database)
if option_box.restrict:
database = gen.proxy.LivingProxyDb(
database, gen.proxy.LivingProxyDb.MODE_INCLUDE_LAST_NAME_ONLY)
# Apply the Person Filter
if not option_box.cfilter.is_empty():
database = gen.proxy.FilterProxyDb(database, option_box.cfilter)
# Apply the Note Filter
if not option_box.nfilter.is_empty():
database = gen.proxy.FilterProxyDb(
database, note_filter=option_box.nfilter)
# Apply the ReferencedProxyDb to remove any objects not referenced if option_box.private:
# after any of the other proxies have been applied database = gen.proxy.PrivateProxyDb(database)
if option_box.unlinked:
database = gen.proxy.ReferencedProxyDb(database) if option_box.restrict:
database = gen.proxy.LivingProxyDb(
database, gen.proxy.LivingProxyDb.MODE_INCLUDE_LAST_NAME_ONLY)
# Apply the Person Filter
if not option_box.cfilter.is_empty():
database = gen.proxy.FilterProxyDb(database, option_box.cfilter)
# Apply the Note Filter
if not option_box.nfilter.is_empty():
database = gen.proxy.FilterProxyDb(
database, note_filter=option_box.nfilter)
# Apply the ReferencedProxyDb to remove any objects not referenced
# after any of the other proxies have been applied
if option_box.unlinked:
database = gen.proxy.ReferencedProxyDb(database)
writer = PackageWriter(database, filename, callback) writer = PackageWriter(database, filename, callback)
return writer.export() return writer.export()
@@ -225,17 +226,20 @@ class PackageWriter:
g.close() g.close()
return True return True
#------------------------------------------------------------------------- #------------------------------------------------------------------------
# #
# Register the plugin # Register with the plugin system
# #
#------------------------------------------------------------------------- #------------------------------------------------------------------------
_title = _('GRAM_PS package (portable XML)')
_description = _('GRAMPS package is an archived XML database together ' _description = _('GRAMPS package is an archived XML database together '
'with the media object files.') 'with the media object files.')
_config = (_('GRAMPS package export options'), ExportOptions.WriterOptionBox) _config = (_('GRAMPS package export options'), ExportOptions.WriterOptionBox)
_filename = 'gpkg'
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(writeData, _title, _description, _config, _filename) plugin = ExportPlugin(name = _('GRAM_PS package (portable XML)'),
description = _description,
export_function = writeData,
extension = "gpkg",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -59,7 +59,7 @@ import Utils
from gen.lib import Date, EventType from gen.lib import Date, EventType
import Errors import Errors
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.plug import PluginManager from gen.plug import PluginManager, ExportPlugin
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -75,9 +75,9 @@ class CalendarWriterOptionBox:
def __init__(self, person): def __init__(self, person):
self.person = person self.person = person
glade_file = "%s/vcalendarexport.glade" % os.path.dirname(__file__) glade_file = os.path.join(os.path.dirname(__file__),
if not os.path.isfile(glade_file): "ExportVCalendar.glade")
glade_file = "plugins/vcalendarexport.glade"
self.topDialog = glade.XML(glade_file, "calendarExport", "gramps") self.topDialog = glade.XML(glade_file, "calendarExport", "gramps")
self.copy = 0 self.copy = 0
self.filter_menu = gtk.Menu() self.filter_menu = gtk.Menu()
@@ -128,10 +128,9 @@ class CalendarWriterOptionBox:
class CalendarWriter: class CalendarWriter:
def __init__(self, database, person, cl=0, filename="", option_box=None, def __init__(self, database, cl=0, filename="", option_box=None,
callback=None): callback=None):
self.db = database self.db = database
self.person = person
self.option_box = option_box self.option_box = option_box
self.cl = cl self.cl = cl
self.filename = filename self.filename = filename
@@ -342,19 +341,22 @@ class CalendarWriter:
# #
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def exportData(database, filename, person, option_box, callback=None): def exportData(database, filename, option_box=None, callback=None):
cw = CalendarWriter(database, person, 0, filename, option_box, callback) cw = CalendarWriter(database, 0, filename, option_box, callback)
return cw.export_data(filename) return cw.export_data(filename)
#------------------------------------------------------------------------- #------------------------------------------------------------------------
# #
# Register with the plugin system
# #
# #------------------------------------------------------------------------
#-------------------------------------------------------------------------
_title = _('vC_alendar')
_description = _('vCalendar is used in many calendaring and pim applications.') _description = _('vCalendar is used in many calendaring and pim applications.')
_config = (_('vCalendar export options'), CalendarWriterOptionBox) _config = (_('vCalendar export options'), CalendarWriterOptionBox)
_filename = 'vcs'
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(exportData, _title, _description, _config, _filename) plugin = ExportPlugin(name = _('vC_alendar'),
description = _description,
export_function = exportData,
extension = "vcs",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -56,7 +56,7 @@ from Filters import GenericFilter, Rules, build_filter_menu
from gen.lib import Date from gen.lib import Date
import Errors import Errors
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.plug import PluginManager from gen.plug import PluginManager, ExportPlugin
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -74,9 +74,8 @@ class CardWriterOptionBox:
def get_option_box(self): def get_option_box(self):
glade_file = "%s/vcardexport.glade" % os.path.dirname(__file__) glade_file = os.path.join(os.path.dirname(__file__),
if not os.path.isfile(glade_file): "ExportVCard.glade")
glade_file = "plugins/vcardexport.glade"
self.topDialog = glade.XML(glade_file,"vcardExport","gramps") self.topDialog = glade.XML(glade_file,"vcardExport","gramps")
@@ -125,10 +124,9 @@ class CardWriterOptionBox:
self.cfilter = self.filter_menu.get_active().get_data("filter") self.cfilter = self.filter_menu.get_active().get_data("filter")
class CardWriter: class CardWriter:
def __init__(self, database, person, cl=0, filename="", option_box=None, def __init__(self, database, cl=0, filename="", option_box=None,
callback=None): callback=None):
self.db = database self.db = database
self.person = person
self.option_box = option_box self.option_box = option_box
self.cl = cl self.cl = cl
self.filename = filename self.filename = filename
@@ -258,19 +256,22 @@ class CardWriter:
# #
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def exportData(database, filename, person, option_box, callback=None): def exportData(database, filename, option_box=None, callback=None):
cw = CardWriter(database, person, 0, filename, option_box, callback) cw = CardWriter(database, 0, filename, option_box, callback)
return cw.export_data(filename) return cw.export_data(filename)
#------------------------------------------------------------------------- #------------------------------------------------------------------------
# #
# Register with the plugin system
# #
# #------------------------------------------------------------------------
#-------------------------------------------------------------------------
_title = _('_vCard')
_description = _('vCard is used in many addressbook and pim applications.') _description = _('vCard is used in many addressbook and pim applications.')
_config = (_('vCard export options'), CardWriterOptionBox) _config = (_('vCard export options'), CardWriterOptionBox)
_filename = 'vcf'
pmgr = PluginManager.get_instance() pmgr = PluginManager.get_instance()
pmgr.register_export(exportData, _title, _description, _config, _filename) plugin = ExportPlugin(name = _('_vCard'),
description = _description,
export_function = exportData,
extension = "vcf",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -2,6 +2,9 @@
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2007 Donald N. Allingham # Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2008 Brian G. Matherly
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2008 Robert Cheramy <robert@cheramy.net>
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -23,8 +26,6 @@
""" """
Contains the interface to allow a database to get written using Contains the interface to allow a database to get written using
GRAMPS' XML file format. GRAMPS' XML file format.
This module contains all that is needed for xml write, however it does not
provide the export plugin functionality. That is provided in _WriteXML.py
""" """
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@@ -33,11 +34,13 @@ provide the export plugin functionality. That is provided in _WriteXML.py
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import time import time
import shutil
import os import os
import codecs import codecs
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
from gettext import gettext as _ from gettext import gettext as _
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# Set up logging # Set up logging
@@ -51,10 +54,14 @@ log = logging.getLogger(".WriteXML")
# load GRAMPS libraries # load GRAMPS libraries
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gen.lib import gen.lib
from BasicUtils import UpdateCallback from BasicUtils import UpdateCallback
from gen.db.exceptions import GrampsDbWriteFailure from gen.db.exceptions import GrampsDbWriteFailure
import const
from QuestionDialog import ErrorDialog
import ExportOptions
import gen.proxy
from gen.plug import PluginManager, ExportPlugin
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -76,15 +83,6 @@ strip_dict = dict.fromkeys(range(9)+range(12,20))
def escxml(d): def escxml(d):
return escape(d, { '"' : '&quot;' } ) return escape(d, { '"' : '&quot;' } )
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def quick_write(database, filename, version="unknown"):
g = GrampsDbXmlWriter(database,0,1,version)
g.write(filename)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# #
@@ -1131,8 +1129,90 @@ def conf_priv(obj):
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# # export_data
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def export_data(database, filename, option_box=None, callback=None):
"""
Call the XML writer with the syntax expected by the export plugin.
"""
if os.path.isfile(filename):
try:
shutil.copyfile(filename, filename + ".bak")
shutil.copystat(filename, filename + ".bak")
except:
pass
# Don't export a writer for plugins, that is the task of _WriteXML.py compress = _gzip_ok == 1
if option_box:
option_box.parse_options()
if option_box.private:
database = gen.proxy.PrivateProxyDb(database)
if option_box.restrict:
database = gen.proxy.LivingProxyDb(
database, gen.proxy.LivingProxyDb.MODE_INCLUDE_LAST_NAME_ONLY)
# Apply the Person Filter
if not option_box.cfilter.is_empty():
database = gen.proxy.FilterProxyDb(database, option_box.cfilter)
# Apply the Note Filter
if not option_box.nfilter.is_empty():
database = gen.proxy.FilterProxyDb(
database, note_filter=option_box.nfilter)
# Apply the ReferencedProxyDb to remove any objects not referenced
# after any of the other proxies have been applied
if option_box.unlinked:
database = gen.proxy.ReferencedProxyDb(database)
g = XmlWriter(database, callback, 0, compress)
return g.write(filename)
#-------------------------------------------------------------------------
#
# XmlWriter
#
#-------------------------------------------------------------------------
class XmlWriter(GrampsDbXmlWriter):
"""
Writes a database to the XML file.
"""
def __init__(self, dbase, callback, strip_photos, compress=1):
GrampsDbXmlWriter.__init__(
self, dbase, strip_photos, compress, const.VERSION, callback)
def write(self, filename):
"""
Write the database to the specified file.
"""
ret = 0 #False
try:
ret = GrampsDbXmlWriter.write(self, filename)
except GrampsDbWriteFailure, msg:
(m1,m2) = msg.messages()
ErrorDialog(m1, m2)
return ret
#------------------------------------------------------------------------
#
# Register with the plugin system
#
#------------------------------------------------------------------------
_description = _('Exporting to CD copies all your data and media object files '
'to the CD Creator. You may later burn the CD with this data, '
'and that copy will be completely portable across different '
'machines and binary architectures.')
_config = (_('GRAMPS XML export options'), ExportOptions.WriterOptionBox)
pmgr = PluginManager.get_instance()
plugin = ExportPlugin(name = _('GRAMPS _XML database'),
description = _description,
export_function = export_data,
extension = "gramps",
config = _config )
pmgr.register_plugin(plugin)

View File

@@ -796,5 +796,5 @@ pmgr = PluginManager.get_instance()
plugin = ImportPlugin(name = _('CSV Spreadheet'), plugin = ImportPlugin(name = _('CSV Spreadheet'),
description = _("Import data from CSV files"), description = _("Import data from CSV files"),
import_function = importData, import_function = importData,
mime_types = [_mime_type, _mime_type_rfc_4180]) extension = "csv")
pmgr.register_plugin(plugin) pmgr.register_plugin(plugin)

View File

@@ -639,7 +639,7 @@
<child> <child>
<widget class="GtkLabel" id="label18"> <widget class="GtkLabel" id="label18">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">This GEDCOM file has identified itself as using ANSEL encoding. Sometimes, this is in error. If the imported data contains unusual characters, undo the import, and override the character set by selecting a different encoding below.</property> <property name="label" translatable="yes">This GEDCOM file has identified itself as using ANSEL enconding. Sometimes, this is in error. If the imported data contains unusual characters, undo the import, and override the character set by selecting a different encoding below.</property>
<property name="use_underline">False</property> <property name="use_underline">False</property>
<property name="use_markup">False</property> <property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property> <property name="justify">GTK_JUSTIFY_LEFT</property>

View File

@@ -45,9 +45,10 @@ LOG = logging.getLogger(".GedcomImport")
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
import Errors import Errors
from _GedcomParse import GedcomParser from GrampsDbUtils._GedcomParse import GedcomParser
from _GedcomStageOne import StageOne from GrampsDbUtils._GedcomStageOne import StageOne
from QuestionDialog import ErrorDialog, DBErrorDialog from QuestionDialog import ErrorDialog, DBErrorDialog
from gen.plug import PluginManager, ImportPlugin
try: try:
import Config import Config
@@ -61,7 +62,7 @@ except ImportError:
# importData # importData
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def importData(database, filename, callback=None, use_trans=False): def importData(database, filename, callback=None):
""" """
Try to handle ANSEL encoded files that are not really ANSEL encoded Try to handle ANSEL encoded files that are not really ANSEL encoded
""" """
@@ -83,7 +84,8 @@ def importData(database, filename, callback=None, use_trans=False):
ifile.close() ifile.close()
if not gramps and ansel: if not gramps and ansel:
glade_file = "%s/gedcomimport.glade" % os.path.dirname(__file__) glade_file = os.path.join(os.path.dirname(__file__),
"ImportGedcom.glade")
top = glade.XML(glade_file, 'encoding','gramps') top = glade.XML(glade_file, 'encoding','gramps')
code = top.get_widget('codeset') code = top.get_widget('codeset')
code.set_active(0) code.set_active(0)
@@ -94,17 +96,6 @@ def importData(database, filename, callback=None, use_trans=False):
dialog.destroy() dialog.destroy()
else: else:
code_set = "" code_set = ""
import2(database, filename, callback, code_set, use_trans)
#-------------------------------------------------------------------------
#
# import2
#
#-------------------------------------------------------------------------
def import2(database, filename, callback, code_set, use_trans):
"""
Import the gedcom file.
"""
assert(isinstance(code_set, basestring)) assert(isinstance(code_set, basestring))
@@ -126,13 +117,10 @@ def import2(database, filename, callback, code_set, use_trans):
_("%s could not be imported") % filename + "\n" + str(msg)) _("%s could not be imported") % filename + "\n" + str(msg))
return return
if database.get_number_of_people() == 0:
use_trans = False
try: try:
read_only = database.readonly read_only = database.readonly
database.readonly = False database.readonly = False
gedparse.parse_gedcom_file(use_trans) gedparse.parse_gedcom_file(False)
database.readonly = read_only database.readonly = read_only
ifile.close() ifile.close()
except IOError, msg: except IOError, msg:
@@ -146,3 +134,17 @@ def import2(database, filename, callback, code_set, use_trans):
ErrorDialog(_('Error reading GEDCOM file'), str(msg)) ErrorDialog(_('Error reading GEDCOM file'), str(msg))
return return
#------------------------------------------------------------------------
#
# Register with the plugin system
#
#------------------------------------------------------------------------
_description = _('GEDCOM is used to transfer data between genealogy programs. '
'Most genealogy software will accept a GEDCOM file as input.')
pmgr = PluginManager.get_instance()
plugin = ImportPlugin(name = _('GE_DCOM'),
description = _description,
import_function = importData,
extension = "ged" )
pmgr.register_plugin(plugin)

View File

@@ -47,7 +47,6 @@ log = logging.getLogger(".ImportGeneWeb")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import Errors import Errors
import gen.lib import gen.lib
import const
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.plug import PluginManager, ImportPlugin from gen.plug import PluginManager, ImportPlugin
from htmlentitydefs import name2codepoint from htmlentitydefs import name2codepoint
@@ -926,5 +925,5 @@ pmgr = PluginManager.get_instance()
plugin = ImportPlugin(name = _('GeneWeb'), plugin = ImportPlugin(name = _('GeneWeb'),
description = _("Import data from GeneWeb files"), description = _("Import data from GeneWeb files"),
import_function = importData, import_function = importData,
mime_types = [const.APP_GENEWEB]) extension = "gw")
pmgr.register_plugin(plugin) pmgr.register_plugin(plugin)

View File

@@ -47,7 +47,7 @@ log = logging.getLogger(".ReadPkg")
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import const import const
from GrampsDbUtils import gramps_db_reader_factory import ImportXml
from QuestionDialog import ErrorDialog, WarningDialog from QuestionDialog import ErrorDialog, WarningDialog
import Utils import Utils
from gen.plug import PluginManager, ImportPlugin from gen.plug import PluginManager, ImportPlugin
@@ -93,7 +93,7 @@ def impData(database, name, cb=None):
imp_db_name = os.path.join(tmpdir_path, const.XMLFILE) imp_db_name = os.path.join(tmpdir_path, const.XMLFILE)
importer = gramps_db_reader_factory(const.APP_GRAMPS_XML) importer = ImportXml.importData
info = importer(database, imp_db_name, cb) info = importer(database, imp_db_name, cb)
newmediapath = database.get_mediapath() newmediapath = database.get_mediapath()
#import of gpkg should not change media path as all media has new paths! #import of gpkg should not change media path as all media has new paths!
@@ -146,5 +146,5 @@ pmgr = PluginManager.get_instance()
plugin = ImportPlugin(name = _('GRAMPS package'), plugin = ImportPlugin(name = _('GRAMPS package'),
description = _("Import data from GRAMPS packages"), description = _("Import data from GRAMPS packages"),
import_function = impData, import_function = impData,
mime_types = ['application/x-gramps-package']) extension = "gpkg")
pmgr.register_plugin(plugin) pmgr.register_plugin(plugin)

View File

@@ -2687,5 +2687,5 @@ plugin = ImportPlugin(name = _('GRAMPS 2.x database'),
description = _("Import data from GRAMPS 2.x " description = _("Import data from GRAMPS 2.x "
"database files"), "database files"),
import_function = importData, import_function = importData,
mime_types = ['application/x-gramps']) extension = "grdb")
pmgr.register_plugin(plugin) pmgr.register_plugin(plugin)

View File

@@ -1218,5 +1218,5 @@ pmgr = PluginManager.get_instance()
plugin = ImportPlugin(name = _('Pro-Gen'), plugin = ImportPlugin(name = _('Pro-Gen'),
description = _("Import data from Pro-Gen files"), description = _("Import data from Pro-Gen files"),
import_function = _importData, import_function = _importData,
mime_types = ["application/x-progen"]) extension = "def")
pmgr.register_plugin(plugin) pmgr.register_plugin(plugin)

View File

@@ -160,7 +160,11 @@ class VCardParser:
self.person = gen.lib.Person() self.person = gen.lib.Person()
def set_nick_name(self, fields, data): def set_nick_name(self, fields, data):
self.person.set_nick_name(data) if self.person is not None:
attr = gen.lib.Attribute()
attr.set_type(gen.lib.AttributeType.NICKNAME)
attr.set_value(data)
self.person.add_attribute(attr)
def add_name(self, fields, data): def add_name(self, fields, data):
data_fields = data.split(";") data_fields = data.split(";")
@@ -170,7 +174,7 @@ class VCardParser:
name.set_first_name(data_fields[1]) name.set_first_name(data_fields[1])
if data_fields[2]: if data_fields[2]:
name.set_first_name(data_fields[1]+" "+data_fields[2]) name.set_first_name(data_fields[1]+" "+data_fields[2])
name.set_prefix(data_fields[3]) name.set_surname_prefix(data_fields[3])
name.set_suffix(data_fields[4]) name.set_suffix(data_fields[4])
self.person.set_primary_name(name) self.person.set_primary_name(name)
@@ -200,7 +204,10 @@ class VCardParser:
event = gen.lib.Event() event = gen.lib.Event()
event.set_type(gen.lib.EventType(gen.lib.EventType.BIRTH)) event.set_type(gen.lib.EventType(gen.lib.EventType.BIRTH))
self.db.add_event(event,self.trans) self.db.add_event(event,self.trans)
self.person.set_birth_handle(event.get_handle())
event_ref = gen.lib.EventRef()
event_ref.set_reference_handle(event.get_handle())
self.person.set_birth_ref(event_ref)
def add_url(self, fields, data): def add_url(self, fields, data):
url = gen.lib.Url() url = gen.lib.Url()
@@ -216,5 +223,5 @@ pmgr = PluginManager.get_instance()
plugin = ImportPlugin(name = _('vCard'), plugin = ImportPlugin(name = _('vCard'),
description = _("Import data from vCard files"), description = _("Import data from vCard files"),
import_function = importData, import_function = importData,
mime_types = ["text/x-vcard", "text/x-vcalendar"]) extension = "vcf")
pmgr.register_plugin(plugin) pmgr.register_plugin(plugin)

View File

@@ -46,8 +46,9 @@ from BasicUtils import name_displayer
from gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, from gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY,
MEDIA_KEY, PLACE_KEY, REPOSITORY_KEY, NOTE_KEY) MEDIA_KEY, PLACE_KEY, REPOSITORY_KEY, NOTE_KEY)
from BasicUtils import UpdateCallback from BasicUtils import UpdateCallback
import _GrampsDbWriteXML import ExportXml
import const import const
from gen.plug import PluginManager, ImportPlugin
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -2443,7 +2444,7 @@ def version_is_valid(filename, cli):
""" """
parser = VersionParser(filename) parser = VersionParser(filename)
if parser.get_xmlns_version() > _GrampsDbWriteXML.XML_VERSION: if parser.get_xmlns_version() > ExportXml.XML_VERSION:
msg = _("The .gramps file you are importing was made by version %s of " msg = _("The .gramps file you are importing was made by version %s of "
"GRAMPS, while you are running an older version %s. " "GRAMPS, while you are running an older version %s. "
"The file will not be imported. Please upgrade to the latest " "The file will not be imported. Please upgrade to the latest "
@@ -2457,3 +2458,18 @@ def version_is_valid(filename, cli):
return False return False
return True return True
#------------------------------------------------------------------------
#
# Register with the plugin system
#
#------------------------------------------------------------------------
pmgr = PluginManager.get_instance()
plugin = ImportPlugin(name = _('GRAMPS _XML database'),
description = _('The GRAMPS XML database is a text '
'version of a family tree. It is '
'read-write compatible with the '
'present GRAMPS database format.'),
import_function = importData,
extension = "gramps" )
pmgr.register_plugin(plugin)

View File

@@ -30,9 +30,15 @@ pkgdata_PYTHON = \
Eval.py\ Eval.py\
EventCmp.py\ EventCmp.py\
EventNames.py\ EventNames.py\
ExportCSV.py\ ExportCd.py\
ExportCsv.py\
ExportFtree.py\
ExportGedcom.py\
ExportGeneweb.py\
ExportPkg.py\
ExportVCalendar.py\ ExportVCalendar.py\
ExportVCard.py\ ExportVCard.py\
ExportXml.py\
ExtractCity.py\ ExtractCity.py\
FamilyGroup.py\ FamilyGroup.py\
FanChart.py\ FanChart.py\
@@ -42,10 +48,13 @@ pkgdata_PYTHON = \
GVHourGlass.py\ GVHourGlass.py\
GVRelGraph.py\ GVRelGraph.py\
ImportCSV.py\ ImportCSV.py\
ImportGedcom.py\
ImportGeneWeb.py\ ImportGeneWeb.py\
ImportGpkg.py\ ImportGpkg.py\
ImportGrdb.py\ ImportGrdb.py\
ImportProGen.py\
ImportvCard.py\ ImportvCard.py\
ImportXml.py\
IndivComplete.py\ IndivComplete.py\
KinshipReport.py\ KinshipReport.py\
Leak.py\ Leak.py\
@@ -89,10 +98,7 @@ pkgdata_PYTHON = \
TimeLine.py\ TimeLine.py\
Verify.py\ Verify.py\
WebCal.py\ WebCal.py\
WriteFtree.py\ WriteFtree.py
WriteGeneWeb.py\
WritePkg.py\
WriteCD.py
# DateParserDisplayTest.py\ # DateParserDisplayTest.py\
# DumpGenderStats.py\ # DumpGenderStats.py\
@@ -104,28 +110,28 @@ pkgpyexecdir = @pkgpyexecdir@/plugins
pkgpythondir = @pkgpythondir@/plugins pkgpythondir = @pkgpythondir@/plugins
GLADEFILES = \ GLADEFILES = \
NotRelated.glade\ book.glade\
changetype.glade\
csvexport.glade\
desbrowse.glade\
eventcmp.glade\
merge.glade\
patchnames.glade\
changenames.glade\ changenames.glade\
changetype.glade\
desbrowse.glade\
eval.glade\
eventcmp.glade\
ExportCsv.glade\
ExportFtree.glade\
ExportGeneWeb.glade\
ExportVCalendar.glade\
ExportVCard.glade\
ImportGedcom.glade\
leak.glade\
merge.glade\
NotRelated.glade\
ownereditor.glade\
patchnames.glade\
relcalc.glade\ relcalc.glade\
soundex.glade\ soundex.glade\
summary.glade\ summary.glade\
verify.glade\ unused.glade\
cdexport.glade\ verify.glade
eval.glade\
leak.glade\
book.glade\
ownereditor.glade\
writeftree.glade\
genewebexport.glade\
vcardexport.glade\
vcalendarexport.glade\
unused.glade
GRAPHICS = GRAPHICS =

View File

@@ -1,189 +0,0 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkDialog" id="packageExport">
<property name="visible">True</property>
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">True</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">8</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancel">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">0</property>
<signal name="clicked" handler="destroy_passed_object" object="packageExport"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-5</property>
<signal name="clicked" handler="on_ok_clicked" object="packageExport"/>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-cdrom</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">_Export to CD</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkButton" id="button1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-help</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-11</property>
<signal name="clicked" handler="on_help_clicked" last_modification_time="Tue, 02 Dec 2003 02:04:37 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child>
<widget class="GtkLabel" id="title">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">6</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Exporting to a CD will not immediately write the CD. It will prepare the nautilus-cd-burner so that you can burn the CD from nautilus.
After exporting, go to the &lt;b&gt;burn:///&lt;/b&gt; directory in nautilus and select the Write to CD button.</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@@ -42,20 +42,6 @@ class FactoryTest(unittest.TestCase):
self.assertRaises(GrampsDb.GrampsDbException, GrampsDb.gramps_db_factory, "gibberish") self.assertRaises(GrampsDb.GrampsDbException, GrampsDb.gramps_db_factory, "gibberish")
def test_gramps_db_reader_factory(self):
"""Test that gramps_db_reader_factory returns the correct method."""
md = GrampsDb.gramps_db_reader_factory(db_type = const.app_gramps)
assert callable(md), "Returned method is %s " % str(md)
md = GrampsDb.gramps_db_reader_factory(db_type = const.app_gramps_xml)
assert callable(md), "Returned method is %s " % str(md)
md = GrampsDb.gramps_db_reader_factory(db_type = const.app_gedcom)
assert callable(md), "Returned method is %s " % str(md)
self.assertRaises(GrampsDb.GrampsDbException, GrampsDb.gramps_db_reader_factory, "gibberish")
class ReferenceMapTest (GrampsDbBaseTest): class ReferenceMapTest (GrampsDbBaseTest):