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