/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to patches/progress.diff

  • Committer: v.ladeuil+lp at free
  • Date: 2006-10-12 14:29:32 UTC
  • mto: (2145.1.1 keepalive)
  • mto: This revision was merged to the branch mainline in revision 2146.
  • Revision ID: v.ladeuil+lp@free.fr-20061012142932-7221fe16d2b48fa3
Shuffle http related test code. Hopefully it ends up at the right place :)

* bzrlib/tests/HttpServer.py: 
New file. bzrlib.tests.ChrootedTestCase use HttpServer. So the
class can't be defined in bzrlib.tests.HTTPUtils because it
creates a circular dependency (bzrlib.tests.HTTPUtils needs to
import bzrlib.tests).

* bzrlib/transport/http/_urllib.py: 
Transfer test server definition to bzrlib.tests.HttpServer. Clean
up imports.

* bzrlib/transport/http/_pycurl.py: 
Transfer test server definition to bzrlib.tests.HttpServer. Clean
up imports.

* bzrlib/transport/http/__init__.py: 
Transfer all test related code to either bzrlib.tests.HttpServer
and bzrlib.tests.HTTPUtils.
Fix all use of TransportNotPossible and InvalidURL by prefixing it
by 'errors.' (this seems to be the preferred way in the rest of
bzr).
Get rid of unused imports.

* bzrlib/tests/test_transport.py:
(ReadonlyDecoratorTransportTest.test_local_parameters,
FakeNFSDecoratorTests.test_http_parameters): Use HttpServer from
bzrlib.tests.HttpServer instead of bzrlib.transport.http.

* bzrlib/tests/test_sftp_transport.py:
(set_test_transport_to_sftp): Use HttpServer from
bzrlib.tests.HttpServer instead of bzrlib.transport.http.

* bzrlib/tests/test_selftest.py:
(TestTestCaseWithTransport.test_get_readonly_url_http): Use
HttpServer from bzrlib.tests.HttpServer instead of
bzrlib.transport.http.

* bzrlib/tests/test_repository.py: 
Does *not* use HttpServer.

* bzrlib/tests/test_http.py: 
Build on top of bzrlib.tests.HttpServer and bzrlib.tests.HTTPUtils
instead of bzrlib.transport.http.

* bzrlib/tests/test_bzrdir.py:
(ChrootedTests.setUp): Use HttpServer from bzrlib.tests.HttpServer
instead of bzrlib.transport.http.

* bzrlib/tests/branch_implementations/test_http.py:
(HTTPBranchTests.setUp): Use HttpServer from bzrlib.tests.HttpServer
instead of bzrlib.transport.http.

* bzrlib/tests/branch_implementations/test_branch.py:
(ChrootedTests.setUp): Use HttpServer from bzrlib.tests.HttpServer
instead of bzrlib.transport.http.

* bzrlib/tests/__init__.py:
(ChrootedTestCase.setUp): Use HttpServer from
bzrlib.tests.HttpServer instead of bzrlib.transport.http.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
*** added file 'bzrlib/progress.py'
2
 
--- /dev/null 
3
 
+++ bzrlib/progress.py 
4
 
@@ -0,0 +1,138 @@
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
 
+import datetime
24
 
+
25
 
+class Progress(object):
26
 
+    def __init__(self, units, current, total=None):
27
 
+        self.units = units
28
 
+        self.current = current
29
 
+        self.total = total
30
 
+
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
34
 
+
35
 
+    percent = property(_get_percent)
36
 
+
37
 
+    def __str__(self):
38
 
+        if self.total is not None:
39
 
+            return "%i of %i %s %.1f%%" % (self.current, self.total, self.units,
40
 
+                                         self.percent)
41
 
+        else:
42
 
+            return "%i %s" (self.current, self.units) 
43
 
+
44
 
+class ProgressBar(object):
45
 
+    def __init__(self):
46
 
+        self.start = None
47
 
+        object.__init__(self)
48
 
+
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)
53
 
+        
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)
59
 
+
60
 
+def str_tdelta(delt):
61
 
+    if delt is None:
62
 
+        return "-:--:--"
63
 
+    return str(datetime.timedelta(delt.days, delt.seconds))
64
 
+
65
 
+def get_eta(start_time, progress, enough_samples=20):
66
 
+    if start_time is None or progress.current == 0:
67
 
+        return None
68
 
+    elif progress.current < enough_samples:
69
 
+        return None
70
 
+    elapsed = datetime.datetime.now() - start_time
71
 
+    total_duration = divide_timedelta((elapsed) * long(progress.total), 
72
 
+                                      progress.current)
73
 
+    if elapsed < total_duration:
74
 
+        eta = total_duration - elapsed
75
 
+    else:
76
 
+        eta = total_duration - total_duration
77
 
+    return eta
78
 
+
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)
83
 
+    else:
84
 
+        eta_str = ""
85
 
+
86
 
+    fmt = " %i of %i %s (%.1f%%)"
87
 
+    f = fmt % (progress.total, progress.total, progress.units, 100.0)
88
 
+    max = len(f)
89
 
+    cols = 77 - max
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,
94
 
+                 progress.percent)
95
 
+    sys.stderr.write("\r[%s%s]%s%s" % ('='*markers, ' '*(cols-markers), txt, 
96
 
+                                       eta_str))
97
 
+
98
 
+def clear_progress_bar():
99
 
+    sys.stderr.write('\r%s\r' % (' '*79))
100
 
+
101
 
+def spinner_str(progress, show_text=False):
102
 
+    """
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
107
 
+
108
 
+    >>> spinner_str(Progress("baloons", 0))
109
 
+    '|'
110
 
+    >>> spinner_str(Progress("baloons", 5))
111
 
+    '/'
112
 
+    >>> spinner_str(Progress("baloons", 6), show_text=True)
113
 
+    '- 6 baloons'
114
 
+    """
115
 
+    positions = ('|', '/', '-', '\\')
116
 
+    text = positions[progress.current % 4]
117
 
+    if show_text:
118
 
+        text+=" %i %s" % (progress.current, progress.units)
119
 
+    return text
120
 
+
121
 
+def spinner(progress, show_text=False, output=sys.stderr):
122
 
+    """
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
127
 
+
128
 
+    >>> spinner(Progress("baloons", 6), show_text=True, output=sys.stdout)
129
 
+    \r- 6 baloons
130
 
+    """
131
 
+    output.write('\r%s' % spinner_str(progress, show_text))
132
 
+
133
 
+def run_tests():
134
 
+    import doctest
135
 
+    result = doctest.testmod()
136
 
+    if result[1] > 0:
137
 
+        if result[0] == 0:
138
 
+            print "All tests passed"
139
 
+    else:
140
 
+        print "No tests to run"
141
 
+if __name__ == "__main__":
142
 
+    run_tests()
143