65
_progress_bar_types = {}
63
class ProgressTask(object):
64
"""Model component of a progress indicator.
66
Most code that needs to indicate progress should update one of these,
67
and it will in turn update the display, if one is present.
70
def __init__(self, parent_task=None):
71
self._parent_task = parent_task
74
self.current_cnt = None
77
def update(self, msg, current_cnt=None, total_cnt=None):
79
self.current_cnt = current_cnt
81
self.total_cnt = total_cnt
82
ui.ui_factory.show_progress(self)
85
ui.ui_factory.progress_finished(self)
87
def make_sub_task(self):
88
return ProgressTask(parent_task=self)
90
def _overall_completion_fraction(self, child_fraction=0.0):
91
"""Return fractional completion of this task and its parents
93
Returns None if no completion can be computed."""
95
own_fraction = (float(self.current_cnt) + child_fraction) / self.total_cnt
98
if self._parent_task is None:
101
if own_fraction is None:
103
return self._parent_task._overall_completion_fraction(own_fraction)
105
def note(self, fmt_string, *args, **kwargs):
106
"""Record a note without disrupting the progress bar."""
107
# XXX: shouldn't be here; put it in mutter or the ui instead
108
ui.ui_factory.clear_term()
109
trace.note(fmt_string % args)
112
# XXX: shouldn't be here; put it in mutter or the ui instead
113
ui.ui_factory.clear_term()
68
116
def ProgressBar(to_file=None, **kwargs):
87
135
_progress_bar_types.keys())
88
136
return _progress_bar_types[requested_bar_type](to_file=to_file, **kwargs)
140
class TextProgressView(object):
141
"""Display of progress bar and other information on a tty.
143
This shows one line of text, including possibly a network indicator, spinner,
144
progress bar, message, etc.
146
One instance of this is created and held by the UI, and fed updates when a
147
task wants to be painted.
150
def __init__(self, term_file):
151
self._term_file = term_file
152
# true when there's output on the screen we may need to clear
153
self._have_output = False
154
self._width = osutils.terminal_width()
155
self._last_transport_msg = ''
156
self._last_task_msg = ''
158
self._last_update = 0
159
self._transport_update_time = 0
160
self._task_fraction = None
162
def _show_line(self, s):
164
self._term_file.write('\r%-*.*s\r' % (n, n, s))
167
if self._have_output:
169
self._have_output = False
171
def _render_bar(self):
172
# return a string for the progress bar itself
173
if self._task_fraction is not None:
175
# number of markers highlighted in bar
176
markers = int(round(float(cols) * self._task_fraction))
177
bar_str = ' [' + ('#' * markers).ljust(cols) + '] '
182
def _format_task(self, task):
183
if task.total_cnt is not None:
184
s = ' %d/%d' % (task.current_cnt, task.total_cnt)
185
elif task.current_cnt is not None:
186
s = ' %d' % (task.current_cnt)
189
self._task_fraction = task._overall_completion_fraction()
190
# compose all the parent messages
193
while t._parent_task:
201
if now < self._last_update + 0.1:
203
if now > self._transport_update_time + 5:
204
# no recent activity; expire it
205
self._last_transport_msg = ''
206
self._last_update = now
207
spin_str = r'/-\|'[self._spin_pos % 4]
209
bar_string = self._render_bar()
210
s = (self._last_transport_msg
211
+ ' ' + spin_str + ' ' +
213
s_max = self._width - 1 - len(bar_string)
218
self._show_line(s + bar_string)
219
self._have_output = True
221
def show_progress(self, task):
222
self._last_task_msg = self._format_task(task)
225
def show_transport_activity(self, msg):
226
self._last_transport_msg = msg
227
self._transport_update_time = time.time()
91
231
class ProgressBarStack(object):
92
232
"""A stack of progress bars."""