2013-06-14 08:01:54 +04:00
|
|
|
require 'open-uri'
|
|
|
|
|
2014-06-24 05:26:21 +04:00
|
|
|
class Downloader
|
2014-09-23 15:56:30 +04:00
|
|
|
def self.gnu(name)
|
|
|
|
"http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=#{name};hb=HEAD"
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.rubygems(name)
|
|
|
|
"https://rubygems.org/downloads/#{name}"
|
|
|
|
end
|
|
|
|
|
2014-09-24 12:55:09 +04:00
|
|
|
def self.unicode(name)
|
|
|
|
"http://www.unicode.org/Public/UCD/latest/ucd/#{name}"
|
|
|
|
end
|
|
|
|
|
2014-09-23 15:56:30 +04:00
|
|
|
def self.uri_to_download(url, name)
|
|
|
|
from, url = url
|
|
|
|
case from
|
|
|
|
when :gnu
|
|
|
|
url = gnu(url || name)
|
|
|
|
when :rubygems, :gems
|
|
|
|
url = rubygems(url || name)
|
2014-09-24 12:55:09 +04:00
|
|
|
when :unicode
|
|
|
|
url = unicode(url || name)
|
2014-09-23 15:56:30 +04:00
|
|
|
when Symbol
|
|
|
|
raise ArgumentError, "unkonwn site - #{from}"
|
|
|
|
else
|
|
|
|
url = from
|
|
|
|
end
|
|
|
|
URI(url)
|
|
|
|
end
|
|
|
|
|
2014-09-23 15:52:23 +04:00
|
|
|
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
|
2014-06-24 05:26:21 +04:00
|
|
|
end
|
2014-09-23 11:08:16 +04:00
|
|
|
|
2014-09-23 15:52:23 +04:00
|
|
|
# Downloader.download(url, name, [dir, [ims]])
|
|
|
|
#
|
2014-09-23 11:08:03 +04:00
|
|
|
# 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.
|
2014-09-24 05:43:44 +04:00
|
|
|
# If +ims+ is false, always download url regardless of its last
|
2014-09-23 15:52:23 +04:00
|
|
|
# modified time.
|
|
|
|
#
|
2014-09-23 11:08:03 +04:00
|
|
|
# Example usage:
|
2014-09-23 15:52:23 +04:00
|
|
|
# download 'http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt',
|
2014-09-23 11:08:03 +04:00
|
|
|
# 'enc/unicode/data/UnicodeData.txt'
|
2014-09-23 15:52:23 +04:00
|
|
|
def self.download(url, name, dir = nil, ims = true)
|
2014-09-23 11:08:03 +04:00
|
|
|
file = dir ? File.join(dir, name) : name
|
2014-09-23 15:56:30 +04:00
|
|
|
url = uri_to_download(url, name)
|
2014-09-23 15:52:23 +04:00
|
|
|
begin
|
|
|
|
data = url.read(http_options(file, ims))
|
|
|
|
rescue OpenURI::HTTPError => http_error
|
|
|
|
return http_error.message =~ /^304 / # 304 Not Modified
|
|
|
|
raise
|
2014-09-23 11:08:03 +04:00
|
|
|
end
|
2014-09-23 15:52:23 +04:00
|
|
|
mtime = nil
|
|
|
|
open(file, "wb", 0600) do |f|
|
|
|
|
f.write(data)
|
|
|
|
f.chmod(mode_for(data))
|
|
|
|
mtime = data.meta["last-modified"]
|
2014-09-23 11:08:03 +04:00
|
|
|
end
|
2014-09-23 15:52:23 +04:00
|
|
|
if mtime
|
|
|
|
mtime = Time.httpdate(mtime)
|
|
|
|
File.utime(mtime, mtime, file)
|
|
|
|
end
|
|
|
|
true
|
|
|
|
rescue => e
|
2014-09-23 15:56:30 +04:00
|
|
|
raise e.class, "failed to download #{name}\n#{e.message}: #{url}", e.backtrace
|
2014-09-23 15:52:23 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.download_if_modified_since(url, name, dir = nil)
|
|
|
|
download(url, name, dir)
|
2014-09-23 11:08:03 +04:00
|
|
|
end
|
2013-06-14 08:01:54 +04:00
|
|
|
end
|