В прошлом я обнаружил, что самый надежный способ получения удаленных файлов - использование инструмента командной строки "wget".Следующий код в основном копируется прямо из существующего производственного приложения (Rails 2.x) с несколькими настройками, подходящими для примеров кода:
class CategoryIconImporter
def self.download_to_tempfile (url)
system(wget_download_command_for(url))
@@tempfile.path
end
def self.clear_tempfile
@@tempfile.delete if @@tempfile && @@tempfile.path && File.exist?(@@tempfile.path)
@@tempfile = nil
end
def self.set_wget
# used for retrieval in NrlImage (and in future from other sies?)
if !@@wget
stdin, stdout, stderr = Open3.popen3('which wget')
@@wget = stdout.gets
@@wget ||= '/usr/local/bin/wget'
@@wget.strip!
end
end
def self.wget_download_command_for (url)
set_wget
@@tempfile = Tempfile.new url.sub(/\?.+$/, '').split(/[\/\\]/).last
command = [ @@wget ]
command << '-q'
if url =~ /^https/
command << '--secure-protocol=auto'
command << '--no-check-certificate'
end
command << '-O'
command << @@tempfile.path
command << url
command.join(' ')
end
def self.import_from_url (category_params, url)
clear_tempfile
filename = url.sub(/\?.+$/, '').split(/[\/\\]/).last
found = MIME::Types.type_for(filename)
content_type = !found.empty? ? found.first.content_type : nil
download_to_tempfile url
nicer_path = RAILS_ROOT + '/tmp/' + filename
File.copy @@tempfile.path, nicer_path
Category.create(category_params.merge({:icon => ActionController::TestUploadedFile.new(nicer_path, content_type, true)}))
end
end
Логика задачи rake может выглядеть следующим образом:
[
['Cat', 'cat'],
['Dog', 'dog'],
].each do |name, icon|
CategoryIconImporter.import_from_url {:name => name}, "https://xyz.com/images/#{icon}.png"
end
Используется гем mime-types для обнаружения типов контента:
gem 'mime-types', :require => 'mime/types'