From f37918ad3a1e3e5fdefc32d989ba6287239c9949 Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Mon, 28 Jan 2008 11:16:54 +0000 Subject: [PATCH] 2008-01-28 Benny Malengier * src/ArgHandler.py: * src/DbManager.py: * src/const.py.in: run ./autogen !! fix #1445, don't open locked/unrepaired dbs, new option -u to unlock svn: r9944 --- ChangeLog | 6 ++++++ src/ArgHandler.py | 53 +++++++++++++++++++++++++++++++++++------------ src/DbManager.py | 30 ++++++++++++++++++++++++--- src/const.py.in | 6 ++++-- 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92fc93bdd..695cdf26f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-01-28 Benny Malengier + * src/ArgHandler.py: + * src/DbManager.py: + * src/const.py.in: run ./autogen !! + fix #1445, don't open locked/unrepaired dbs, new option -u to unlock + 2008-01-27 Brian Matherly * src/PluginUtils/__init__.py: Remove the use of dbstate for GuiMenuOptions in tools. diff --git a/src/ArgHandler.py b/src/ArgHandler.py index 35ef9a85f..4338d24c4 100644 --- a/src/ArgHandler.py +++ b/src/ArgHandler.py @@ -57,7 +57,7 @@ import Config import RecentFiles import Utils import gen.db.exceptions as GX -from DbManager import CLIDbManager, NAME_FILE +from DbManager import CLIDbManager, NAME_FILE, find_locker_name from PluginUtils import Tool, cl_list, cli_tool_list from ReportBase import CATEGORY_BOOK, CATEGORY_CODE, CATEGORY_WEB, cl_report @@ -83,7 +83,7 @@ Application options -p, --options=OPTIONS_STRING Specify options -d, --debug=LOGGER_NAME Enable debug logs -l List Family Trees - + -u Force unlock of family tree """ #------------------------------------------------------------------------- @@ -131,6 +131,8 @@ class ArgHandler: self.imp_db_path = None self.list = False self.help = False + self.force_unlock = False + self.dbman = CLIDbManager(self.state) self.parse_args() @@ -154,6 +156,8 @@ class ArgHandler: 'gramps-xml','gramps-pkg','iso','wft','geneweb') 5/ -a, --action: An action (possible: 'check', 'summary', 'report', 'tool') + 6/ -u, --force-unlock: A locked database can be unlocked by given this + argument when opening it """ try: @@ -172,6 +176,12 @@ class ArgHandler: # use it as a file to open and return self.open_gui = leftargs[0] print "Trying to open: %s ..." % leftargs[0] + #see if force open is on + for opt_ix in range(len(options)): + option, value = options[opt_ix] + if option in ('-u', '--force-unlock'): + self.force_unlock = True + break return # Go over all given option and place them into appropriate lists @@ -185,8 +195,7 @@ class ArgHandler: 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) + data = self.dbman.family_tree(fname) if data is not None: fname, ftype, title = data else: @@ -208,8 +217,7 @@ class ArgHandler: 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) + data = self.dbman.family_tree(fname) if data is not None: fname, ftype, title = data else: @@ -306,6 +314,8 @@ class ArgHandler: self.list = True elif option in ('-h', '-?', '--help'): self.help = True + elif option in ('-u', '--force-unlock'): + self.force_unlock = True #------------------------------------------------------------------------- # Determine the need for GUI @@ -342,8 +352,7 @@ class ArgHandler: 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(): + for name, dirname in self.dbman.family_tree_list(): print dirname, ', with name ', name sys.exit(0) if self.help: @@ -379,14 +388,12 @@ class ArgHandler: elif filetype == const.APP_GRAMPS_PKG: print "Type: GRAMPS XML package" - dbman = CLIDbManager(self.state) - filename, filetype, name = dbman.import_new_db(filetype, + filename, filetype, name = self.dbman.import_new_db(filetype, filename, None) success = True else: #see if not just a name of a database is given - dbman = CLIDbManager(self.state) - data = dbman.family_tree(self.open_gui) + data = self.dbman.family_tree(self.open_gui) if data is not None: filename, filetype= data[0], data[1] success = True @@ -398,6 +405,9 @@ class ArgHandler: print "Exiting..." sys.exit(0) if success: + # Test if not locked or problematic + if not self.__check_db(filename, self.force_unlock): + sys.exit(0) # Add the file to the recent items path = os.path.join(filename, "name.txt") try: @@ -424,6 +434,8 @@ class ArgHandler: if os.path.isfile(path_name): filetype = const.APP_FAMTREE filename = name + if not self.__check_db(filename, self.force_unlock): + sys.exit(0) success = True else: print "No valid Family tree given, cannot be opened." @@ -484,10 +496,23 @@ class ArgHandler: filename = Config.get(Config.RECENT_FILE) if os.path.isdir(filename) and \ os.path.isfile(os.path.join(filename, "name.txt")) and \ - not os.path.isfile(os.path.join(filename, "need_recover")): + self.__check_db(filename): self.vm.db_loader.read_file(filename) return (filename, const.APP_FAMTREE) + def __check_db(self, dbpath, force_unlock = False): + # Test if not locked or problematic + if force_unlock: + self.dbman.break_lock(dbpath) + if self.dbman.is_locked(dbpath): + print _("Database is locked, cannot open it!") + print _(" Info: %s") % find_locker_name(dbpath) + return False + if self.dbman.needs_recovery(dbpath): + print _("Database needs recovery, cannot open it!") + return False + return True + #------------------------------------------------------------------------- # # Import handler @@ -500,6 +525,8 @@ class ArgHandler: """ if format == 'famtree': #3.x database + if not self.__check_db(filename): + sys.exit(0) try: GrampsDbUtils.gramps_db_reader_factory(const.APP_FAMTREE)( self.state.db, filename, empty) diff --git a/src/DbManager.py b/src/DbManager.py index 33d044ecc..797fe79e2 100644 --- a/src/DbManager.py +++ b/src/DbManager.py @@ -232,6 +232,29 @@ class CLIDbManager: return new_path, 'x-directory/normal', title return None, None, None + def is_locked(self, dbpath): + """ + returns True if there is a lock file in the dirpath + """ + if os.path.isfile(os.path.join(dbpath,"lock")): + return True + return False + + def needs_recovery(self, dbpath): + """ + returns True if the database in dirpath needs recovery + """ + if os.path.isfile(os.path.join(dbpath,"need_recover")): + return True + return False + + def break_lock(self, dbpath): + """ + Breaks the lock on a database + """ + if os.path.exists(os.path.join(dbpath, "lock")): + os.unlink(os.path.join(dbpath, "lock")) + class DbManager(CLIDbManager): """ Database Manager. Opens a database manager window that allows users to @@ -489,8 +512,7 @@ class DbManager(CLIDbManager): the display appropriately. """ try: - if os.path.exists(os.path.join(self.lock_file, "lock")): - os.unlink(os.path.join(self.lock_file, "lock")) + self.break_lock(self.lock_file) store, node = self.selection.get_selected() dbpath = store.get_value(node, PATH_COL) (tval, last) = time_val(dbpath) @@ -953,7 +975,9 @@ def find_revisions(name): def find_locker_name(dirpath): """ Opens the lock file if it exists, reads the contexts and returns - the contents. If a file is encountered, we return 'Unknown' + the contents, which should be like "Locked by USERNAME". + If a file is encountered with errors, we return 'Unknown' + This data is displayed in the time column of the manager """ try: fname = os.path.join(dirpath, "lock") diff --git a/src/const.py.in b/src/const.py.in index 571f54ee5..8c8ea7e2f 100644 --- a/src/const.py.in +++ b/src/const.py.in @@ -194,7 +194,8 @@ POPT_TABLE = [ ("action", 'a', str, None, 0, 'Specify action', "ACTION"), ("options", 'p', str, None, 0, 'Specify options', "OPTIONS_STRING"), ("debug", 'd', str, None, 0, 'Enable debug logs', "LOGGER_NAME"), - ("", 'l', None, None, 0, 'List Family Trees', ""), + ("", 'l', None, None, 0, 'List Family Trees', ""), + ("force-unlock", 'u', None, None, 0, 'Force unlock of family tree', ""), ] LONGOPTS = [ @@ -206,6 +207,7 @@ LONGOPTS = [ "disable-crash-dialog", "enable-sound", "espeaker=", + "force-unlock", "format=", "gdk-debug=", "gdk-no-debug=", @@ -233,5 +235,5 @@ LONGOPTS = [ "version", ] -SHORTOPTS = "O:i:o:f:a:p:d:lh?" +SHORTOPTS = "O:i:o:f:a:p:d:lhu?"