Home | History | Annotate | Download | only in test
      1 #!/usr/bin/python
      2 
      3 import sys
      4 import time
      5 
      6 class ProgressBar(object):
      7     """ProgressBar class holds the options of the progress bar.
      8     The options are:
      9         start   State from which start the progress. For example, if start is 
     10                 5 and the end is 10, the progress of this state is 50%
     11         end     State in which the progress has terminated.
     12         width   --
     13         fill    String to use for "filled" used to represent the progress
     14         blank   String to use for "filled" used to represent remaining space.
     15         format  Format
     16         incremental
     17     """
     18     light_block = unichr(0x2591).encode("utf-8")
     19     solid_block = unichr(0x2588).encode("utf-8")
     20     solid_right_arrow = unichr(0x25BA).encode("utf-8")
     21     
     22     def __init__(self, 
     23                  start=0, 
     24                  end=10, 
     25                  width=12, 
     26                  fill=unichr(0x25C9).encode("utf-8"), 
     27                  blank=unichr(0x25CC).encode("utf-8"), 
     28                  marker=unichr(0x25CE).encode("utf-8"), 
     29                  format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 
     30                  incremental=True):
     31         super(ProgressBar, self).__init__()
     32 
     33         self.start = start
     34         self.end = end
     35         self.width = width
     36         self.fill = fill
     37         self.blank = blank
     38         self.marker = marker
     39         self.format = format
     40         self.incremental = incremental
     41         self.step = 100 / float(width) #fix
     42         self.reset()
     43 
     44     def __add__(self, increment):
     45         increment = self._get_progress(increment)
     46         if 100 > self.progress + increment:
     47             self.progress += increment
     48         else:
     49             self.progress = 100
     50         return self
     51 
     52     def complete(self):
     53         self.progress = 100
     54         return self
     55 
     56     def __str__(self):
     57         progressed = int(self.progress / self.step) #fix
     58         fill = progressed * self.fill
     59         blank = (self.width - progressed) * self.blank
     60         return self.format % {'fill': fill, 'blank': blank, 'marker': self.marker, 'progress': int(self.progress)}
     61 
     62     __repr__ = __str__
     63 
     64     def _get_progress(self, increment):
     65         return float(increment * 100) / self.end
     66 
     67     def reset(self):
     68         """Resets the current progress to the start point"""
     69         self.progress = self._get_progress(self.start)
     70         return self
     71 
     72 
     73 class AnimatedProgressBar(ProgressBar):
     74     """Extends ProgressBar to allow you to use it straighforward on a script.
     75     Accepts an extra keyword argument named `stdout` (by default use sys.stdout)
     76     and may be any file-object to which send the progress status.
     77     """
     78     def __init__(self, 
     79                  start=0, 
     80                  end=10, 
     81                  width=12, 
     82                  fill=unichr(0x25C9).encode("utf-8"), 
     83                  blank=unichr(0x25CC).encode("utf-8"), 
     84                  marker=unichr(0x25CE).encode("utf-8"), 
     85                  format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 
     86                  incremental=True,
     87                  stdout=sys.stdout):
     88         super(AnimatedProgressBar, self).__init__(start,end,width,fill,blank,marker,format,incremental)
     89         self.stdout = stdout
     90 
     91     def show_progress(self):
     92         if hasattr(self.stdout, 'isatty') and self.stdout.isatty():
     93             self.stdout.write('\r')
     94         else:
     95             self.stdout.write('\n')
     96         self.stdout.write(str(self))
     97         self.stdout.flush()
     98 
     99 class ProgressWithEvents(AnimatedProgressBar):
    100     """Extends AnimatedProgressBar to allow you to track a set of events that
    101        cause the progress to move. For instance, in a deletion progress bar, you
    102        can track files that were nuked and files that the user doesn't have access to
    103     """
    104     def __init__(self, 
    105                  start=0, 
    106                  end=10, 
    107                  width=12, 
    108                  fill=unichr(0x25C9).encode("utf-8"), 
    109                  blank=unichr(0x25CC).encode("utf-8"), 
    110                  marker=unichr(0x25CE).encode("utf-8"), 
    111                  format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 
    112                  incremental=True,
    113                  stdout=sys.stdout):
    114         super(ProgressWithEvents, self).__init__(start,end,width,fill,blank,marker,format,incremental,stdout)
    115         self.events = {}
    116 
    117     def add_event(self,event):
    118         if event in self.events:
    119             self.events[event] += 1
    120         else:
    121             self.events[event] = 1
    122 
    123     def show_progress(self):
    124         isatty = hasattr(self.stdout, 'isatty') and self.stdout.isatty()
    125         if isatty:
    126             self.stdout.write('\r')
    127         else:
    128             self.stdout.write('\n')
    129         self.stdout.write(str(self))
    130         if len(self.events) == 0:
    131             return
    132         self.stdout.write('\n')
    133         for key in self.events.keys():
    134             self.stdout.write(str(key) + ' = ' + str(self.events[key]) + ' ')
    135         if isatty:
    136             self.stdout.write('\033[1A')
    137         self.stdout.flush()
    138 
    139 
    140 if __name__ == '__main__':
    141     p = AnimatedProgressBar(end=200, width=200)
    142 
    143     while True:
    144         p + 5
    145         p.show_progress()
    146         time.sleep(0.3)
    147         if p.progress == 100:
    148             break
    149     print #new line