lib/progress.rb in progress-3.0.2 vs lib/progress.rb in progress-3.1.0

- old
+ new

@@ -1,10 +1,19 @@ # encoding: UTF-8 require 'singleton' require 'thread' +require 'progress/class_methods' +require 'progress/beeper' +require 'progress/eta' + +require 'progress/kernel' +require 'progress/enumerable' +require 'progress/integer' +require 'progress/active_record' if defined?(ActiveRecord::Base) + # ==== Procedural example # Progress.start('Test', 1000) # 1000.times do # Progress.step do # # do something @@ -34,17 +43,18 @@ # sleep(0.001) # end # end class Progress include Singleton + extend ClassMethods attr_reader :total attr_reader :current attr_reader :title attr_accessor :note def initialize(total, title) - if !total.kind_of?(Numeric) && (title.nil? || title.kind_of?(Numeric)) + if !total.is_a?(Numeric) && (title.nil? || title.is_a?(Numeric)) total, title = title, total end total = total && total != 0 ? Float(total) : 1.0 @total = total @@ -57,11 +67,11 @@ inner *= @step if @step (current + inner) / total end def step(step, note) - if !step.kind_of?(Numeric) + unless step.is_a?(Numeric) step, note = nil, step end step = 1 if step.nil? @step = step @@ -80,225 +90,6 @@ Thread.exclusive do @current = new_current end ret end - - @lock = Mutex.new - class << self - - # start progress indication - def start(total = nil, title = nil) - lock do - if running? - unless @started_in == Thread.current - warn 'Can\'t start inner progress in different thread' - if block_given? - return yield - else - return - end - end - else - @started_in = Thread.current - @eta = Eta.new - start_beeper - end - @levels ||= [] - @levels.push new(total, title) - end - print_message :force => true - if block_given? - begin - yield - ensure - stop - end - end - end - - # step current progress - def step(step = nil, note = nil, &block) - if running? - ret = @levels.last.step(step, note, &block) - print_message - ret - elsif block - block.call - end - end - - # set value of current progress - def set(new_current, note = nil, &block) - if running? - ret = @levels.last.set(new_current, note, &block) - print_message - ret - elsif block - block.call - end - end - - # stop progress - def stop - if running? - if @levels.length == 1 - print_message :force => true, :finish => true - stop_beeper - end - @levels.pop - end - end - - # check if progress was started - def running? - @levels && !@levels.empty? - end - - # set note - def note=(note) - if running? - @levels.last.note = note - end - end - - # stay on one line - def stay_on_line? - @stay_on_line.nil? ? io_tty? : @stay_on_line - end - - # explicitly set staying on one line [true/false/nil] - def stay_on_line=(value) - @stay_on_line = true && value - end - - # highlight output using control characters - def highlight? - @highlight.nil? ? io_tty? : @highlight - end - - # explicitly set highlighting [true/false/nil] - def highlight=(value) - @highlight = true && value - end - - # show progerss in terminal title - def set_terminal_title? - @set_terminal_title.nil? ? io_tty? : @set_terminal_title - end - - # explicitly set showing progress in terminal title [true/false/nil] - def set_terminal_title=(value) - @set_terminal_title = true && value - end - - private - - def lock(force = true) - if force ? @lock.lock : @lock.try_lock - begin - yield - ensure - @lock.unlock - end - end - end - - def io - @io || $stderr - end - - def io_tty? - io.tty? || ENV['PROGRESS_TTY'] - end - - def start_beeper - @beeper = Beeper.new(10) do - print_message - end - end - - def stop_beeper - @beeper.stop if @beeper - end - - def restart_beeper - @beeper.restart if @beeper - end - - def time_to_print? - !@next_time_to_print || @next_time_to_print <= Time.now - end - - def eta(current) - @eta.left(current) - end - - def elapsed - @eta.elapsed - end - - def print_message(options = {}) - force = options[:force] - lock force do - if force || time_to_print? - @next_time_to_print = Time.now + 0.3 - restart_beeper - - current = 0 - parts = [] - title_parts = [] - @levels.reverse.each do |level| - current = level.to_f(current) - - percent = current == 0 ? '......' : "#{'%5.1f' % (current * 100.0)}%" - title = level.title && "#{level.title}: " - if !highlight? || percent == '100.0%' - parts << "#{title}#{percent}" - else - parts << "#{title}\e[1m#{percent}\e[0m" - end - title_parts << "#{title}#{percent}" - end - - timing = if options[:finish] - " (elapsed: #{elapsed})" - elsif eta_ = eta(current) - " (ETA: #{eta_})" - end - - message = "#{parts.reverse * ' > '}#{timing}" - text_message = "#{title_parts.reverse * ' > '}#{timing}" - - if note = running? && @levels.last.note - message << " - #{note}" - text_message << " - #{note}" - end - - message = "\r#{message}\e[K" if stay_on_line? - message << "\n" if !stay_on_line? || options[:finish] - io << message - - if set_terminal_title? - title = options[:finish] ? nil : text_message.to_s.gsub("\a", '␇') - io << "\e]0;#{title}\a" - end - end - end - end - - end -end - -require 'progress/beeper' -require 'progress/eta' - -require 'progress/enumerable' -require 'progress/integer' -require 'progress/active_record' if defined?(ActiveRecord::Base) - -module Kernel - def Progress(*args, &block) - Progress.start(*args, &block) - end - private :Progress end