def __init__(self, denominator, max_width=None): super(ProgressBar, self).__init__(denominator, max_width=max_width) if self.undefined: self.template = '{numerator} {bar} eta --:-- {spinner}' self.bar = BarUndefinedAnimated() else: self.template = '{percent:3d}% ({fraction}) {bar} eta {eta} {spinner}' self.bar = Bar()
def __init__(self, denominator, max_width=None, eta_every=1): super(ProgressBarWget, self).__init__(denominator, max_width=max_width, eta_every=eta_every) if self.undefined: self.template = ' {bar} {numerator:<11s} {rate:>9s} {eta:<12s}' BarUndefinedAnimated.CHAR_ANIMATED = '<=>' self.bar = BarUndefinedAnimated() else: self.template = '{percent:^4s}{bar} {numerator:<11s} {rate:>9s} {eta:<12s}' Bar.CHAR_FULL = '=' Bar.CHAR_LEADING = '>' self.bar = Bar()
def test_bar(): bar = Bar() assert '[ ]' == bar.bar(12, 0) assert '[ ]' == bar.bar(12, 9) assert '[# ]' == bar.bar(12, 10) assert '[# ]' == bar.bar(12, 15) assert '[## ]' == bar.bar(12, 20) assert '[##### ]' == bar.bar(12, 50) assert '[######### ]' == bar.bar(12, 99) assert '[##########]' == bar.bar(12, 100)
def test_bar_leading_empty_char(request): def fin(): Bar.CHAR_EMPTY = ' ' Bar.CHAR_FULL = '#' Bar.CHAR_LEADING = '#' request.addfinalizer(fin) Bar.CHAR_EMPTY = '.' Bar.CHAR_FULL = '=' Bar.CHAR_LEADING = '>' bar = Bar() assert '[..........]' == bar.bar(12, 0) assert '[..........]' == bar.bar(12, 9) assert '[>.........]' == bar.bar(12, 10) assert '[>.........]' == bar.bar(12, 15) assert '[=>........]' == bar.bar(12, 20) assert '[====>.....]' == bar.bar(12, 50) assert '[========>.]' == bar.bar(12, 99) assert '[=========>]' == bar.bar(12, 100)
class ProgressBar(BaseProgressBar): """Draw a progress bar showing the ETA, percentage, done/total items, and a spinner. Looks like one of these: 8% ( 8/100) [## ] eta 00:24 / 100% (100/100) [####################################] eta 00:01 - 23 [ ? ] eta --:-- | Positional arguments: denominator -- the final/total number of units (like the expected file size of a download). 0 if unknown. Keyword arguments: max_with -- limit number of characters shown (by default the full progress bar takes up the entire terminal width). Instance variables: template -- string template of the full progress bar. bar -- class instance of the 'bar' part of the full progress bar. More instance variables in etaprogress.components.base_progress_bar.BaseProgressBar. """ def __init__(self, denominator, max_width=None): super(ProgressBar, self).__init__(denominator, max_width=max_width) if self.undefined: self.template = '{numerator} {bar} eta --:-- {spinner}' self.bar = BarUndefinedAnimated() else: self.template = '{percent:3d}% ({fraction}) {bar} eta {eta} {spinner}' self.bar = Bar() def __str__(self): """Returns the fully-built progress bar and other data.""" # Partially build out template. bar = '{bar}' spinner = next(SPINNER) if self.undefined: numerator = self.str_numerator template = self.template.format(numerator=numerator, bar=bar, spinner=spinner) else: percent = int(self.percent) fraction = self.str_fraction eta = self._eta_string or '--:--' template = self.template.format(percent=percent, fraction=fraction, bar=bar, eta=eta, spinner=spinner) # Determine bar width and finish. width = get_remaining_width(template.format(bar=''), self.max_width or None) bar = self.bar.bar(width, percent=self.percent) return template.format(bar=bar) @staticmethod def _generate_eta(seconds): """Returns a human readable ETA string.""" return '' if seconds is None else eta_hms(seconds, always_show_minutes=True) @property def str_fraction(self): """Returns the fraction with additional whitespace.""" if self.undefined: return None denominator = locale.format('%d', self.denominator, grouping=True) numerator = self.str_numerator.rjust(len(denominator)) return '{0}/{1}'.format(numerator, denominator) @property def str_numerator(self): """Returns the numerator as a formatted string.""" return locale.format('%d', self.numerator, grouping=True)
class ProgressBarWget(BaseProgressBar): """Progress bar modeled after the one in wget. Looks like one of these: 35% [=======> ] 35,802,443 4.66MiB/s eta 14s 100%[======================>] 100,000,000 4.59MiB/s in 21s [ <=> ] 22,222,206 4.65MiB/s [ <=> ] 100,000,000 4.59MiB/s in 21s Positional arguments: denominator -- the final/total number of units (like the expected file size of a download). 0 if unknown. Keyword arguments: max_with -- limit number of characters shown (by default the full progress bar takes up the entire terminal width). eta_every -- calculate and cache the ETA string after this many numerator setting iteration. Default is every iter. Instance variables: template -- string template of the full progress bar. bar -- class instance of the 'bar' part of the full progress bar. More instance variables in etaprogress.components.base_progress_bar.BaseProgressBar. """ def __init__(self, denominator, max_width=None, eta_every=1): super(ProgressBarWget, self).__init__(denominator, max_width=max_width, eta_every=eta_every) if self.undefined: self.template = ' {bar} {numerator:<11s} {rate:>9s} {eta:<12s}' BarUndefinedAnimated.CHAR_ANIMATED = '<=>' self.bar = BarUndefinedAnimated() else: self.template = '{percent:^4s}{bar} {numerator:<11s} {rate:>9s} {eta:<12s}' Bar.CHAR_FULL = '=' Bar.CHAR_LEADING = '>' self.bar = Bar() def __str__(self): """Returns the fully-built progress bar and other data.""" # Partially build out template. bar = '{bar}' numerator = locale.format('%d', self.numerator, grouping=True) rate = self.str_rate eta = self.str_eta if self.undefined: template = self.template.format(bar=bar, numerator=numerator, rate=rate, eta=eta) else: percent = '{0}%'.format(int(self.percent)) template = self.template.format(percent=percent, bar=bar, numerator=numerator, rate=rate, eta=eta) # Determine bar width and finish. width = get_remaining_width(template.format(bar=''), self.max_width or None) bar = self.bar.bar(width, percent=self.percent) return template.format(bar=bar) @staticmethod def _generate_eta(seconds): """Returns a human readable ETA string.""" return '' if seconds is None else eta_letters(seconds) @property def str_eta(self): """Returns a formatted ETA value for the progress bar.""" eta = eta_letters(self._eta.elapsed) if self.done else self._eta_string if not eta: return '' if eta.count(' ') > 1: eta = ' '.join( eta.split(' ') [:2]) # Only show up to two units (h and m, no s for example). return (' in {0}' if self.done else 'eta {0}').format(eta) @property def str_rate(self): """Returns the rate with formatting. If done, returns the overall rate instead.""" # Handle special cases. if not self._eta.started or self._eta.stalled or not self.rate: return '--.-KiB/s' unit_rate, unit = UnitByte( self._eta.rate_overall if self.done else self.rate).auto if unit_rate >= 100: formatter = '%d' elif unit_rate >= 10: formatter = '%.1f' else: formatter = '%.2f' return '{0}{1}/s'.format( locale.format(formatter, unit_rate, grouping=False), unit)
class ProgressBarWget(BaseProgressBar): """Progress bar modeled after the one in wget. Looks like one of these: 35% [=======> ] 35,802,443 4.66MiB/s eta 14s 100%[======================>] 100,000,000 4.59MiB/s in 21s [ <=> ] 22,222,206 4.65MiB/s [ <=> ] 100,000,000 4.59MiB/s in 21s Positional arguments: denominator -- the final/total number of units (like the expected file size of a download). 0 if unknown. Keyword arguments: max_with -- limit number of characters shown (by default the full progress bar takes up the entire terminal width). eta_every -- calculate and cache the ETA string after this many numerator setting iteration. Default is every iter. Instance variables: template -- string template of the full progress bar. bar -- class instance of the 'bar' part of the full progress bar. More instance variables in etaprogress.components.base_progress_bar.BaseProgressBar. """ def __init__(self, denominator, max_width=None, eta_every=1): super(ProgressBarWget, self).__init__(denominator, max_width=max_width, eta_every=eta_every) if self.undefined: self.template = ' {bar} {numerator:<11s} {rate:>9s} {eta:<12s}' BarUndefinedAnimated.CHAR_ANIMATED = '<=>' self.bar = BarUndefinedAnimated() else: self.template = '{percent:^4s}{bar} {numerator:<11s} {rate:>9s} {eta:<12s}' Bar.CHAR_FULL = '=' Bar.CHAR_LEADING = '>' self.bar = Bar() def __str__(self): """Returns the fully-built progress bar and other data.""" # Partially build out template. bar = '{bar}' numerator = locale.format('%d', self.numerator, grouping=True) rate = self.str_rate eta = self.str_eta if self.undefined: template = self.template.format(bar=bar, numerator=numerator, rate=rate, eta=eta) else: percent = '{0}%'.format(int(self.percent)) template = self.template.format(percent=percent, bar=bar, numerator=numerator, rate=rate, eta=eta) # Determine bar width and finish. width = get_remaining_width(template.format(bar=''), self.max_width or None) bar = self.bar.bar(width, percent=self.percent) return template.format(bar=bar) @staticmethod def _generate_eta(seconds): """Returns a human readable ETA string.""" return '' if seconds is None else eta_letters(seconds) @property def str_eta(self): """Returns a formatted ETA value for the progress bar.""" eta = eta_letters(self._eta.elapsed) if self.done else self._eta_string if not eta: return '' if eta.count(' ') > 1: eta = ' '.join(eta.split(' ')[:2]) # Only show up to two units (h and m, no s for example). return (' in {0}' if self.done else 'eta {0}').format(eta) @property def str_rate(self): """Returns the rate with formatting. If done, returns the overall rate instead.""" # Handle special cases. if not self._eta.started or self._eta.stalled or not self.rate: return '--.-KiB/s' unit_rate, unit = UnitByte(self._eta.rate_overall if self.done else self.rate).auto if unit_rate >= 100: formatter = '%d' elif unit_rate >= 10: formatter = '%.1f' else: formatter = '%.2f' return '{0}{1}/s'.format(locale.format(formatter, unit_rate, grouping=False), unit)