~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/progress.py

merge from aaron - fixes bare excepts, adds ancestor namespace

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
import sys
40
40
import time
41
41
import os
42
 
from collections import deque
 
42
 
 
43
 
 
44
def _width():
 
45
    """Return estimated terminal width.
 
46
 
 
47
    TODO: Do something smart on Windows?
 
48
 
 
49
    TODO: Is there anything that gets a better update when the window
 
50
          is resized while the program is running?
 
51
    """
 
52
    try:
 
53
        return int(os.environ['COLUMNS'])
 
54
    except (IndexError, KeyError, ValueError):
 
55
        return 80
43
56
 
44
57
 
45
58
def _supports_progress(f):
148
161
 
149
162
 
150
163
    def __init__(self, **kwargs):
151
 
        from bzrlib.osutils import terminal_width
152
164
        _BaseProgressBar.__init__(self, **kwargs)
153
165
        self.spin_pos = 0
154
 
        self.width = terminal_width()
 
166
        self.width = _width()
155
167
        self.start_time = None
156
168
        self.last_update = None
157
 
        self.last_updates = deque()
158
169
    
159
170
 
160
171
    def throttle(self):
168
179
            if interval > 0 and interval < self.MIN_PAUSE:
169
180
                return True
170
181
 
171
 
        self.last_updates.append(now - self.last_update)
172
182
        self.last_update = now
173
183
        return False
174
184
        
181
191
    def update(self, msg, current_cnt=None, total_cnt=None):
182
192
        """Update and redraw progress bar."""
183
193
 
184
 
        if current_cnt < 0:
185
 
            current_cnt = 0
186
 
            
187
 
        if current_cnt > total_cnt:
188
 
            total_cnt = current_cnt
189
 
 
190
194
        # save these for the tick() function
191
195
        self.last_msg = msg
192
196
        self.last_cnt = current_cnt
195
199
        if self.throttle():
196
200
            return 
197
201
        
 
202
        if total_cnt:
 
203
            assert current_cnt <= total_cnt
 
204
        if current_cnt:
 
205
            assert current_cnt >= 0
 
206
        
198
207
        if self.show_eta and self.start_time and total_cnt:
199
 
            eta = get_eta(self.start_time, current_cnt, total_cnt,
200
 
                    last_updates = self.last_updates)
 
208
            eta = get_eta(self.start_time, current_cnt, total_cnt)
201
209
            eta_str = " " + str_tdelta(eta)
202
210
        else:
203
211
            eta_str = ""
271
279
                             delt % 60)
272
280
 
273
281
 
274
 
def get_eta(start_time, current, total, enough_samples=3, last_updates=None, n_recent=10):
 
282
def get_eta(start_time, current, total, enough_samples=3):
275
283
    if start_time is None:
276
284
        return None
277
285
 
293
301
 
294
302
    assert total_duration >= elapsed
295
303
 
296
 
    if last_updates and len(last_updates) >= n_recent:
297
 
        while len(last_updates) > n_recent:
298
 
            last_updates.popleft()
299
 
        avg = sum(last_updates) / float(len(last_updates))
300
 
        time_left = avg * (total - current)
301
 
 
302
 
        old_time_left = total_duration - elapsed
303
 
 
304
 
        # We could return the average, or some other value here
305
 
        return (time_left + old_time_left) / 2
306
 
 
307
304
    return total_duration - elapsed
308
305
 
309
306