Add option -y, prettier output
authorStefan Huber <shuber2@gmx.at>
Mon, 14 May 2012 08:26:07 +0000 (10:26 +0200)
committerStefan Huber <shuber2@gmx.at>
Mon, 14 May 2012 08:26:07 +0000 (10:26 +0200)
shbackup

index cbd5396cc897636c93a272c4df36caae195c4818..351aef95d877e3f0d095289ab582e7619ef21811 100755 (executable)
--- a/shbackup
+++ b/shbackup
@@ -31,11 +31,31 @@ class Backup:
         self.epoch = epoch
         self.mode = mode
 
         self.epoch = epoch
         self.mode = mode
 
+    @staticmethod
+    def fromDirName(dirname):
+            [strdate, strtime, epoch, mode] = dirname.split("-")
+
+            if not epoch in Epoch.keys():
+                raise ValueError("Invalid epoch: " + epoch)
+
+            if not mode in Mode:
+                raise ValueError("Invalid mode: " + mode)
+
+            date = datetime.datetime(int(strdate[0:4]),
+                    int(strdate[4:6]), int(strdate[6:8]),\
+                    int(strtime[0:2]), int(strtime[2:4]))
+
+            return Backup(date, epoch, mode)
+
     def __str__(self):
         return "[date: " + self.date.ctime() + \
                 ", epoch: " + self.epoch + \
                 ", mode: " + self.mode + "]"
 
     def __str__(self):
         return "[date: " + self.date.ctime() + \
                 ", epoch: " + self.epoch + \
                 ", mode: " + self.mode + "]"
 
+    def colAlignedString(self):
+        return "%16s    %8s    %4s" % ( \
+                self.date.strftime("%Y-%m-%d %H:%M"), self.epoch, self.mode)
+
     @staticmethod
     def getDirName(date, epoch, mode):
         """Get directory name of backup by given properties."""
     @staticmethod
     def getDirName(date, epoch, mode):
         """Get directory name of backup by given properties."""
@@ -175,8 +195,9 @@ class Config:
 class BackupManager:
     """List and create backups"""
 
 class BackupManager:
     """List and create backups"""
 
-    def __init__(self, conffn):
+    def __init__(self, conffn, alwaysyes):
         self.conf = Config()
         self.conf = Config()
+        self.alwaysyes = alwaysyes
         self.conf.read(conffn)
 
 
         self.conf.read(conffn)
 
 
@@ -196,18 +217,7 @@ class BackupManager:
         backups = []
 
         for entry in [ b for b in self.listAllDirs() if Backup.isBackupDir(b) ]:
         backups = []
 
         for entry in [ b for b in self.listAllDirs() if Backup.isBackupDir(b) ]:
-            [strdate, strtime, epoch, mode] = entry.split("-")
-
-            if not epoch in Epoch.keys():
-                raise ValueError("Invalid epoch: " + epoch)
-
-            if not mode in Mode:
-                raise ValueError("Invalid mode: " + mode)
-
-            date = datetime.datetime(int(strdate[0:4]),
-                    int(strdate[4:6]), int(strdate[6:8]),\
-                    int(strtime[0:2]), int(strtime[2:4]))
-            backups += [ Backup(date, epoch, mode) ]
+            backups += [ Backup.fromDirName(entry) ]
 
         return backups
 
 
         return backups
 
@@ -329,32 +339,54 @@ class BackupManager:
     def prune(self):
         """Prune old backup files"""
 
     def prune(self):
         """Prune old backup files"""
 
+        allDirs = self.listAllDirs()
         # Collect all directories not matching backup name
         # Collect all directories not matching backup name
-        dirs = [ d for d in self.listAllDirs() if not Backup.isBackupDir(d) ]
+        removeDirs = [ d for d in allDirs if not Backup.isBackupDir(d) ]
 
 
-        # Get all directories which are outdated
+        # Get all directories which are kept
         backups = self.listOldBackups()
         backups = self.listOldBackups()
