Module: Dapp::Downloader

Defined in:
lib/dapp/downloader.rb

Defined Under Namespace

Modules: Error Classes: BytesCount

Class Method Summary collapse

Class Method Details

.download(url, destination, show_progress: false, progress_titile: nil) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# 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