1#!/usr/bin/python 2 3import sys 4import time 5 6class 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 73class 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 99class 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 140if __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