Created
March 25, 2010 14:13
-
-
Save epitron/343594 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'progressbar' | |
class Mechanize | |
class Chain | |
class ResponseReader | |
def handle(ctx, params) | |
params[:response] = @response | |
body = StringIO.new | |
total = 0 | |
if @response.respond_to? :content_type | |
pbar = ProgressBar.new(" |_ #{@response.content_type}", @response.content_length) | |
else | |
pbar = nil | |
end | |
@response.read_body { |part| | |
total += part.length | |
body.write(part) | |
pbar.set(total) if pbar | |
Mechanize.log.debug("Read #{total} bytes") if Mechanize.log | |
} | |
pbar.finish if pbar | |
body.rewind | |
res_klass = Net::HTTPResponse::CODE_TO_OBJ[@response.code.to_s] | |
raise ResponseCodeError.new(@response) unless res_klass | |
# Net::HTTP ignores EOFError if Content-length is given, so we emulate it here. | |
unless res_klass <= Net::HTTPRedirection | |
raise EOFError if (!params[:request].is_a?(Net::HTTP::Head)) && @response.content_length() && @response.content_length() != total | |
end | |
@response.each_header { |k,v| | |
Mechanize.log.debug("response-header: #{ k } => #{ v }") | |
} if Mechanize.log | |
params[:response_body] = body | |
params[:res_klass] = res_klass | |
super | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Ruby/ProgressBar - a text progress bar library | |
# | |
# Copyright (C) 2001-2005 Satoru Takabayashi <[email protected]> | |
# All rights reserved. | |
# This is free software with ABSOLUTELY NO WARRANTY. | |
# | |
# You can redistribute it and/or modify it under the terms | |
# of Ruby's license. | |
# | |
class ProgressBar | |
VERSION = "0.9" | |
def initialize (title, total=nil, out = STDERR) | |
@title = title | |
@total = total | |
@out = out | |
@terminal_width = 80 | |
@bar_mark = "." | |
@current = 0 | |
@previous = 0 | |
@finished_p = false | |
@start_time = Time.now | |
@previous_time = @start_time | |
@title_width = 18 | |
#@format = "%-#{@title_width}s %3d%% %s %s" | |
if @total | |
#@format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer] | |
@format_arguments = [:title, :percentage, :stat_for_file_transfer] | |
else | |
@format_arguments = [:title, :stat_for_file_transfer] | |
end | |
clear | |
show | |
end | |
attr_reader :title | |
attr_reader :current | |
attr_reader :total | |
attr_accessor :start_time | |
private | |
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 | |
"%3d%%" % do_percentage | |
end | |
def fmt_stat | |
if @finished_p then elapsed else eta end | |
end | |
def fmt_stat_for_file_transfer | |
if !@total or @finished_p then | |
sprintf("%s %s %s", bytes, transfer_rate, elapsed) | |
else | |
sprintf("%s %s %s", bytes, transfer_rate, eta) | |
end | |
end | |
def fmt_title | |
title = (@title[0,(@title_width - 1)] + ":") | |
@total ? "%-#{@title_width}s" % title : title | |
end | |
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 transfer_rate | |
bytes_per_second = @current.to_f / (Time.now - @start_time) | |
sprintf("%s/s", convert_bytes(bytes_per_second)) | |
end | |
def bytes | |
convert_bytes(@current) | |
end | |
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 | |
# 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 elapsed | |
elapsed = Time.now - @start_time | |
sprintf("Time: %s", format_time(elapsed)) | |
end | |
def eol | |
if @finished_p then "\n" else "\r" end | |
end | |
def do_percentage | |
if @total.zero? | |
100 | |
else | |
@current * 100 / @total | |
end | |
end | |
def get_width | |
# FIXME: I don't know how portable it is. | |
default_width = 80 | |
begin | |
tiocgwinsz = 0x5413 | |
data = [0, 0, 0, 0].pack("SSSS") | |
if @out.ioctl(tiocgwinsz, data) >= 0 then | |
rows, cols, xpixels, ypixels = data.unpack("SSSS") | |
if cols >= 0 then cols else default_width end | |
else | |
default_width | |
end | |
rescue Exception | |
default_width | |
end | |
end | |
def show | |
arguments = @format_arguments.map {|method| | |
send("fmt_#{method}") | |
} | |
#line = sprintf(@format, *arguments) | |
line = arguments.join(" ") | |
# width = 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 | |
@out.print(line + eol) | |
@out.flush | |
@previous_time = Time.now | |
end | |
def show_if_needed | |
if @total | |
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_p | |
show | |
end | |
else | |
if Time.now - @previous_time >= 1 || @finished_p | |
show | |
end | |
end | |
end | |
public | |
def clear | |
@out.print "\r" | |
@out.print(" " * (get_width - 1)) | |
@out.print "\r" | |
end | |
def finish | |
@current = @total if @total | |
@finished_p = true | |
show | |
end | |
def finished? | |
@finished_p | |
end | |
def file_transfer_mode | |
@format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer] | |
end | |
def format=(format) | |
@format = format | |
end | |
def format_arguments=(arguments) | |
@format_arguments = arguments | |
end | |
def halt | |
@finished_p = true | |
show | |
end | |
def inc(step = 1) | |
@current += step | |
@current = @total if @total and @current > @total | |
show_if_needed | |
@previous = @current | |
end | |
def set(count) | |
if @total and (count < 0 || count > @total) | |
raise "invalid count: #{count} (total: #{@total})" | |
end | |
@current = count | |
show_if_needed | |
@previous = @current | |
end | |
def inspect | |
"#<ProgressBar:#{@current}/#{@total}>" | |
end | |
end | |
class ReversedProgressBar < ProgressBar | |
def do_percentage | |
100 - super | |
end | |
end | |
if $0 == __FILE__ | |
pb = ProgressBar.new("no_total") | |
5.times do | |
pb.inc 4000 | |
sleep 1 | |
end | |
pb.finish | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment