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