Browse Source

add formatters for Cache and Statistics objects

this greatly simplifies the display of those objects, as the
__format__() parameter allows for arbitrary display of the internal
fields of both objects

this will allow us to display those summaries without having to pass a
label to the string representation. we can also print the objects
directly without formatting at all.
Antoine Beaupré 9 years ago
parent
commit
e5a0936a05
2 changed files with 28 additions and 8 deletions
  1. 17 1
      borg/cache.py
  2. 11 7
      borg/helpers.py

+ 17 - 1
borg/cache.py

@@ -1,5 +1,6 @@
 from configparser import RawConfigParser
 from .remote import cache_if_remote
+from collections import namedtuple
 import errno
 import logging
 logger = logging.getLogger(__name__)
@@ -15,7 +16,7 @@ import tempfile
 
 from .key import PlaintextKey
 from .helpers import Error, get_cache_dir, decode_dict, st_mtime_ns, unhexlify, int_to_bigint, \
-    bigint_to_int
+    bigint_to_int, format_file_size
 from .locking import UpgradableLock
 from .hashindex import ChunkIndex
 
@@ -73,6 +74,21 @@ class Cache:
     def __del__(self):
         self.close()
 
+    def __str__(self):
+        return format(self, """All archives:   {0.total_size:>20s} {0.total_csize:>20s} {0.unique_csize:>20s}
+
+                       Unique chunks         Total chunks
+Chunk index:    {0.total_unique_chunks:20d} {0.total_chunks:20d}""")
+
+    def __format__(self, format_spec):
+        # XXX: this should really be moved down to `hashindex.pyx`
+        Summary = namedtuple('Summary', ['total_size', 'total_csize', 'unique_size', 'unique_csize', 'total_unique_chunks', 'total_chunks'])
+        stats = Summary(*self.chunks.summarize())._asdict()
+        for field in ['total_size', 'total_csize', 'unique_csize']:
+            stats[field] = format_file_size(stats[field])
+        stats = Summary(**stats)
+        return format_spec.format(stats)
+
     def _confirm(self, message, env_var_override=None):
         print(message, file=sys.stderr)
         if env_var_override and os.environ.get(env_var_override):

+ 11 - 7
borg/helpers.py

@@ -145,16 +145,20 @@ class Statistics:
             self.usize += csize
 
     def print_(self, label, cache):
-        total_size, total_csize, unique_size, unique_csize, total_unique_chunks, total_chunks = cache.chunks.summarize()
-        buf = "\n"
-        buf += '                       Original size      Compressed size    Deduplicated size'
-        buf += '%-15s %20s %20s %20s' % (label, format_file_size(self.osize), format_file_size(self.csize), format_file_size(self.usize))
-        buf += 'All archives:   %20s %20s %20s' % (format_file_size(total_size), format_file_size(total_csize), format_file_size(unique_csize))
+        buf = str(self) % label
         buf += "\n"
-        buf += '                       Unique chunks         Total chunks'
-        buf += 'Chunk index:    %20d %20d' % (total_unique_chunks, total_chunks)
+        buf += str(cache)
         return buf
 
+    def __str__(self):
+        return format(self, """                       Original size      Compressed size    Deduplicated size
+%-15s {0.osize:>20s} {0.csize:>20s} {0.usize:>20s}""")
+
+    def __format__(self, format_spec):
+        fields = ['osize', 'csize', 'usize']
+        FormattedStats = namedtuple('FormattedStats', fields)
+        return format_spec.format(FormattedStats(*map(format_file_size, [ getattr(self, x) for x in fields ])))
+
     def show_progress(self, item=None, final=False):
         if not final:
             path = remove_surrogates(item[b'path']) if item else ''