1be691f3bSpatrick#!/usr/bin/env python 2061da546Spatrick 3061da546Spatrickfrom __future__ import print_function 4061da546Spatrick 5061da546Spatrickimport use_lldb_suite 6061da546Spatrick 7061da546Spatrickimport sys 8061da546Spatrickimport time 9061da546Spatrick 10061da546Spatrick 11061da546Spatrickclass ProgressBar(object): 12061da546Spatrick """ProgressBar class holds the options of the progress bar. 13061da546Spatrick The options are: 14061da546Spatrick start State from which start the progress. For example, if start is 15061da546Spatrick 5 and the end is 10, the progress of this state is 50% 16061da546Spatrick end State in which the progress has terminated. 17061da546Spatrick width -- 18061da546Spatrick fill String to use for "filled" used to represent the progress 19061da546Spatrick blank String to use for "filled" used to represent remaining space. 20061da546Spatrick format Format 21061da546Spatrick incremental 22061da546Spatrick """ 23*f6aab3d8Srobert light_block = chr(0x2591).encode("utf-8") 24*f6aab3d8Srobert solid_block = chr(0x2588).encode("utf-8") 25*f6aab3d8Srobert solid_right_arrow = chr(0x25BA).encode("utf-8") 26061da546Spatrick 27061da546Spatrick def __init__(self, 28061da546Spatrick start=0, 29061da546Spatrick end=10, 30061da546Spatrick width=12, 31*f6aab3d8Srobert fill=chr(0x25C9).encode("utf-8"), 32*f6aab3d8Srobert blank=chr(0x25CC).encode("utf-8"), 33*f6aab3d8Srobert marker=chr(0x25CE).encode("utf-8"), 34061da546Spatrick format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 35061da546Spatrick incremental=True): 36061da546Spatrick super(ProgressBar, self).__init__() 37061da546Spatrick 38061da546Spatrick self.start = start 39061da546Spatrick self.end = end 40061da546Spatrick self.width = width 41061da546Spatrick self.fill = fill 42061da546Spatrick self.blank = blank 43061da546Spatrick self.marker = marker 44061da546Spatrick self.format = format 45061da546Spatrick self.incremental = incremental 46061da546Spatrick self.step = 100 / float(width) # fix 47061da546Spatrick self.reset() 48061da546Spatrick 49061da546Spatrick def __add__(self, increment): 50061da546Spatrick increment = self._get_progress(increment) 51061da546Spatrick if 100 > self.progress + increment: 52061da546Spatrick self.progress += increment 53061da546Spatrick else: 54061da546Spatrick self.progress = 100 55061da546Spatrick return self 56061da546Spatrick 57061da546Spatrick def complete(self): 58061da546Spatrick self.progress = 100 59061da546Spatrick return self 60061da546Spatrick 61061da546Spatrick def __str__(self): 62061da546Spatrick progressed = int(self.progress / self.step) # fix 63061da546Spatrick fill = progressed * self.fill 64061da546Spatrick blank = (self.width - progressed) * self.blank 65061da546Spatrick return self.format % { 66061da546Spatrick 'fill': fill, 67061da546Spatrick 'blank': blank, 68061da546Spatrick 'marker': self.marker, 69061da546Spatrick 'progress': int( 70061da546Spatrick self.progress)} 71061da546Spatrick 72061da546Spatrick __repr__ = __str__ 73061da546Spatrick 74061da546Spatrick def _get_progress(self, increment): 75061da546Spatrick return float(increment * 100) / self.end 76061da546Spatrick 77061da546Spatrick def reset(self): 78061da546Spatrick """Resets the current progress to the start point""" 79061da546Spatrick self.progress = self._get_progress(self.start) 80061da546Spatrick return self 81061da546Spatrick 82061da546Spatrick 83061da546Spatrickclass AnimatedProgressBar(ProgressBar): 84061da546Spatrick """Extends ProgressBar to allow you to use it straighforward on a script. 85061da546Spatrick Accepts an extra keyword argument named `stdout` (by default use sys.stdout) 86061da546Spatrick and may be any file-object to which send the progress status. 87061da546Spatrick """ 88061da546Spatrick 89061da546Spatrick def __init__(self, 90061da546Spatrick start=0, 91061da546Spatrick end=10, 92061da546Spatrick width=12, 93*f6aab3d8Srobert fill=chr(0x25C9).encode("utf-8"), 94*f6aab3d8Srobert blank=chr(0x25CC).encode("utf-8"), 95*f6aab3d8Srobert marker=chr(0x25CE).encode("utf-8"), 96061da546Spatrick format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 97061da546Spatrick incremental=True, 98061da546Spatrick stdout=sys.stdout): 99061da546Spatrick super( 100061da546Spatrick AnimatedProgressBar, 101061da546Spatrick self).__init__( 102061da546Spatrick start, 103061da546Spatrick end, 104061da546Spatrick width, 105061da546Spatrick fill, 106061da546Spatrick blank, 107061da546Spatrick marker, 108061da546Spatrick format, 109061da546Spatrick incremental) 110061da546Spatrick self.stdout = stdout 111061da546Spatrick 112061da546Spatrick def show_progress(self): 113061da546Spatrick if hasattr(self.stdout, 'isatty') and self.stdout.isatty(): 114061da546Spatrick self.stdout.write('\r') 115061da546Spatrick else: 116061da546Spatrick self.stdout.write('\n') 117061da546Spatrick self.stdout.write(str(self)) 118061da546Spatrick self.stdout.flush() 119061da546Spatrick 120061da546Spatrick 121061da546Spatrickclass ProgressWithEvents(AnimatedProgressBar): 122061da546Spatrick """Extends AnimatedProgressBar to allow you to track a set of events that 123061da546Spatrick cause the progress to move. For instance, in a deletion progress bar, you 124061da546Spatrick can track files that were nuked and files that the user doesn't have access to 125061da546Spatrick """ 126061da546Spatrick 127061da546Spatrick def __init__(self, 128061da546Spatrick start=0, 129061da546Spatrick end=10, 130061da546Spatrick width=12, 131*f6aab3d8Srobert fill=chr(0x25C9).encode("utf-8"), 132*f6aab3d8Srobert blank=chr(0x25CC).encode("utf-8"), 133*f6aab3d8Srobert marker=chr(0x25CE).encode("utf-8"), 134061da546Spatrick format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 135061da546Spatrick incremental=True, 136061da546Spatrick stdout=sys.stdout): 137061da546Spatrick super( 138061da546Spatrick ProgressWithEvents, 139061da546Spatrick self).__init__( 140061da546Spatrick start, 141061da546Spatrick end, 142061da546Spatrick width, 143061da546Spatrick fill, 144061da546Spatrick blank, 145061da546Spatrick marker, 146061da546Spatrick format, 147061da546Spatrick incremental, 148061da546Spatrick stdout) 149061da546Spatrick self.events = {} 150061da546Spatrick 151061da546Spatrick def add_event(self, event): 152061da546Spatrick if event in self.events: 153061da546Spatrick self.events[event] += 1 154061da546Spatrick else: 155061da546Spatrick self.events[event] = 1 156061da546Spatrick 157061da546Spatrick def show_progress(self): 158061da546Spatrick isatty = hasattr(self.stdout, 'isatty') and self.stdout.isatty() 159061da546Spatrick if isatty: 160061da546Spatrick self.stdout.write('\r') 161061da546Spatrick else: 162061da546Spatrick self.stdout.write('\n') 163061da546Spatrick self.stdout.write(str(self)) 164061da546Spatrick if len(self.events) == 0: 165061da546Spatrick return 166061da546Spatrick self.stdout.write('\n') 167061da546Spatrick for key in list(self.events.keys()): 168061da546Spatrick self.stdout.write(str(key) + ' = ' + str(self.events[key]) + ' ') 169061da546Spatrick if isatty: 170061da546Spatrick self.stdout.write('\033[1A') 171061da546Spatrick self.stdout.flush() 172061da546Spatrick 173061da546Spatrick 174061da546Spatrickif __name__ == '__main__': 175061da546Spatrick p = AnimatedProgressBar(end=200, width=200) 176061da546Spatrick 177061da546Spatrick while True: 178061da546Spatrick p + 5 179061da546Spatrick p.show_progress() 180061da546Spatrick time.sleep(0.3) 181061da546Spatrick if p.progress == 100: 182061da546Spatrick break 183061da546Spatrick print() # new line 184