module Dapp::Downloader

Public Class Methods

download(url, destination, show_progress: false, progress_titile: nil) click to toggle source
# File lib/dapp/downloader.rb, line 56
def download(url, destination, show_progress: false, progress_titile: nil)
  resp = nil
  location = URI(url)
  done = false
  state = {}

  loop do
    Net::HTTP.start(location.host, location.port, use_ssl: true) do |http|
      req = Net::HTTP::Get.new location
      http.request req do |resp|
        case resp
        when Net::HTTPRedirection
          location = URI(resp["location"])
          next
        when Net::HTTPSuccess
          File.open(destination, "wb") do |file|
            file_size_bytes = nil
            file_size_bytes = BytesCount.new(resp.to_hash["content-length"].first.to_f) if show_progress

            if show_progress
              old_DEFAULT_BEGINNING_POSITION = ProgressBar::Progress.send(:remove_const, :DEFAULT_BEGINNING_POSITION)
              ProgressBar::Progress.send(:const_set, :DEFAULT_BEGINNING_POSITION, BytesCount.new(0, total_bytes_count: file_size_bytes))
            end

            begin
              progressbar = nil
              progressbar = ProgressBar.create(
                format: "   %cMB / %CMB   %B  %t",
                starting_at: BytesCount.new(0, total_bytes_count: file_size_bytes),
                total: file_size_bytes,
                progress_mark: "#",
                remainder_mark: ".",
                title: progress_titile,
                length: 100,
                autofinish: true
              ) if show_progress

              resp.read_body do |segment|
                progressbar.progress = progressbar.progress + segment.bytesize if show_progress
                file.write segment
              end
            ensure
              if show_progress
                ProgressBar::Progress.send(:remove_const, :DEFAULT_BEGINNING_POSITION)
                ProgressBar::Progress.send(:const_set, :DEFAULT_BEGINNING_POSITION, old_DEFAULT_BEGINNING_POSITION)
              end
            end
          end # File.open

          done = true
        else
          raise Error::DownloadFailed, "Failed to download #{url}: #{resp.code} #{resp.message}"
        end # when
      end # http.request
    end # Net::HTTP.start

    break if done
  end # loop
end