require 'uri'
require 'net/http'
require 'uuidtools'
module Zena
module Use
module Upload
UPLOAD_KEY = defined?(Mongrel) ? 'upload_id' : "X-Progress-ID"
def self.has_network?
response = nil
Net::HTTP.new('example.com', '80').start do |http|
response = http.head('/')
end
response.kind_of? Net::HTTPSuccess
rescue
false
end
module UploadedFile
protected
def uploaded_file(file, filename = nil, content_type = nil)
(class << file; self; end;).class_eval do
alias local_path path if respond_to?(:path) # FIXME: do we need this ?
define_method(:original_filename) { filename }
define_method(:content_type) { content_type }
end
file
end
end # UploadedFile
module ControllerMethods
include UploadedFile
protected
include ActionView::Helpers::NumberHelper # number_to_human_size
def get_attachment
att, error = nil, nil
if !params['attachment_url'].blank?
att, error = fetch_uri(params['attachment_url'])
else
att = params['attachment']
end
yield(att, error) if block_given?
[att, error]
end
private
def fetch_uri(uri_str, max_file_size = 10)
max_file_size = max_file_size * 1024 * 1024 # Mo
# first check head
response, error = fetch_response(uri_str, :head)
return [nil, error] unless response
if response['Content-Length'].nil?
return [nil, 'unknown size: cannot fetch url']
elsif response['Content-Length'].to_i > max_file_size
return [nil, 'size (%s) too big to fetch url' % number_to_human_size(response['Content-Length'].to_i)]
end
# Size is ok, get content
response, error = fetch_response(uri_str, :body)
return [nil, error] unless response
tmpf = Tempfile.new('fetch_uri')
File.open(tmpf.path, 'wb') do |file|
file.write(response.body)
end
if content_disposition = response['Content-Disposition']
original_filename = content_disposition[/filename\s*=\s*('|")(.+)\1/,2]
else
original_filename = uri_str.split('/').last
end
[uploaded_file(tmpf, original_filename, response['Content-Type'])]
end
def fetch_response(uri_str, type = :body, limit = 10)
return [nil, 'too many redirects'] if limit == 0
response = nil
uri = URI.parse(URI.escape(uri_str))
return [nil, 'invalid url'] unless uri.kind_of?(URI::HTTP)
Net::HTTP.new(uri.host, uri.port).start do |http|
if type == :body
response = http.request_get(uri.request_uri)
else
response = http.head(uri.request_uri)
end
end
case response
when Net::HTTPSuccess
response
when Net::HTTPRedirection
redirect = response['location']
port = (uri.scheme == 'http' && uri.port == 80) ? '' : ":#{uri.port}"
redirect = "#{uri.scheme}://#{uri.host}#{port}/#{redirect}" unless redirect =~ /\A\w+:\/\//
fetch_response(redirect, type, limit - 1)
else
[nil, 'not found']
end
rescue URI::InvalidURIError
[nil, 'invalid url']
end
def render_get_uf
@uuid = params[:uuid]
render :inline => "<%= link_to_function(_('cancel'), \"['file', 'upload_field'].each(Element.toggle);$('upload_field').innerHTML = '';\")%><%= upload_field %>"
end
def render_upload_progress
# When using the mod_upload_progress module, this is never hit:
#