| #!/usr/bin/python |
| |
| import sys |
| import time |
| |
| class ProgressBar(object): |
| """ProgressBar class holds the options of the progress bar. |
| The options are: |
| start State from which start the progress. For example, if start is |
| 5 and the end is 10, the progress of this state is 50% |
| end State in which the progress has terminated. |
| width -- |
| fill String to use for "filled" used to represent the progress |
| blank String to use for "filled" used to represent remaining space. |
| format Format |
| incremental |
| """ |
| light_block = unichr(0x2591).encode("utf-8") |
| solid_block = unichr(0x2588).encode("utf-8") |
| solid_right_arrow = unichr(0x25BA).encode("utf-8") |
| |
| def __init__(self, |
| start=0, |
| end=10, |
| width=12, |
| fill=unichr(0x25C9).encode("utf-8"), |
| blank=unichr(0x25CC).encode("utf-8"), |
| marker=unichr(0x25CE).encode("utf-8"), |
| format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', |
| incremental=True): |
| super(ProgressBar, self).__init__() |
| |
| self.start = start |
| self.end = end |
| self.width = width |
| self.fill = fill |
| self.blank = blank |
| self.marker = marker |
| self.format = format |
| self.incremental = incremental |
| self.step = 100 / float(width) #fix |
| self.reset() |
| |
| def __add__(self, increment): |
| increment = self._get_progress(increment) |
| if 100 > self.progress + increment: |
| self.progress += increment |
| else: |
| self.progress = 100 |
| return self |
| |
| def complete(self): |
| self.progress = 100 |
| return self |
| |
| def __str__(self): |
| progressed = int(self.progress / self.step) #fix |
| fill = progressed * self.fill |
| blank = (self.width - progressed) * self.blank |
| return self.format % {'fill': fill, 'blank': blank, 'marker': self.marker, 'progress': int(self.progress)} |
| |
| __repr__ = __str__ |
| |
| def _get_progress(self, increment): |
| return float(increment * 100) / self.end |
| |
| def reset(self): |
| """Resets the current progress to the start point""" |
| self.progress = self._get_progress(self.start) |
| return self |
| |
| |
| class AnimatedProgressBar(ProgressBar): |
| """Extends ProgressBar to allow you to use it straighforward on a script. |
| Accepts an extra keyword argument named `stdout` (by default use sys.stdout) |
| and may be any file-object to which send the progress status. |
| """ |
| def __init__(self, |
| start=0, |
| end=10, |
| width=12, |
| fill=unichr(0x25C9).encode("utf-8"), |
| blank=unichr(0x25CC).encode("utf-8"), |
| marker=unichr(0x25CE).encode("utf-8"), |
| format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', |
| incremental=True, |
| stdout=sys.stdout): |
| super(AnimatedProgressBar, self).__init__(start,end,width,fill,blank,marker,format,incremental) |
| self.stdout = stdout |
| |
| def show_progress(self): |
| if hasattr(self.stdout, 'isatty') and self.stdout.isatty(): |
| self.stdout.write('\r') |
| else: |
| self.stdout.write('\n') |
| self.stdout.write(str(self)) |
| self.stdout.flush() |
| |
| class ProgressWithEvents(AnimatedProgressBar): |
| """Extends AnimatedProgressBar to allow you to track a set of events that |
| cause the progress to move. For instance, in a deletion progress bar, you |
| can track files that were nuked and files that the user doesn't have access to |
| """ |
| def __init__(self, |
| start=0, |
| end=10, |
| width=12, |
| fill=unichr(0x25C9).encode("utf-8"), |
| blank=unichr(0x25CC).encode("utf-8"), |
| marker=unichr(0x25CE).encode("utf-8"), |
| format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', |
| incremental=True, |
| stdout=sys.stdout): |
| super(ProgressWithEvents, self).__init__(start,end,width,fill,blank,marker,format,incremental,stdout) |
| self.events = {} |
| |
| def add_event(self,event): |
| if event in self.events: |
| self.events[event] += 1 |
| else: |
| self.events[event] = 1 |
| |
| def show_progress(self): |
| isatty = hasattr(self.stdout, 'isatty') and self.stdout.isatty() |
| if isatty: |
| self.stdout.write('\r') |
| else: |
| self.stdout.write('\n') |
| self.stdout.write(str(self)) |
| if len(self.events) == 0: |
| return |
| self.stdout.write('\n') |
| for key in self.events.keys(): |
| self.stdout.write(str(key) + ' = ' + str(self.events[key]) + ' ') |
| if isatty: |
| self.stdout.write('\033[1A') |
| self.stdout.flush() |
| |
| |
| if __name__ == '__main__': |
| p = AnimatedProgressBar(end=200, width=200) |
| |
| while True: |
| p + 5 |
| p.show_progress() |
| time.sleep(0.3) |
| if p.progress == 100: |
| break |
| print #new line |