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