2007-12-28 Benny Malengier <benny.malengier@gramps-project.org>

* src/ViewManager.py: remove unused functions, add alt actions left/right
	* src/GrampsDb: deleted with _GrampsDbWriteXML.py,
		_GrampsDbFactories.py, _GrampsGEDDB.py, _GrampsXMLDB.py,
		__init__.py, Makefile.am, _GrampsInMemDB.py, _GrampsBSDDB.py.
		No more inmemory databases
	* src/GrampsDbUtils: moved here _GrampsDbWriteXML.py and _GrampsBSDDB.py
	* src/plugins/ReadGrdb.py:
	* src/plugins/Checkpoint.py:
	* src/ObjectSelector/_ObjectSelectorWindow.py:
	* src/DbManager.py:
	* src/GrampsDbUtils/_WriteGrdb.py:
	* src/GrampsDbUtils/__init__.py:
	* src/GrampsDbUtils/_GrampsDbWRFactories.py:
	* src/GrampsDbUtils/_WriteXML.py:
	* src/GrampsDbUtils/Makefile.am:
	* src/gramps_main.py:
	* src/RecentFiles.py: recent-files-gramps.xml, don't overwrite 2.2.x data
	* src/ArgHandler.py:
	* src/DbLoader.py: remove unused functions
	* src/Makefile.am:
	* po/POTFILES.in:
	* src/GrampsDbUtils/importdbdir.py: allow import of new database via cli
	Remove inMem Editing, move remaining to DbUtils, fix ArgHandler



svn: r9613
This commit is contained in:
Benny Malengier 2007-12-28 15:09:01 +00:00
parent 5ea0cd4b3e
commit dc9f03b6c0
26 changed files with 760 additions and 1392 deletions

View File

@ -1,3 +1,28 @@
2007-12-28 Benny Malengier <benny.malengier@gramps-project.org>
* src/ViewManager.py: remove unused functions, add alt actions left/right
* src/GrampsDb: deleted with _GrampsDbWriteXML.py,
_GrampsDbFactories.py, _GrampsGEDDB.py, _GrampsXMLDB.py,
__init__.py, Makefile.am, _GrampsInMemDB.py, _GrampsBSDDB.py.
No more inmemory databases
* src/GrampsDbUtils: moved here _GrampsDbWriteXML.py and _GrampsBSDDB.py
* src/plugins/ReadGrdb.py:
* src/plugins/Checkpoint.py:
* src/ObjectSelector/_ObjectSelectorWindow.py:
* src/DbManager.py:
* src/GrampsDbUtils/_WriteGrdb.py:
* src/GrampsDbUtils/__init__.py:
* src/GrampsDbUtils/_GrampsDbWRFactories.py:
* src/GrampsDbUtils/_WriteXML.py:
* src/GrampsDbUtils/Makefile.am:
* src/gramps_main.py:
* src/RecentFiles.py: recent-files-gramps.xml, don't overwrite 2.2.x data
* src/ArgHandler.py:
* src/DbLoader.py: remove unused functions
* src/Makefile.am:
* po/POTFILES.in:
* src/GrampsDbUtils/importdbdir.py: allow import of new database via cli
Remove inMem Editing, move remaining to DbUtils, fix ArgHandler
2007-12-28 Stéphane Charette <stephanecharette@gmail.com> 2007-12-28 Stéphane Charette <stephanecharette@gmail.com>
* src/ReportBase/_GraphvizReportDialog.py * src/ReportBase/_GraphvizReportDialog.py
* src/plugins/GVFamilyLines.py * src/plugins/GVFamilyLines.py

View File

@ -193,11 +193,6 @@ src/Editors/_EditSourceRef.py
src/Editors/_EditUrl.py src/Editors/_EditUrl.py
src/Editors/__init__.py src/Editors/__init__.py
# GrampsDb package
src/GrampsDb/_GrampsDbFactories.py
src/GrampsDb/_GrampsDbWriteXML.py
src/GrampsDb/__init__.py
# GrampsDbUtils package # GrampsDbUtils package
src/GrampsDbUtils/_Backup.py src/GrampsDbUtils/_Backup.py
src/GrampsDbUtils/_GedcomInfo.py src/GrampsDbUtils/_GedcomInfo.py
@ -205,7 +200,10 @@ 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/_GrampsBSDDB.py
src/GrampsDbUtils/_GrampsDbWriteXML.py
src/GrampsDbUtils/_GrampsDbWRFactories.py src/GrampsDbUtils/_GrampsDbWRFactories.py
src/GrampsDbUtils/importdbdir.py
src/GrampsDbUtils/_ReadGedcom.py src/GrampsDbUtils/_ReadGedcom.py
src/GrampsDbUtils/_ReadXML.py src/GrampsDbUtils/_ReadXML.py
src/GrampsDbUtils/_WriteGedcom.py src/GrampsDbUtils/_WriteGedcom.py

View File

