/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
649 by Martin Pool
- some cleanups for the progressbar method
1
# Copyright (C) 2005 Aaron Bentley <aaron.bentley@utoronto.ca>
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
2
# Copyright (C) 2005, 2006 Canonical <canonical.com>
648 by Martin Pool
- import aaron's progress-indicator code
3
#
4
#    This program is free software; you can redistribute it and/or modify
5
#    it under the terms of the GNU General Public License as published by
6
#    the Free Software Foundation; either version 2 of the License, or
7
#    (at your option) any later version.
8
#
9
#    This program is distributed in the hope that it will be useful,
10
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
#    GNU General Public License for more details.
13
#
14
#    You should have received a copy of the GNU General Public License
15
#    along with this program; if not, write to the Free Software
16
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
649 by Martin Pool
- some cleanups for the progressbar method
18
889 by Martin Pool
- show progress bar during inventory conversion to weave, and make profiling optional
19
"""Simple text-mode progress indicator.
649 by Martin Pool
- some cleanups for the progressbar method
20
21
To display an indicator, create a ProgressBar object.  Call it,
22
passing Progress objects indicating the current state.  When done,
23
call clear().
24
25
Progress is suppressed when output is not sent to a terminal, so as
26
not to clutter log files.
27
"""
28
652 by Martin Pool
doc
29
# TODO: should be a global option e.g. --silent that disables progress
30
# indicators, preferably without needing to adjust all code that
31
# potentially calls them.
32
962 by Martin Pool
todo
33
# TODO: If not on a tty perhaps just print '......' for the benefit of IDEs, etc
655 by Martin Pool
- better calculation of progress bar position
34
934 by Martin Pool
todo
35
# TODO: Optionally show elapsed time instead/as well as ETA; nicer
36
# when the rate is unpredictable
37
649 by Martin Pool
- some cleanups for the progressbar method
38
648 by Martin Pool
- import aaron's progress-indicator code
39
import sys
660 by Martin Pool
- use plain unix time, not datetime module
40
import time
964 by Martin Pool
- show progress on dumb terminals by printing dots
41
import os
1185.16.75 by Martin Pool
- improved eta estimation for progress bar
42
from collections import deque
648 by Martin Pool
- import aaron's progress-indicator code
43
649 by Martin Pool
- some cleanups for the progressbar method
44
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
45
import bzrlib.errors as errors
1551.2.27 by Aaron Bentley
Got propogation under test
46
from bzrlib.trace import mutter 
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
47
48
649 by Martin Pool
- some cleanups for the progressbar method
49
def _supports_progress(f):
695 by Martin Pool
- don't display progress bars on really dumb terminals
50
    if not hasattr(f, 'isatty'):
51
        return False
52
    if not f.isatty():
53
        return False
54
    if os.environ.get('TERM') == 'dumb':
55
        # e.g. emacs compile window
56
        return False
57
    return True
649 by Martin Pool
- some cleanups for the progressbar method
58
59
60
964 by Martin Pool
- show progress on dumb terminals by printing dots
61
def ProgressBar(to_file=sys.stderr, **kwargs):
62
    """Abstract factory"""
63
    if _supports_progress(to_file):
64
        return TTYProgressBar(to_file=to_file, **kwargs)
65
    else:
66
        return DotsProgressBar(to_file=to_file, **kwargs)
67
    
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
68
 
69
class ProgressBarStack(object):
70
    """A stack of progress bars."""
71
72
    def __init__(self,
73
                 to_file=sys.stderr,
74
                 show_pct=False,
1551.2.33 by Aaron Bentley
Hide ETA, show spinner by default
75
                 show_spinner=True,
76
                 show_eta=False,
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
77
                 show_bar=True,
78
                 show_count=True,
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
79
                 to_messages_file=sys.stdout,
80
                 klass=None):
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
81
        """Setup the stack with the parameters the progress bars should have."""
82
        self._to_file = to_file
83
        self._show_pct = show_pct
