~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to progress.py

  • Committer: Aaron Bentley
  • Date: 2011-01-26 01:15:21 UTC
  • Revision ID: aaron@aaronbentley.com-20110126011521-nl09rwxzrymt2gva
Update version to 2.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2005 Aaron Bentley
2
 
# <aaron.bentley@utoronto.ca>
 
2
# <aaron@aaronbentley.com>
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
20
21
 
21
22
class Progress(object):
22
23
    def __init__(self, units, current, total=None):
36
37
            return "%i of %i %s %.1f%%" % (self.current, self.total, self.units,
37
38
                                         self.percent)
38
39
        else:
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))
 
40
            return "%i %s" (self.current, self.units)
 
41
 
 
42
def show_progress(pi, prog):
 
43
    pi.update(prog.units, prog.current, prog.total)
94
44
 
95
45
def clear_progress_bar():
96
46
    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()