@ -1,7 +1,8 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2006 Donald N. Allingham # Copyright (C) 2000-2006 Donald N. Allingham, A. Roitman
# Copyright (C) 2007 B. Malengier
# #
# 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
@ -20,8 +21,6 @@
# $Id$ # $Id$
# Written by Alex Roitman
""" """
Module responsible for handling the command line arguments for GRAMPS. Module responsible for handling the command line arguments for GRAMPS.
""" """
@ -51,7 +50,6 @@ import glob
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import const import const
import GrampsDb
import GrampsDbUtils import GrampsDbUtils
import Mime import Mime
import QuestionDialog import QuestionDialog
@ -59,10 +57,14 @@ import Config
import RecentFiles import RecentFiles
import Utils import Utils
import gen.db.exceptions as GX import gen.db.exceptions as GX
from DbManager import CLIDbManager, NAME_FILE
from PluginUtils import Tool, cl_list, cli_tool_list from PluginUtils import Tool, cl_list, cli_tool_list
from ReportBase import CATEGORY_BOOK, CATEGORY_CODE, CATEGORY_WEB, cl_report from ReportBase import CATEGORY_BOOK, CATEGORY_CODE, CATEGORY_WEB, cl_report
IMPORT_TYPES = (const.APP_GRAMPS_XML, const.APP_GEDCOM,
const.APP_GRAMPS_PKG, const.APP_GENEWEB,
const.APP_GRAMPS)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# ArgHandler # ArgHandler
@ -72,16 +74,15 @@ class ArgHandler:
This class is responsible for handling command line arguments (if any) This class is responsible for handling command line arguments (if any)
given to gramps. The valid arguments are: given to gramps. The valid arguments are:
FILE : filename to open. FAMTREE : family tree name or database dir to open.
All following arguments will be ignored. All following arguments will be ignored.
-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, --open=FILE : filename to open.
-o, --output=FILE : filename to export. -o, --output=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
launched using data from filename. If the filename is not in a natvive launched using data from filename.
(grdb) format, dialog will be presented to set up a grdb database.
In this mode (filename, no flags), the rest of the arguments is ignored. In this mode (filename, no flags), the rest of the arguments is ignored.
This is a mode suitable by default for GUI launchers, mime type handlers, This is a mode suitable by default for GUI launchers, mime type handlers,
and the like and the like
@ -96,7 +97,7 @@ class ArgHandler:
interactive session will not be launched. interactive session will not be launched.
""" """
def __init__(self,state,vm,args): def __init__(self, state, vm, args):
self.state = state self.state = state
self.vm = vm self.vm = vm
self.args = args self.args = args
@ -107,11 +108,11 @@ class ArgHandler:
self.exports = [] self.exports = []
self.actions = [] self.actions = []
self.imports = [] self.imports = []
self.imp_db_path = None
self.list = False
self.parse_args() self.parse_args()
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Argument parser: sorts out given arguments # Argument parser: sorts out given arguments
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -120,11 +121,21 @@ class ArgHandler:
Fill in lists with open, exports, imports, and actions options. Fill in lists with open, exports, imports, and actions options.
Any parsing errors lead to abort via sys.exit(1). Any parsing errors lead to abort via sys.exit(1).
Possible:
1/ Just the family tree (name or database dir)
2/ -O, Open of a family tree
3/ -i, Import of any format understood by an importer, optionally provide
-f to indicate format (possible: 'gedcom','gramps-xml','gramps-pkg',
'grdb','geneweb'
4/ -o, output a family tree in required format, optionally provide
-f to indicate format (possible: 'gedcom',
'gramps-xml','gramps-pkg','iso','wft','geneweb')
5/ An action
""" """
try: try:
options,leftargs = getopt.getopt(self.args[1:], options, leftargs = getopt.getopt(self.args[1:],
const.SHORTOPTS,const.LONGOPTS) const.SHORTOPTS, const.LONGOPTS)
except getopt.GetoptError: except getopt.GetoptError:
# return without filling anything if we could not parse the args # return without filling anything if we could not parse the args
print "Error parsing arguments: %s " % self.args[1:] print "Error parsing arguments: %s " % self.args[1:]
@ -139,47 +150,49 @@ class ArgHandler:
# Go over all given option and place them into appropriate lists # Go over all given option and place them into appropriate lists
for opt_ix in range(len(options)): for opt_ix in range(len(options)):
o,v = options[opt_ix] option, value = options[opt_ix]
if o in ( '-O', '--open'): if option in ( '-O', '--open'):
fname = v #only family trees can be opened
format = 'famtree'
fname = value
fullpath = os.path.abspath(os.path.expanduser(fname)) fullpath = os.path.abspath(os.path.expanduser(fname))
if not os.path.exists(fullpath):
print "Input file does not exist: %s" % fullpath
continue
ftype = Mime.get_type(fullpath) ftype = Mime.get_type(fullpath)
if opt_ix<len(options)-1 \ if not os.path.exists(fullpath):
and options[opt_ix+1][0] in ( '-f', '--format'): #see if not just a name of a database is given
format = options[opt_ix+1][1] dbman = CLIDbManager(self.state)
if format not in ('gedcom','gramps-xml','grdb'): data = dbman.family_tree(fname)
print "Invalid format: %s" % format if data is not None:
print "Ignoring input file: %s" % fname fname, ftype, title = data
else:
print "Input family tree does not exist: %s" % fullpath
print "If gedcom, gramps-xml or grdb, use the -i option"
continue continue
elif ftype == const.APP_GEDCOM:
format = 'gedcom'
elif ftype == const.APP_GRAMPS_XML:
format = 'gramps-xml'
elif ftype == const.APP_GRAMPS:
format = 'grdb'
elif ftype in [const.APP_GRAMPS_PKG,const.APP_GENEWEB]:
print 'Unsupported type: "%s" for input file: %s' \
% (ftype,fname)
print 'Please create a new GRAMPS database and import the file.'
continue
else: else:
print 'Unrecognized type: "%s" for input file: %s' \ if not os.path.isdir(fullpath):
% (ftype,fname) print "A file is given, not an existing family tree",
print "Ignoring input file: %s" % fname print ", use the -i option to import in a family tree",
continue print " instead"
self.open = (fname,format) continue
elif o in ( '-i', '--import'): self.open = (fname, format)
fname = v elif option in ( '-i', '--import'):
fname = value
fullpath = os.path.abspath(os.path.expanduser(fname)) fullpath = os.path.abspath(os.path.expanduser(fname))
if not os.path.exists(fullpath):
print "Input file does not exist: %s" % fullpath
continue
ftype = Mime.get_type(fullpath)
if opt_ix<len(options)-1 \ format = 'famtree'
ftype = Mime.get_type(fullpath)
if not os.path.exists(fullpath):
#see if not just a name of a database is given
dbman = CLIDbManager(self.state)
data = dbman.family_tree(fname)
if data is not None:
fname, ftype, title = data
else:
print "Input file does not exist: %s" % fullpath
continue
elif os.path.isdir(fullpath):
ftype = const.APP_FAMTREE
fname = fullpath
elif 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]
if format not in ('gedcom', if format not in ('gedcom',
@ -205,16 +218,16 @@ class ArgHandler:
% (ftype,fname) % (ftype,fname)
print "Ignoring input file: %s" % fname print "Ignoring input file: %s" % fname
continue continue
self.imports.append((fname,format)) self.imports.append((fname, format))
elif o in ( '-o', '--output' ): elif option in ( '-o', '--output' ):
outfname = v outfname = value
fullpath = os.path.abspath(os.path.expanduser(outfname)) fullpath = os.path.abspath(os.path.expanduser(outfname))
if os.path.exists(fullpath): if os.path.exists(fullpath):
print "WARNING: Output file already exist!" print "WARNING: Output file already exist!"
print "WARNING: It will be overwritten:\n %s" % fullpath print "WARNING: It will be overwritten:\n %s" % fullpath
answer = None answer = None
while not answer: while not answer:
answer = raw_input('OK to overwrite? ') answer = raw_input('OK to overwrite? (yes/no) ')
if answer.upper() in ('Y','YES'): if answer.upper() in ('Y','YES'):
print "Will overwrite the existing file: %s" % fullpath print "Will overwrite the existing file: %s" % fullpath
else: else:
@ -230,7 +243,7 @@ class ArgHandler:
'iso', 'iso',
'wft', 'wft',
'geneweb'): 'geneweb'):
print "Invalid format: %s" % outformat print "Invalid format for output: %s" % outformat
print "Ignoring output file: %s" % outfname print "Ignoring output file: %s" % outfname
continue continue
elif outfname[-3:].upper() == "GED": elif outfname[-3:].upper() == "GED":
@ -249,9 +262,9 @@ class ArgHandler:
print "Unrecognized format for output file %s" % outfname print "Unrecognized format for output file %s" % outfname
print "Ignoring output file: %s" % outfname print "Ignoring output file: %s" % outfname
continue continue
self.exports.append((outfname,outformat)) self.exports.append((fullpath,outformat))
elif o in ( '-a', '--action' ): elif option in ( '-a', '--action' ):
action = v action = value
if action not in ( 'check', 'summary', 'report', 'tool' ): if action not in ( 'check', 'summary', 'report', 'tool' ):
print "Unknown action: %s. Ignoring." % action print "Unknown action: %s. Ignoring." % action
continue continue
@ -260,9 +273,11 @@ class ArgHandler:
and options[opt_ix+1][0] in ( '-p', '--options' ): and options[opt_ix+1][0] in ( '-p', '--options' ):
options_str = options[opt_ix+1][1] options_str = options[opt_ix+1][1]
self.actions.append((action,options_str)) self.actions.append((action,options_str))
elif o in ('-d', '--debug'): elif option in ('-d', '--debug'):
l = logging.getLogger(v) logger = logging.getLogger(value)
l.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
elif option in ('-l',) :
self.list = True
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Determine the need for GUI # Determine the need for GUI
@ -297,94 +312,98 @@ class ArgHandler:
session, write files, and/or perform actions. session, write files, and/or perform actions.
""" """
if self.list:
print 'List of known family trees in your database path\n'
dbman = CLIDbManager(self.state)
for name, dirname in dbman.family_tree_list():
print name, ', in dir ', dirname
if self.open_gui: if self.open_gui:
# Filename was given. Open a session with that file. Forget # Filename was given as gramps FILENAME.
# the rest of given arguments. # Open a session with that file. Forget the rest of given arguments
success = False success = False
filename = os.path.abspath(os.path.expanduser(self.open_gui)) if os.path.isdir(self.open_gui):
filetype = Mime.get_type(filename) #only accept if a name.txt is found
if filetype in (const.APP_GRAMPS,const.APP_GEDCOM, path_name = os.path.join(self.open_gui, NAME_FILE)
const.APP_GRAMPS_XML, 'x-directory/normal'): 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 in ('x-directory/normal',):
success = True
pass
elif filetype in IMPORT_TYPES:
# Say the type outloud # Say the type outloud
if filetype == const.APP_GRAMPS: if filetype == const.APP_GRAMPS:
print "Type: GRAMPS database" print "Type: GRAMPS 2.2.x GRDB database"
elif filetype == const.APP_GEDCOM: elif filetype == const.APP_GEDCOM:
print "Type: GEDCOM file" print "Type: GEDCOM file"
elif filetype == const.APP_GRAMPS_XML: elif filetype == const.APP_GRAMPS_XML:
print "Type: GRAMPS XML database" print "Type: GRAMPS XML database"
try:
self.vm.db_loader.read_file(filename, filetype)
print "Opened successfully!"
success = True
except:
print "Cannot open '%s'. Exiting..." % filename
elif filetype in (const.APP_GRAMPS_PKG,):
QuestionDialog.OkDialog( _("Opening non-native format"),
_("New GRAMPS database has to be set up "
"when opening non-native formats. The "
"following dialog will let you select "
"the new database."),
self.vm.window)
prompter = NewNativeDbPrompter(self.vm,self.state)
if not prompter.chooser():
QuestionDialog.ErrorDialog(
_("New GRAMPS database was not set up"),
_('GRAMPS cannot open non-native data '
'without setting up new GRAMPS database.'))
print "Cannot continue without native database. Exiting..."
sys.exit(1)
elif filetype == const.APP_GRAMPS_PKG: elif filetype == const.APP_GRAMPS_PKG:
print "Type: GRAMPS package" print "Type: GRAMPS XML package"
self.vm.import_pkg(filename)
dbman = CLIDbManager(self.state)
filename, filetype, name = dbman.import_new_db(filetype,
filename, None)
success = True success = True
else: else:
print "Unknown file type: %s" % filetype #see if not just a name of a database is given
QuestionDialog.ErrorDialog( dbman = CLIDbManager(self.state)
data = dbman.family_tree(self.open_gui)
if data is not None:
filename, filetype= data[0], data[1]
success = True
else:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename, _("Could not open file: %s") % filename,
_('File type "%s" is unknown to GRAMPS.\n\n' _('Not a valid Family tree given to open\n\n'
'Valid types are: GRAMPS database, GRAMPS XML, ' ))
'GRAMPS package, and GEDCOM.') % filetype) print "Exiting..."
print "Exiting..." sys.exit(1)
sys.exit(1)
if success: if success:
# Add the file to the recent items # Add the file to the recent items
RecentFiles.recent_files(filename,const.APP_GRAMPS) path = os.path.join(filename, "name.txt")
try:
ifile = open(path)
title = ifile.readline().strip()
ifile.close()
except:
title = filename
RecentFiles.recent_files(filename, title)
else: else:
sys.exit(1) sys.exit(1)
return (filename, filetype) return (filename, filetype)
if self.open: if self.open:
# Filename to open was given. Open it natively (grdb or any of # Family Tree to open was given. Open it
# the InMem formats, without setting up a new database. Then # Then go on and process the rest of the command line arguments.
# go on and process the rest of the command line arguments.
self.cl = bool(self.exports or self.actions) self.cl = bool(self.exports or self.actions)
name,format = self.open name, format = self.open
success = False success = False
filename = os.path.abspath(os.path.expanduser(name))
if format == 'grdb': if format == 'famtree':
filetype = const.APP_GRAMPS path_name = os.path.join(name, NAME_FILE)
print "Type: GRAMPS database" if os.path.isfile(path_name):
elif format == 'gedcom': filetype = const.APP_FAMTREE
filetype = const.APP_GEDCOM filename = name
print "Type: GEDCOM" success = True
elif format == 'gramps-xml': else:
filetype = const.APP_GRAMPS_XML print "No valid Family tree given, cannot be opened."
print "Type: GRAMPS XML" print "Exiting..."
elif format == 'x-directory/normal': sys.exit(1)
filetype = 'x-directory/normal'
print "Type: GRAMPS DIR"
else: else:
print "Unknown file type: %s" % format print "Only Family trees can be opened."
print "Exiting..." print "Exiting..."
sys.exit(1) sys.exit(1)
try: try:
self.vm.read_recent_file(filename, filetype) self.vm.open_activate(filename)
print "Opened successfully!" print "Opened successfully!"
success = True success = True
except: except:
@ -395,14 +414,14 @@ class ArgHandler:
if self.imports: if self.imports:
self.cl = bool(self.exports or self.actions or self.cl) self.cl = bool(self.exports or self.actions or self.cl)
# Create empty dir for imported database(s) if not self.open:
self.imp_db_path = Utils.get_empty_tempdir("import_dbdir") # Create empty dir for imported database(s)
self.imp_db_path = Utils.get_empty_tempdir("import_dbdir")
self.vm.db_loader.read_file(self.imp_db_path,const.APP_GRAMPS) self.vm.db_loader.read_file(self.imp_db_path)
for imp in self.imports: for imp in self.imports:
print "Importing: file %s, format %s." % imp print "Importing: file %s, format %s." % imp
self.cl_import(imp[0],imp[1]) self.cl_import(imp[0], imp[1])
elif len(self.args) > 1 and not self.open: elif len(self.args) > 1 and not self.open:
print "No data was given -- will launch interactive session." print "No data was given -- will launch interactive session."
@ -429,7 +448,6 @@ class ArgHandler:
print "Exiting." print "Exiting."
sys.exit(0) sys.exit(0)
## read recent file is broken in GRAMPS 30 ! DISABLE
elif Config.get(Config.RECENT_FILE) and Config.get(Config.AUTOLOAD): elif Config.get(Config.RECENT_FILE) and Config.get(Config.AUTOLOAD):
filename = Config.get(Config.RECENT_FILE) filename = Config.get(Config.RECENT_FILE)
self.vm.db_loader.read_file(filename, const.APP_GRAMPS) self.vm.db_loader.read_file(filename, const.APP_GRAMPS)
@ -448,12 +466,21 @@ class ArgHandler:
# Import handler # Import handler
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def cl_import(self,filename,format): def cl_import(self, filename, format):
""" """
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': if format == 'famtree':
#3.x database
try:
GrampsDbUtils.gramps_db_reader_factory(const.APP_FAMTREE)(
self.state.db, filename, empty)
except AttributeError:
print "Error importing Family Tree %s" % filename
sys.exit(1)
elif format == 'grdb':
#2.x database
filename = os.path.normpath(os.path.abspath(filename)) filename = os.path.normpath(os.path.abspath(filename))
try: try:
GrampsDbUtils.gramps_db_reader_factory(const.APP_GRAMPS)( GrampsDbUtils.gramps_db_reader_factory(const.APP_GRAMPS)(
@ -534,7 +561,10 @@ class ArgHandler:
print "Invalid format: %s" % format print "Invalid format: %s" % format
sys.exit(1) sys.exit(1)
if not self.cl: if not self.cl:
return self.vm.post_load() if self.imp_db_path:
return self.vm.open_activate(self.imp_db_path)
else:
return self.vm.open_activate(self.open[0])
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -549,16 +579,13 @@ class ArgHandler:
""" """
filename = os.path.abspath(os.path.expanduser(filename)) filename = os.path.abspath(os.path.expanduser(filename))
if format == 'grdb': if format == 'grdb':
try: print "GRDB format write is no longer supported!"
GrampsDbUtils.gramps_db_writer_factory(const.APP_GRAMPS)( sys.exit(1)
self.state.db,filename)
except:
print "Error exporting %s" % filename
sys.exit(1)
elif format == 'gedcom': elif format == 'gedcom':
try: try:
gw = GrampsDbUtils.GedcomWriter(self.state.db, None, 1) gw = GrampsDbUtils.GedcomWriter(self.state.db, None, 1)
ret = gw.write_gedcom_file(filename) ret = gw.write_gedcom_file(filename)
print "... finished writing %s" % filename
except: except:
print "Error exporting %s" % filename print "Error exporting %s" % filename
sys.exit(1) sys.exit(1)
@ -568,30 +595,37 @@ class ArgHandler:
try: try:
g = GrampsDbUtils.XmlWriter(self.state.db,None,0,1) g = GrampsDbUtils.XmlWriter(self.state.db,None,0,1)
ret = g.write(filename) ret = g.write(filename)
print "... finished writing %s" % filename
except: except:
print "Error exporting %s" % filename print "Error exporting %s" % filename
sys.exit(1) sys.exit(1)
else:
print "Error exporting %s" % filename
elif format == 'gramps-pkg': elif format == 'gramps-pkg':
try: try:
import WritePkg import WritePkg
writer = WritePkg.PackageWriter(self.state.db,filename) writer = WritePkg.PackageWriter(self.state.db, filename)
ret = writer.export() ret = writer.export()
print "... finished writing %s" % filename
except: except:
print "Error creating %s" % filename print "Error creating %s" % filename
sys.exit(1) sys.exit(1)
elif format == 'iso': elif format == 'iso':
import WriteCD import WriteCD
try: try:
writer = WriteCD.PackageWriter(self.state.db,filename,1) writer = WriteCD.PackageWriter(self.state.db, filename, 1)
ret = writer.export() ret = writer.export()
print "... finished writing %s" % filename
except: except:
print "Error exporting %s" % filename print "Error exporting %s" % filename
sys.exit(1) sys.exit(1)
elif format == 'wft': elif format == 'wft':
import WriteFtree import WriteFtree
try: try:
writer = WriteFtree.FtreeWriter(self.state.db,None,1,filename) writer = WriteFtree.FtreeWriter(self.state.db, None, 1,
filename)
ret = writer.export_data() ret = writer.export_data()
print "... finished writing %s" % filename
except: except:
print "Error exporting %s" % filename print "Error exporting %s" % filename
sys.exit(1) sys.exit(1)
@ -599,8 +633,9 @@ class ArgHandler:
import WriteGeneWeb import WriteGeneWeb
try: try:
writer = WriteGeneWeb.GeneWebWriter(self.state.db, writer = WriteGeneWeb.GeneWebWriter(self.state.db,
None,1,filename) None, 1, filename)
ret = writer.export_data() ret = writer.export_data()
print "... finished writing %s" % filename
except: except:
print "Error exporting %s" % filename print "Error exporting %s" % filename
sys.exit(1) sys.exit(1)
@ -690,78 +725,6 @@ class ArgHandler:
print "Unknown action: %s." % action print "Unknown action: %s." % action
sys.exit(1) sys.exit(1)
#-------------------------------------------------------------------------
#
# NewNativeDbPrompter
#
#-------------------------------------------------------------------------
class NewNativeDbPrompter:
"""
This class allows to set up a new empty native (grdb) database.
The filename is forced to have an '.grdb' extension. If not given,
it is appended.
"""
def __init__(self,vm,state):
self.vm = vm
self.state = state
def chooser(self):
"""
Select the new file. Suggest the Untitled_X.grdb name.
Return 1 when selection is made and 0 otherwise.
"""
choose = gtk.FileChooserDialog(_('GRAMPS: Create GRAMPS database'),
self.vm.window,
gtk.FILE_CHOOSER_ACTION_SAVE,
(gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL,
gtk.STOCK_NEW,
gtk.RESPONSE_OK))
self.state.db.close()
# Always add automatic (macth all files) filter
add_all_files_filter(choose)
add_grdb_filter(choose)
# Suggested folder: try last open file, import, then last export,
# then home.
default_dir = os.path.split(Config.get(Config.RECENT_FILE))[0] + os.path.sep
if len(default_dir)<=1:
default_dir = Config.get(Config.RECENT_IMPORT_DIR)
if len(default_dir)<=1:
default_dir = Config.get(Config.RECENT_EXPORT_DIR)
if len(default_dir)<=1:
default_dir = '~/'
new_filename = Utils.get_new_filename('grdb',default_dir)
choose.set_current_folder(default_dir)
choose.set_current_name(os.path.split(new_filename)[1])
while (True):
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = Utils.get_unicode_path(choose.get_filename())
if filename == None:
continue
if os.path.splitext(filename)[1] != ".grdb":
filename = filename + ".grdb"
choose.destroy()
self.state.db = GrampsDb.gramps_db_factory(const.APP_GRAMPS)(
Config.TRANSACTIONS)
self.vm.db_loader.read_file(filename, const.APP_GRAMPS)
self.state.signal_change()
#self.change_page(None, None)
# Add the file to the recent items
RecentFiles.recent_files(filename,const.APP_GRAMPS)
return True
else:
choose.destroy()
return False
choose.destroy()
return False
def add_all_files_filter(chooser): def add_all_files_filter(chooser):
""" """
Add an all-permitting filter to the file chooser dialog. Add an all-permitting filter to the file chooser dialog.

View File

@ -56,7 +56,6 @@ import gtk
import const import const
import Config import Config
import Mime import Mime
import GrampsDb
import gen.db import gen.db
import GrampsDbUtils import GrampsDbUtils
import Utils import Utils
@ -87,122 +86,6 @@ class DbLoader:
self.dbstate = dbstate self.dbstate = dbstate
self.uistate = uistate self.uistate = uistate
def open_file(self):
"""
Presents a file open dialog and opens the corresponding exsting file
"""
choose = gtk.FileChooserDialog(
_('GRAMPS: Open database'),
self.uistate.window,
gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))
# Always add automatic (macth all files) filter
add_all_files_filter(choose)
add_grdb_filter(choose)
add_xml_filter(choose)
add_gedcom_filter(choose)
(box, type_selector) = format_maker(OPEN_FORMATS)
choose.set_extra_widget(box)
choose.set_current_folder(get_default_dir())
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = Utils.get_unicode_path(choose.get_filename())
if self.check_errors(filename):
return ('','')
filetype = type_selector.get_value()
if filetype == 'auto':
filetype = Mime.get_type(filename)
# (the_path, the_file) = os.path.split(filename)
choose.destroy()
if filetype in OPEN_FORMATS:
self.read_file(filename, filetype)
try:
os.chdir(os.path.dirname(filename))
except:
return ('', '')
return (filename, filetype)
elif filetype in [const.APP_GRAMPS_PKG, const.APP_GENEWEB]:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
_('Files of type "%s" cannot be opened directly.\n\n'
'Please create a new GRAMPS database and import '
'the file.') % filetype)
return ('', '')
else:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
_('File type "%s" is unknown to GRAMPS.\n\n'
'Valid types are: GRAMPS database, GRAMPS XML, '
'GRAMPS package, and GEDCOM.') % filetype)
return ('', '')
choose.destroy()
return ('', '')
def save_as(self):
choose = gtk.FileChooserDialog(
_('GRAMPS: Create GRAMPS database'),
self.uistate.window,
gtk.FILE_CHOOSER_ACTION_SAVE,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_SAVE, gtk.RESPONSE_OK))
# Always add automatic (macth all files) filter
add_all_files_filter(choose)
add_gramps_files_filter(choose)
add_grdb_filter(choose)
add_xml_filter(choose)
add_gedcom_filter(choose)
(box, type_selector) = format_maker(OPEN_FORMATS)
choose.set_extra_widget(box)
default_dir = get_default_dir()
new_filename = Utils.get_new_filename('grdb', default_dir)
choose.set_current_folder(default_dir)
choose.set_current_name(os.path.split(new_filename)[1])
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = Utils.get_unicode_path(choose.get_filename())
if self.check_errors(filename):
return ('','')
# Do not allow saving as into the currently open file
if filename == self.dbstate.db.full_name:
return ('','')
filetype = type_selector.get_value()
if filetype == 'auto':
try:
the_file = open(filename,'wb')
the_file.close()
filetype = Mime.get_type(filename)
os.remove(filename)
except RuntimeError, msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
str(msg))
return ('','')
# First we try our best formats
if filetype not in OPEN_FORMATS:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
_("Unknown type: %s") % filetype
)
return ('','')
choose.destroy()
self.open_saved_as(filename, filetype)
return (filename, filetype)
else:
choose.destroy()
return ('','')
def import_file(self): def import_file(self):
# First thing first: import is a batch transaction # First thing first: import is a batch transaction
# so we will lose the undo history. Warn the user. # so we will lose the undo history. Warn the user.
@ -342,9 +225,11 @@ class DbLoader:
return False return False
def read_file(self, filename, filetype): def read_file(self, filename):
""" """
This method takes care of changing database, and loading the data. This method takes care of changing database, and loading the data.
In 3.0 we only allow reading of real databases of filetype
'x-directory/normal'
This method should only return on success. This method should only return on success.
Returning on failure makes no sense, because we cannot recover, Returning on failure makes no sense, because we cannot recover,
@ -363,26 +248,10 @@ class DbLoader:
'to the selected file.')) 'to the selected file.'))
else: else:
mode = "w" mode = "w"
elif filetype == 'unknown':
QuestionDialog.WarningDialog(
_('Missing or Invalid database'),
_('%s could not be found.\n'
'It is possible that this file no longer exists '
'or has been moved.') % filename)
return False
else: else:
mode = 'w' mode = 'w'
try: dbclass = gen.db.GrampsDBDir
#dbclass = GrampsDb.gramps_db_factory(db_type = filetype)
dbclass = gen.db.GrampsDBDir
except gen.db.GrampsDbException, msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
_("This may be caused by an improper installation of GRAMPS.") +
"\n" + str(msg))
return
self.dbstate.change_database(dbclass(Config.get(Config.TRANSACTIONS))) self.dbstate.change_database(dbclass(Config.get(Config.TRANSACTIONS)))
self.dbstate.db.disable_signals() self.dbstate.db.disable_signals()
@ -395,38 +264,19 @@ class DbLoader:
self.dbstate.db.set_save_path(filename) self.dbstate.db.set_save_path(filename)
try: try:
os.chdir(os.path.dirname(filename)) os.chdir(os.path.dirname(filename))
except: except (OSError, IOError):
print "could not change directory" print "could not change directory"
except OSError, msg: except OSError, msg:
QuestionDialog.ErrorDialog( QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename, str(msg)) _("Could not open file: %s") % filename, str(msg))
except Errors.DbError, msg: except Errors.DbError, msg:
QuestionDialog.DBErrorDialog(str(msg.value)) QuestionDialog.DBErrorDialog(str(msg.value))
self.dbstate.db.close() self.state.no_database()
except Exception: except Exception:
_LOG.error("Failed to open database.", exc_info=True) _LOG.error("Failed to open database.", exc_info=True)
return True return True
def open_saved_as(self, filename, filetype):
dbclass = GrampsDb.gramps_db_factory(db_type = filetype)
new_database = dbclass()
old_database = self.dbstate.db
self.dbstate.change_database_noclose(new_database)
old_database.disable_signals()
new_database.disable_signals()
self.uistate.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
self.uistate.progress.show()
try:
new_database.load_from(old_database, filename,
self.uistate.pulse_progressbar)
old_database.close()
except Exception:
_LOG.error("Failed to open database.", exc_info=True)
return False
def do_import(self, dialog, importer, filename): def do_import(self, dialog, importer, filename):
dialog.destroy() dialog.destroy()