84
        self._show_spinner = show_spinner
85
        self._show_eta = show_eta
86
        self._show_bar = show_bar
87
        self._show_count = show_count
88
        self._to_messages_file = to_messages_file
89
        self._stack = []
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
90
        self._klass = klass or TTYProgressBar
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
91
1551.2.29 by Aaron Bentley
Got stack handling under test
92
    def top(self):
93
        if len(self._stack) != 0:
94
            return self._stack[-1]
95
        else:
96
            return None
97
1558.8.1 by Aaron Bentley
Fix overall progress bar's interaction with 'note' and 'warning'
98
    def bottom(self):
99
        if len(self._stack) != 0:
100
            return self._stack[0]
101
        else:
102
            return None
103
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
104
    def get_nested(self):
105
        """Return a nested progress bar."""
1551.2.29 by Aaron Bentley
Got stack handling under test
106
        if len(self._stack) == 0:
107
            func = self._klass
108
        else:
109
            func = self.top().child_progress
110
        new_bar = func(to_file=self._to_file,
111
                       show_pct=self._show_pct,
112
                       show_spinner=self._show_spinner,
113
                       show_eta=self._show_eta,
114
                       show_bar=self._show_bar,
115
                       show_count=self._show_count,
116
                       to_messages_file=self._to_messages_file,
117
                       _stack=self)
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
118
        self._stack.append(new_bar)
119
        return new_bar
120
121
    def return_pb(self, bar):
122
        """Return bar after its been used."""
1594.1.4 by Robert Collins
Fix identity test in ProgressBarStack.return_pb
123
        if bar is not self._stack[-1]:
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
124
            raise errors.MissingProgressBarFinish()
125
        self._stack.pop()
126
127
 
964 by Martin Pool
- show progress on dumb terminals by printing dots
128
class _BaseProgressBar(object):
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
129
964 by Martin Pool
- show progress on dumb terminals by printing dots
130
    def __init__(self,
131
                 to_file=sys.stderr,
132
                 show_pct=False,
133
                 show_spinner=False,
134
                 show_eta=True,
135
                 show_bar=True,
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
136
                 show_count=True,
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
137
                 to_messages_file=sys.stdout,
138
                 _stack=None):
964 by Martin Pool
- show progress on dumb terminals by printing dots
139
        object.__init__(self)
140
        self.to_file = to_file
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
141
        self.to_messages_file = to_messages_file
964 by Martin Pool
- show progress on dumb terminals by printing dots
142
        self.last_msg = None
143
        self.last_cnt = None
144
        self.last_total = None
145
        self.show_pct = show_pct
146
        self.show_spinner = show_spinner
147
        self.show_eta = show_eta
148
        self.show_bar = show_bar
149
        self.show_count = show_count
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
150
        self._stack = _stack
151
152
    def finished(self):
153
        """Return this bar to its progress stack."""
154
        self.clear()
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
155
        assert self._stack is not None
1594.1.1 by Robert Collins
Introduce new bzr progress bar api. ui_factory.nested_progress_bar.
156
        self._stack.return_pb(self)
1104 by Martin Pool
- Add a simple UIFactory
157
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
158
    def note(self, fmt_string, *args, **kwargs):
159
        """Record a note without disrupting the progress bar."""
160
        self.clear()
161
        self.to_messages_file.write(fmt_string % args)
162
        self.to_messages_file.write('\n')
1104 by Martin Pool
- Add a simple UIFactory
163
1551.2.29 by Aaron Bentley
Got stack handling under test
164
    def child_progress(self, **kwargs):
165
        return ChildProgress(**kwargs)
166
1104 by Martin Pool
- Add a simple UIFactory
167
168
class DummyProgress(_BaseProgressBar):
169
    """Progress-bar standin that does nothing.
170
171
    This can be used as the default argument for methods that
172
    take an optional progress indicator."""
173
    def tick(self):
174
        pass
175
176
    def update(self, msg=None, current=None, total=None):
