~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to progress.py

  • Committer: Aaron Bentley
  • Date: 2005-06-15 15:53:52 UTC
  • Revision ID: abentley@panoramicfeedback.com-20050615155352-afb1ccd8c20839c7
updated docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
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):
39
38
        else:
40
39
            return "%i %s" (self.current, self.units) 
41
40
 
42
 
def show_progress(pi, prog):
43
 
    pi.update(prog.units, prog.current, prog.total)
 
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)
44
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))
 
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()