View File

@ -66,7 +66,7 @@ import pango
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import const import const
import QuestionDialog import QuestionDialog
import GrampsDb import gen.db
import GrampsDbUtils import GrampsDbUtils
import Config import Config
import Mime import Mime
@ -97,7 +97,145 @@ STOCK_COL = 6
RCS_BUTTON = { True : _('Extract'), False : _('Archive') } RCS_BUTTON = { True : _('Extract'), False : _('Archive') }
class DbManager: class CLIDbManager:
"""
Database manager without GTK functionality, allows users to create and
open databases
"""
def __init__(self, dbstate):
self.dbstate = dbstate
self.msg = None
if dbstate:
self.active = dbstate.db.get_save_path()
else:
self.active = None
self.current_names = []
self._populate_cli()
def empty(self, val):
'''Callback that does nothing
'''
pass
def _populate_cli(self):
''' Get the list of current names in the database dir
'''
# make the default directory if it does not exist
dbdir = os.path.expanduser(Config.get(Config.DATABASE_PATH))
make_dbdir(dbdir)
self.current_names = []
for dpath in os.listdir(dbdir):
dirpath = os.path.join(dbdir, dpath)
path_name = os.path.join(dirpath, NAME_FILE)
if os.path.isfile(path_name):
name = file(path_name).readline().strip()
(tval, last) = time_val(dirpath)
(enable, stock_id) = icon_values(dirpath, self.active,
self.dbstate.db.is_open())
if (stock_id == 'gramps-lock'):
last = find_locker_name(dirpath)
self.current_names.append(
(name, os.path.join(dbdir, dpath), path_name,
last, tval, enable, stock_id))
self.current_names.sort()
def family_tree(self, name):
'''Given a name, return None if name not existing or
filename, filetype, name
if a known database name
'''
for data in self.current_names:
if data[0] == name:
return data[1], 'x-directory/normal', name
return None
def family_tree_list(self):
'''Return a list of name, dirname of the known family trees
'''
lst = [(x[0], x[1]) for x in self.current_names]
return lst
def __start_cursor(self, msg):
"""
Do needed things to start import visually, eg busy cursor
"""
print _('Starting Import, %s') % msg
def __end_cursor(self):
"""
Set end of a busy cursor
"""
print _('Import finished...')
def __create_new_db_cli(self, title=None):
"""
Create a new database.
"""
new_path = find_next_db_dir()
os.mkdir(new_path)
path_name = os.path.join(new_path, NAME_FILE)
if title == None:
name_list = [ name[0] for name in self.current_names ]
title = find_next_db_name(name_list)
name_file = open(path_name, "w")
name_file.write(title)
name_file.close()
self.current_names.append(title)
return new_path
def __create_new_db(self, title=None):
"""
Create a new database, do extra stuff needed
"""
return self.__create_new_db_cli(title)
def import_new_db(self, filetype, filename, callback):
if filetype in IMPORT_TYPES:
# get the name of the database from the filename of the file
(name, ext) = os.path.splitext(os.path.basename(filename))
# create the database
new_path = self.__create_new_db(name)
trans = Config.TRANSACTIONS
# get the import function using the filetype, but create a db
# based on the DBDir
self.__start_cursor(_("Importing data..."))
dbclass = gen.db.GrampsDBDir
dbase = dbclass(trans)
dbase.load(new_path, callback)
rdr = GrampsDbUtils.gramps_db_reader_factory(filetype)
rdr(dbase, filename, callback)
# finish up
self.__end_cursor()
dbase.close()
path = os.path.join(new_path, "name.txt")
try:
ifile = open(path)
title = ifile.readline().strip()
ifile.close()
except:
title = new_path
return new_path, 'x-directory/normal', title
return None, None, None
class DbManager(CLIDbManager):
""" """
Database Manager. Opens a database manager window that allows users to Database Manager. Opens a database manager window that allows users to
create, rename, delete and open databases. create, rename, delete and open databases.
@ -108,6 +246,7 @@ class DbManager:
Creates the top level window from the glade description, and extracts Creates the top level window from the glade description, and extracts
the GTK widgets that are needed. the GTK widgets that are needed.
""" """
CLIDbManager.__init__(self, dbstate)
self.glade = gtk.glade.XML(const.GLADE_FILE, "dbmanager", "gramps") self.glade = gtk.glade.XML(const.GLADE_FILE, "dbmanager", "gramps")
self.top = self.glade.get_widget('dbmanager') self.top = self.glade.get_widget('dbmanager')
if parent: if parent:
@ -123,24 +262,16 @@ class DbManager:
self.rcs = self.glade.get_widget('rcs') self.rcs = self.glade.get_widget('rcs')
self.msg = self.glade.get_widget('msg') self.msg = self.glade.get_widget('msg')
self.model = None self.model = None
self.dbstate = dbstate
self.column = None self.column = None
self.lock_file = None self.lock_file = None
self.data_to_delete = None self.data_to_delete = None
if dbstate:
self.active = dbstate.db.get_save_path()
else:
self.active = None
self.selection = self.dblist.get_selection() self.selection = self.dblist.get_selection()
self.dblist.set_rules_hint(True) self.dblist.set_rules_hint(True)
self.current_names = []
self.__connect_signals() self.__connect_signals()
self.__build_interface() self.__build_interface()
self.__populate() self._populate_model()
def __connect_signals(self): def __connect_signals(self):
""" """
@ -276,37 +407,19 @@ class DbManager:
self.dblist.set_rules_hint(True) self.dblist.set_rules_hint(True)
def __populate(self): def __populate(self):
"""
Builds the data and the display model.
"""
self._populate_cli()
self._populate_model()
def _populate_model(self):
""" """
Builds the display model. Builds the display model.
""" """
self.model = gtk.TreeStore(str, str, str, str, int, bool, str) self.model = gtk.TreeStore(str, str, str, str, int, bool, str)
# make the default directory if it does not exist #use current names to set up the model
dbdir = os.path.expanduser(Config.get(Config.DATABASE_PATH))
make_dbdir(dbdir)
self.current_names = []
for dpath in os.listdir(dbdir):
dirpath = os.path.join(dbdir, dpath)
path_name = os.path.join(dirpath, NAME_FILE)
if os.path.isfile(path_name):
name = file(path_name).readline().strip()
(tval, last) = time_val(dirpath)
(enable, stock_id) = icon_values(dirpath, self.active,
self.dbstate.db.is_open())
if (stock_id == 'gramps-lock'):
last = find_locker_name(dirpath)
self.current_names.append(
(name, os.path.join(dbdir, dpath), path_name,
last, tval, enable, stock_id))
self.current_names.sort()
for items in self.current_names: for items in self.current_names:
data = [items[0], items[1], items[2], items[3], data = [items[0], items[1], items[2], items[3],
items[4], items[5], items[6]] items[4], items[5], items[6]]
@ -473,10 +586,10 @@ class DbManager:
""" """
new_path = self.__create_new_db("%s : %s" % (parent_name, name)) new_path = self.__create_new_db("%s : %s" % (parent_name, name))
trans = Config.TRANSACTIONS trans = Config.TRANSACTIONS
dbtype = 'x-directory/normal'
self.__start_cursor(_("Extracting archive...")) self.__start_cursor(_("Extracting archive..."))
dbase = GrampsDb.gramps_db_factory(dbtype)(trans) dbclass = gen.db.GrampsDBDir
dbase = dbclass(trans)
dbase.load(new_path, None) dbase.load(new_path, None)
self.__start_cursor(_("Importing archive...")) self.__start_cursor(_("Importing archive..."))
@ -600,7 +713,7 @@ class DbManager:
fname = os.path.join(dirname, filename) fname = os.path.join(dirname, filename)
os.unlink(fname) os.unlink(fname)
dbclass = GrampsDb.gramps_db_factory(db_type = "x-directory/normal") dbclass = gen.db.GrampsDBDir
dbase = dbclass(Config.get(Config.TRANSACTIONS)) dbase = dbclass(Config.get(Config.TRANSACTIONS))
dbase.set_save_path(dirname) dbase.set_save_path(dirname)
dbase.load(dirname, None) dbase.load(dirname, None)
@ -642,29 +755,16 @@ class DbManager:
QuestionDialog.ErrorDialog(_("Could not create family tree"), QuestionDialog.ErrorDialog(_("Could not create family tree"),
str(msg)) str(msg))
def __create_new_db(self, title=None): def __create_new_db(self, title=None):
""" """
Create a new database. Create a new database, append to model
""" """
new_path = self.__create_new_db_cli(title)
new_path = find_next_db_dir()
os.mkdir(new_path)
path_name = os.path.join(new_path, NAME_FILE) path_name = os.path.join(new_path, NAME_FILE)
if title == None:
name_list = [ name[0] for name in self.current_names ]
title = find_next_db_name(name_list)
name_file = open(path_name, "w")
name_file.write(title)
name_file.close()
self.current_names.append(title)
node = self.model.append(None, [title, new_path, path_name, node = self.model.append(None, [title, new_path, path_name,
_("Never"), 0, False, '']) _("Never"), 0, False, ''])
self.selection.select_iter(node) self.selection.select_iter(node)
path = self.model.get_path(node) path = self.model.get_path(node)
self.dblist.set_cursor(path, focus_column=self.column, self.dblist.set_cursor(path, focus_column=self.column,
start_editing=True) start_editing=True)
@ -675,10 +775,11 @@ class DbManager:
""" """
Handle the reception of drag data Handle the reception of drag data
""" """
drag_value = selection.data drag_value = selection.data
print drag_value print drag_value
fname = None
type = None
title = None
# we are only interested in this if it is a file:// URL. # we are only interested in this if it is a file:// URL.
if drag_value and drag_value[0:7] == "file://": if drag_value and drag_value[0:7] == "file://":
@ -687,30 +788,10 @@ class DbManager:
# deterimine the mime type. If it is one that we are interested in, # deterimine the mime type. If it is one that we are interested in,
# we process it # we process it
filetype = Mime.get_type(drag_value) filetype = Mime.get_type(drag_value)
if filetype in IMPORT_TYPES: fname, type, title = self.import_new_db(filetype, drag_value[7:],
None)
# get the name of the database from the filename of the file return fname, type, title
(name, ext) = os.path.splitext(os.path.basename(drag_value))
# create the database
new_path = self.__create_new_db(name)
trans = Config.TRANSACTIONS
dbtype = 'x-directory/normal'
# get the import function using the filetype, but create a db
# based on the DBDir
self.__start_cursor(_("Importing data..."))
dbase = GrampsDb.gramps_db_factory(dbtype)(trans)
dbase.load(new_path, None)
rdr = GrampsDbUtils.gramps_db_reader_factory(filetype)
rdr(dbase, drag_value[7:], None)
# finish up
self.__end_cursor()
dbase.close()
return True
def drag_motion(wid, context, xpos, ypos, time_stamp): def drag_motion(wid, context, xpos, ypos, time_stamp):
""" """

