]> git.phdru.name Git - m_lib.git/blob - m_lib/pbar/tty_pbar.py
3903d1f2d4205ef53baaf0bac617a95eccb47bee
[m_lib.git] / m_lib / pbar / tty_pbar.py
1 """
2    Progress bar (TTY version)
3
4    Written by Broytman, Jan 1997 - Sep 2003. Copyright (C) 1997-2003 PhiloSoft Design
5 """
6
7
8 import sys, os
9
10
11 class ttyProgressBar:
12    """
13       Simple progress indicator - displays bar "graph" using standard tty
14       commands - space, backspace, etc. This method is compatible with
15       (almost) all UNIX consoles and DOS boxes.
16
17       Example:
18
19          ====------  42%
20
21       This is a "bar" (width 10 chars) for 42%
22
23       Certainly, to use it nicely, do not write anything on screen
24       (to stdout or stderr), while using it (or use erase()/redraw() methods).
25       Erase or delete it after using.
26    """
27
28    left_c = '#'     # Chars for "graphics"
29    right_c = '_'
30    space_c = ' '    # a space
31    back_c = chr(8)  # a backspace
32
33    if os.name == 'dos' or os.name == 'nt' : # Use nice chars on DOS screen
34       left_c = chr(178)
35       right_c = chr(176)
36
37
38    def __init__(self, min, max, out = sys.stderr, width1 = 10,
39          width2 = 1+3+1): # 1 space + 3 chars for "100" + 1 for "%"
40       self.min = min
41       self.current = min
42       self.max = max - min
43
44       self.width1 = width1
45       self.width2 = width2
46       self.out = out
47
48       self.redraw()
49
50
51    def __del__(self):
52       self.erase()
53
54
55    def display(self, current):
56       """
57          Draw current value on indicator.
58          Optimized to draw as little as possible.
59       """
60
61       self.current = current
62       current -= self.min
63       lng = (current * self.width1) / self.max
64
65       if current >= self.max:
66          percent = 100
67       else:
68          percent = (current * 100) / self.max
69
70       flush = False
71
72       if self.lng <> lng:
73          self.lng =  lng
74          self.out.write(ttyProgressBar.back_c*(self.width1+self.width2))
75          self.out.write(ttyProgressBar.left_c*lng)
76          self.out.write(ttyProgressBar.right_c*(self.width1-lng) + ttyProgressBar.space_c)
77          self.percent = -1 # force to redraw percentage; the bug was fixed by William McVey
78          flush = True
79
80       elif self.percent <> percent:
81          self.out.write(ttyProgressBar.back_c * (self.width2-1))
82          flush = True
83
84
85       if self.percent <> percent:
86          self.percent =  percent
87          self.out.write(str(percent).rjust(3) + '%')
88          flush = True
89
90
91       if flush:
92          self.out.flush()
93
94       self.visible = True
95
96
97    def erase(self):
98       if self.visible: # Prevent erase() to be called twice - explicitly and from __del__()
99          self.out.write(ttyProgressBar.back_c*(self.width1+self.width2))
100          self.out.write(ttyProgressBar.space_c*(self.width1+self.width2))
101          self.out.write(ttyProgressBar.back_c*(self.width1+self.width2))
102          self.out.flush()
103          self.visible = False
104
105
106    def redraw(self):
107       self.lng = -1 # force to draw bar on the first call
108       self.percent = -1
109
110       # Clear space - just in case there was some cruft left
111       self.out.write(ttyProgressBar.space_c*(self.width1+self.width2))
112       # redraw everything
113       self.display(self.current)