xref: /openbsd-src/gnu/llvm/lldb/third_party/Python/module/progress/progress.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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