From f94104ed9f1adc942b684e5c93210eadfa2f6915 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 20 Jun 2009 02:05:11 +0900 Subject: [PATCH] new backup-friendly backup handling --- anki/deck.py | 66 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/anki/deck.py b/anki/deck.py index 7ac78fb18..78c7012b2 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -3234,48 +3234,48 @@ nextFactor, reps, thinkingTime, yesCount, noCount from reviewHistory""") _setUTCOffset = staticmethod(_setUTCOffset) def backup(modified, path): - # need a non-unicode path - def backupName(path, num): + """Path must not be unicode.""" + #path = os.path.join(backupDir, path) + if not numBackups: + return + def escape(path): path = os.path.abspath(path) path = path.replace("\\", "!") path = path.replace("/", "!") path = path.replace(":", "") - path = os.path.join(backupDir, path) - path = re.sub("\.anki$", ".backup-%d.anki" % num, path) return path - if not numBackups: - return - if not os.path.exists(backupDir): - os.makedirs(backupDir) - # if the mod time is identical, don't make a new backup - firstBack = backupName(path, 0) - if os.path.exists(firstBack): - s1 = int(modified) - s2 = int(os.stat(firstBack)[stat.ST_MTIME]) - if s1 == s2: + escp = escape(path) + # find existing backups + gen = re.sub("\.anki$", ".backup-(\d+).anki", re.escape(escp)) + backups = [] + for file in os.listdir(backupDir): + m = re.match(gen, file) + if m: + backups.append((int(m.group(1)), file)) + backups.sort() + # check if last backup is the same + if backups: + latest = os.path.join(backupDir, backups[-1][1]) + if int(modified) == int( + os.stat(latest)[stat.ST_MTIME]): return - # remove the oldest backup if it exists - oldest = backupName(path, numBackups) - if os.path.exists(oldest): - os.chmod(oldest, 0666) - os.unlink(oldest) - # move all the other backups up one - for n in range(numBackups - 1, -1, -1): - name = backupName(path, n) - if os.path.exists(name): - newname = backupName(path, n+1) - if os.path.exists(newname): - os.chmod(newname, 0666) - os.unlink(newname) - os.rename(name, newname) - # save the current path - newpath = backupName(path, 0) - if os.path.exists(newpath): - os.chmod(newpath, 0666) - os.unlink(newpath) + # get next num + if not backups: + n = 1 + else: + n = backups[-1][0] + 1 + # do backup + newpath = os.path.join(backupDir, os.path.basename( + re.sub("\.anki$", ".backup-%s.anki" % n, escp))) shutil.copy2(path, newpath) # set mtimes to be identical os.utime(newpath, (modified, modified)) + # remove if over + if len(backups) + 1 > numBackups: + delete = len(backups) + 1 - numBackups + delete = backups[:delete] + for file in delete: + os.unlink(os.path.join(backupDir, file[1])) backup = staticmethod(backup) def newCardOrderLabels():