diff --git a/bin/autojump b/bin/autojump index 46af6d4..9ab52de 100755 --- a/bin/autojump +++ b/bin/autojump @@ -104,41 +104,29 @@ class Database: Try to open the database file, recovering from backup if needed. """ if os.path.exists(self.filename): - with open(self.filename, 'r') as f: - for line in f.readlines(): - weight, path = line[:-1].split("\t", 1) - path = decode(path, 'utf-8') - self.data[path] = float(weight) - elif os.path.exists(self.filename + '.bak'): + try: + with open(self.filename, 'r') as f: + for line in f.readlines(): + weight, path = line[:-1].split("\t", 1) + path = decode(path, 'utf-8') + self.data[path] = float(weight) + except (IOError, EOFError): + self.load_backup(error_recovery) + else: + self.load_backup(error_recovery) + + def load_backup(self, error_recovery = False): + """ + Loads database from backup file. + """ + if os.path.exists(self.filename + '.bak'): if not error_recovery: print('Problem with autojump database,\ trying to recover from backup...', file=sys.stderr) shutil.copy(self.filename + '.bak', self.filename) return self.load(True) else: - # migration code, autojump_py last used in v17 - self.filename = get_db_file('autojump_py') - if os.path.exists(self.filename): - try: # fix to get optimised pickle in python < 3 - import cPickle as pickle - except ImportError: - import pickle - - try: - with open(self.filename, 'rb') as f: - # encoding is only specified for Python 2 compatibility - if sys.version_info[0] > 2: - self.data = pickle.load(f, encoding="utf-8") - else: - self.data = pickle.load(f) - unicode_dict = {} - for k, v in self.data.items(): - print(k) - unicode_dict[decode(k, errors="replace")] = v - return unicode_dict - except (IOError, EOFError, pickle.UnpicklingError): - pass - return {} # if everything fails, return an empty dictionary + self.migrate() def maintenance(self): """ @@ -150,6 +138,33 @@ class Database: self.trim() self.save() + def migrate(self): + """ + Migrates database from old format autojump_py, last used in release-v17. + """ + self.filename = get_db_file('autojump_py') + if os.path.exists(self.filename): + try: # fix to get optimised pickle in python < 3 + import cPickle as pickle + except ImportError: + import pickle + + try: + with open(self.filename, 'rb') as f: + # encoding is only specified for Python 2 compatibility + if sys.version_info[0] > 2: + self.data = pickle.load(f, encoding="utf-8") + else: + self.data = pickle.load(f) + unicode_dict = {} + for k, v in self.data.items(): + print(k) + unicode_dict[decode(k, errors="replace")] = v + return unicode_dict + except (IOError, EOFError, pickle.UnpicklingError): + pass + return {} # if everything fails, return an empty dictionary + def purge(self): """ Deletes all entries that no longer exist on system. diff --git a/tests/runtests.py b/tests/runtests.py index 0381c08..e36f47b 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -91,7 +91,7 @@ class TestAutojump(unittest.TestCase): os.remove(fname) os.remove(fname + '.bak') - def test_db_load_migrate(self): + def test_db_migration(self): ORIG_CONFIG_DIR = autojump.CONFIG_DIR try: # setup @@ -101,8 +101,8 @@ class TestAutojump(unittest.TestCase): fname = CONFIG_DIR + '/autojump_py' db = autojump.Database(fname) db.add('/1') - shutil.copy(fname, fname + '.bak') db.add('/2') + shutil.copy(fname, fname + '.bak') # test missing_fname = '/tmp/autojump_test_db_load_missing_' + str(random.randint(0,32678)) + '.txt'