177
        pass
178
1551.2.27 by Aaron Bentley
Got propogation under test
179
    def child_update(self, message, current, total):
180
        pass
181
1104 by Martin Pool
- Add a simple UIFactory
182
    def clear(self):
183
        pass
964 by Martin Pool
- show progress on dumb terminals by printing dots
184
        
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
185
    def note(self, fmt_string, *args, **kwargs):
186
        """See _BaseProgressBar.note()."""
1534.5.9 by Robert Collins
Advise users running upgrade on a checkout to also run it on the branch.
187
1551.2.29 by Aaron Bentley
Got stack handling under test
188
    def child_progress(self, **kwargs):
189
        return DummyProgress(**kwargs)
1534.5.9 by Robert Collins
Advise users running upgrade on a checkout to also run it on the branch.
190
964 by Martin Pool
- show progress on dumb terminals by printing dots
191
class DotsProgressBar(_BaseProgressBar):
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
192
964 by Martin Pool
- show progress on dumb terminals by printing dots
193
    def __init__(self, **kwargs):
194
        _BaseProgressBar.__init__(self, **kwargs)
195
        self.last_msg = None
196
        self.need_nl = False
197
        
198
    def tick(self):
199
        self.update()
200
        
201
    def update(self, msg=None, current_cnt=None, total_cnt=None):
202
        if msg and msg != self.last_msg:
203
            if self.need_nl:
204
                self.to_file.write('\n')
205
            
206
            self.to_file.write(msg + ': ')
207
            self.last_msg = msg
208
        self.need_nl = True
209
        self.to_file.write('.')
210
        
211
    def clear(self):
212
        if self.need_nl:
213
            self.to_file.write('\n')
214
        
1551.2.28 by Aaron Bentley
Ensure all ProgressBar implementations can be used as parents
215
    def child_update(self, message, current, total):
216
        self.tick()
964 by Martin Pool
- show progress on dumb terminals by printing dots
217
    
218
class TTYProgressBar(_BaseProgressBar):
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
219
    """Progress bar display object.
220
221
    Several options are available to control the display.  These can
222
    be passed as parameters to the constructor or assigned at any time:
223
224
    show_pct
225
        Show percentage complete.
226
    show_spinner
227
        Show rotating baton.  This ticks over on every update even
228
        if the values don't change.
229
    show_eta
230
        Show predicted time-to-completion.
231
    show_bar
232
        Show bar graph.
233
    show_count
234
        Show numerical counts.
235
236
    The output file should be in line-buffered or unbuffered mode.
237
    """
238
    SPIN_CHARS = r'/-\|'
661 by Martin Pool
- limit rate at which progress bar is updated
239
    MIN_PAUSE = 0.1 # seconds
240
964 by Martin Pool
- show progress on dumb terminals by printing dots
241
242
    def __init__(self, **kwargs):
1185.33.60 by Martin Pool
Use full terminal width for verbose test output.
243
        from bzrlib.osutils import terminal_width
964 by Martin Pool
- show progress on dumb terminals by printing dots
244
        _BaseProgressBar.__init__(self, **kwargs)
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
245
        self.spin_pos = 0
1185.33.60 by Martin Pool
Use full terminal width for verbose test output.
246
        self.width = terminal_width()
964 by Martin Pool
- show progress on dumb terminals by printing dots
247
        self.start_time = None
248
        self.last_update = None
1185.16.75 by Martin Pool
- improved eta estimation for progress bar
249
        self.last_updates = deque()
1551.2.28 by Aaron Bentley
Ensure all ProgressBar implementations can be used as parents
250
        self.child_fraction = 0
964 by Martin Pool
- show progress on dumb terminals by printing dots
251
    
252
253
    def throttle(self):
254
        """Return True if the bar was updated too recently"""
255
        now = time.time()
256
        if self.start_time is None:
257
            self.start_time = self.last_update = now
258
            return False
259
        else:
260
            interval = now - self.last_update