View File

@ -1,26 +0,0 @@
# This is the src/RelLib level Makefile for Gramps
# We could use GNU make's ':=' syntax for nice wildcard use,
# but that is not necessarily portable.
# If not using GNU make, then list all .py files individually
pkgdatadir = $(datadir)/@PACKAGE@/GrampsDb
pkgdata_PYTHON = \
_GrampsDbFactories.py\
_GrampsDbWriteXML.py \
_GrampsGEDDB.py\
_GrampsInMemDB.py\
__init__.py
pkgpyexecdir = @pkgpyexecdir@/GrampsDb
pkgpythondir = @pkgpythondir@/GrampsDb
# Clean up all the byte-compiled files
MOSTLYCLEANFILES = *pyc *pyo
GRAMPS_PY_MODPATH = "../"
pycheck:
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
pychecker $(pkgdata_PYTHON));

View File

@ -1,89 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004-2005 Donald N. Allingham
#
# 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 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 the class for the grdb backend
> db_class = GrampsDb.gramps_db_factory(db_type = const.APP_GRAMPS)
>
> # To get a XML writer
> GrampsDb.gramps_db_writer_factory(db_type = const.APP_GRAMPS_XML)
>
> # To get a Gedcom reader
> GrampsDb.gramps_db_reader_factory(db_type = const.APP_GEDCOM)
"""
import gen.db.dbconst as const
from gen.db.exceptions import GrampsDbException
import logging
log = logging.getLogger(".GrampDb")
try:
import Config
config = Config
except:
log.warn("No Config module available, using defaults.")
config = None
def gramps_db_factory(db_type):
"""Factory class for obtaining a Gramps database backend.
@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:
from gen.db import GrampsBSDDB
#from _GrampsBSDDB import GrampsBSDDB
cls = GrampsBSDDB
# elif db_type == const.APP_GRAMPS_XML:
# from _GrampsXMLDB import GrampsXMLDB
# cls = GrampsXMLDB
elif db_type == const.APP_GEDCOM:
from gen.db import GrampsGEDDB
#from _GrampsGEDDB import GrampsGEDDB
cls = GrampsGEDDB
elif db_type == 'x-directory/normal':
from gen.db import GrampsDBDir
#from _GrampsDBDir import GrampsGEDDB
cls = GrampsDBDir
else:
raise GrampsDbException("Attempt to create unknown "
"database backend class: "
"db_type = %s" % (str(db_type),))
cls.__config__ = config
return cls

View File

@ -1,97 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
#
# 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$
"""
Provides the GRAMPS DB interface for supporting in-memory editing
of GEDCOM files.
"""
from gen.lib import *
from _GrampsInMemDB import *
from _GrampsDbExceptions import GrampsDbException
from gen.utils import db_copy
#-------------------------------------------------------------------------
#
# GrampsGEDDB
#
#-------------------------------------------------------------------------
class GrampsGEDDB(GrampsInMemDB):
"""GRAMPS database object. This object is a base class for other
objects."""
def __init__(self, use_txn = False):
"""creates a new GrampsDB"""
GrampsInMemDB.__init__(self)
def load(self, name, callback, mode="w"):
if self.db_is_open:
self.close()
GrampsInMemDB.load(self,name,callback,mode)
try:
from GrampsDbUtils._ReadGedcom import importData
except:
log.warning("Failed to load Gedcom reader", exc_info=True)
raise GrampsDbException("Failed to load Gedcom reader")
importData(self,name,callback,use_trans=False)
self.bookmarks = GrampsDbBookmarks(self.metadata.get('bookmarks',[]))
self.db_is_open = True
self.readonly = True
self.abort_possible = True
return 1
def load_from(self, other_database, filename, callback):
db_copy(other_database,self,callback)
GrampsInMemDB.load(self,filename,callback)
self.bookmarks = GrampsDbBookmarks(self.metadata.get('bookmarks',[]))
self.db_is_open = True
try:
from GrampsDbUtils._WriteGedcom import GedcomWriter
except:
log.warning("Failed to load Gedcom writer", exc_info=True)
raise GrampsDbException("Failed to load Gedcom writer")
writer = GedcomWriter(self,self.get_default_person(),
callback=callback)
writer.export_data(self.full_name)
return 1
def close(self):
if not self.db_is_open:
return
try:
from GrampsDbUtils._WriteGedcom import GedcomWriter
except:
log.warning("Failed to load Gedcom writer", exc_info=True)
raise GrampsDbException("Failed to load Gedcom writer")
if self.db_is_changed():
writer = GedcomWriter(self,self.get_default_person())
writer.export_data(self.full_name)
self.db_is_open = False
GrampsInMemDB.close(self)

View File

@ -1,392 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
#
# 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$
"""
Provides the common infrastructure for database formats that
must hold all of their data in memory.
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import time
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gen.lib import *
from _GrampsDbBase import *
from _GrampsCursor import GrampsCursor
class GrampsInMemCursor(GrampsCursor):
"""
Cursor class for in-memory database classes. Since the in-memory
classes use python dictionaries, the python iter class is used
to provide the cursor function.
"""
def __init__(self,src_map):
self.src_map = src_map
self.current = iter(src_map)
def first(self):
self.current = iter(self.src_map)
return self.next()
def next(self):
try:
index = self.current.next()
return (index,self.src_map[index])
except StopIteration:
return None
def close(self):
pass
def get_length(self):
return len(self.src_map)
#-------------------------------------------------------------------------
#
# GrampsInMemDB
#
#-------------------------------------------------------------------------
class GrampsInMemDB(GrampsDbBase):
"""GRAMPS database object. This object is a base class for other
objects."""
ID_INDEX = 1 # an index of the gramps id in the data tuple
def __init__(self):
"""creates a new GrampsDB"""
GrampsDbBase.__init__(self)
self.filename = ""
def load(self,name,callback,mode="w"):
self.full_name = name
self.readonly = mode == "r"
self.open_undodb()
# Re-set the undo history to a fresh session start
self.undoindex = -1
self.translist = [None] * len(self.translist)
self.abort_possible = True
self.undo_history_timestamp = time.time()
def transaction_commit(self,transaction,msg):
GrampsDbBase.transaction_commit(self,transaction,msg)
if transaction.batch:
self.build_surname_list()
def get_person_cursor(self):
return GrampsInMemCursor(self.person_map)
def get_family_cursor(self):
return GrampsInMemCursor(self.family_map)
def get_event_cursor(self):
return GrampsInMemCursor(self.event_map)
def get_place_cursor(self):
return GrampsInMemCursor(self.place_map)
def get_source_cursor(self):
return GrampsInMemCursor(self.source_map)
def get_repository_cursor(self):
return GrampsInMemCursor(self.repository_map)
def get_note_cursor(self):
return GrampsInMemCursor(self.note_map)
def get_media_cursor(self):
return GrampsInMemCursor(self.media_map)
def close(self):
self.close_undodb()
def set_name_group_mapping(self,name,group):
if group == None and self.name_group.has_key(name):
del self.name_group[name]
if group is not None :
self.name_group[name] = group
def build_surname_list(self):
a = set()
for person_id in iter(self.person_map):
p = self.get_person_from_handle(person_id)
a.add(unicode(p.get_primary_name().get_surname()))
self.surname_list = list(a)
self.sort_surname_list()
def remove_from_surname_list(self,person):
"""
Check whether there are persons with the same surname left in
the database. If not then we need to remove the name from the list.
The function must be overridden in the derived class.
"""
name = str(person.get_primary_name().get_surname())
count = 0
do_remove = True
for person_id in iter(self.person_map):
p = self.get_person_from_handle(person_id)
pn = str(p.get_primary_name().get_surname())
if pn == name:
count += 1
if count > 1:
do_remove = False
break
if do_remove:
self.surname_list.remove(unicode(name))
def del_person(self,handle):
person = self.get_person_from_handle(str(handle))
del self.id_trans[person.get_gramps_id()]
del self.person_map[str(handle)]
def del_source(self,handle):
source = self.get_source_from_handle(str(handle))
del self.sid_trans[source.get_gramps_id()]
del self.source_map[str(handle)]
def del_repository(self,handle):
repository = self.get_repository_from_handle(str(handle))
del self.rid_trans[repository.get_gramps_id()]
del self.repository_map[str(handle)]
def del_note(self,handle):
note = self.get_note_from_handle(str(handle))
del self.nid_trans[note.get_gramps_id()]
del self.note_map[str(handle)]
def del_place(self,handle):
place = self.get_place_from_handle(str(handle))
del self.pid_trans[place.get_gramps_id()]
del self.place_map[str(handle)]
def del_media(self,handle):
obj = self.get_object_from_handle(str(handle))
del self.oid_trans[obj.get_gramps_id()]
del self.media_map[str(handle)]
def del_family(self,handle):
family = self.get_family_from_handle(str(handle))
del self.fid_trans[family.get_gramps_id()]
del self.family_map[str(handle)]
def del_event(self,handle):
event = self.get_event_from_handle(str(handle))
del self.eid_trans[event.get_gramps_id()]
del self.event_map[str(handle)]
def get_trans_map(self,signal_root):
"""
A silly method to get the secondary index map based on the
signal name root for a given object type. The BDB backend
manages this transparently, but we need to manually take
care of secondary indices in the InMem backend.
"""
trans_maps = {
'person': self.id_trans,
'family': self.fid_trans,
'source': self.sid_trans,
'event' : self.eid_trans,
'media' : self.oid_trans,
'place' : self.pid_trans,
'repository': self.rid_trans,
'note': self.nid_trans,
}
return trans_maps[signal_root]
def undo_data(self, data, handle, db_map, signal_root):
"""
The BDB backend manages secondary indices transparently,
but we need to manually take care of secondary indices
in the InMem backend.
"""
trans_map = self.get_trans_map(signal_root)
obj = db_map.get(handle)
if data == None:
self.emit(signal_root + '-delete', ([handle], ))
del trans_map[obj[self.ID_INDEX]]
del db_map[handle]
else:
if obj:
signal = signal_root + '-update'
if obj[self.ID_INDEX] != data[self.ID_INDEX]:
del trans_map[obj[self.ID_INDEX]]
else:
signal = signal_root + '-add'
db_map[handle] = data
trans_map[data[self.ID_INDEX]] = str(handle)
self.emit(signal, ([handle], ))
def __commit_inmem_base(self,obj,db_map,trans_map):
if self.readonly or not obj or not obj.get_handle():
return False
gid = obj.gramps_id
old_data = db_map.get(obj.handle)
if old_data:
old_id = old_data[self.ID_INDEX]
if old_id is not None and obj.gramps_id != old_id:
del trans_map[old_id]
#on load of xml for backref that are encountered before object exists,
#the object is created empty with gid None. Do not add this to
#trans_map. Broken ref will then also not be exported (good!)
if gid is not None:
trans_map[gid] = obj.handle
return True
def commit_person(self,person,transaction,change_time=None):
if not self.__commit_inmem_base(person,self.person_map,self.id_trans):
return
GrampsDbBase.commit_person(self,person,transaction,change_time)
def commit_place(self,place,transaction,change_time=None):
if not self.__commit_inmem_base(place,self.place_map,self.pid_trans):
return
GrampsDbBase.commit_place(self,place,transaction,change_time)
def commit_family(self,family,transaction,change_time=None):
if not self.__commit_inmem_base(family,self.family_map,self.fid_trans):
return
GrampsDbBase.commit_family(self,family,transaction,change_time)
def commit_event(self,event,transaction,change_time=None):
if not self.__commit_inmem_base(event,self.event_map,self.eid_trans):
return
GrampsDbBase.commit_event(self,event,transaction,change_time)
def commit_media_object(self,obj,transaction,change_time=None):
if not self.__commit_inmem_base(obj,self.media_map,self.oid_trans):
return
GrampsDbBase.commit_media_object(self,obj,transaction,change_time)
def commit_source(self,source,transaction,change_time=None):
if not self.__commit_inmem_base(source,self.source_map,self.sid_trans):
return
GrampsDbBase.commit_source(self,source,transaction,change_time)
def commit_repository(self,repository,transaction,change_time=None):
if not self.__commit_inmem_base(repository,self.repository_map,
self.rid_trans):
return
GrampsDbBase.commit_repository(self,repository,transaction,change_time)
def commit_note(self,note,transaction,change_time=None):
if not self.__commit_inmem_base(note, self.note_map,
self.nid_trans):
return
GrampsDbBase.commit_note(self,note,transaction,change_time)
def get_person_from_gramps_id(self,val):
handle = self.id_trans.get(str(val))
if handle:
data = self.person_map[handle]
if data:
person = Person()
person.unserialize(data)
return person
return None
def get_family_from_gramps_id(self,val):
handle = self.fid_trans.get(str(val))
if handle:
data = self.family_map[handle]
if data:
family = Family()
family.unserialize(data)
return family
return None
def get_event_from_gramps_id(self,val):
handle = self.eid_trans.get(str(val))
if handle:
data = self.event_map[handle]
if data:
event = Event()
event.unserialize(data)
return event
return None
def get_place_from_gramps_id(self,val):
handle = self.pid_trans.get(str(val))
if handle:
data = self.place_map[handle]
if data:
place = Place()
place.unserialize(data)
return place
return None
def get_source_from_gramps_id(self,val):
handle = self.sid_trans.get(str(val))
if handle:
data = self.source_map[handle]
if data:
source = Source()
source.unserialize(data)
return source
return None
def get_repository_from_gramps_id(self,val):
handle = self.rid_trans.get(str(val))
if handle:
data = self.repository_map[handle]
if data:
repository = Repository()
repository.unserialize(data)
return repository
return None
def get_note_from_gramps_id(self,val):
handle = self.nid_trans.get(str(val))
if handle:
data = self.note_map[handle]
if data:
note = Note()
note.unserialize(data)
return note
return None
def get_object_from_gramps_id(self,val):
handle = self.oid_trans.get(str(val))
if handle:
data = self.media_map[handle]
if data:
obj = MediaObject()
obj.unserialize(data)
return obj
return None
def db_is_changed(self):
"""return True if core data of database has changed in Memory
Note: this excludes most meta-data, you should check that separately
"""
return not self.readonly and \
(len(self.undodb) > 0 or
not self.abort_possible)

View File

@ -1,100 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
#
# 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$
"""
Provides the GRAMPS DB interface for supporting in-memory editing
of GRAMPS XML format.
"""
import logging
log = logging.getLogger(".GrampsDb")
from gen.lib import *
from _GrampsInMemDB import *
from _GrampsDbExceptions import GrampsDbException
from gen.utils import db_copy
#-------------------------------------------------------------------------
#
# GrampsXMLDB
#
#-------------------------------------------------------------------------
class GrampsXMLDB(GrampsInMemDB):
"""GRAMPS database object. This object is a base class for other
objects."""
def __init__(self, use_txn = True):
"""creates a new GrampsDB"""
GrampsInMemDB.__init__(self)
def load(self, name, callback, mode="w"):
if self.db_is_open:
self.close()
GrampsInMemDB.load(self, name, callback, mode)
self.id_trans = {}
try:
from GrampsDbUtils._ReadXML import importData
except:
log.warning("Failed to load XML reader", exc_info=True)
raise GrampsDbException("Failed to load XML reader")
try:
importData(self, name, callback, use_trans=False)
except OSError, IOError:
return 1
self.db_is_open = True
self.abort_possible = True
return 1
def load_from(self, other_database, filename, callback):
self.id_trans = {}
db_copy(other_database,self,callback)
GrampsInMemDB.load(self,filename,callback)
self.db_is_open = True
try:
from GrampsDbUtils._WriteXML import quick_write
except:
log.warning("Failed to load XML writer", exc_info=True)
raise GrampsDbException("Failed to load XML writer")
quick_write(self,self.full_name,callback)
return 1
def close(self):
if not self.db_is_open:
return
try:
from GrampsDbUtils._WriteXML import quick_write
except:
log.warning("Failed to load XML writer", exc_info=True)
raise GrampsDbException("Failed to load XML writer")
if self.db_is_changed() or self.db_has_bm_changes():
quick_write(self,self.full_name)
self.db_is_open = False
GrampsInMemDB.close(self)

View File

@ -1,46 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004-2006 Donald N. Allingham
#
# 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 package implements the GrampsDb database. It provides a number
of different backends for different storage mechanisms.
A number of importers and exporters are provided to convert between
the different backend formats.
To obtain a class that implements the backend required you should use the
gramps_db_factory method, likewise for writers use the gramps_db_writer_factory
method and for readers use the gramps_db_reader_factory method. For information
on using these factories see the _GrampsDbFactories.py file comments.
The package also contains GrampsDBCallback which provides signal/slot type
functionality to allow objects to hook into signals that are generated from
the database objects. Read the comments in _GrampsDBCallback.py for more
information.
"""
from _GrampsDbFactories import gramps_db_factory
from _GrampsDbWriteXML import GrampsDbXmlWriter, \
exportData, quick_write

View File

@ -14,7 +14,10 @@ pkgdata_PYTHON = \
_GedcomStageOne.py\ _GedcomStageOne.py\
_GedcomTokens.py\ _GedcomTokens.py\
_GedcomUtils.py\ _GedcomUtils.py\
_GrampsBSDDB.py\
_GrampsDbWRFactories.py\ _GrampsDbWRFactories.py\
_GrampsDbWriteXML.py\
importdbdir.py\
__init__.py\ __init__.py\
_ReadGedcom.py\ _ReadGedcom.py\
_ReadXML.py\ _ReadXML.py\

View File

@ -47,7 +47,7 @@ __LOG = logging.getLogger(".GrampsDb")
from gen.lib import * from gen.lib import *
from gen.db.base import * from gen.db.base import *
from gen.utils import db_copy from gen.utils import db_copy
import const import gen.db.dbconst as const
from gen.db.exceptions import FileVersionError from gen.db.exceptions import FileVersionError
from BasicUtils import UpdateCallback from BasicUtils import UpdateCallback
@ -398,7 +398,8 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
if self.readonly: if self.readonly:
self.UseTXN = False self.UseTXN = False
callback(12) if callback:
callback(12)
self.full_name = os.path.abspath(name) self.full_name = os.path.abspath(name)
self.brief_name = os.path.basename(name) self.brief_name = os.path.basename(name)
@ -427,7 +428,8 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
if self.UseTXN: if self.UseTXN:
self.env.txn_checkpoint() self.env.txn_checkpoint()
callback(25) if callback:
callback(25)
self.metadata = self.__open_table(self.full_name, "meta") self.metadata = self.__open_table(self.full_name, "meta")
# If we cannot work with this DB version, # If we cannot work with this DB version,
@ -689,71 +691,83 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
self.id_trans.close() self.id_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "idtrans") junk.remove(self.full_name, "idtrans")
callback(1) if callback:
callback(1)
self.surnames.close() self.surnames.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "surnames") junk.remove(self.full_name, "surnames")
callback(2) if callback:
callback(2)
# Repair secondary indices related to family_map # Repair secondary indices related to family_map
self.fid_trans.close() self.fid_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "fidtrans") junk.remove(self.full_name, "fidtrans")
callback(3) if callback:
callback(3)
# Repair secondary indices related to place_map # Repair secondary indices related to place_map
self.pid_trans.close() self.pid_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "pidtrans") junk.remove(self.full_name, "pidtrans")
callback(4) if callback:
callback(4)
# Repair secondary indices related to media_map # Repair secondary indices related to media_map
self.oid_trans.close() self.oid_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "oidtrans") junk.remove(self.full_name, "oidtrans")
callback(5) if callback:
callback(5)
# Repair secondary indices related to source_map # Repair secondary indices related to source_map
self.sid_trans.close() self.sid_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "sidtrans") junk.remove(self.full_name, "sidtrans")
callback(6) if callback:
callback(6)
# Repair secondary indices related to event_map # Repair secondary indices related to event_map
self.eid_trans.close() self.eid_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "eidtrans") junk.remove(self.full_name, "eidtrans")
callback(7) if callback:
callback(7)
# Repair secondary indices related to repository_map # Repair secondary indices related to repository_map
self.rid_trans.close() self.rid_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "ridtrans") junk.remove(self.full_name, "ridtrans")
callback(8) if callback:
callback(8)
# Repair secondary indices related to note_map # Repair secondary indices related to note_map
self.nid_trans.close() self.nid_trans.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "nidtrans") junk.remove(self.full_name, "nidtrans")
callback(9) if callback:
callback(9)
# Repair secondary indices related to reference_map # Repair secondary indices related to reference_map
self.reference_map_primary_map.close() self.reference_map_primary_map.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "reference_map_primary_map") junk.remove(self.full_name, "reference_map_primary_map")
callback(10) if callback:
callback(10)
self.reference_map_referenced_map.close() self.reference_map_referenced_map.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "reference_map_referenced_map") junk.remove(self.full_name, "reference_map_referenced_map")
callback(11) if callback:
callback(11)
# Set flag saying that we have removed secondary indices # Set flag saying that we have removed secondary indices
# and then call the creating routine # and then call the creating routine
self.secondary_connected = False self.secondary_connected = False
self.connect_secondary() self.connect_secondary()
callback(12) if callback:
callback(12)
def find_backlink_handles(self, handle, include_classes=None): def find_backlink_handles(self, handle, include_classes=None):
""" """
@ -966,17 +980,20 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
self.reference_map_referenced_map.close() self.reference_map_referenced_map.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "reference_map_referenced_map") junk.remove(self.full_name, "reference_map_referenced_map")
callback(1) if callback:
callback(1)
self.reference_map_primary_map.close() self.reference_map_primary_map.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "reference_map_primary_map") junk.remove(self.full_name, "reference_map_primary_map")
callback(2) if callback:
callback(2)
self.reference_map.close() self.reference_map.close()
junk = db.DB(self.env) junk = db.DB(self.env)
junk.remove(self.full_name, "reference_map") junk.remove(self.full_name, "reference_map")
callback(3) if callback:
callback(3)
# Open reference_map and primapry map # Open reference_map and primapry map
self.reference_map = self.__open_table(self.full_name, "reference_map", self.reference_map = self.__open_table(self.full_name, "reference_map",
@ -1014,7 +1031,8 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
} }
transaction = self.transaction_begin(batch=True, no_magic=True) transaction = self.transaction_begin(batch=True, no_magic=True)
callback(4) if callback:
callback(4)
# Now we use the functions and classes defined above # Now we use the functions and classes defined above
# to loop through each of the primary object tables. # to loop through each of the primary object tables.
@ -1044,7 +1062,8 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
data = cursor.next() data = cursor.next()
cursor.close() cursor.close()
callback(5) if callback:
callback(5)
self.transaction_commit(transaction, _("Rebuild reference map")) self.transaction_commit(transaction, _("Rebuild reference map"))
self.reference_map_referenced_map = db.DB(self.env) self.reference_map_referenced_map = db.DB(self.env)
@ -1054,7 +1073,8 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
db.DB_BTREE, flags=open_flags) db.DB_BTREE, flags=open_flags)
self.reference_map.associate(self.reference_map_referenced_map, self.reference_map.associate(self.reference_map_referenced_map,
find_referenced_handle, open_flags) find_referenced_handle, open_flags)
callback(6) if callback:
callback(6)
return return

View File

