module Arfor::Download

Constants

TEMP_EXT
WRAP

Public Class Methods

gem(gem) click to toggle source
# File lib/arfor/download.rb, line 97
def self.gem(gem)
  system("gem fetch #{gem}")
end
get(url) click to toggle source
# File lib/arfor/download.rb, line 56
def self.get(url)
  resolved_url, file_size = resolve_url(url)

  uri = URI.parse(resolved_url)
  target_file = File.basename(uri.path)
  tempfile = target_file + TEMP_EXT

  # check if the resolved filename exists locally - this will work even when
  # user hits the download url that includes ver=latest since we resolve to
  # the real filenam
  if ! File.exists?(target_file)
    progressbar = ProgressBar.create(:title => target_file)
    Net::HTTP.start(uri.host, uri.port, :use_ssl=>(uri.scheme == 'https')) do |http|
      request = Net::HTTP::Get.new uri


      http.request request do |resp|
        puts "Downloading: #{resolved_url}"
        downloaded_bytes = 0
        File.open tempfile, 'wb' do |io|
          resp.read_body do |chunk|
            downloaded_bytes += chunk.size
            percent_complete = (downloaded_bytes.to_f / file_size.to_i) * 100

            io.write chunk
            progressbar.progress=(percent_complete)
          end
        end
      end
    end

    if File.exist?(tempfile)
      # get to here without erroring then safe to move
      FileUtils.mv(tempfile, target_file)
    end

  else
    puts "installer for #{target_file} already downloaded"
  end
end
resolve_url(url,limit = 10) click to toggle source
# File lib/arfor/download.rb, line 28
def self.resolve_url(url,limit = 10)
  url_resolved = false
  file_size = -1

  raise ArgumentError, 'HTTP redirect too deep' if limit == 0
  uri = URI.parse(url)
  Net::HTTP.start(uri.host, uri.port, :use_ssl=>(uri.scheme == 'https')) { |http|
    http.read_timeout = 1000
    resp  = http.head(url)


    file_size = resp['content-length']

    case resp
    when Net::HTTPSuccess
      url_resolved = url
    when Net::HTTPRedirection
      url_resolved, file_size = resolve_url(resp['location'], limit - 1)
    else
      #resp.error!
      raise "Error #{resp.code} downloading #{url}"
    end
  }

  return url_resolved, file_size
end