From c7cdc549fffc9ef6a2ef77841dc500d6ef2d087d Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 23 Sep 2014 11:52:23 +0000 Subject: downloader.rb: integrate with download_if_modified_since * tool/downloader.rb (Downloader.download): integrate with download_if_modified_since and allow to use `since` parameter if it is not true/false. also set last-modified time and permission. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- tool/downloader.rb | 65 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 18 deletions(-) (limited to 'tool/downloader.rb') diff --git a/tool/downloader.rb b/tool/downloader.rb index f212442d71..ba6ddc15c5 100644 --- a/tool/downloader.rb +++ b/tool/downloader.rb @@ -1,33 +1,62 @@ require 'open-uri' class Downloader - def self.download(url, name, dir = nil) - data = URI(url).read - file = dir ? File.join(dir, name) : name - open(file, "wb", 0755) {|f| f.write(data)} - rescue => e - raise "failed to download #{name}\n#{e.message}: #{url}" + def self.mode_for(data) + data.start_with?("#!") ? 0755 : 0644 + end + + def self.http_options(file, since) + options = {} + if since + case since + when true + since = (File.mtime(file).httpdate rescue nil) + when Time + since = since.httpdate + end + if since + options['If-Modified-Since'] = since + end + end + options end + # Downloader.download(url, name, [dir, [ims]]) + # # Update a file from url if newer version is available. # Creates the file if the file doesn't yet exist; however, the # directory where the file is being created has to exist already. + # If +ims+ is false, already download url regardless its last + # modified time. + # # Example usage: - # download_if_modified_since 'http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt', + # download 'http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt', # 'enc/unicode/data/UnicodeData.txt' - def self.download_if_modified_since(url, name, dir=nil, since=nil) + def self.download(url, name, dir = nil, ims = true) file = dir ? File.join(dir, name) : name - since = Date.new(1980,1,1) unless File.exist? file # use very old date to assure file creation - since = File.mtime file unless since # get last modification time for file - since = since.to_datetime if since.respond_to? :to_datetime # convert Time/Date to DateTime - since = since.httpdate if since.respond_to? :httpdate # convert DateTime to String - open(url, 'If-Modified-Since' => since) do |r| - body = r.read - open(file, 'wb', 0755) { |f| f.write(body) } + url = URI(url) + begin + data = url.read(http_options(file, ims)) + rescue OpenURI::HTTPError => http_error + return http_error.message =~ /^304 / # 304 Not Modified + raise end - rescue OpenURI::HTTPError => http_error - unless http_error.message =~ /^304 / # 304 Not Modified - raise "Failed to (check for) downloading #{url}: #{http_error.message}" + mtime = nil + open(file, "wb", 0600) do |f| + f.write(data) + f.chmod(mode_for(data)) + mtime = data.meta["last-modified"] end + if mtime + mtime = Time.httpdate(mtime) + File.utime(mtime, mtime, file) + end + true + rescue => e + raise "failed to download #{name}\n#{e.message}: #{url}" + end + + def self.download_if_modified_since(url, name, dir = nil) + download(url, name, dir) end end -- cgit v1.2.3