1*515bc8c1Sserge-sans-paille#!/usr/bin/env python 26c29ca7dSZachary Turner 36c29ca7dSZachary Turnerfrom __future__ import print_function 46c29ca7dSZachary Turner 56c29ca7dSZachary Turnerimport use_lldb_suite 66c29ca7dSZachary Turnerimport six 76c29ca7dSZachary Turner 86c29ca7dSZachary Turnerimport sys 96c29ca7dSZachary Turnerimport time 106c29ca7dSZachary Turner 11b9c1b51eSKate Stone 126c29ca7dSZachary Turnerclass ProgressBar(object): 136c29ca7dSZachary Turner """ProgressBar class holds the options of the progress bar. 146c29ca7dSZachary Turner The options are: 156c29ca7dSZachary Turner start State from which start the progress. For example, if start is 166c29ca7dSZachary Turner 5 and the end is 10, the progress of this state is 50% 176c29ca7dSZachary Turner end State in which the progress has terminated. 186c29ca7dSZachary Turner width -- 196c29ca7dSZachary Turner fill String to use for "filled" used to represent the progress 206c29ca7dSZachary Turner blank String to use for "filled" used to represent remaining space. 216c29ca7dSZachary Turner format Format 226c29ca7dSZachary Turner incremental 236c29ca7dSZachary Turner """ 246c29ca7dSZachary Turner light_block = six.unichr(0x2591).encode("utf-8") 256c29ca7dSZachary Turner solid_block = six.unichr(0x2588).encode("utf-8") 266c29ca7dSZachary Turner solid_right_arrow = six.unichr(0x25BA).encode("utf-8") 276c29ca7dSZachary Turner 286c29ca7dSZachary Turner def __init__(self, 296c29ca7dSZachary Turner start=0, 306c29ca7dSZachary Turner end=10, 316c29ca7dSZachary Turner width=12, 326c29ca7dSZachary Turner fill=six.unichr(0x25C9).encode("utf-8"), 336c29ca7dSZachary Turner blank=six.unichr(0x25CC).encode("utf-8"), 346c29ca7dSZachary Turner marker=six.unichr(0x25CE).encode("utf-8"), 356c29ca7dSZachary Turner format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 366c29ca7dSZachary Turner incremental=True): 376c29ca7dSZachary Turner super(ProgressBar, self).__init__() 386c29ca7dSZachary Turner 396c29ca7dSZachary Turner self.start = start 406c29ca7dSZachary Turner self.end = end 416c29ca7dSZachary Turner self.width = width 426c29ca7dSZachary Turner self.fill = fill 436c29ca7dSZachary Turner self.blank = blank 446c29ca7dSZachary Turner self.marker = marker 456c29ca7dSZachary Turner self.format = format 466c29ca7dSZachary Turner self.incremental = incremental 476c29ca7dSZachary Turner self.step = 100 / float(width) # fix 486c29ca7dSZachary Turner self.reset() 496c29ca7dSZachary Turner 506c29ca7dSZachary Turner def __add__(self, increment): 516c29ca7dSZachary Turner increment = self._get_progress(increment) 526c29ca7dSZachary Turner if 100 > self.progress + increment: 536c29ca7dSZachary Turner self.progress += increment 546c29ca7dSZachary Turner else: 556c29ca7dSZachary Turner self.progress = 100 566c29ca7dSZachary Turner return self 576c29ca7dSZachary Turner 586c29ca7dSZachary Turner def complete(self): 596c29ca7dSZachary Turner self.progress = 100 606c29ca7dSZachary Turner return self 616c29ca7dSZachary Turner 626c29ca7dSZachary Turner def __str__(self): 636c29ca7dSZachary Turner progressed = int(self.progress / self.step) # fix 646c29ca7dSZachary Turner fill = progressed * self.fill 656c29ca7dSZachary Turner blank = (self.width - progressed) * self.blank 66b9c1b51eSKate Stone return self.format % { 67b9c1b51eSKate Stone 'fill': fill, 68b9c1b51eSKate Stone 'blank': blank, 69b9c1b51eSKate Stone 'marker': self.marker, 70b9c1b51eSKate Stone 'progress': int( 71b9c1b51eSKate Stone self.progress)} 726c29ca7dSZachary Turner 736c29ca7dSZachary Turner __repr__ = __str__ 746c29ca7dSZachary Turner 756c29ca7dSZachary Turner def _get_progress(self, increment): 766c29ca7dSZachary Turner return float(increment * 100) / self.end 776c29ca7dSZachary Turner 786c29ca7dSZachary Turner def reset(self): 796c29ca7dSZachary Turner """Resets the current progress to the start point""" 806c29ca7dSZachary Turner self.progress = self._get_progress(self.start) 816c29ca7dSZachary Turner return self 826c29ca7dSZachary Turner 836c29ca7dSZachary Turner 846c29ca7dSZachary Turnerclass AnimatedProgressBar(ProgressBar): 856c29ca7dSZachary Turner """Extends ProgressBar to allow you to use it straighforward on a script. 866c29ca7dSZachary Turner Accepts an extra keyword argument named `stdout` (by default use sys.stdout) 876c29ca7dSZachary Turner and may be any file-object to which send the progress status. 886c29ca7dSZachary Turner """ 89b9c1b51eSKate Stone 906c29ca7dSZachary Turner def __init__(self, 916c29ca7dSZachary Turner start=0, 926c29ca7dSZachary Turner end=10, 936c29ca7dSZachary Turner width=12, 946c29ca7dSZachary Turner fill=six.unichr(0x25C9).encode("utf-8"), 956c29ca7dSZachary Turner blank=six.unichr(0x25CC).encode("utf-8"), 966c29ca7dSZachary Turner marker=six.unichr(0x25CE).encode("utf-8"), 976c29ca7dSZachary Turner format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 986c29ca7dSZachary Turner incremental=True, 996c29ca7dSZachary Turner stdout=sys.stdout): 100b9c1b51eSKate Stone super( 101b9c1b51eSKate Stone AnimatedProgressBar, 102b9c1b51eSKate Stone self).__init__( 103b9c1b51eSKate Stone start, 104b9c1b51eSKate Stone end, 105b9c1b51eSKate Stone width, 106b9c1b51eSKate Stone fill, 107b9c1b51eSKate Stone blank, 108b9c1b51eSKate Stone marker, 109b9c1b51eSKate Stone format, 110b9c1b51eSKate Stone incremental) 1116c29ca7dSZachary Turner self.stdout = stdout 1126c29ca7dSZachary Turner 1136c29ca7dSZachary Turner def show_progress(self): 1146c29ca7dSZachary Turner if hasattr(self.stdout, 'isatty') and self.stdout.isatty(): 1156c29ca7dSZachary Turner self.stdout.write('\r') 1166c29ca7dSZachary Turner else: 1176c29ca7dSZachary Turner self.stdout.write('\n') 1186c29ca7dSZachary Turner self.stdout.write(str(self)) 1196c29ca7dSZachary Turner self.stdout.flush() 1206c29ca7dSZachary Turner 121b9c1b51eSKate Stone 1226c29ca7dSZachary Turnerclass ProgressWithEvents(AnimatedProgressBar): 1236c29ca7dSZachary Turner """Extends AnimatedProgressBar to allow you to track a set of events that 1246c29ca7dSZachary Turner cause the progress to move. For instance, in a deletion progress bar, you 1256c29ca7dSZachary Turner can track files that were nuked and files that the user doesn't have access to 1266c29ca7dSZachary Turner """ 127b9c1b51eSKate Stone 1286c29ca7dSZachary Turner def __init__(self, 1296c29ca7dSZachary Turner start=0, 1306c29ca7dSZachary Turner end=10, 1316c29ca7dSZachary Turner width=12, 1326c29ca7dSZachary Turner fill=six.unichr(0x25C9).encode("utf-8"), 1336c29ca7dSZachary Turner blank=six.unichr(0x25CC).encode("utf-8"), 1346c29ca7dSZachary Turner marker=six.unichr(0x25CE).encode("utf-8"), 1356c29ca7dSZachary Turner format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%', 1366c29ca7dSZachary Turner incremental=True, 1376c29ca7dSZachary Turner stdout=sys.stdout): 138b9c1b51eSKate Stone super( 139b9c1b51eSKate Stone ProgressWithEvents, 140b9c1b51eSKate Stone self).__init__( 141b9c1b51eSKate Stone start, 142b9c1b51eSKate Stone end, 143b9c1b51eSKate Stone width, 144b9c1b51eSKate Stone fill, 145b9c1b51eSKate Stone blank, 146b9c1b51eSKate Stone marker, 147b9c1b51eSKate Stone format, 148b9c1b51eSKate Stone incremental, 149b9c1b51eSKate Stone stdout) 1506c29ca7dSZachary Turner self.events = {} 1516c29ca7dSZachary Turner 1526c29ca7dSZachary Turner def add_event(self, event): 1536c29ca7dSZachary Turner if event in self.events: 1546c29ca7dSZachary Turner self.events[event] += 1 1556c29ca7dSZachary Turner else: 1566c29ca7dSZachary Turner self.events[event] = 1 1576c29ca7dSZachary Turner 1586c29ca7dSZachary Turner def show_progress(self): 1596c29ca7dSZachary Turner isatty = hasattr(self.stdout, 'isatty') and self.stdout.isatty() 1606c29ca7dSZachary Turner if isatty: 1616c29ca7dSZachary Turner self.stdout.write('\r') 1626c29ca7dSZachary Turner else: 1636c29ca7dSZachary Turner self.stdout.write('\n') 1646c29ca7dSZachary Turner self.stdout.write(str(self)) 1656c29ca7dSZachary Turner if len(self.events) == 0: 1666c29ca7dSZachary Turner return 1676c29ca7dSZachary Turner self.stdout.write('\n') 1686c29ca7dSZachary Turner for key in list(self.events.keys()): 1696c29ca7dSZachary Turner self.stdout.write(str(key) + ' = ' + str(self.events[key]) + ' ') 1706c29ca7dSZachary Turner if isatty: 1716c29ca7dSZachary Turner self.stdout.write('\033[1A') 1726c29ca7dSZachary Turner self.stdout.flush() 1736c29ca7dSZachary Turner 1746c29ca7dSZachary Turner 1756c29ca7dSZachary Turnerif __name__ == '__main__': 1766c29ca7dSZachary Turner p = AnimatedProgressBar(end=200, width=200) 1776c29ca7dSZachary Turner 1786c29ca7dSZachary Turner while True: 1796c29ca7dSZachary Turner p + 5 1806c29ca7dSZachary Turner p.show_progress() 1816c29ca7dSZachary Turner time.sleep(0.3) 1826c29ca7dSZachary Turner if p.progress == 100: 1836c29ca7dSZachary Turner break 1846c29ca7dSZachary Turner print() # new line 185