Skip to content

Instantly share code, notes, and snippets.

@wazery
Last active August 29, 2015 14:11
Show Gist options
  • Save wazery/d1ae8c554dd9d23aad91 to your computer and use it in GitHub Desktop.
Save wazery/d1ae8c554dd9d23aad91 to your computer and use it in GitHub Desktop.
Upload public images to Amazon S3
require 's3'
require 'digest/md5'
require 'mime/types'
## These are some constants to keep track of my S3 credentials and
## bucket name. Nothing fancy here.
AWS_ACCESS_KEY_ID = ENV["AWS_ACCESS_KEY_ID"]
AWS_SECRET_ACCESS_KEY = ENV["AWS_SECRET_ACCESS_KEY"]
AWS_BUCKET = ENV["AWS_S3_BUCKET"]
## This defines the rake task `assets:deploy`.
namespace :assets do
desc "Deploy all matching assets in public/**/* to S3/Cloudfront"
task :deploy => :environment do |t, args|#, :env, :branch do |t, args|
## Use the `s3` gem to connect my bucket
puts "== Uploading assets to S3/Cloudfront"
service = S3::Service.new(
:access_key_id => AWS_SECRET_ACCESS_KEY,
:secret_access_key => AWS_SECRET_ACCESS_KEY)
bucket = service.buckets.find(AWS_BUCKET)
## Needed to show progress
STDOUT.sync = true
## Get all images in the image model, check their URLs, and upload only them
## Looping through images in the DB
images = Image.all
images.each do |image|
file = Dir["#{Rails.root}/public#{image.image.url}"].first
remote_file = "#{image.image.url}"
remote_file = remote_file.gsub("/uploads/", "uploads/")
if file
## Only upload files, we're not interested in directories
if File.file?(file)
## Try to find the remote_file, an error is thrown when no
## such file can be found, that's okay.
begin
obj = bucket.objects.find_first(remote_file)
rescue
obj = nil
end
## If the object does not exist, or if the MD5 Hash / etag of the
## file has changed, upload it.
if !obj || (obj.etag != Digest::MD5.hexdigest(File.read(file)))
print "U"
## Simply create a new object, write the content and set the proper
## mime-type. `obj.save` will upload and store the file to S3.
obj = bucket.objects.build(remote_file)
obj.content = open(file)
obj.content_type = MIME::Types.type_for(file).to_s
obj.save
else
print "."
end
end
end
end
STDOUT.sync = false # Done with progress output.
puts
puts "== Done syncing assets"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment