2007-06-22 Don Allingham <don@gramps-project.org>
* src/DbManager.py: pylint fixes * src/glade/gramps.glade: widen with DbManager window svn: r8634
This commit is contained in:
parent
7edd3be9c3
commit
9fc7370400
@ -1,3 +1,7 @@
|
|||||||
|
2007-06-22 Don Allingham <don@gramps-project.org>
|
||||||
|
* src/DbManager.py: pylint fixes
|
||||||
|
* src/glade/gramps.glade: widen with DbManager window
|
||||||
|
|
||||||
2007-06-23 Brian Matherly <brian@gramps-project.org>
|
2007-06-23 Brian Matherly <brian@gramps-project.org>
|
||||||
* src/plugins/NarrativeWeb.py: 0001016: [narrative website] Why is the mime
|
* src/plugins/NarrativeWeb.py: 0001016: [narrative website] Why is the mime
|
||||||
type shown on each image page
|
type shown on each image page
|
||||||
|
161
src/DbManager.py
161
src/DbManager.py
@ -45,9 +45,9 @@ import logging
|
|||||||
LOG = logging.getLogger(".DbManager")
|
LOG = logging.getLogger(".DbManager")
|
||||||
|
|
||||||
if os.sys.platform == "win32":
|
if os.sys.platform == "win32":
|
||||||
_rcs_found = os.system("rcs -V >nul 2>nul") == 0
|
RCS_FOUND = os.system("rcs -V >nul 2>nul") == 0
|
||||||
else:
|
else:
|
||||||
_rcs_found = os.system("rcs -V >/dev/null 2>/dev/null") == 0
|
RCS_FOUND = os.system("rcs -V >/dev/null 2>/dev/null") == 0
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -56,6 +56,7 @@ else:
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
import gtk
|
import gtk
|
||||||
import gtk.glade
|
import gtk.glade
|
||||||
|
import pango
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -87,6 +88,8 @@ DSORT_COL = 4
|
|||||||
OPEN_COL = 5
|
OPEN_COL = 5
|
||||||
STOCK_COL = 6
|
STOCK_COL = 6
|
||||||
|
|
||||||
|
RCS_BUTTON = { True : _('Extract'), False : _('Archive') }
|
||||||
|
|
||||||
class DbManager:
|
class DbManager:
|
||||||
"""
|
"""
|
||||||
Database Manager. Opens a database manager window that allows users to
|
Database Manager. Opens a database manager window that allows users to
|
||||||
@ -115,6 +118,7 @@ class DbManager:
|
|||||||
self.model = None
|
self.model = None
|
||||||
self.dbstate = dbstate
|
self.dbstate = dbstate
|
||||||
self.column = None
|
self.column = None
|
||||||
|
self.lock_file = None
|
||||||
self.data_to_delete = None
|
self.data_to_delete = None
|
||||||
|
|
||||||
if dbstate:
|
if dbstate:
|
||||||
@ -138,7 +142,7 @@ class DbManager:
|
|||||||
self.new.connect('clicked', self.__new_db)
|
self.new.connect('clicked', self.__new_db)
|
||||||
self.rename.connect('clicked', self.__rename_db)
|
self.rename.connect('clicked', self.__rename_db)
|
||||||
self.repair.connect('clicked', self.__repair_db)
|
self.repair.connect('clicked', self.__repair_db)
|
||||||
if _rcs_found:
|
if RCS_FOUND:
|
||||||
self.rcs.connect('clicked', self.__rcs)
|
self.rcs.connect('clicked', self.__rcs)
|
||||||
self.selection.connect('changed', self.__selection_changed)
|
self.selection.connect('changed', self.__selection_changed)
|
||||||
self.dblist.connect('button-press-event', self.__button_press)
|
self.dblist.connect('button-press-event', self.__button_press)
|
||||||
@ -186,19 +190,16 @@ class DbManager:
|
|||||||
|
|
||||||
is_rev = len(self.model.get_path(node)) > 1
|
is_rev = len(self.model.get_path(node)) > 1
|
||||||
|
|
||||||
if is_rev:
|
self.rcs.set_label(RCS_BUTTON[is_rev])
|
||||||
self.rcs.set_label(_("Extract"))
|
|
||||||
else:
|
|
||||||
self.rcs.set_label(_("Archive"))
|
|
||||||
self.rename.set_sensitive(True)
|
self.rename.set_sensitive(True)
|
||||||
|
|
||||||
if store.get_value(node, STOCK_COL) == gtk.STOCK_OPEN:
|
if store.get_value(node, STOCK_COL) == gtk.STOCK_OPEN:
|
||||||
self.connect.set_sensitive(False)
|
self.connect.set_sensitive(False)
|
||||||
if _rcs_found:
|
if RCS_FOUND:
|
||||||
self.rcs.show()
|
self.rcs.show()
|
||||||
else:
|
else:
|
||||||
self.connect.set_sensitive(not is_rev)
|
self.connect.set_sensitive(not is_rev)
|
||||||
if _rcs_found and is_rev:
|
if RCS_FOUND and is_rev:
|
||||||
self.rcs.show()
|
self.rcs.show()
|
||||||
else:
|
else:
|
||||||
self.rcs.hide()
|
self.rcs.hide()
|
||||||
@ -233,10 +234,13 @@ class DbManager:
|
|||||||
# build the database name column
|
# build the database name column
|
||||||
render = gtk.CellRendererText()
|
render = gtk.CellRendererText()
|
||||||
render.set_property('editable', True)
|
render.set_property('editable', True)
|
||||||
|
render.set_property('ellipsize', pango.ELLIPSIZE_END)
|
||||||
render.connect('edited', self.__change_name)
|
render.connect('edited', self.__change_name)
|
||||||
self.column = gtk.TreeViewColumn(_('Family tree name'), render,
|
self.column = gtk.TreeViewColumn(_('Family tree name'), render,
|
||||||
text=NAME_COL)
|
text=NAME_COL)
|
||||||
self.column.set_sort_column_id(NAME_COL)
|
self.column.set_sort_column_id(NAME_COL)
|
||||||
|
self.column.set_resizable(True)
|
||||||
|
self.column.set_min_width(275)
|
||||||
self.dblist.append_column(self.column)
|
self.dblist.append_column(self.column)
|
||||||
|
|
||||||
# build the icon column
|
# build the icon column
|
||||||
@ -264,11 +268,7 @@ class DbManager:
|
|||||||
|
|
||||||
dbdir = os.path.expanduser(Config.get(Config.DATABASE_PATH))
|
dbdir = os.path.expanduser(Config.get(Config.DATABASE_PATH))
|
||||||
|
|
||||||
try:
|
make_dbdir(dbdir)
|
||||||
if not os.path.isdir(dbdir):
|
|
||||||
os.makedirs(dbdir)
|
|
||||||
except (IOError, OSError), msg:
|
|
||||||
LOG.error(_("Could not make database directory: ") + str(msg))
|
|
||||||
|
|
||||||
self.current_names = []
|
self.current_names = []
|
||||||
|
|
||||||
@ -283,13 +283,7 @@ class DbManager:
|
|||||||
self.dbstate.db.is_open())
|
self.dbstate.db.is_open())
|
||||||
|
|
||||||
if (stock_id == 'gramps-lock'):
|
if (stock_id == 'gramps-lock'):
|
||||||
try:
|
last = find_locker_name(dirpath)
|
||||||
fname = os.path.join(dirpath, "lock")
|
|
||||||
f = open(fname)
|
|
||||||
last = f.read().strip()
|
|
||||||
f.close()
|
|
||||||
except:
|
|
||||||
last = _("Unknown")
|
|
||||||
|
|
||||||
self.current_names.append(
|
self.current_names.append(
|
||||||
(name, os.path.join(dbdir, dpath), path_name,
|
(name, os.path.join(dbdir, dpath), path_name,
|
||||||
@ -321,6 +315,10 @@ class DbManager:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def __ask_to_break_lock(self, store, node):
|
def __ask_to_break_lock(self, store, node):
|
||||||
|
"""
|
||||||
|
Prompts the user for permission to break the lock file that another
|
||||||
|
process has set on the file.
|
||||||
|
"""
|
||||||
path = store.get_path(node)
|
path = store.get_path(node)
|
||||||
self.lock_file = store[path][PATH_COL]
|
self.lock_file = store[path][PATH_COL]
|
||||||
|
|
||||||
@ -336,6 +334,10 @@ class DbManager:
|
|||||||
self.__really_break_lock)
|
self.__really_break_lock)
|
||||||
|
|
||||||
def __really_break_lock(self):
|
def __really_break_lock(self):
|
||||||
|
"""
|
||||||
|
Deletes the lock file associated with the selected database, then updates
|
||||||
|
the display appropriately.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
os.unlink(os.path.join(self.lock_file, "lock"))
|
os.unlink(os.path.join(self.lock_file, "lock"))
|
||||||
store, node = self.selection.get_selected()
|
store, node = self.selection.get_selected()
|
||||||
@ -346,7 +348,7 @@ class DbManager:
|
|||||||
store.set_value(node, DATE_COL, last)
|
store.set_value(node, DATE_COL, last)
|
||||||
store.set_value(node, DSORT_COL, tval)
|
store.set_value(node, DSORT_COL, tval)
|
||||||
except:
|
except:
|
||||||
pass
|
return
|
||||||
|
|
||||||
def __change_name(self, text, path, new_text):
|
def __change_name(self, text, path, new_text):
|
||||||
"""
|
"""
|
||||||
@ -363,6 +365,13 @@ class DbManager:
|
|||||||
self.__rename_database(path, new_text)
|
self.__rename_database(path, new_text)
|
||||||
|
|
||||||
def __rename_revision(self, path, new_text):
|
def __rename_revision(self, path, new_text):
|
||||||
|
"""
|
||||||
|
Renames the RCS revision using the rcs command. The rcs command
|
||||||
|
is in the format of:
|
||||||
|
|
||||||
|
rcs -mREV:NEW_NAME archive
|
||||||
|
|
||||||
|
"""
|
||||||
node = self.model.get_iter(path)
|
node = self.model.get_iter(path)
|
||||||
db_dir = self.model.get_value(node, FILE_COL)
|
db_dir = self.model.get_value(node, FILE_COL)
|
||||||
rev = self.model.get_value(node, PATH_COL)
|
rev = self.model.get_value(node, PATH_COL)
|
||||||
@ -388,6 +397,9 @@ class DbManager:
|
|||||||
self.model.set_value(node, NAME_COL, new_text)
|
self.model.set_value(node, NAME_COL, new_text)
|
||||||
|
|
||||||
def __rename_database(self, path, new_text):
|
def __rename_database(self, path, new_text):
|
||||||
|
"""
|
||||||
|
Renames the database by writing the new value to the name.txt file
|
||||||
|
"""
|
||||||
node = self.model.get_iter(path)
|
node = self.model.get_iter(path)
|
||||||
filename = self.model.get_value(node, FILE_COL)
|
filename = self.model.get_value(node, FILE_COL)
|
||||||
try:
|
try:
|
||||||
@ -401,6 +413,11 @@ class DbManager:
|
|||||||
str(msg))
|
str(msg))
|
||||||
|
|
||||||
def __rcs(self, obj):
|
def __rcs(self, obj):
|
||||||
|
"""
|
||||||
|
Callback for the RCS button. If the tree path is > 1, then we are
|
||||||
|
on an RCS revision, in which case we can check out. If not, then
|
||||||
|
we can only check in.
|
||||||
|
"""
|
||||||
store, node = self.selection.get_selected()
|
store, node = self.selection.get_selected()
|
||||||
tree_path = store.get_path(node)
|
tree_path = store.get_path(node)
|
||||||
if len(tree_path) > 1:
|
if len(tree_path) > 1:
|
||||||
@ -410,26 +427,33 @@ class DbManager:
|
|||||||
revision = store.get_value(node, PATH_COL)
|
revision = store.get_value(node, PATH_COL)
|
||||||
db_path = store.get_value(node, FILE_COL)
|
db_path = store.get_value(node, FILE_COL)
|
||||||
|
|
||||||
new_path = self.__create_new_db("%s : %s" % (parent_name, name))
|
self.__checkout_copy(parent_name, name, revision, db_path)
|
||||||
trans = Config.TRANSACTIONS
|
|
||||||
dbtype = 'x-directory/normal'
|
|
||||||
|
|
||||||
self.__start_cursor(_("Extracting archive..."))
|
|
||||||
db = GrampsDb.gramps_db_factory(dbtype)(trans)
|
|
||||||
db.load(new_path, None)
|
|
||||||
|
|
||||||
self.__start_cursor(_("Importing archive..."))
|
|
||||||
check_out(db, revision, db_path, name, None)
|
|
||||||
self.__end_cursor()
|
|
||||||
db.close()
|
|
||||||
self.__populate()
|
|
||||||
else:
|
else:
|
||||||
base_path = self.dbstate.db.get_save_path()
|
base_path = self.dbstate.db.get_save_path()
|
||||||
archive = os.path.join(base_path, ARCHIVE)
|
archive = os.path.join(base_path, ARCHIVE)
|
||||||
check_in(self.dbstate.db, archive, None, self.__start_cursor)
|
check_in(self.dbstate.db, archive, None, self.__start_cursor)
|
||||||
self.__end_cursor()
|
self.__end_cursor()
|
||||||
|
|
||||||
self.__populate()
|
self.__populate()
|
||||||
|
|
||||||
|
def __checkout_copy(self, parent_name, name, revision, db_path):
|
||||||
|
"""
|
||||||
|
Creates a new database, then extracts a revision from RCS and
|
||||||
|
imports it into the db
|
||||||
|
"""
|
||||||
|
new_path = self.__create_new_db("%s : %s" % (parent_name, name))
|
||||||
|
trans = Config.TRANSACTIONS
|
||||||
|
dbtype = 'x-directory/normal'
|
||||||
|
|
||||||
|
self.__start_cursor(_("Extracting archive..."))
|
||||||
|
dbase = GrampsDb.gramps_db_factory(dbtype)(trans)
|
||||||
|
dbase.load(new_path, None)
|
||||||
|
|
||||||
|
self.__start_cursor(_("Importing archive..."))
|
||||||
|
check_out(dbase, revision, db_path, None)
|
||||||
|
self.__end_cursor()
|
||||||
|
dbase.close()
|
||||||
|
|
||||||
def __remove_db(self, obj):
|
def __remove_db(self, obj):
|
||||||
"""
|
"""
|
||||||
Callback associated with the Remove button. Get the selected
|
Callback associated with the Remove button. Get the selected
|
||||||
@ -536,15 +560,15 @@ class DbManager:
|
|||||||
os.unlink(fname)
|
os.unlink(fname)
|
||||||
|
|
||||||
dbclass = GrampsDb.gramps_db_factory(db_type = "x-directory/normal")
|
dbclass = GrampsDb.gramps_db_factory(db_type = "x-directory/normal")
|
||||||
db = dbclass(Config.get(Config.TRANSACTIONS))
|
dbase = dbclass(Config.get(Config.TRANSACTIONS))
|
||||||
db.set_save_path(dirname)
|
dbase.set_save_path(dirname)
|
||||||
db.load(dirname, None)
|
dbase.load(dirname, None)
|
||||||
|
|
||||||
self.__start_cursor(_("Rebuilding database from backup files"))
|
self.__start_cursor(_("Rebuilding database from backup files"))
|
||||||
GrampsDbUtils.Backup.restore(db)
|
GrampsDbUtils.Backup.restore(dbase)
|
||||||
self.__end_cursor()
|
self.__end_cursor()
|
||||||
|
|
||||||
db.close()
|
dbase.close()
|
||||||
self.dbstate.no_database()
|
self.dbstate.no_database()
|
||||||
self.__populate()
|
self.__populate()
|
||||||
|
|
||||||
@ -631,6 +655,16 @@ def find_next_db_dir():
|
|||||||
break
|
break
|
||||||
return new_path
|
return new_path
|
||||||
|
|
||||||
|
def make_dbdir(dbdir):
|
||||||
|
"""
|
||||||
|
Creates the default database directory, as defined by dbdir
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if not os.path.isdir(dbdir):
|
||||||
|
os.makedirs(dbdir)
|
||||||
|
except (IOError, OSError), msg:
|
||||||
|
LOG.error(_("Could not make database directory: ") + str(msg))
|
||||||
|
|
||||||
def time_val(dirpath):
|
def time_val(dirpath):
|
||||||
"""
|
"""
|
||||||
Return the last modified time of the database. We do this by looking
|
Return the last modified time of the database. We do this by looking
|
||||||
@ -646,14 +680,14 @@ def time_val(dirpath):
|
|||||||
last = _("Never")
|
last = _("Never")
|
||||||
return (tval, last)
|
return (tval, last)
|
||||||
|
|
||||||
def icon_values(dirpath, active, open):
|
def icon_values(dirpath, active, is_open):
|
||||||
"""
|
"""
|
||||||
If the directory path is the active path, then return values
|
If the directory path is the active path, then return values
|
||||||
that indicate to use the icon, and which icon to use.
|
that indicate to use the icon, and which icon to use.
|
||||||
"""
|
"""
|
||||||
if os.path.isfile(os.path.join(dirpath,"need_recover")):
|
if os.path.isfile(os.path.join(dirpath,"need_recover")):
|
||||||
return (True, gtk.STOCK_DIALOG_ERROR)
|
return (True, gtk.STOCK_DIALOG_ERROR)
|
||||||
elif dirpath == active and open:
|
elif dirpath == active and is_open:
|
||||||
return (True, gtk.STOCK_OPEN)
|
return (True, gtk.STOCK_OPEN)
|
||||||
elif os.path.isfile(os.path.join(dirpath,"lock")):
|
elif os.path.isfile(os.path.join(dirpath,"lock")):
|
||||||
return (True, 'gramps-lock')
|
return (True, 'gramps-lock')
|
||||||
@ -702,11 +736,29 @@ def find_revisions(name):
|
|||||||
revlist.append((rev_str, date_str, com_str))
|
revlist.append((rev_str, date_str, com_str))
|
||||||
return revlist
|
return revlist
|
||||||
|
|
||||||
def check_out(db, rev, path, name, callback):
|
def find_locker_name(dirpath):
|
||||||
co = [ "co", "-q%s" % rev] + [ os.path.join(path, ARCHIVE),
|
"""
|
||||||
|
Opens the lock file if it exists, reads the contexts and returns
|
||||||
|
the contents. If a file is encountered, we return 'Unknown'
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
fname = os.path.join(dirpath, "lock")
|
||||||
|
ifile = open(fname)
|
||||||
|
last = ifile.read().strip()
|
||||||
|
ifile.close()
|
||||||
|
except (OSError, IOError):
|
||||||
|
last = _("Unknown")
|
||||||
|
return last
|
||||||
|
|
||||||
|
def check_out(dbase, rev, path, callback):
|
||||||
|
"""
|
||||||
|
Checks out the revision from rcs, and loads the resulting XML file
|
||||||
|
into the database.
|
||||||
|
"""
|
||||||
|
co_cmd = [ "co", "-q%s" % rev] + [ os.path.join(path, ARCHIVE),
|
||||||
os.path.join(path, ARCHIVE_V)]
|
os.path.join(path, ARCHIVE_V)]
|
||||||
|
|
||||||
proc = subprocess.Popen(co, stderr = subprocess.PIPE)
|
proc = subprocess.Popen(co_cmd, stderr = subprocess.PIPE)
|
||||||
status = proc.wait()
|
status = proc.wait()
|
||||||
message = "\n".join(proc.stderr.readlines())
|
message = "\n".join(proc.stderr.readlines())
|
||||||
proc.stderr.close()
|
proc.stderr.close()
|
||||||
@ -724,12 +776,15 @@ def check_out(db, rev, path, name, callback):
|
|||||||
|
|
||||||
rdr = GrampsDbUtils.gramps_db_reader_factory(const.app_gramps_xml)
|
rdr = GrampsDbUtils.gramps_db_reader_factory(const.app_gramps_xml)
|
||||||
xml_file = os.path.join(path, ARCHIVE)
|
xml_file = os.path.join(path, ARCHIVE)
|
||||||
rdr(db, xml_file, callback)
|
rdr(dbase, xml_file, callback)
|
||||||
os.unlink(xml_file)
|
os.unlink(xml_file)
|
||||||
|
|
||||||
def check_in(db, filename, callback, cursor_func = None):
|
def check_in(dbase, filename, callback, cursor_func = None):
|
||||||
|
"""
|
||||||
|
Checks in the specified file into RCS
|
||||||
|
"""
|
||||||
init = [ "rcs", '-i', '-U', '-q', '-t-"GRAMPS database"', ]
|
init = [ "rcs", '-i', '-U', '-q', '-t-"GRAMPS database"', ]
|
||||||
ci = [ "ci", "-q", "-f" ]
|
ci_cmd = [ "ci", "-q", "-f" ]
|
||||||
|
|
||||||
glade = gtk.glade.XML(const.gladeFile, "comment", "gramps")
|
glade = gtk.glade.XML(const.gladeFile, "comment", "gramps")
|
||||||
top = glade.get_widget('comment')
|
top = glade.get_widget('comment')
|
||||||
@ -749,17 +804,15 @@ def check_in(db, filename, callback, cursor_func = None):
|
|||||||
|
|
||||||
if cursor_func:
|
if cursor_func:
|
||||||
cursor_func(_("Creating data to be archived..."))
|
cursor_func(_("Creating data to be archived..."))
|
||||||
xmlwrite = GrampsDbUtils.XmlWriter(db, callback, False, 0)
|
xmlwrite = GrampsDbUtils.XmlWriter(dbase, callback, False, 0)
|
||||||
xmlwrite.write(filename)
|
xmlwrite.write(filename)
|
||||||
|
|
||||||
cmd = ci + ['-m%s' % comment, filename, filename + ",v" ]
|
cmd = ci_cmd + ['-m%s' % comment, filename, filename + ",v" ]
|
||||||
|
|
||||||
if cursor_func:
|
if cursor_func:
|
||||||
cursor_func(_("Saving archive..."))
|
cursor_func(_("Saving archive..."))
|
||||||
proc = subprocess.Popen(
|
|
||||||
cmd,
|
proc = subprocess.Popen(cmd, stderr = subprocess.PIPE )
|
||||||
stdin = subprocess.PIPE,
|
|
||||||
stderr = subprocess.PIPE )
|
|
||||||
proc.stdin.close()
|
proc.stdin.close()
|
||||||
message = "\n".join(proc.stderr.readlines())
|
message = "\n".join(proc.stderr.readlines())
|
||||||
proc.stderr.close()
|
proc.stderr.close()
|
||||||
|
@ -15425,7 +15425,7 @@ Very High</property>
|
|||||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||||
<property name="modal">False</property>
|
<property name="modal">False</property>
|
||||||
<property name="default_width">550</property>
|
<property name="default_width">640</property>
|
||||||
<property name="default_height">300</property>
|
<property name="default_height">300</property>
|
||||||
<property name="resizable">True</property>
|
<property name="resizable">True</property>
|
||||||
<property name="destroy_with_parent">False</property>
|
<property name="destroy_with_parent">False</property>
|
||||||
|
Loading…
Reference in New Issue
Block a user