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