You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.3 KiB
136 lines
4.3 KiB
# -*- coding: utf-8 -*-
|
|
import sys, time
|
|
from array import array
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
setLocalTranslate('calculate_console',sys.modules[__name__])
|
|
|
|
try:
|
|
from fcntl import ioctl
|
|
import termios
|
|
except ImportError:
|
|
pass
|
|
import signal
|
|
|
|
class ProgressBarWidgetHFill(object):
|
|
def update(self, pbar, width):
|
|
pass
|
|
|
|
class ETA(object):
|
|
"Widget for the Estimated Time of Arrival"
|
|
def format_time(self, seconds):
|
|
return time.strftime('%H:%M:%S', time.gmtime(seconds))
|
|
def update(self, pbar):
|
|
if pbar.finished:
|
|
return _('Time').decode('utf-8') + ': %s' \
|
|
%self.format_time(pbar.seconds_elapsed)
|
|
else:
|
|
return _('Time').decode('utf-8') + ': %s' \
|
|
%self.format_time(pbar.seconds_elapsed)
|
|
|
|
class Percentage(object):
|
|
"Just the percentage done."
|
|
def update(self, pbar):
|
|
return '%3d%%' % pbar.percentage()
|
|
|
|
class Bar(ProgressBarWidgetHFill):
|
|
"The bar of progress. It will strech to fill the line."
|
|
def __init__(self, marker='=', left='[', right=']'):
|
|
self.marker = marker
|
|
self.left = left
|
|
self.right = right
|
|
def _format_marker(self, pbar):
|
|
if isinstance(self.marker, (str, unicode)):
|
|
return self.marker
|
|
else:
|
|
return self.marker.update(pbar)
|
|
def update(self, pbar, width):
|
|
percent = pbar.percentage()
|
|
cwidth = width - len(self.left) - len(self.right)
|
|
marked_width = int(percent * cwidth / 100)
|
|
m = self._format_marker(pbar)
|
|
bar = (self.left + (m*(marked_width-1)+'>').ljust(cwidth)+self.right)
|
|
return bar
|
|
|
|
default_widgets = [Percentage(), ' ', Bar()]
|
|
class ProgressBar(object):
|
|
def __init__(self, maxval=100, widgets=default_widgets, term_width=None,
|
|
fd=sys.stderr):
|
|
assert maxval > 0
|
|
self.maxval = maxval
|
|
self.widgets = widgets
|
|
self.fd = fd
|
|
self.signal_set = False
|
|
if term_width is None:
|
|
try:
|
|
self.handle_resize(None,None)
|
|
signal.signal(signal.SIGWINCH, self.handle_resize)
|
|
self.signal_set = True
|
|
except:
|
|
self.term_width = 99
|
|
else:
|
|
self.term_width = term_width
|
|
|
|
self.currval = 0
|
|
self.finished = False
|
|
self.prev_percentage = -1
|
|
self.start_time = None
|
|
self.seconds_elapsed = 0
|
|
|
|
def handle_resize(self, signum, frame):
|
|
h, self.term_width = array('h', ioctl(self.fd,termios.TIOCGWINSZ,
|
|
'\0'*8))[:2]
|
|
|
|
def percentage(self):
|
|
"Returns the percentage of the progress."
|
|
return self.currval*100.0 / self.maxval
|
|
|
|
def _format_widgets(self):
|
|
r = []
|
|
hfill_inds = []
|
|
num_hfill = 0
|
|
currwidth = 0
|
|
for i, w in enumerate(self.widgets):
|
|
if isinstance(w, ProgressBarWidgetHFill):
|
|
r.append(w)
|
|
hfill_inds.append(i)
|
|
num_hfill += 1
|
|
elif isinstance(w, (str, unicode)):
|
|
r.append(w)
|
|
currwidth += len(w)
|
|
else:
|
|
weval = w.update(self)
|
|
currwidth += len(weval)
|
|
r.append(weval)
|
|
for iw in hfill_inds:
|
|
r[iw] = r[iw].update(self, (self.term_width-currwidth)/num_hfill)
|
|
return r
|
|
|
|
def _format_line(self):
|
|
return ''.join(self._format_widgets()).ljust(self.term_width)
|
|
|
|
def update(self, value):
|
|
"Updates the progress bar to a new value."
|
|
assert 0 <= value <= self.maxval
|
|
self.currval = value
|
|
if self.finished:
|
|
return
|
|
if not self.start_time:
|
|
self.start_time = time.time()
|
|
self.seconds_elapsed = time.time() - self.start_time
|
|
self.prev_percentage = self.percentage()
|
|
if value != self.maxval:
|
|
self.fd.write(self._format_line() + '\r')
|
|
else:
|
|
self.finished = True
|
|
self.fd.write(self._format_line() + '\n')
|
|
|
|
def start(self):
|
|
self.update(0)
|
|
return self
|
|
|
|
def finish(self):
|
|
"""Used to tell the progress is finished."""
|
|
self.update(self.maxval)
|
|
if self.signal_set:
|
|
signal.signal(signal.SIGWINCH, signal.SIG_DFL) |