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:
parent
5ea0cd4b3e
commit
dc9f03b6c0
25
ChangeLog
25
ChangeLog
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
162
src/DbLoader.py
162
src/DbLoader.py
@ -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()
|
||||||
|
243
src/DbManager.py
243
src/DbManager.py
@ -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):
|
||||||
"""
|
"""
|
||||||
|
@ -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));
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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\
|
||||||
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
288
src/GrampsDbUtils/importdbdir.py
Normal file
288
src/GrampsDbUtils/importdbdir.py
Normal 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
|
@ -10,7 +10,6 @@ SUBDIRS = \
|
|||||||
Filters \
|
Filters \
|
||||||
FilterEditor \
|
FilterEditor \
|
||||||
gen \
|
gen \
|
||||||
GrampsDb \
|
|
||||||
GrampsDbUtils \
|
GrampsDbUtils \
|
||||||
GrampsLocale \
|
GrampsLocale \
|
||||||
Merge \
|
Merge \
|
||||||
|
@ -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')
|
|
||||||
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
@ -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:
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user