~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to progress.py

  • Committer: Aaron Bentley
  • Date: 2005-06-01 23:18:28 UTC
  • Revision ID: abentley@bruiser-20050601231828-9083a3d5b1aaae74
Ensured temp dir is on same filesystem as output dir

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):
24
23
        self.units = units
25
24
        self.current = current
26
25
        self.total = total
27
 
 
28
 
    def _get_percent(self):
29
 
        if self.total is None:
30
 
            return None
31
 
        return 100.0 * self.current / self.total
32
 
 
33
 
    percent = property(_get_percent)
 
26
        self.percent = None
 
27
        if self.total is not None:
 
28
            self.percent = 100.0 * current / total
34
29
 
35
30
    def __str__(self):
36
31
        if self.total is not None:
39
34
        else:
40
35
            return "%i %s" (self.current, self.units) 
41
36
 
42
 
def show_progress(pi, prog):
43
 
    pi.update(prog.units, prog.current, prog.total)
 
37
class ProgressBar(object):
 
38
    def __init__(self):
 
39
        self.start = None
 
40
        object.__init__(self)
 
41
 
 
42
    def __call__(self, progress):
 
43
        if self.start is None:
 
44
            self.start = datetime.datetime.now()
 
45
        progress_bar(progress, start_time=self.start)
44
46
        
 
47
def divide_timedelta(delt, divisor):
 
48
    """Divides a timedelta object"""
 
49
    return datetime.timedelta(float(delt.days)/divisor, 
 
50
                              float(delt.seconds)/divisor, 
 
51
                              float(delt.microseconds)/divisor)
 
52
 
 
53
def str_tdelta(delt):
 
54
    if delt is None:
 
55
        return "-:--:--"
 
56
    return str(datetime.timedelta(delt.days, delt.seconds))
 
57
 
 
58
def get_eta(start_time, progress, enough_samples=20):
 
59
    if start_time is None or progress.current == 0:
 
60
        return None
 
61
    elif progress.current < enough_samples:
 
62
        return None
 
63
    elapsed = datetime.datetime.now() - start_time
 
64
    total_duration = divide_timedelta((elapsed) * long(progress.total), 
 
65
                                      progress.current)
 
66
    if elapsed < total_duration:
 
67
        eta = total_duration - elapsed
 
68
    else:
 
69
        eta = total_duration - total_duration
 
70
    return eta
 
71
 
 
72
def progress_bar(progress, start_time=None):
 
73
    eta = get_eta(start_time, progress)
 
74
    if start_time is not None:
 
75
        eta_str = " "+str_tdelta(eta)
 
76
    else:
 
77
        eta_str = ""
 
78
 
 
79
    fmt = " %i of %i %s (%.1f%%)"
 
80
    f = fmt % (progress.total, progress.total, progress.units, 100.0)
 
81
    max = len(f)
 
82
    cols = 77 - max
 
83
    if start_time is not None:
 
84
        cols -= len(eta_str)
 
85
    markers = int (float(cols) * progress.current / progress.total)
 
86
    txt = fmt % (progress.current, progress.total, progress.units,
 
87
                 progress.percent)
 
88
    sys.stderr.write("\r[%s%s]%s%s" % ('='*markers, ' '*(cols-markers), txt, 
 
89
                                       eta_str))
 
90
 
45
91
def clear_progress_bar():
46
92
    sys.stderr.write('\r%s\r' % (' '*79))
 
93
 
 
94
def spinner_str(progress, show_text=False):
 
95
    """
 
96
    Produces the string for a textual "spinner" progress indicator
 
97
    :param progress: an object represinting current progress
 
98
    :param show_text: If true, show progress text as well
 
99
    :return: The spinner string
 
100
 
 
101
    >>> spinner_str(Progress("baloons", 0))
 
102
    '|'
 
103
    >>> spinner_str(Progress("baloons", 5))
 
104
    '/'
 
105
    >>> spinner_str(Progress("baloons", 6), show_text=True)
 
106
    '- 6 baloons'
 
107
    """
 
108
    positions = ('|', '/', '-', '\\')
 
109
    text = positions[progress.current % 4]
 
110
    if show_text:
 
111
        text+=" %i %s" % (progress.current, progress.units)
 
112
    return text
 
113
 
 
114
def spinner(progress, show_text=False, output=sys.stderr):
 
115
    """
 
116
    Update a spinner progress indicator on an output
 
117
    :param progress: The progress to display
 
118
    :param show_text: If true, show text as well as spinner
 
119
    :param output: The output to write to
 
120
 
 
121
    >>> spinner(Progress("baloons", 6), show_text=True, output=sys.stdout)
 
122
    \r- 6 baloons
 
123
    """
 
124
    output.write('\r%s' % spinner_str(progress, show_text))
 
125
 
 
126
def run_tests():
 
127
    import doctest
 
128
    result = doctest.testmod()
 
129
    if result[1] > 0:
 
130
        if result[0] == 0:
 
131
            print "All tests passed"
 
132
    else:
 
133
        print "No tests to run"
 
134
if __name__ == "__main__":
 
135
    run_tests()