class RTUI::Progress


Progress indicators

def bytes

def bytes
  convert_bytes(@current)
end

def clear

def clear
  @out.print "\r#{(" " * (TTY.get_width - 1))}\r"
end

def components= (arguments)

def components= (arguments)
  @components = arguments
end

def convert_bytes (bytes)

def convert_bytes (bytes)
  if bytes < 1024
    sprintf("%6dB", bytes)
  elsif bytes < 1024 * 1000 # 1000kb
    sprintf("%5.1fKB", bytes.to_f / 1024)
  elsif bytes < 1024 * 1024 * 1000  # 1000mb
    sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
  else
    sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
  end
end

def do_percentage

def do_percentage
  return 100 if @total.zero?
  @current  * 100 / @total
end

def elapsed

def elapsed
  sprintf("Time: %s", format_time(Time.now - @start_time))
end

def eol

def eol
  @finished ? "\n" : "\r"
end

def eta

ETA stands for Estimated Time of Arrival.
def eta
  if @current == 0
    "ETA:  --:--:--"
  else
    elapsed = Time.now - @start_time
    eta = elapsed * @total / @current - elapsed;
    sprintf("ETA:  %s", format_time(eta))
  end
end

def file_transfer_mode

def file_transfer_mode
  return unless @components.index(:stat)
  @components[@components.index(:stat)] = :stat_for_file_transfer
end

def finish

def finish
  @current = @total
  @finished = true
  show
end

def finished?

def finished?
  @finished
end

def fmt_bar

def fmt_bar
  bar_width = do_percentage * @terminal_width / 100
  sprintf("|%s%s|",
    @bar_mark * bar_width,
    " " *  (@terminal_width - bar_width))
end

def fmt_percentage

def fmt_percentage
  "%3d%%" % do_percentage
end

def fmt_pong

def fmt_pong
  bar_width = do_percentage * @terminal_width / 100
  sprintf("|%s%s|",
    " " * bar_width + @bar_mark,
    " " *  (@terminal_width - bar_width))
end

def fmt_spinner

def fmt_spinner
  bar_width = do_percentage * @terminal_width / 100
  sprintf(" %s%s ",
    do_percentage == 100 ? " " : '/-\\|'[do_percentage%4].chr ,
    " " *  (@terminal_width / 100) )
end

def fmt_stat

def fmt_stat
  @finished ? elapsed : eta
end

def fmt_stat_for_file_transfer

def fmt_stat_for_file_transfer
  sprintf("%s %s %s", bytes, transfer_rate, fmt_stat)
end

def fmt_subject

def fmt_subject
  @subject ||= ""
  blank = @terminal_width - @subject.length
  out = "   " + @subject
  out <<  " " * blank if blank > 0
  out[0, @terminal_width - 5]
end

def fmt_title

def fmt_title
  @title[0,(@title_width - 1)] + ":"
end

def format_time t

def format_time t
  t = t.to_i
  sec = t % 60
  min  = (t / 60) % 60
  hour = t / 3600
  sprintf("%02d:%02d:%02d", hour, min, sec);
end

def halt

def halt
  @finished = true
  show
end

def inc step = 1

def inc step = 1
  @current += step
  @current = @total if @current > @total
  show_if_needed
  @previous = @current
end

def initialize (title, total, *options)


- bar
- stat
- percentage
- spinner
- title
Components:

- out => STDERR
- bar => "="
Options:


RTUI::Progress.new("Foo", 10, { :components => [:spinner, :percentage]})
A Spinner with just percentage:

RTUI::Progress.new("Foo", 10, { :components => [:bar, :stat]})
Just a bar and ETA:

Examples:

Initializes a progress indicator.
def initialize (title, total, *options)
  options = options.first || {}
  @title = title
  @total = total
  @terminal_width = 80
  @current = 0
  @previous = 0
  @finished = false
  @start_time = Time.now
  @previous_time = @start_time
  @title_width = 14
  @subject = ""
  @out        = options[:out] || STDOUT
  @bar_mark   = options[:bar] || "="
  @colors     = options[:colors] || false
  @components = options[:components] || [:title, :percentage, :bar, :stat]
  clear
  show
end

def inspect

def inspect
  "#<RTUI::Progress:#{@current}/#{@total}>"
end

def set (count)

def set (count)
  if count < 0 || count > @total
    raise "invalid count: #{count} (total: #{@total})"
  end
  @current = count
  show_if_needed
  @previous = @current
end

def show

def show
  line = @components.map {|method|
    send(sprintf("fmt_%s", method))
  }.join " "
  width = TTY.get_width
  if line.length == width - 1
    @out.print(line + eol)
    @out.flush
  elsif line.length >= width
    @terminal_width = [@terminal_width - (line.length - width + 1), 0].max
    if @terminal_width == 0 then @out.print(line + eol) else show end
  else # line.length < width - 1
    @terminal_width += width - line.length + 1
    show
  end
  @previous_time = Time.now
end

def show_if_needed

def show_if_needed
  if @total.zero?
    cur_percentage = 100
    prev_percentage = 0
  else
    cur_percentage  = (@current  * 100 / @total).to_i
    prev_percentage = (@previous * 100 / @total).to_i
  end
  # Use "!=" instead of ">" to support negative changes
  if cur_percentage != prev_percentage ||
      Time.now - @previous_time >= 1 || @finished
    show
  end
end

def subject=(subject)

def subject=(subject)
  @subject = subject
end

def transfer_rate

def transfer_rate
  bytes_per_second = @current.to_f / (Time.now - @start_time)
  sprintf("%s/s", convert_bytes(bytes_per_second))
end