+        keepdirs = []
         byepoch = { e : list(sorted( [ b for b in backups if b.epoch == e ], \
                 key=lambda b : b.date, reverse=True)) for e in RealEpoch }
         for e in byepoch:
             keep = self.conf.epochkeeps[e]
             old = byepoch[e][keep:]
         byepoch = { e : list(sorted( [ b for b in backups if b.epoch == e ], \
                 key=lambda b : b.date, reverse=True)) for e in RealEpoch }
         for e in byepoch:
             keep = self.conf.epochkeeps[e]
             old = byepoch[e][keep:]
-            dirs += [ Backup.getDirName(b.date, b.epoch, b.mode) for b in old]
+            removeDirs += [ Backup.getDirName(b.date, b.epoch, b.mode) for b in old]
 
 
-        if len(dirs) == 0:
-            print("No stale/outdated entries to remove.")
-            return
 
         print("List of stale/outdated entries:")
 
         print("List of stale/outdated entries:")
-        for d in dirs:
-            print("  " + d)
+        for d in allDirs:
+            if d in removeDirs:
+                print("[*]  ", end="")
+            else:
+                print("[ ]  ", end="")
+
+            if Backup.isBackupDir(d):
+                print( Backup.fromDirName(d).colAlignedString())
+            else:
+                print(d)
+
+        # Check that dirs to be removed is in list of all dirs
+        for d in removeDirs:
+            assert( d in allDirs )
+
+        if len(removeDirs) == 0:
+            print("No stale/outdated entries to remove.")
+            return
 
         basedir = self.conf.directory
 
         basedir = self.conf.directory
-        yesno = input("Remove listed entries? [y, N] ")
+        yesno = self.ask_user_yesno("Remove entries marked by '*'?")
         if yesno == "y":
         if yesno == "y":
-            for d in dirs:
+            for d in removeDirs:
                 shutil.rmtree(os.path.join(basedir, d))
 
                 shutil.rmtree(os.path.join(basedir, d))
 
+    def ask_user_yesno(self, question):
+        if self.alwaysyes:
+            print(question + " y")
+            return "y"
+        else:
+            return input(question + " [y, N] ")
+
 
 def printUsage():
     """Print --help text"""
 
 def printUsage():
     """Print --help text"""
@@ -377,6 +409,7 @@ def printUsage():
     print("  -e, --epoch <epoch>        force to create backup for given epoch:")
     print("                             year, month, week, day, hour, sporadic")
     print("  -m, --mode <mode>          override mode: full, diff, or incr")
     print("  -e, --epoch <epoch>        force to create backup for given epoch:")
     print("                             year, month, week, day, hour, sporadic")
     print("  -m, --mode <mode>          override mode: full, diff, or incr")
+    print("  -y, --yes                  always assume 'yes' when user is asked")
 
 
 if __name__ == "__main__":
 
 
 if __name__ == "__main__":
@@ -385,6 +418,7 @@ if __name__ == "__main__":
     cmd = "list"
     mode = None
     epoch = None
     cmd = "list"
     mode = None
     epoch = None
+    yes = False
 
     i = 0
     while i < len(sys.argv)-1:
 
     i = 0
     while i < len(sys.argv)-1:
@@ -399,6 +433,9 @@ if __name__ == "__main__":
             i += 1
             conffn = sys.argv[i]
 
             i += 1
             conffn = sys.argv[i]
 
+        elif opt in ["-y", "--yes"]:
+            yes = True
+
         elif opt in ["-m", "--mode"]:
             i += 1
             mode = sys.argv[i]
         elif opt in ["-m", "--mode"]:
             i += 1
             mode = sys.argv[i]
@@ -422,15 +459,14 @@ if __name__ == "__main__":
             exit(1)
 
     try:
             exit(1)
 
     try:
-        man = BackupManager(conffn)
+        man = BackupManager(conffn, yes)
 
         if cmd == "backup":
             man.backup(epoch, mode)
 
         if cmd == "list":
             for b in sorted(man.listOldBackups(), key=lambda b: b.date):
 
         if cmd == "backup":
             man.backup(epoch, mode)
 
         if cmd == "list":
             for b in sorted(man.listOldBackups(), key=lambda b: b.date):
-                print(b.date.strftime("%Y-%m-%d %H:%M") + \
-                        "\t" + b.epoch + "\t" + b.mode)
+                print(b.colAlignedString())
 
         if cmd == "prune":
             man.prune()
 
         if cmd == "prune":
             man.prune()