~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to progress.py

  • Committer: Aaron Bentley
  • Date: 2005-06-15 15:25:13 UTC
  • Revision ID: abentley@panoramicfeedback.com-20050615152512-e2afe3f794604a12
Added Michael Ellerman's shelf/unshelf

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2005 Aaron Bentley
2
 
# <aaron@aaronbentley.com>
 
2
# <aaron.bentley@utoronto.ca>
3
3
#
4
4
#    This program is free software; you can redistribute it and/or modify
5
5
#    it under the terms of the GNU General Public License as published by
17
17
 
18
18
import sys
19
19
import datetime
20
 
from bzrlib.progress import ProgressBar
21
20
 
22
21
class Progress(object):
23
22
    def __init__(self, units, current, total=None):
37
36
            return "%i of %i %s %.1f%%" % (self.current, self.total, self.units,
38
37
                                         self.percent)
39
38
        else:
40
 
            return "%i %s" (self.current, self.units)
41
 
 
42
 
def show_progress(pi, prog):
43
 
    pi.update(prog.units, prog.current, prog.total)
 
39
            return "%i %s" (self.current, self.units) 
 
40
 
 
41
class ProgressBar(object):
 
42
    def __init__(self):
 
43
        self.start = None
 
44
        object.__init__(self)
 
45
 
 
46
    def __call__(self, progress):
 
47
        if self.start is None:
 
48
            self.start = datetime.datetime.now()
 
49
        progress_bar(progress, start_time=self.start)
 
50
        
 
51
def divide_timedelta(delt, divisor):
 
52
    """Divides a timedelta object"""
 
53
    return datetime.timedelta(float(delt.days)/divisor, 
 
54
                              float(delt.seconds)/divisor, 
 
55
                              float(delt.microseconds)/divisor)
 
56
 
 
57
def str_tdelta(delt):
 
58
    if delt is None:
 
59
        return "-:--:--"
 
60
    return str(datetime.timedelta(delt.days, delt.seconds))
 
61
 
 
62
def get_eta(start_time, progress, enough_samples=20):
 
63
    if start_time is None or progress.current == 0:
 
64
        return None
 
65
    elif progress.current < enough_samples:
 
66
        return None
 
67
    elapsed = datetime.datetime.now() - start_time
 
68
    total_duration = divide_timedelta((elapsed) * long(progress.total), 
 
69
                                      progress.current)
 
70
    if elapsed < total_duration:
 
71
        eta = total_duration - elapsed
 
72
    else:
 
73
        eta = total_duration - total_duration
 
74
    return eta
 
75
 
 
76
def progress_bar(progress, start_time=None):
 
77
    eta = get_eta(start_time, progress)
 
78
    if start_time is not None:
 
79
        eta_str = " "+str_tdelta(eta)
 
80
    else:
 
81
        eta_str = ""
 
82
 
 
83
    fmt = " %i of %i %s (%.1f%%)"
 
84
    f = fmt % (progress.total, progress.total, progress.units, 100.0)
 
85
    max = len(f)
 
86
    cols = 77 - max
 
87
    if start_time is not None:
 
88
        cols -= len(eta_str)
 
89
    markers = int (float(cols) * progress.current / progress.total)
 
90
    txt = fmt % (progress.current, progress.total, progress.units,
 
91
                 progress.percent)
 
92
    sys.stderr.write("\r[%s%s]%s%s" % ('='*markers, ' '*(cols-markers), txt, 
 
93
                                       eta_str))
44
94
 
45
95
def clear_progress_bar():
46
96
    sys.stderr.write('\r%s\r' % (' '*79))
 
97
 
 
98
def spinner_str(progress, show_text=False):
 
99
    """
 
100
    Produces the string for a textual "spinner" progress indicator
 
101
    :param progress: an object represinting current progress
 
102
    :param show_text: If true, show progress text as well
 
103
    :return: The spinner string
 
104
 
 
105
    >>> spinner_str(Progress("baloons", 0))
 
106
    '|'
 
107
    >>> spinner_str(Progress("baloons", 5))
 
108
    '/'
 
109
    >>> spinner_str(Progress("baloons", 6), show_text=True)
 
110
    '- 6 baloons'
 
111
    """
 
112
    positions = ('|', '/', '-', '\\')
 
113
    text = positions[progress.current % 4]
 
114
    if show_text:
 
115
        text+=" %i %s" % (progress.current, progress.units)
 
116
    return text
 
117
 
 
118
def spinner(progress, show_text=False, output=sys.stderr):
 
119
    """
 
120
    Update a spinner progress indicator on an output
 
121
    :param progress: The progress to display
 
122
    :param show_text: If true, show text as well as spinner
 
123
    :param output: The output to write to
 
124
 
 
125
    >>> spinner(Progress("baloons", 6), show_text=True, output=sys.stdout)
 
126
    \r- 6 baloons
 
127
    """
 
128
    output.write('\r%s' % spinner_str(progress, show_text))
 
129
 
 
130
def run_tests():
 
131
    import doctest
 
132
    result = doctest.testmod()
 
133
    if result[1] > 0:
 
134
        if result[0] == 0:
 
135
            print "All tests passed"
 
136
    else:
 
137
        print "No tests to run"
 
138
 
 
139
def rewriting_supported(out=sys.stdout):
 
140
    return hasattr(out, 'isatty') and out.isatty()
 
141
 
 
142
if __name__ == "__main__":
 
143
    run_tests()