1
1
# Copyright (C) 2005 Aaron Bentley <aaron.bentley@utoronto.ca>
2
# Copyright (C) 2005 Canonical <canonical.com>
2
# Copyright (C) 2005, 2006 Canonical <canonical.com>
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
42
42
from collections import deque
45
import bzrlib.errors as errors
45
48
def _supports_progress(f):
46
49
if not hasattr(f, 'isatty'):
62
65
return DotsProgressBar(to_file=to_file, **kwargs)
68
class ProgressBarStack(object):
69
"""A stack of progress bars."""
78
to_messages_file=sys.stdout,
80
"""Setup the stack with the parameters the progress bars should have."""
81
self._to_file = to_file
82
self._show_pct = show_pct
83
self._show_spinner = show_spinner
84
self._show_eta = show_eta
85
self._show_bar = show_bar
86
self._show_count = show_count
87
self._to_messages_file = to_messages_file
89
self._klass = klass or TTYProgressBar
92
"""Return a nested progress bar."""
93
# initial implementation - return a new bar each time.
94
new_bar = self._klass(to_file=self._to_file,
95
show_pct=self._show_pct,
96
show_spinner=self._show_spinner,
97
show_eta=self._show_eta,
98
show_bar=self._show_bar,
99
show_count=self._show_count,
100
to_messages_file=self._to_messages_file,
102
self._stack.append(new_bar)
105
def return_pb(self, bar):
106
"""Return bar after its been used."""
107
if bar is not self._stack[-1]:
108
raise errors.MissingProgressBarFinish()
65
112
class _BaseProgressBar(object):
66
114
def __init__(self,
67
115
to_file=sys.stderr,
69
117
show_spinner=False,
121
to_messages_file=sys.stdout,
73
123
object.__init__(self)
74
124
self.to_file = to_file
125
self.to_messages_file = to_messages_file
76
126
self.last_msg = None
77
127
self.last_cnt = None
78
128
self.last_total = None
81
131
self.show_eta = show_eta
82
132
self.show_bar = show_bar
83
133
self.show_count = show_count
137
"""Return this bar to its progress stack."""
139
assert self._stack is not None
140
self._stack.return_pb(self)
142
def note(self, fmt_string, *args, **kwargs):
143
"""Record a note without disrupting the progress bar."""
145
self.to_messages_file.write(fmt_string % args)
146
self.to_messages_file.write('\n')
87
149
class DummyProgress(_BaseProgressBar):
163
def note(self, fmt_string, *args, **kwargs):
164
"""See _BaseProgressBar.note()."""
102
167
class DotsProgressBar(_BaseProgressBar):
103
169
def __init__(self, **kwargs):
104
170
_BaseProgressBar.__init__(self, **kwargs)
105
171
self.last_msg = None
187
253
if current_cnt > total_cnt:
188
254
total_cnt = current_cnt
256
old_msg = self.last_msg
190
257
# save these for the tick() function
191
258
self.last_msg = msg
192
259
self.last_cnt = current_cnt
193
260
self.last_total = total_cnt
262
if old_msg == self.last_msg and self.throttle():
198
265
if self.show_eta and self.start_time and total_cnt: