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
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