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