@ -42,6 +42,7 @@ log = logging.getLogger(".GrampDb")
from gen.db import GrampsDbException from gen.db import GrampsDbException
from PluginUtils import import_list
def gramps_db_writer_factory(db_type): def gramps_db_writer_factory(db_type):
@ -54,10 +55,7 @@ def gramps_db_writer_factory(db_type):
Raises GrampsDbException if the db_type is not recognised. Raises GrampsDbException if the db_type is not recognised.
""" """
if db_type == const.APP_GRAMPS: if db_type == const.APP_GRAMPS_XML:
import _WriteGrdb as WriteGrdb
md = WriteGrdb.exportData
elif db_type == const.APP_GRAMPS_XML:
import _WriteXML as WriteXML import _WriteXML as WriteXML
md = WriteXML.exportData md = WriteXML.exportData
elif db_type == const.APP_GEDCOM: elif db_type == const.APP_GEDCOM:
@ -71,24 +69,35 @@ def gramps_db_writer_factory(db_type):
return md return md
def gramps_db_reader_factory(db_type): def gramps_db_reader_factory(db_type):
"""Factory class for obtaining a Gramps database writers. """Factory class for obtaining a Gramps database importers.
@param db_type: the type of backend required. @param db_type: the type of backend required.
@type db_type: one of the app_* constants in const.py @type db_type: one of the app_* constants in const.py
Raises GrampsDbException if the db_type is not recognised. Raises GrampsDbException if the db_type is not recognised.
""" """
if db_type == const.APP_FAMTREE :
if db_type == const.APP_GRAMPS_XML: import importdbdir
md = importdbdir.importData
elif db_type == const.APP_GRAMPS_XML:
import _ReadXML as ReadXML import _ReadXML as ReadXML
md = ReadXML.importData md = ReadXML.importData
elif db_type == const.APP_GEDCOM: elif db_type == const.APP_GEDCOM:
import _ReadGedcom as ReadGedcom import _ReadGedcom as ReadGedcom
md = ReadGedcom.importData md = ReadGedcom.importData
else: else:
raise GrampsDbException("Attempt to create a database " #see if registered importer
"reader for unknown format: " found = False
"db_type = %s" % (str(db_type),)) for data in import_list:
if db_type == data[2]:
print "Found import plugin for %s" % data[4]
found = True
md = data[0]
break
if not found:
raise GrampsDbException("Attempt to create a database "
"reader for unknown format: "
"db_type = %s" % (str(db_type),))
return md return md

View File

@ -35,7 +35,7 @@ from gettext import gettext as _
# Gramps Modules # Gramps Modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from GrampsDb._GrampsBSDDB import GrampsBSDDB from GrampsDbUtils._GrampsBSDDB import GrampsBSDDB
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from gen.utils import db_copy from gen.utils import db_copy

View File

@ -40,8 +40,9 @@ from gettext import gettext as _
import const import const
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
import GrampsDb import GrampsDbUtils
import ExportOptions import ExportOptions
from gen.db.exceptions import GrampsDbWriteFailure
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -52,7 +53,7 @@ def export_data(database, filename, person, option_box, callback=None):
""" """
Calls the XML writer with the syntax expected by the export plugin Calls the XML writer with the syntax expected by the export plugin
""" """
return GrampsDb.exportData(database, filename, person, option_box, return GrampsDbUtils.exportData(database, filename, person, option_box,
callback, const.VERSION) callback, const.VERSION)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -60,13 +61,13 @@ def export_data(database, filename, person, option_box, callback=None):
# XmlWriter # XmlWriter
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class XmlWriter(GrampsDb.GrampsDbXmlWriter): class XmlWriter(GrampsDbUtils.GrampsDbXmlWriter):
""" """
Writes a database to the XML file. Writes a database to the XML file.
""" """
def __init__(self, dbase, callback, strip_photos, compress=1): def __init__(self, dbase, callback, strip_photos, compress=1):
GrampsDb.GrampsDbXmlWriter.__init__( GrampsDbUtils.GrampsDbXmlWriter.__init__(
self, dbase, strip_photos, compress, const.VERSION, callback) self, dbase, strip_photos, compress, const.VERSION, callback)
def write(self, filename): def write(self, filename):
@ -74,8 +75,8 @@ class XmlWriter(GrampsDb.GrampsDbXmlWriter):
Write the database to the specified file. Write the database to the specified file.
""" """
try: try:
ret = GrampsDb.GrampsDbXmlWriter.write(self, filename) ret = GrampsDbUtils.GrampsDbXmlWriter.write(self, filename)
except GrampsDb.GrampsDbWriteFailure, val: except GrampsDbWriteFailure, val:
ErrorDialog(val[0], val[1]) ErrorDialog(val[0], val[1])
return ret return ret
@ -85,8 +86,8 @@ class XmlWriter(GrampsDb.GrampsDbXmlWriter):
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
TITLE = _('GRAMPS _XML database') TITLE = _('GRAMPS _XML database')
DESCRIPTION = _('The GRAMPS XML database is a format used by older ' DESCRIPTION = _('The GRAMPS XML database is a text version of a family tree. '
'versions of GRAMPS. It is read-write compatible with ' 'It is read-write compatible with '
'the present GRAMPS database format.') 'the present GRAMPS database format.')
CONFIG = (_('GRAMPS XML export options'), ExportOptions.WriterOptionBox) CONFIG = (_('GRAMPS XML export options'), ExportOptions.WriterOptionBox)
FILENAME = 'gramps' FILENAME = 'gramps'

View File

@ -45,10 +45,9 @@ from _GrampsDbWRFactories import \
from _GedcomParse import GedcomParser from _GedcomParse import GedcomParser
from _WriteGedcom import GedcomWriter from _WriteGedcom import GedcomWriter
from _GrampsDbWriteXML import GrampsDbXmlWriter, \
exportData, quick_write
from _WriteXML import XmlWriter from _WriteXML import XmlWriter
import _Backup as Backup import _Backup as Backup
#from _PrivateProxyDb import PrivateProxyDb
#from _LivingProxyDb import LivingProxyDb

View File

@ -0,0 +1,288 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2005-2007 Donald N. Allingham
# Copyright (C) 2007 B. Malengier
#
# 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: $
# Based on ReadGrdb of version 2.x
#-------------------------------------------------------------------------
#
# Standard Python Modules
#
#-------------------------------------------------------------------------
import os
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
from gen.db import GrampsDBDir
from QuestionDialog import ErrorDialog
from Errors import HandleError
from BasicUtils import UpdateCallback
from BasicUtils import name_displayer
#-------------------------------------------------------------------------
#
# Importing data into the currently open database.
#
#-------------------------------------------------------------------------
def importData(database, dirname, callback=None, cl=0, use_trans=True):
'''
Import dbdir database in dirname into dbdir database.
'''
name = os.path.normpath(dirname)
other_database = GrampsDBDir()
try:
other_database.load(name, callback)
except:
if cl:
print "Error: %s could not be opened. Exiting." % filename
else:
ErrorDialog(_("%s could not be opened") % filename)
return
if not other_database.version_supported():
if cl:
print "Error: %s could not be opened.\n%s Exiting." \
% (filename,
_("The database version is not supported "
"by this version of GRAMPS.\n"\
"Please upgrade to the corresponding version "
"or use XML for porting data between different "
"database versions."))
else:
ErrorDialog(_("%s could not be opened") % filename,
_("The Database version is not supported "
"by this version of GRAMPS."))
return
# If other_database contains its custom name formats,
# we need to do tricks to remap the format numbers
if len(other_database.name_formats) > 0:
formats_map = remap_name_formats(database, other_database)
name_displayer.set_name_format(database.name_formats)
get_person = make_peron_name_remapper(other_database, formats_map)
else:
# No remapping necessary, proceed as usual
get_person = other_database.get_person_from_handle
# Prepare table and method definitions
tables = {
'Person' : {'table' : database.person_map,
'id_table' : database.id_trans,
'add_obj' : database.add_person,
'find_next_gramps_id' :database.find_next_person_gramps_id,
'other_get_from_handle':
get_person,
'other_table': other_database.person_map,
},
'Family' : {'table' : database.family_map,
'id_table' : database.fid_trans,
'add_obj' : database.add_family,
'find_next_gramps_id' :database.find_next_family_gramps_id,
'other_get_from_handle':
other_database.get_family_from_handle,
'other_table': other_database.family_map,
},
'Event' : {'table' : database.event_map,
'id_table' : database.eid_trans,
'add_obj' : database.add_event,
'find_next_gramps_id' : database.find_next_event_gramps_id,
'other_get_from_handle':
other_database.get_event_from_handle,
'other_table': other_database.event_map,
},
'Source' : {'table' : database.source_map,
'id_table' : database.sid_trans,
'add_obj' : database.add_source,
'find_next_gramps_id': database.find_next_source_gramps_id,
'other_get_from_handle':
other_database.get_source_from_handle,
'other_table': other_database.source_map,
},
'Place' : {'table' : database.place_map,
'id_table' : database.pid_trans,
'add_obj' : database.add_place,
'find_next_gramps_id' :database.find_next_place_gramps_id,
'other_get_from_handle':
other_database.get_place_from_handle,
'other_table': other_database.place_map,
},
'Media' : {'table' : database.media_map,
'id_table' : database.oid_trans,
'add_obj' : database.add_object,
'find_next_gramps_id' : database.find_next_object_gramps_id,
'other_get_from_handle':
other_database.get_object_from_handle,
'other_table': other_database.media_map,
},
'Repository' : {'table' : database.repository_map,
'id_table' : database.rid_trans,
'add_obj' : database.add_repository,
'find_next_gramps_id' :
database.find_next_repository_gramps_id,
'other_get_from_handle':
other_database.get_repository_from_handle,
'other_table': other_database.repository_map,
},
'Note' : {'table': database.note_map,
'id_table': database.nid_trans,
'add_obj': database.add_note,
'find_next_gramps_id': database.find_next_note_gramps_id,
'other_get_from_handle':
other_database.get_note_from_handle,
'other_table': other_database.note_map,
},
}
uc = UpdateCallback(callback)
uc.set_total(len(tables.keys()))
the_len = 0
# Check for duplicate handles.
for key in tables:
table_dict = tables[key]
table = table_dict['table']
other_table = table_dict['other_table']
msg = '%s handles in two databases overlap.' % key
the_len += check_common_handles(table, other_table, msg)
uc.update()
# Proceed with preparing for import
if use_trans:
trans = database.transaction_begin("", batch=True)
else:
print "Transaction is None! This is no way to go!"
trans = None
database.disable_signals()
# copy all data from new_database to database,
# rename gramps IDs of first-class objects when conflicts are found
uc.set_total(the_len)
for key in tables:
table_dict = tables[key]
id_table = table_dict['id_table']
add_obj = table_dict['add_obj']
find_next_gramps_id = table_dict['find_next_gramps_id']
other_table = table_dict['other_table']
other_get_from_handle = table_dict['other_get_from_handle']
import_table(id_table, add_obj, find_next_gramps_id,
other_table, other_get_from_handle, trans, uc)
# Copy bookmarks over:
# we already know that there's no overlap in handles anywhere
database.bookmarks.append_list(other_database.bookmarks.get())
database.family_bookmarks.append_list(other_database.family_bookmarks.get())
database.event_bookmarks.append_list(other_database.event_bookmarks.get())
database.source_bookmarks.append_list(other_database.source_bookmarks.get())
database.place_bookmarks.append_list(other_database.place_bookmarks.get())
database.media_bookmarks.append_list(other_database.media_bookmarks.get())
database.repo_bookmarks.append_list(other_database.repo_bookmarks.get())
database.note_bookmarks.append_list(other_database.note_bookmarks.get())
# Copy grouping table
group_map = other_database.get_name_group_keys()
name_len = len(group_map)
if name_len > 0:
for key in group_map:
value = other_database.get_name_group_mapping(key)
if database.has_name_group_key(key) :
present = database.get_name_group_mapping(key)
if not value == present:
msg = _("Your family tree groups name %s together"
" with %s, did not change this grouping to %s") % (
key, present, value)
print msg
else:
database.set_name_group_mapping(key, value)
# close the other database and clean things up
other_database.close()
database.transaction_commit(trans, _("Import database"))
database.enable_signals()
database.request_rebuild()
def check_common_handles(table, other_table, msg):
# Check for duplicate handles. At the moment we simply exit here,
# before modifying any data. In the future we will need to handle
# this better. How?
handles = set(table.keys())
other_handles = set(other_table.keys())
if handles.intersection(other_handles):
raise HandleError(msg)
return len(other_handles)
def import_table(id_table, add_obj, find_next_gramps_id,
other_table, other_get_from_handle, trans, uc):
for handle in other_table.keys():
obj = other_get_from_handle(handle)
# Then we check gramps_id for conflicts and change it if needed
gramps_id = str(obj.gramps_id)
if id_table.has_key(gramps_id):
gramps_id = find_next_gramps_id()
obj.gramps_id = gramps_id
add_obj(obj, trans)
uc.update()
def remap_name_formats(database, other_database):
formats_map = {}
taken_numbers = [num for (num, name, fmt_str, active)
in database.name_formats]
for (number, name, fmt_str, act) in other_database.name_formats:
if number in taken_numbers:
new_number = -1
while new_number in taken_numbers:
new_number -= 1
taken_numbers.append(new_number)
formats_map[number] = new_number
else:
new_number = number
database.name_formats.append((new_number, name, fmt_str, act))
return formats_map
def remap_name(person, formats_map):
for name in [person.primary_name] + person.alternate_names:
try:
name.sort_as = formats_map[name.sort_as]
except KeyError:
pass
try:
name.display_as = formats_map[name.display_as]
except KeyError:
pass
def make_peron_name_remapper(other_database, formats_map):
def new_get_person(handle):
person = other_database.get_person_from_handle(handle)
remap_name(person, formats_map)
return person
return new_get_person