261
            if interval > 0 and interval < self.MIN_PAUSE:
262
                return True
263
1185.16.75 by Martin Pool
- improved eta estimation for progress bar
264
        self.last_updates.append(now - self.last_update)
964 by Martin Pool
- show progress on dumb terminals by printing dots
265
        self.last_update = now
266
        return False
929 by Martin Pool
- progress bar: avoid repeatedly checking screen width
267
        
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
268
269
    def tick(self):
1551.2.27 by Aaron Bentley
Got propogation under test
270
        self.update(self.last_msg, self.last_cnt, self.last_total, 
271
                    self.child_fraction)
272
1551.2.28 by Aaron Bentley
Ensure all ProgressBar implementations can be used as parents
273
    def child_update(self, message, current, total):
1551.2.35 by Aaron Bentley
Fix division-by-zero
274
        if current is not None and total != 0:
1551.2.30 by Aaron Bentley
Bugfixes to progress stuff
275
            child_fraction = float(current) / total
276
            if self.last_cnt is None:
277
                pass
278
            elif self.last_cnt + child_fraction <= self.last_total:
279
                self.child_fraction = child_fraction
280
            else:
281
                mutter('not updating child fraction')
282
        if self.last_msg is None:
283
            self.last_msg = ''
1551.2.28 by Aaron Bentley
Ensure all ProgressBar implementations can be used as parents
284
        self.tick()
285
286
1551.2.27 by Aaron Bentley
Got propogation under test
287
    def update(self, msg, current_cnt=None, total_cnt=None, 
288
               child_fraction=0):
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
289
        """Update and redraw progress bar."""
1551.2.27 by Aaron Bentley
Got propogation under test
290
        self.child_fraction = child_fraction
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
291
1308 by Martin Pool
- make progress bar more tolerant of out-of-range values
292
        if current_cnt < 0:
293
            current_cnt = 0
294
            
295
        if current_cnt > total_cnt:
296
            total_cnt = current_cnt
1570.1.9 by Robert Collins
Do not throttle updates to progress bars that change the message.
297
        
298
        old_msg = self.last_msg
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
299
        # save these for the tick() function
300
        self.last_msg = msg
301
        self.last_cnt = current_cnt
302
        self.last_total = total_cnt
303
            
1570.1.9 by Robert Collins
Do not throttle updates to progress bars that change the message.
304
        if old_msg == self.last_msg and self.throttle():
964 by Martin Pool
- show progress on dumb terminals by printing dots
305
            return 
661 by Martin Pool
- limit rate at which progress bar is updated
306
        
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
307
        if self.show_eta and self.start_time and total_cnt:
1551.2.30 by Aaron Bentley
Bugfixes to progress stuff
308
            eta = get_eta(self.start_time, current_cnt+child_fraction, 
309
                    total_cnt, last_updates = self.last_updates)
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
310
            eta_str = " " + str_tdelta(eta)
311
        else:
312
            eta_str = ""
313
314
        if self.show_spinner:
315
            spin_str = self.SPIN_CHARS[self.spin_pos % 4] + ' '            
316
        else:
317
            spin_str = ''
318
319
        # always update this; it's also used for the bar
320
        self.spin_pos += 1
321
322
        if self.show_pct and total_cnt and current_cnt:
1551.2.30 by Aaron Bentley
Bugfixes to progress stuff
323
            pct = 100.0 * ((current_cnt + child_fraction) / total_cnt)
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
324
            pct_str = ' (%5.1f%%)' % pct
325
        else:
326
            pct_str = ''
327
328
        if not self.show_count:
329
            count_str = ''
330
        elif current_cnt is None:
331
            count_str = ''
332
        elif total_cnt is None:
333
            count_str = ' %i' % (current_cnt)
334
        else:
335
            # make both fields the same size
336
            t = '%i' % (total_cnt)
337
            c = '%*i' % (len(t), current_cnt)
338
            count_str = ' ' + c + '/' + t 
339
340
        if self.show_bar:
