Last active
September 14, 2016 09:29
-
-
Save dux/bccf681cf7ff0ae9fa10fb9669db3e56 to your computer and use it in GitHub Desktop.
AWS S3 local file or URL upload
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'aws-sdk' | |
require 'json' | |
require 'digest' | |
['AWS_REGION', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY'].each { |key| | |
next if ENV[key] | |
puts "ENV key '#{key}' not defined (AwsS3)" | |
exit | |
} | |
Aws.config.update({ | |
region: ENV['AWS_REGION'], | |
credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']) | |
}) | |
module AwsS3 | |
extend self | |
def list_buckets | |
s3c = Aws::S3::Client.new | |
s3c.list_buckets.buckets.map(&:name) | |
end | |
# options | |
# :max_age - defaults to 5 years | |
# :max_width - resize image to desired max_width before upload | |
# :bucket | |
# :is_image - check if downloaded file is image | |
# upload_file('http://foo.bar/baz.jpeg', max_width:800) | |
def upload_file(source, opts={}) | |
opts[:is_image] = true if opts[:max_width] | |
opts[:bucket] ||= ENV['AWS_BUCKET'] | |
raise "no bucket defined and no ENV['AWS_BUCKET'] set" unless opts[:bucket] | |
ext = source.split('.').last || 'jpeg' | |
ext = 'jpeg' if ext == 'jpg' || ext.length != 3 | |
file_name = source.split('/').last.split('?').first.gsub(/[^\w\-\.](\.\w+)/,'') | |
file_name.gsub!(/%../,'') | |
file_name.gsub!(/[^\w\-\.]/,'') | |
file_name = "#{Digest::MD5.hexdigest(source)}-#{file_name}.#{ext}".downcase | |
local_file = "./tmp/tmp-#{file_name}" | |
File.unlink(local_file) if File.exists?(local_file) | |
if source =~ /^http/ | |
# find local file name and unlink if present | |
source = source.gsub(' ','%20') | |
# download image | |
system "curl -o '#{local_file}' '#{source}' " | |
else | |
raise "File #{source} not found" unless File.exists?(source) | |
`cp '#{cource}}' '#{local_file}'` | |
end | |
raise 'Local file not found' unless File.exists? local_file | |
# resize image if needed | |
`convert '#{local_file}' -resize '#{opts[:max_width]}x3000>' '#{local_file}'` if opts[:max_width] | |
if opts[:is_image] | |
dimensions = `identify #{local_file}`.split(' ')[2].to_s.split('x').map(&:to_i) | |
raise "Not an image" unless dimensions[0] > 10 && dimensions[1] > 10 | |
end | |
remote_file = "#{Time.now.strftime('%Y/%m/%d/%H')}/#{file_name}" | |
s3r = Aws::S3::Resource.new | |
meta = {} | |
meta['Content-Type'] = "image/#{ext}" | |
meta['ETag'] = Digest::MD5.hexdigest File.read local_file | |
meta['Cache-Control'] = "max-age=#{opts[:max_age] || 60*60*24*365*5}" | |
s3_bucket = s3r.bucket(opts[:bucket]) | |
if s3_bucket.object(remote_file).upload_file(local_file, { metadata: meta, acl: 'public-read' }) | |
remote_file | |
else | |
false | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment