jbox-web/jenkins-peace

View on GitHub
lib/jenkins/peace/content_downloader.rb

Summary

Maintainability
A
35 mins
Test Coverage
A
100%
require 'ruby-progressbar'
require 'net/http'
require 'uri'

module Jenkins
  module Peace
    class ContentDownloader

      attr_reader :target_file
      attr_reader :logger


      def initialize(target_file, logger)
        @target_file = target_file
        @logger      = logger
      end


      def download(url, limit = 10)
        raise ArgumentError, 'too many HTTP redirects' if limit == 0

        start_http_session(url) do |http, uri|
          response = http.request_head(uri.path)
          case response
          when Net::HTTPSuccess
            download_content(url)
          when Net::HTTPRedirection
            redirect = response['location']
            logger.info "Redirected to : '#{redirect}'"
            download(redirect, limit - 1)
          else
            logger.error response.value
          end
        end
      rescue => e
        logger.error "Error while downloading '#{url}' : #{e.message}"
      end


      def download_content(url)
        logger.info "Downloading   : '#{url}'"
        start_http_session(url) do |http, uri|
          response = http.request_head(uri.path)
          progressbar = build_progress_bar(response['content-length'].to_i)
          File.open(target_file, 'wb') do |file|
            http.get(uri.path) do |chunk|
              file.write chunk
              progressbar.progress += chunk.length
            end
          end
        end
      rescue => e
        logger.error "Error while downloading '#{url}' : #{e.message}"
      end


      def build_progress_bar(total)
        ProgressBar.create(title: 'Downloading', starting_at: 0, total: total, format: '%a |%b>%i| %p%% %t')
      end


      def start_http_session(url)
        uri = URI(url)
        Net::HTTP.start(uri.host, uri.port) do |http|
          yield http, uri
        end
      end

    end
  end
end