341
            # progress bar, if present, soaks up all remaining space
929 by Martin Pool
- progress bar: avoid repeatedly checking screen width
342
            cols = self.width - 1 - len(msg) - len(spin_str) - len(pct_str) \
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
343
                   - len(eta_str) - len(count_str) - 3
344
345
            if total_cnt:
346
                # number of markers highlighted in bar
1551.2.30 by Aaron Bentley
Bugfixes to progress stuff
347
                markers = int(round(float(cols) * 
348
                              (current_cnt + child_fraction) / total_cnt))
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
349
                bar_str = '[' + ('=' * markers).ljust(cols) + '] '
669 by Martin Pool
- don't show progress bar unless completion is known
350
            elif False:
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
351
                # don't know total, so can't show completion.
352
                # so just show an expanded spinning thingy
353
                m = self.spin_pos % cols
668 by Martin Pool
- fix sweeping bar progress indicator
354
                ms = (' ' * m + '*').ljust(cols)
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
355
                
356
                bar_str = '[' + ms + '] '
669 by Martin Pool
- don't show progress bar unless completion is known
357
            else:
358
                bar_str = ''
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
359
        else:
360
            bar_str = ''
361
362
        m = spin_str + bar_str + msg + count_str + pct_str + eta_str
363
929 by Martin Pool
- progress bar: avoid repeatedly checking screen width
364
        assert len(m) < self.width
365
        self.to_file.write('\r' + m.ljust(self.width - 1))
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
366
        #self.to_file.flush()
367
            
964 by Martin Pool
- show progress on dumb terminals by printing dots
368
    def clear(self):        
929 by Martin Pool
- progress bar: avoid repeatedly checking screen width
369
        self.to_file.write('\r%s\r' % (' ' * (self.width - 1)))
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
370
        #self.to_file.flush()        
649 by Martin Pool
- some cleanups for the progressbar method
371
1551.2.27 by Aaron Bentley
Got propogation under test
372
1551.2.28 by Aaron Bentley
Ensure all ProgressBar implementations can be used as parents
373
class ChildProgress(_BaseProgressBar):
1551.2.27 by Aaron Bentley
Got propogation under test
374
    """A progress indicator that pushes its data to the parent"""
1551.2.29 by Aaron Bentley
Got stack handling under test
375
    def __init__(self, _stack, **kwargs):
376
        _BaseProgressBar.__init__(self, _stack=_stack, **kwargs)
377
        self.parent = _stack.top()
1551.2.27 by Aaron Bentley
Got propogation under test
378
        self.current = None
379
        self.total = None
380
        self.child_fraction = 0
381
        self.message = None
382
383
    def update(self, msg, current_cnt=None, total_cnt=None):
384
        self.current = current_cnt
385
        self.total = total_cnt
386
        self.message = msg
387
        self.child_fraction = 0
388
        self.tick()
389
390
    def child_update(self, message, current, total):
1551.2.35 by Aaron Bentley
Fix division-by-zero
391
        if current is None or total == 0:
1551.2.30 by Aaron Bentley
Bugfixes to progress stuff
392
            self.child_fraction = 0
393
        else:
394
            self.child_fraction = float(current) / total
1551.2.27 by Aaron Bentley
Got propogation under test
395
        self.tick()
396
397
    def tick(self):
1551.2.30 by Aaron Bentley
Bugfixes to progress stuff
398
        if self.current is None:
399
            count = None
400
        else:
401
            count = self.current+self.child_fraction
402
            if count > self.total:
403
                mutter('clamping count of %d to %d' % (count, self.total))
404
                count = self.total
1551.2.27 by Aaron Bentley
Got propogation under test
405
        self.parent.child_update(self.message, count, self.total)
406
1551.2.29 by Aaron Bentley
Got stack handling under test
407
    def clear(self):
1551.2.30 by Aaron Bentley
Bugfixes to progress stuff
408
        pass
