~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/progress.py

  • Committer: Aaron Bentley
  • Date: 2007-12-25 04:17:50 UTC
  • mto: This revision was merged to the branch mainline in revision 3160.
  • Revision ID: aaron.bentley@utoronto.ca-20071225041750-t6chr3pmgnebvqcz
Handle non-directory parent conflicts (abentley, #177390)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
18
 
19
 
"""Progress indicators.
20
 
 
21
 
The usual way to use this is via bzrlib.ui.ui_factory.nested_progress_bar which
22
 
will maintain a ProgressBarStack for you.
23
 
 
24
 
For direct use, the factory ProgressBar will return an auto-detected progress
25
 
bar that should match your terminal type. You can manually create a
26
 
ProgressBarStack too if you need multiple levels of cooperating progress bars.
27
 
Note that bzrlib's internal functions use the ui module, so if you are using
28
 
bzrlib it really is best to use bzrlib.ui.ui_factory.
 
19
"""Simple text-mode progress indicator.
 
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.
29
27
"""
30
28
 
 
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
 
 
33
# TODO: If not on a tty perhaps just print '......' for the benefit of IDEs, etc
 
34
 
31
35
# TODO: Optionally show elapsed time instead/as well as ETA; nicer
32
36
# when the rate is unpredictable
33
37
 
189
193
    def finished(self):
190
194
        """Return this bar to its progress stack."""
191
195
        self.clear()
 
196
        assert self._stack is not None
192
197
        self._stack.return_pb(self)
193
198
 
194
199
    def note(self, fmt_string, *args, **kwargs):
293
298
        self.child_fraction = 0
294
299
        self._have_output = False
295
300
    
 
301
 
296
302
    def throttle(self, old_msg):
297
303
        """Return True if the bar was updated too recently"""
298
304
        # time.time consistently takes 40/4000 ms = 0.01 ms.
314
320
        return False
315
321
        
316
322
    def tick(self):
317
 
        self.update(self.last_msg, self.last_cnt, self.last_total,
 
323
        self.update(self.last_msg, self.last_cnt, self.last_total, 
318
324
                    self.child_fraction)
319
325
 
320
326
    def child_update(self, message, current, total):
324
330
                pass
325
331
            elif self.last_cnt + child_fraction <= self.last_total:
326
332
                self.child_fraction = child_fraction
 
333
            else:
 
334
                mutter('not updating child fraction')
327
335
        if self.last_msg is None:
328
336
            self.last_msg = ''
329
337
        self.tick()
330
338
 
331
 
    def update(self, msg, current_cnt=None, total_cnt=None,
 
339
    def update(self, msg, current_cnt=None, total_cnt=None, 
332
340
               child_fraction=0):
333
341
        """Update and redraw progress bar."""
334
342
        if msg is None:
430
438
        self._have_output = True
431
439
        #self.to_file.flush()
432
440
            
433
 
    def clear(self):
 
441
    def clear(self):        
434
442
        if self._have_output:
435
443
            self.to_file.write('\r%s\r' % (' ' * (self.width - 1)))
436
444
        self._have_output = False
483
491
    def note(self, *args, **kwargs):
484
492
        self.parent.note(*args, **kwargs)
485
493
 
486
 
 
487
 
class InstrumentedProgress(TTYProgressBar):
488
 
    """TTYProgress variant that tracks outcomes"""
489
 
 
490
 
    def __init__(self, *args, **kwargs):
491
 
        self.always_throttled = True
492
 
        self.never_throttle = False
493
 
        TTYProgressBar.__init__(self, *args, **kwargs)
494
 
 
495
 
    def throttle(self, old_message):
496
 
        if self.never_throttle:
497
 
            result =  False
498
 
        else:
499
 
            result = TTYProgressBar.throttle(self, old_message)
500
 
        if result is False:
501
 
            self.always_throttled = False
502
 
 
503
 
 
 
494
 
504
495
def str_tdelta(delt):
505
496
    if delt is None:
506
497
        return "-:--:--"
530
521
    
531
522
    total_duration = float(elapsed) * float(total) / float(current)
532
523
 
 
524
    assert total_duration >= elapsed
 
525
 
533
526
    if last_updates and len(last_updates) >= n_recent:
534
527
        avg = sum(last_updates) / float(len(last_updates))
535
528
        time_left = avg * (total - current)
556
549
            self.cur_phase = 0
557
550
        else:
558
551
            self.cur_phase += 1
 
552
        assert self.cur_phase < self.total
559
553
        self.pb.update(self.message, self.cur_phase, self.total)
 
554
 
 
555
 
 
556
def run_tests():
 
557
    import doctest
 
558
    result = doctest.testmod()
 
559
    if result[1] > 0:
 
560
        if result[0] == 0:
 
561
            print "All tests passed"
 
562
    else:
 
563
        print "No tests to run"
 
564
 
 
565
 
 
566
def demo():
 
567
    sleep = time.sleep
 
568
    
 
569
    print 'dumb-terminal test:'
 
570
    pb = DotsProgressBar()
 
571
    for i in range(100):
 
572
        pb.update('Leoparden', i, 99)
 
573
        sleep(0.1)
 
574
    sleep(1.5)
 
575
    pb.clear()
 
576
    sleep(1.5)
 
577
    
 
578
    print 'smart-terminal test:'
 
579
    pb = ProgressBar(show_pct=True, show_bar=True, show_spinner=False)
 
580
    for i in range(100):
 
581
        pb.update('Elephanten', i, 99)
 
582
        sleep(0.1)
 
583
    sleep(2)
 
584
    pb.clear()
 
585
    sleep(1)
 
586
 
 
587
    print 'done!'
 
588
 
 
589
if __name__ == "__main__":
 
590
    demo()