|
3 | 3 | ''' |
4 | 4 | from time import time |
5 | 5 | from math import log |
| 6 | +from terminalsize import get_terminal_size |
6 | 7 |
|
7 | | -class _JdtAlreadyClosedError(BaseException): |
| 8 | +class JdtAlreadyClosedError(BaseException): |
8 | 9 | '''Cannot update Jdt after complete. ''' |
9 | 10 |
|
10 | | -class _CannotDisplayMultiJdts(BaseException): |
11 | | - pass |
12 | | - |
13 | | -def smartUnit(size,is_speed=False): |
14 | | - if size==0: |
| 11 | +def smartUnit(size, is_speed=False): |
| 12 | + ''' |
| 13 | + n_byte => 6-char string with smart unit (KB, MG, GB) |
| 14 | + ''' |
| 15 | + if size == 0: |
15 | 16 | return ' 0 ' |
16 | 17 | if is_speed: |
17 | | - magnitude=int(log(size,1024)) |
| 18 | + magnitude = int(log(size, 1024)) |
18 | 19 | else: |
19 | | - magnitude=int(log(size/9,1024)) |
20 | | - magnitude=min(magnitude,3) |
21 | | - return format(size/1024**magnitude,'4.0f')+ \ |
22 | | - {0:'B ',1:'KB',2:'MB',3:'GB'}[magnitude] |
23 | | - |
24 | | -class CommJdt: |
25 | | - ''' |
26 | | - msg [****____] 50% Total: 44MB Done: 22MB Speed: 1MB/s |
27 | | - ''' |
28 | | - occupied=False |
29 | | - |
30 | | - def __init__(self,goal,msg='',width=15): |
31 | | - if self.__class__.occupied: |
32 | | - raise _CannotDisplayMultiJdts |
33 | | - self.__class__.occupied=True |
34 | | - self.active=True |
35 | | - self.width=width |
36 | | - self.goal=goal |
37 | | - self.msg=msg |
38 | | - self.last_time=time() |
39 | | - self.last_done=0 |
40 | | - |
41 | | - def update(self,done): |
42 | | - if not self.active: |
43 | | - raise _JdtAlreadyClosedError |
44 | | - dt=time()-self.last_time |
45 | | - self.last_time=time() |
46 | | - dd=done-self.last_done |
47 | | - self.last_done=done |
48 | | - if dt==0: |
49 | | - speed=999999999 |
50 | | - else: |
51 | | - speed=dd/dt |
52 | | - |
53 | | - progress=done/self.goal |
54 | | - bar=int(self.width*progress) |
55 | | - print('\r'+self.msg, \ |
56 | | - '['+'*'*bar+'_'*(self.width-bar)+']'+ \ |
57 | | - format(progress,'4.0%'), \ |
58 | | - 'Total:',smartUnit(self.goal), \ |
59 | | - 'Done:',smartUnit(done), \ |
60 | | - 'Speed:',smartUnit(speed,is_speed=True)+'/s', \ |
61 | | - end='',flush=True) |
62 | | - |
63 | | - def complete(self): |
64 | | - self.active=False |
65 | | - self.__class__.occupied=False |
66 | | - print('\r'+self.msg,'['+'#'*self.width+'] Complete! Total:', \ |
67 | | - smartUnit(self.goal),' '*22) |
| 20 | + magnitude = int(log(size / 9, 1024)) |
| 21 | + magnitude = min(magnitude, 3) |
| 22 | + return format(size / 1024**magnitude, '4.0f') + \ |
| 23 | + {0: 'B ', 1: 'KB', 2: 'MB', 3: 'GB'}[magnitude] |
68 | 24 |
|
69 | 25 | class Jdt: |
70 | | - ''' |
71 | | - msg [****____] 50% Total: 44 Done: 22 |
72 | | - ''' |
73 | | - occupied=False |
74 | | - |
75 | | - def __init__(self,goal,msg='',width=32, UPP = 1): |
76 | | - if self.__class__.occupied: |
77 | | - raise _CannotDisplayMultiJdts |
78 | | - self.__class__.occupied=True |
79 | | - self.active=True |
80 | | - self.width=width |
81 | | - self.goal=goal |
82 | | - self.msg=msg |
| 26 | + MIN_BAR_WIDTH = 6 |
| 27 | + |
| 28 | + def __init__(self, goal, msg='', width=None, UPP = 1): |
| 29 | + self.active = True |
| 30 | + self.goal = goal |
| 31 | + self.msg = msg |
| 32 | + if width is not None: |
| 33 | + print('jdt Warning: argument `width` is deprecated. ') |
83 | 34 | self.done = 0 |
84 | 35 | self.UPP = UPP |
85 | 36 | self.UPP_count = 0 |
86 | 37 | # updates per print |
87 | 38 |
|
88 | | - def update(self,done): |
| 39 | + def getSuffix(self, done, progress): |
| 40 | + return '%s Total: %d Done: %d' % ( |
| 41 | + format(progress, '4.0%'), |
| 42 | + self.goal, |
| 43 | + done |
| 44 | + ) |
| 45 | + |
| 46 | + def update(self, new_done, symbol = '*', getSuffix = None): |
89 | 47 | if not self.active: |
90 | | - raise _JdtAlreadyClosedError |
91 | | - self.done = done |
92 | | - self.UPP_count += 1 |
93 | | - if self.UPP_count == self.UPP: |
94 | | - self.UPP_count = 0 |
95 | | - else: |
| 48 | + raise JdtAlreadyClosedError |
| 49 | + self.done = new_done |
| 50 | + if self.UPP_count != self.UPP: |
| 51 | + self.UPP_count += 1 |
96 | 52 | return |
97 | | - progress=done/self.goal |
98 | | - bar=int(self.width*progress) |
99 | | - print('\r'+self.msg, \ |
100 | | - '['+'*'*bar+'_'*(self.width-bar)+']'+ \ |
101 | | - format(progress,'4.0%'), \ |
102 | | - 'Total:',self.goal, \ |
103 | | - 'Done:',done, \ |
104 | | - end='',flush=True) |
105 | | - |
| 53 | + self.UPP_count = 0 |
| 54 | + progress = new_done / self.goal |
| 55 | + terminal_width = get_terminal_size()[0] - 4 |
| 56 | + if getSuffix is None: |
| 57 | + getSuffix = self.getSuffix |
| 58 | + suffix = getSuffix(new_done, progress) |
| 59 | + msg_and_bar_width = terminal_width - len(suffix) |
| 60 | + msg_width = min(len(self.msg), int(msg_and_bar_width / 2)) |
| 61 | + msg_to_print = self.msg[:msg_width] |
| 62 | + bar_width = msg_and_bar_width - msg_width |
| 63 | + if bar_width < self.MIN_BAR_WIDTH: |
| 64 | + bar_width = terminal_width - 2 |
| 65 | + msg_to_print = '' |
| 66 | + suffix = '' |
| 67 | + bar_inner_width = bar_width - 2 |
| 68 | + bar_fill_width = int(bar_inner_width * progress) |
| 69 | + bar_empty_width = bar_inner_width - bar_fill_width |
| 70 | + print('\r', msg_to_print, ' ', |
| 71 | + '[', symbol * bar_fill_width, '_'*bar_empty_width, ']', |
| 72 | + ' ', suffix, |
| 73 | + sep = '', end='',flush=True) |
| 74 | + |
106 | 75 | def acc(self): |
107 | 76 | self.update(self.done + 1) |
108 | 77 |
|
109 | 78 | def complete(self): |
110 | | - self.active=False |
111 | | - self.__class__.occupied=False |
112 | | - print('\r'+self.msg,'['+'#'*self.width+'] Complete! Total:', \ |
113 | | - self.goal,' '*22) |
| 79 | + def getSuffix(done, progress): |
| 80 | + return 'Complete! Total: %d' % self.goal |
| 81 | + self.update(self.goal), symbol = '#', getSuffix = getSuffix) |
| 82 | + self.active = False |
| 83 | + |
| 84 | +class CommJdt(Jdt): |
| 85 | + def __init__(self, *argv, **kw): |
| 86 | + super(__class__, self).__init__(*argv, **kw) |
| 87 | + self.last_time = time() |
| 88 | + |
| 89 | + def update(self, new_done, *argv, **kw): |
| 90 | + delta_time = time() - self.last_time |
| 91 | + self.last_time += delta_time |
| 92 | + delta_done = new_done - self.done |
| 93 | + self.done = new_done |
| 94 | + if delta_time == 0: |
| 95 | + speed = 999999999 |
| 96 | + else: |
| 97 | + speed = delta_done / delta_time |
| 98 | + def getSuffix(done, progress): |
| 99 | + nonlocal speed |
| 100 | + return '%s Total: %s Done: %s Speed: %s' % ( |
| 101 | + format(progress, '4.0%'), |
| 102 | + smartUnit(self.goal), |
| 103 | + smartUnit(done), |
| 104 | + smartUnit(speed, is_speed = True) |
| 105 | + ) |
| 106 | + kw['getSuffix'] = getSuffix |
| 107 | + super(__class__, self).update(new_done, *argv, **kw) |
114 | 108 |
|
115 | 109 | if __name__=='__main__': |
116 | 110 | from time import sleep |
|
0 commit comments