1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 from __future__ import print_function, division
25 import os, sys, re
26
28 """
29 Finds the terminal size if possible otherwise it assumes 25, 80
30 @returns: lines the number of rows
31 @returns: cols the number of columns
32 """
33 import os, struct
34 def ioctl_GWINSZ(fd):
35 import fcntl, termios
36 return struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234"))
37
38 if (not sys.stdout.isatty()):
39 return (25, 80)
40
41 fd = 1
42 try:
43 return ioctl_GWINSZ(fd)
44 except:
45 pass
46
47 try:
48 fd = os.open(os.ctermid(), os.O_RDONLY)
49 try:
50 return ioctl_GWINSZ(fd)
51 finally:
52 os.close(fd)
53 except:
54 pass
55
56 try:
57 return tuple(int(x) for x in os.popen("stty size", "r").read().split())
58 except:
59 pass
60
61 try:
62 return tuple(int(os.getenv(var)) for var in ("LINES", "COLUMNS"))
63 except:
64 pass
65
66 return (25, 80)
67
69 """ A progress bar display class """
70
71 - def __init__(self, termWidth=None, barWidth=None, maxVal=None, ttyOnly=False, fd=sys.stderr):
72 """
73 Ctor that figures out the range of the progress bar.
74 @param termWidth: The terminal width
75 @param barWidth: The number of character that make up the bar
76 @param maxVal: The maximum value (required)
77 @param ttyOnly: If true then only print progress bar element if connected to a terminal.
78 @param fd: The output stream.
79 """
80 if (not maxVal):
81 ValueError('Must specify maxVal')
82
83 self.__maxVal = maxVal
84 if (not barWidth):
85 barWidth = termWidth
86 if (not barWidth):
87 r, barWidth = getTerminalSize()
88 if (barWidth < 40):
89 barWidth = 40
90
91 barWidth = min(barWidth, self.__maxVal)
92
93 self.__active = True
94 if (ttyOnly and not sys.stdout.isatty()):
95 self.__active = False
96
97
98
99 self.__fd = fd
100 self.__barWidth = barWidth
101
102 self.__unit = 100/self.__barWidth
103 self.__fence = self.__unit
104 self.__mark = 10
105 self.__count = -1
106 self.__symbolT = [ '+', '+', '+', '+', '|', '+', '+', '+', '+', '|' ]
107
108
110 """
111 Update progress bar.
112 @param i: input value
113 """
114
115 if (not self.__active):
116 return
117
118 j = 100*i//self.__maxVal
119 k = 100*(i+1)//self.__maxVal
120
121
122
123 if (j >= self.__fence):
124 symbol = "-"
125 if (( j <= self.__mark and k >= self.__mark) or
126 ( j == k and j == self.__mark) or
127 (self.__fence > self.__mark)):
128
129 self.__count += 1
130 self.__mark += 10
131 symbol = self.__symbolT[self.__count]
132 self.__fd.write(symbol)
133 self.__fence += self.__unit
135 """ Finish progress bar output. """
136 if (not self.__active):
137 return
138 self.__fd.write("\n")
139
141 """
142 Test program for progress bar.
143 """
144
145 num = 200
146 pbar = ProgressBar(maxVal=num, ttyOnly=False)
147 for i in xrange(num):
148 pbar.update(i+1)
149 pbar.fini()
150
151 if ( __name__ == '__main__'): main()
152