Commits

Lars Yencken  committed c8c918b

Simplifies the ProgressBar class by using Slots.

  • Participants
  • Parent commits b6b2744

Comments (0)

Files changed (2)

File src/progressBar.py

 import sys
 import time
 
-import io, shellColor
+import io
+import shellColor
+import slot
 
 #----------------------------------------------------------------------------#
 
     "A progress bar which gets printed to stdout."
     def __init__(self, stringSize=20):
         "Creates a new instance, setting the size as needed."
+        self._slot = slot.Slot()
         self._stringSize = stringSize
         self._count = 0
         self._totalCount = None
-        self._lastLineSize = None
         self._lastRotation = 0
         self._startTime = None
 
         self._totalCount = totalCount
         progressLine = '[' + shellColor.color('/', 'red') + \
                 (self._stringSize-1)*' ' + ']   0%'
-        sys.stdout.write(progressLine)
-        sys.stdout.flush()
-        self._lastLineSize = shellColor.realLen(progressLine)
-
+        self._slot.update(progressLine)
         self._startTime = time.time()
 
-        return
-
     def update(self, count):
         """
         Updates the progress bar with the current count. This is useful
 
         progressLine = '[' + shellColor.color(n*'-' + rotChar, 'red') + \
                 m*' ' + '] ' + str('%3d%%' % percent)
-        sys.stdout.write('\b'*(self._lastLineSize))
-        sys.stdout.write(progressLine)
-        sys.stdout.flush()
-        self._lastLineSize = shellColor.realLen(progressLine)
-
-        return
+        self._slot.update(progressLine)
 
     def tick(self):
         "Perform a quick update."
         self.update(self._count)
-        return
 
     def fractional(self, fraction):
         "Set a fractional percentage completion, e.g. 0.3333 -> 33%."
         assert fraction >= 0 and fraction <= 1
         self.update(int(fraction * self._totalCount))
-
-        return
     
     def finish(self):
         "Fixes to 100% complete, and writes the time taken."
         timeTaken = int(time.time() - self._startTime)
         (mins, secs) = divmod(timeTaken, 60)
         if not mins:
-            timeString = ' (%ds)\n' % secs
+            timeString = ' (%ds)' % secs
         else:
             (hours, mins) = divmod(mins, 60)
             if not hours:
-                timeString = ' (%dm %ds)\n' % (mins, secs)
+                timeString = ' (%dm %ds)' % (mins, secs)
             else:
-                timeString = ' (%dh %dm %ds)\n' % (hours, mins, secs)
+                timeString = ' (%dh %dm %ds)' % (hours, mins, secs)
 
-        sys.stdout.write(timeString)
-
-        # precautionary, in case finish() is called more than once
-        self._lastLineSize += len(timeString)
-
-        return
+        print >> sys.stdout, timeString
 
 #----------------------------------------------------------------------------#
 
 
 import sys
 
+import shellColor
+
 class Slot(object):
     """
     A generic text slot which can be overwritten repeatedly.
     """
-    def __init__(self, text='', stream=sys.stdout):
-        if '\n' in text:
+    def __init__(self, text=u'', stream=sys.stdout):
+        if u'\n' in text:
             raise Exception('slots cannot undo newlines')
         self.stream = stream
         self.last_text = None
             self.update(text)
 
     def update(self, text):
+        if isinstance(text, unicode):
+            text = text.encode('utf8')
+
         if self.last_text:
+            last_len = shellColor.realLen(self.last_text)
             self.stream.write('\r' * len(self.last_text))
-            if len(text) < len(self.last_text):
-                text = text + ' ' * (len(self.last_text) - len(text))
+            this_len = shellColor.realLen(text)
+            if this_len < last_len:
+                text = text + ' ' * (last_len - this_len)
 
         self.stream.write(text)
         self.stream.flush()