~bzr-pqm/bzr/bzr.dev

645 by Martin Pool
- split out proposed progress module
1
*** added file 'bzrlib/progress.py'
2
--- /dev/null 
3
+++ bzrlib/progress.py 
4
@@ -0,0 +1,91 @@
5
+# Copyright (C) 2005 Aaron Bentley
6
+# <aaron.bentley@utoronto.ca>
7
+#
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.
12
+#
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.
17
+#
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
21
+
22
+import sys
23
+
24
+class Progress(object):
25
+    def __init__(self, units, current, total=None):
26
+        self.units = units
27
+        self.current = current
28
+        self.total = total
29
+        self.percent = None
30
+        if self.total is not None:
31
+            self.percent = 100.0 * current / total
32
+
33
+    def __str__(self):
34
+        if self.total is not None:
35
+            return "%i of %i %s %.1f%%" % (self.current, self.total, self.units,
36
+                                         self.percent)
37
+        else:
38
+            return "%i %s" (self.current, self.units) 
39
+
40
+
41
+def progress_bar(progress):
42
+    fmt = " %i of %i %s (%.1f%%)"
43
+    f = fmt % (progress.total, progress.total, progress.units, 100.0)
44
+    max = len(f)
45
+    cols = 77 - max
46
+    markers = int (float(cols) * progress.current / progress.total)
47
+    txt = fmt % (progress.current, progress.total, progress.units,
48
+                 progress.percent)
49
+    sys.stderr.write("\r[%s%s]%s" % ('='*markers, ' '*(cols-markers), txt))
50
+
51
+def clear_progress_bar():
52
+    sys.stderr.write('\r%s\r' % (' '*79))
53
+
54
+def spinner_str(progress, show_text=False):
55
+    """
56
+    Produces the string for a textual "spinner" progress indicator
57
+    :param progress: an object represinting current progress
58
+    :param show_text: If true, show progress text as well
59
+    :return: The spinner string
60
+
61
+    >>> spinner_str(Progress("baloons", 0))
62
+    '|'
63
+    >>> spinner_str(Progress("baloons", 5))
64
+    '/'
65
+    >>> spinner_str(Progress("baloons", 6), show_text=True)
66
+    '- 6 baloons'
67
+    """
68
+    positions = ('|', '/', '-', '\\')
69
+    text = positions[progress.current % 4]
70
+    if show_text:
71
+        text+=" %i %s" % (progress.current, progress.units)
72
+    return text
73
+
74
+def spinner(progress, show_text=False, output=sys.stderr):
75
+    """
76
+    Update a spinner progress indicator on an output
77
+    :param progress: The progress to display
78
+    :param show_text: If true, show text as well as spinner
79
+    :param output: The output to write to
80
+
81
+    >>> spinner(Progress("baloons", 6), show_text=True, output=sys.stdout)
82
+    \r- 6 baloons
83
+    """
84
+    output.write('\r%s' % spinner_str(progress, show_text))
85
+
86
+def run_tests():
87
+    import doctest
88
+    result = doctest.testmod()
89
+    if result[1] > 0:
90
+        if result[0] == 0:
91
+            print "All tests passed"
92
+    else:
93
+        print "No tests to run"
94
+if __name__ == "__main__":
95
+    run_tests()
96