class ProgressBar

Constants

ArgumentError
Error
HOUR
MINUTE
VERSION

Attributes

count[RW]
max[RW]
meters[RW]

Public Class Methods

new(*args) click to toggle source
# File lib/progress_bar.rb, line 12
def initialize(*args)
  @count      = 0
  @max        = 100
  @meters     = [:bar, :counter, :percentage, :elapsed, :eta, :rate]

  @max = args.shift if args.first.is_a? Numeric
  raise ArgumentError, "Max must be a positive integer" unless @max >= 0

  @meters = args unless args.empty?

  @last_write = ::Time.at(0)
  @start      = ::Time.now

  @hl = HighLine.new
  @terminal_width = 80
  @last_width_adjustment = ::Time.at(0)
end

Public Instance Methods

elapsed() click to toggle source
# File lib/progress_bar.rb, line 62
def elapsed
  ::Time.now - @start
end
eta() click to toggle source
# File lib/progress_bar.rb, line 74
def eta
  if count > 0
    remaining / rate
  else
    0
  end
end
increment!(count = 1) click to toggle source
# File lib/progress_bar.rb, line 30
def increment!(count = 1)
  @count += count
  now = ::Time.now
  if (now - @last_write) > 0.2 || @count >= max
    write
    @last_write = now
  end
end
percentage() click to toggle source
# File lib/progress_bar.rb, line 58
def percentage
  ratio * 100
end
puts(text) click to toggle source
# File lib/progress_bar.rb, line 39
def puts(text)
  clear!
  $stderr.write(text)
  $stderr.puts
  write
end
rate() click to toggle source
# File lib/progress_bar.rb, line 66
def rate
  if count > 0
    count / elapsed
  else
    0
  end
end
ratio() click to toggle source
# File lib/progress_bar.rb, line 54
def ratio
  [count.to_f / max, 1.0].min # never go above 1, even if count > max
end
remaining() click to toggle source
# File lib/progress_bar.rb, line 50
def remaining
  max - count
end
to_s() click to toggle source
# File lib/progress_bar.rb, line 82
def to_s
  self.count = max if count > max
  meters.inject(String.new) do |text, meter|
    text << "#{render(meter)} "
  end.strip
end
write() click to toggle source
# File lib/progress_bar.rb, line 46
def write
  print "\r" + to_s
end

Protected Instance Methods

bar_width() click to toggle source
# File lib/progress_bar.rb, line 149
def bar_width
  terminal_width - non_bar_width
end
clear!() click to toggle source
# File lib/progress_bar.rb, line 95
def clear!
  print "\r" + " " * terminal_width + "\r"
end
counter_width() click to toggle source
# File lib/progress_bar.rb, line 159
def counter_width # [  1/100]
  max_width * 2 + 3
end
elapsed_width() click to toggle source
# File lib/progress_bar.rb, line 171
def elapsed_width
  format_interval(elapsed).length + 2
end
eta_width() click to toggle source
# File lib/progress_bar.rb, line 175
def eta_width
  format_interval(eta).length + 2
end
format_interval(interval) click to toggle source
# File lib/progress_bar.rb, line 189
def format_interval(interval)
  if interval > HOUR
    "%02i:%02i:%02i" % [interval / HOUR, interval % HOUR / MINUTE, interval % MINUTE]
  else
    "%02i:%02i" % [interval / MINUTE, interval % MINUTE]
  end
end
max_width() click to toggle source
# File lib/progress_bar.rb, line 183
def max_width
  max.to_s.length
end
non_bar_width() click to toggle source
# File lib/progress_bar.rb, line 153
def non_bar_width
  meters.reject { |meter| meter == :bar }.inject(0) do |width, meter|
    width += width_of(meter) + 1
  end
end
percentage_width() click to toggle source
# File lib/progress_bar.rb, line 163
def percentage_width
  if max == 100      # [ 24%]
    6
  else               # [ 24.00%]
    9
  end
end
print(str) click to toggle source
rate_width() click to toggle source
# File lib/progress_bar.rb, line 179
def rate_width     # [ 23.45/s]
  render_rate.length
end
render(meter) click to toggle source
# File lib/progress_bar.rb, line 99
def render(meter)
  send(:"render_#{meter}")
end
render_bar() click to toggle source
# File lib/progress_bar.rb, line 107
def render_bar
  return "" if bar_width < 2

  progress_width = (ratio * (bar_width - 2)).floor
  remainder_width = bar_width - 2 - progress_width
  "[#{'#' * progress_width}#{' ' * remainder_width}]"
end
render_counter() click to toggle source
# File lib/progress_bar.rb, line 115
def render_counter
  "[%#{max_width}i/%i]" % [count, max]
end
render_elapsed() click to toggle source
# File lib/progress_bar.rb, line 124
def render_elapsed
  "[#{format_interval(elapsed)}]"
end
render_eta() click to toggle source
# File lib/progress_bar.rb, line 128
def render_eta
  "[#{format_interval(eta)}]"
end
render_percentage() click to toggle source
# File lib/progress_bar.rb, line 119
def render_percentage
  format = (max == 100 ? "%3i" : "%6.2f")
  "[#{format}%%]" % percentage
end
render_rate() click to toggle source
# File lib/progress_bar.rb, line 132
def render_rate
  "[%#{max_width + 3}.2f/s]" % rate
end
terminal_width() click to toggle source
# File lib/progress_bar.rb, line 136
def terminal_width
  # HighLine check takes a long time, so only update width every second.
  now = ::Time.now
  if now - @last_width_adjustment > 1
    @last_width_adjustment = now
    new_width = @hl.output_cols.to_i
    new_width = 80 if new_width < 1
    @terminal_width = new_width
  else
    @terminal_width
  end
end
width_of(meter) click to toggle source
# File lib/progress_bar.rb, line 103
def width_of(meter)
  send(:"#{meter}_width")
end