View File

@ -10,7 +10,6 @@ SUBDIRS = \
Filters \ Filters \
FilterEditor \ FilterEditor \
gen \ gen \
GrampsDb \
GrampsDbUtils \ GrampsDbUtils \
GrampsLocale \ GrampsLocale \
Merge \ Merge \

View File

@ -345,61 +345,3 @@ class ObjectSelectorWindow(gtk.Window,ManagedWindow):
if gtk.pygtk_version < (2,8,0): if gtk.pygtk_version < (2,8,0):
gobject.type_register(ObjectSelectorWindow) gobject.type_register(ObjectSelectorWindow)
if __name__ == "__main__":
import GrampsDb
import ViewManager
import const
import logging
import sys,os.path
form = logging.Formatter(fmt="%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s")
stderrh = logging.StreamHandler(sys.stderr)
stderrh.setFormatter(form)
stderrh.setLevel(logging.DEBUG)
# everything.
l = logging.getLogger()
l.setLevel(logging.DEBUG)
l.addHandler(stderrh)
def cb(d):
pass
state = GrampsDb.DbState()
vm = ViewManager.ViewManager(state)
db = GrampsDb.gramps_db_factory(const.APP_GRAMPS)()
db.load(os.path.realpath(sys.argv[1]),
cb, # callback
"w")
class D:
pass
dbstate = D()
dbstate.db = db
def prof_fun():
global dbstate, vm
w = ObjectSelectorWindow(dbstate=dbstate,
uistate=vm.uistate,
track=[],
filter_spec=None,
default_object_type = ObjectTypes.PERSON,
object_list=[ObjectTypes.PERSON,])
#object_list=[ObjectTypes.PERSON,ObjectTypes.FAMILY])
w.show()
w.connect("destroy", gtk.main_quit)
def add(w,results):
print str(results)
w.connect('add-object',add)
gtk.main()
prof_fun()
import profile
profile.run("prof_fun()",'profile.dat')

View File

@ -44,7 +44,7 @@ import const
# Constants # Constants
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
GRAMPS_FILENAME = os.path.join(const.HOME_DIR,"recent-files.xml") GRAMPS_FILENAME = os.path.join(const.HOME_DIR,"recent-files-gramps.xml")
MAX_GRAMPS_ITEMS = 10 MAX_GRAMPS_ITEMS = 10
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -242,7 +242,7 @@ class RecentParser:
# Helper functions # Helper functions
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def recent_files(filename,name): def recent_files(filename, name):
""" """
Add an entry to both GNOME and GRAMPS recent-items storages. Add an entry to both GNOME and GRAMPS recent-items storages.
""" """

View File

@ -186,6 +186,8 @@ UIDEFAULT = '''<ui>
<accelerator action="<CONTROL>J"/> <accelerator action="<CONTROL>J"/>
<accelerator action="<Alt>N"/> <accelerator action="<Alt>N"/>
<accelerator action="<Alt>P"/> <accelerator action="<Alt>P"/>
<accelerator action="<Alt>Left"/>
<accelerator action="<Alt>Right"/>
</ui> </ui>
''' '''
@ -416,9 +418,7 @@ class ViewManager:
self.tip_of_day_activate), self.tip_of_day_activate),
] ]
self._readonly_action_list = [ self._readonly_action_list = [
('SaveAs', gtk.STOCK_SAVE_AS, _('_Save As'), "<control><shift>s",
None, self.__save_as_activate),
('Export', 'gramps-export', _('_Export'), "<control>e", None, ('Export', 'gramps-export', _('_Export'), "<control>e", None,
self.export_data), self.export_data),
('Abandon', gtk.STOCK_REVERT_TO_SAVED, ('Abandon', gtk.STOCK_REVERT_TO_SAVED,
@ -447,7 +447,11 @@ class ViewManager:
('<CONTROL>J', None, '<CONTROL>J', ('<CONTROL>J', None, '<CONTROL>J',
"<CONTROL>J", None, self.__keypress), "<CONTROL>J", None, self.__keypress),
('<Alt>N', None, '<Alt>N', "<Alt>N", None, self.__next_view), ('<Alt>N', None, '<Alt>N', "<Alt>N", None, self.__next_view),
('<Alt>P', None, '<Alt>P', "<Alt>P", None, self.__prev_view), ('<Alt>P', None, '<Alt>P', "<Alt>P", None, self.__prev_view),
('<Alt>Left', None, '<Alt>Left', "<Alt>Left", None,
self.__prev_view),
('<Alt>Right', None, '<Alt>Right', "<Alt>Right", None,
self.__next_view),
] ]
self._action_action_list = [ self._action_action_list = [
@ -566,13 +570,13 @@ class ViewManager:
if self.filter_menu.get_active() != Config.get(Config.FILTER): if self.filter_menu.get_active() != Config.get(Config.FILTER):
self.filter_menu.set_active(Config.get(Config.FILTER)) self.filter_menu.set_active(Config.get(Config.FILTER))
def post_init_interface(self): def post_init_interface(self, show_manager=True):
""" """
Showing the main window is deferred so that Showing the main window is deferred so that
ArgHandler can work without it always shown ArgHandler can work without it always shown
""" """
self.window.show() self.window.show()
if not self.state.db.is_open(): if not self.state.db.is_open() and show_manager:
self.__open_activate(None) self.__open_activate(None)
def post_load_newdb(self, filename, filetype): def post_load_newdb(self, filename, filetype):
@ -1044,98 +1048,34 @@ class ViewManager:
if self.state.db.is_open(): if self.state.db.is_open():
self.db_loader.import_file() self.db_loader.import_file()
self.__post_load() self.__post_load()
def open_activate(self, path):
"""
Open and make a family tree active
"""
self.__read_recent_file(path)
def __open_activate(self, obj): def __open_activate(self, obj):
""" """
Called when the Open button is clicked Called when the Open button is clicked, opens the DbManager
""" """
import DbManager import DbManager
dialog = DbManager.DbManager(self.state, self.window) dialog = DbManager.DbManager(self.state, self.window)
value = dialog.run() value = dialog.run()
if value: if value:
(filename, title) = value (filename, title) = value
self.read_file(filename, 'x-directory/normal') self.db_loader.read_file(filename)
try: try:
os.chdir(os.path.dirname(filename)) os.chdir(os.path.dirname(filename))
except (IOError, OSError): except (IOError, OSError):
pass pass
self.__post_load_newdb(filename, 'x-directory/normal', title) self.__post_load_newdb(filename, 'x-directory/normal', title)
def read_file(self, filename, filetype):
"""
This method takes care of changing database, and loading the data.
This method should only return on success.
Returning on failure makes no sense, because we cannot recover,
since database has already beeen changed.
Therefore, any errors should raise exceptions.
On success, return with the disabled signals. The post-load routine
should enable signals, as well as finish up with other UI goodies.
"""
if os.path.exists(filename):
if not os.access(filename, os.W_OK):
mode = "r"
QuestionDialog.WarningDialog(_('Read only database'),
_('You do not have write access '
'to the selected file.'))
else:
mode = "w"
elif filetype == 'unknown':
QuestionDialog.WarningDialog(
_('Missing or Invalid database'),
_('%s could not be found.\n'
'It is possible that this file no longer exists '
'or has been moved.') % filename)
return False
else:
mode = 'w'
try:
dbclass = gen.db.dbdir.GrampsDBDir
except gen.db.exceptions.GrampsDbException, msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
_("This may be caused by an improper installation of GRAMPS.") +
"\n" + str(msg))
return
self.state.change_database(dbclass(Config.get(Config.TRANSACTIONS)))
self.state.db.disable_signals()
self.uistate.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
self.uistate.progress.show()
try:
self.state.db.load(filename, self.uistate.pulse_progressbar, mode)
self.state.db.set_save_path(filename)
try:
os.chdir(os.path.dirname(filename))
except (OSError, IOError):
print "could not change directory"
except Errors.DbError, msg:
QuestionDialog.DBErrorDialog(str(msg.value))
self.state.no_database()
except Exception:
LOG.error("Failed to open database.", exc_info=True)
return True
def __save_as_activate(self, obj):
"""
Called when the SaveAs button is clicked
"""
if self.state.db.is_open():
(filename, filetype) = self.db_loader.save_as()
self.__post_load_newdb(filename, filetype)
def __read_recent_file(self, filename): def __read_recent_file(self, filename):
""" """
Called when the recent file is loaded Called when the recent file is loaded
""" """
if self.db_loader.read_file(filename, 'x-directory/normal'): if self.db_loader.read_file(filename):
# Attempt to figure out the database title # Attempt to figure out the database title
path = os.path.join(filename, "name.txt") path = os.path.join(filename, "name.txt")
try: try:

View File

@ -45,7 +45,6 @@ import gtk
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import ViewManager import ViewManager
import GrampsDb
import ArgHandler import ArgHandler
import Config import Config
import const import const
@ -249,10 +248,12 @@ class Gramps:
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() retval = ah.handle_args()
self.vm.post_init_interface()
if retval: if retval:
filename, filetype = retval filename, filetype = retval
self.vm.post_load_newdb(filename, filetype) self.vm.post_init_interface(show_manager=False)
self.vm.open_activate(filename)
else:
self.vm.post_init_interface()
else: else:
ah.handle_args() ah.handle_args()
self.vm.post_init_interface() self.vm.post_init_interface()

View File

@ -46,7 +46,6 @@ import gtk.glade
# gramps modules # gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import GrampsDb
import GrampsDbUtils import GrampsDbUtils
import Utils import Utils
import GrampsDisplay import GrampsDisplay

View File

@ -45,7 +45,7 @@ import gtk
# Gramps Modules # Gramps Modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from GrampsDb._GrampsBSDDB import GrampsBSDDB from GrampsDbUtils._GrampsBSDDB import GrampsBSDDB
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from Errors import HandleError from Errors import HandleError
from BasicUtils import UpdateCallback from BasicUtils import UpdateCallback