1551.2.29 by Aaron Bentley
Got stack handling under test
409
1551.2.27 by Aaron Bentley
Got propogation under test
410
 
648 by Martin Pool
- import aaron's progress-indicator code
411
def str_tdelta(delt):
412
    if delt is None:
413
        return "-:--:--"
660 by Martin Pool
- use plain unix time, not datetime module
414
    delt = int(round(delt))
415
    return '%d:%02d:%02d' % (delt/3600,
416
                             (delt/60) % 60,
417
                             delt % 60)
418
419
1185.16.75 by Martin Pool
- improved eta estimation for progress bar
420
def get_eta(start_time, current, total, enough_samples=3, last_updates=None, n_recent=10):
660 by Martin Pool
- use plain unix time, not datetime module
421
    if start_time is None:
422
        return None
423
424
    if not total:
425
        return None
426
427
    if current < enough_samples:
428
        return None
429
430
    if current > total:
431
        return None                     # wtf?
432
433
    elapsed = time.time() - start_time
434
435
    if elapsed < 2.0:                   # not enough time to estimate
436
        return None
437
    
438
    total_duration = float(elapsed) * float(total) / float(current)
439
440
    assert total_duration >= elapsed
441
1185.16.75 by Martin Pool
- improved eta estimation for progress bar
442
    if last_updates and len(last_updates) >= n_recent:
443
        while len(last_updates) > n_recent:
444
            last_updates.popleft()
445
        avg = sum(last_updates) / float(len(last_updates))
446
        time_left = avg * (total - current)
447
448
        old_time_left = total_duration - elapsed
449
450
        # We could return the average, or some other value here
451
        return (time_left + old_time_left) / 2
452
660 by Martin Pool
- use plain unix time, not datetime module
453
    return total_duration - elapsed
648 by Martin Pool
- import aaron's progress-indicator code
454
649 by Martin Pool
- some cleanups for the progressbar method
455
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
456
class ProgressPhase(object):
457
    """Update progress object with the current phase"""
458
    def __init__(self, message, total, pb):
459
        object.__init__(self)
460
        self.pb = pb
461
        self.message = message
462
        self.total = total
463
        self.cur_phase = None
464
465
    def next_phase(self):
466
        if self.cur_phase is None:
467
            self.cur_phase = 0
468
        else:
469
            self.cur_phase += 1
470
        assert self.cur_phase < self.total 
471
        self.pb.update(self.message, self.cur_phase, self.total)
472
473
648 by Martin Pool
- import aaron's progress-indicator code
474
def run_tests():
475
    import doctest
476
    result = doctest.testmod()
477
    if result[1] > 0:
478
        if result[0] == 0:
479
            print "All tests passed"
480
    else:
481
        print "No tests to run"
649 by Martin Pool
- some cleanups for the progressbar method
482
483
484
def demo():
964 by Martin Pool
- show progress on dumb terminals by printing dots
485
    sleep = time.sleep
486
    
487
    print 'dumb-terminal test:'
488
    pb = DotsProgressBar()
489
    for i in range(100):
490
        pb.update('Leoparden', i, 99)
491
        sleep(0.1)
492
    sleep(1.5)
493
    pb.clear()
494
    sleep(1.5)
495
    
496
    print 'smart-terminal test:'
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
497
    pb = ProgressBar(show_pct=True, show_bar=True, show_spinner=False)
649 by Martin Pool
- some cleanups for the progressbar method
498
    for i in range(100):
658 by Martin Pool
- clean up and add a bunch of options to the progress indicator
499
        pb.update('Elephanten', i, 99)
500
        sleep(0.1)
501
    sleep(2)
502
    pb.clear()
503
    sleep(1)
964 by Martin Pool
- show progress on dumb terminals by printing dots
504
649 by Martin Pool
- some cleanups for the progressbar method
505
    print 'done!'
506
648 by Martin Pool
- import aaron's progress-indicator code
507
if __name__ == "__main__":
649 by Martin Pool
- some cleanups for the progressbar method
508
    demo()