1
*** added file 'bzrlib/progress.py'
 
 
5
+# Copyright (C) 2005 Aaron Bentley
 
 
6
+# <aaron.bentley@utoronto.ca>
 
 
8
+#    This program is free software; you can redistribute it and/or modify
 
 
9
+#    it under the terms of the GNU General Public License as published by
 
 
10
+#    the Free Software Foundation; either version 2 of the License, or
 
 
11
+#    (at your option) any later version.
 
 
13
+#    This program is distributed in the hope that it will be useful,
 
 
14
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 
15
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 
16
+#    GNU General Public License for more details.
 
 
18
+#    You should have received a copy of the GNU General Public License
 
 
19
+#    along with this program; if not, write to the Free Software
 
 
20
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
25
+class Progress(object):
 
 
26
+    def __init__(self, units, current, total=None):
 
 
28
+        self.current = current
 
 
31
+    def _get_percent(self):
 
 
32
+        if self.total is not None and self.current is not None:
 
 
33
+            return 100.0 * self.current / self.total
 
 
35
+    percent = property(_get_percent)
 
 
38
+        if self.total is not None:
 
 
39
+            return "%i of %i %s %.1f%%" % (self.current, self.total, self.units,
 
 
42
+            return "%i %s" (self.current, self.units) 
 
 
44
+class ProgressBar(object):
 
 
47
+        object.__init__(self)
 
 
49
+    def __call__(self, progress):
 
 
50
+        if self.start is None:
 
 
51
+            self.start = datetime.datetime.now()
 
 
52
+        progress_bar(progress, start_time=self.start)
 
 
54
+def divide_timedelta(delt, divisor):
 
 
55
+    """Divides a timedelta object"""
 
 
56
+    return datetime.timedelta(float(delt.days)/divisor, 
 
 
57
+                              float(delt.seconds)/divisor, 
 
 
58
+                              float(delt.microseconds)/divisor)
 
 
60
+def str_tdelta(delt):
 
 
63
+    return str(datetime.timedelta(delt.days, delt.seconds))
 
 
65
+def get_eta(start_time, progress, enough_samples=20):
 
 
66
+    if start_time is None or progress.current == 0:
 
 
68
+    elif progress.current < enough_samples:
 
 
70
+    elapsed = datetime.datetime.now() - start_time
 
 
71
+    total_duration = divide_timedelta((elapsed) * long(progress.total), 
 
 
73
+    if elapsed < total_duration:
 
 
74
+        eta = total_duration - elapsed
 
 
76
+        eta = total_duration - total_duration
 
 
79
+def progress_bar(progress, start_time=None):
 
 
80
+    eta = get_eta(start_time, progress)
 
 
81
+    if start_time is not None:
 
 
82
+        eta_str = " "+str_tdelta(eta)
 
 
86
+    fmt = " %i of %i %s (%.1f%%)"
 
 
87
+    f = fmt % (progress.total, progress.total, progress.units, 100.0)
 
 
90
+    if start_time is not None:
 
 
91
+        cols -= len(eta_str)
 
 
92
+    markers = int (float(cols) * progress.current / progress.total)
 
 
93
+    txt = fmt % (progress.current, progress.total, progress.units,
 
 
95
+    sys.stderr.write("\r[%s%s]%s%s" % ('='*markers, ' '*(cols-markers), txt, 
 
 
98
+def clear_progress_bar():
 
 
99
+    sys.stderr.write('\r%s\r' % (' '*79))
 
 
101
+def spinner_str(progress, show_text=False):
 
 
103
+    Produces the string for a textual "spinner" progress indicator
 
 
104
+    :param progress: an object represinting current progress
 
 
105
+    :param show_text: If true, show progress text as well
 
 
106
+    :return: The spinner string
 
 
108
+    >>> spinner_str(Progress("baloons", 0))
 
 
110
+    >>> spinner_str(Progress("baloons", 5))
 
 
112
+    >>> spinner_str(Progress("baloons", 6), show_text=True)
 
 
115
+    positions = ('|', '/', '-', '\\')
 
 
116
+    text = positions[progress.current % 4]
 
 
118
+        text+=" %i %s" % (progress.current, progress.units)
 
 
121
+def spinner(progress, show_text=False, output=sys.stderr):
 
 
123
+    Update a spinner progress indicator on an output
 
 
124
+    :param progress: The progress to display
 
 
125
+    :param show_text: If true, show text as well as spinner
 
 
126
+    :param output: The output to write to
 
 
128
+    >>> spinner(Progress("baloons", 6), show_text=True, output=sys.stdout)
 
 
131
+    output.write('\r%s' % spinner_str(progress, show_text))
 
 
135
+    result = doctest.testmod()
 
 
138
+            print "All tests passed"
 
 
140
+        print "No tests to run"
 
 
141
+if __name__ == "__main__":