Skip to content

Instantly share code, notes, and snippets.

@builtinnya
Created August 25, 2015 12:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save builtinnya/24c2ca12969fc79a0d69 to your computer and use it in GitHub Desktop.
Save builtinnya/24c2ca12969fc79a0d69 to your computer and use it in GitHub Desktop.
Paperclip S3 copy attachments
### S3 implementation of Paperclip module that supports deep
### cloning of objects by copying image attachments.
###
### Tested with: aws-sdk (1.33.0)
###
### Refer to Paperclip issue: https://github.com/thoughtbot/paperclip/issues/1361#issuecomment-39684643
### Original gist works with fog: https://gist.github.com/stereoscott/10011887
### gist works from which this code is derived: https://gist.github.com/ksin/7747334d60b1947f14e9
module Paperclip
module CopyAttachments
def copy_attachments_from(source_obj, source_bucket = nil, destination_bucket = nil)
self.class.attachment_definitions.keys.each do |attachment_name|
source_attachment = source_obj.send(attachment_name)
next if source_attachment.blank?
destination_attachment = self.send(attachment_name)
source_bucket ||= bucket source_attachment
destination_bucket ||= bucket destination_attachment
[:original, *destination_attachment.styles.keys].uniq.map do |style|
source_path = path(source_attachment, style)
destination_path = path(destination_attachment, style)
Paperclip.log("Copying #{style} from #{source_bucket}/#{source_path} ---> #{destination_bucket}/#{destination_path}")
begin
copy_object(source_bucket, source_path, destination_bucket, destination_path)
rescue AWS::S3::Errors::NotFound
Paperclip.log("Could not find #{style} from #{source_bucket}/#{source_path}")
end
end
end
end
private
def path(attachment, style)
path = attachment.path(style)
path.slice!(0) if path.start_with? '/'
path
end
def bucket(attachment)
s3.buckets[attachment.bucket_name]
end
def s3
return @s3 if @s3
# Load credentials from a file.
# Change this line (and key names below) to match your environment.
creds = YAML.load(File.read("#{ Rails.root }/config/s3.yml"))
@s3 = AWS::S3.new(
access_key_id: creds['access_key_id'],
secret_access_key: creds['secret_access_key'],
s3_endpoint: 'YOUR_S3_ENDPOINT'
)
end
def copy_object(source_bucket, source_path, destination_bucket, destination_path)
source_obj = source_bucket.objects[source_path]
destination_obj = destination_bucket.objects[destination_path]
source_obj.copy_to(destination_obj, acl: :public_read)
end
end
end
@airblade
Copy link

airblade commented Nov 4, 2015

@builtinnya What version of Paperclip does this work with?

@builtinnya
Copy link
Author

@airblade It works at least with paperclip 4.2.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment