How to copy file across buckets using aws-s3 or aws-sdk gem in ruby on rails
Using the right_aws
gem:
# With s3 being an S3 object acquired via S3Interface.new
# Copies key1 from bucket b1 to key1_copy in bucket b2:
s3.copy('b1', 'key1', 'b2', 'key1_copy')
the gotcha I ran into is that if you have pics/1234/yourfile.jpg
the bucket
is only pics
and the key
is 1234/yourfile.jpg
I got the answer from here: How do I copy files between buckets using s3 from a rails application?
Copying a file inside an S3 bucket (ruby)
Extracted from the documentation, you'll have to use the copy_to
. For instance:
s3 = AWS::S3.new
# Upload a file and set server-side encryption.
bucket1 = s3.buckets[source_bucket]
bucket2 = s3.buckets[target_bucket]
obj1 = bucket1.objects[source_key]
obj2 = bucket2.objects[target_key]
obj1.copy_to(obj2)
How do I only copy missing objects between buckets using ruby aws-sdk?
I never worked with that gem, but you code looks like it is possible to receive an array with all items store in a bucket. Load that list for both buckets and determine the missing files with a simple array operations. Should be much faster.
# load file lists (looks up objects in batches of 1000)
source_files = AWS::S3.new.buckets[prod_bucket].objects.map(&:key)
target_files = AWS::S3.new.buckets[dev_bucket].objects.map(&:key)
# determine files missing in dev
files_to_copy = source_files - target_files
files_to_copy.each_with_index do |file_name, i|
puts "Coping #{i}/#{files_to_copy.size}: #{file_name}"
S3Object.store(file_name,
S3Object.value(file_name, PROD_BUCKET_NAME),
DEV_BUCKET_NAME)
end
# determine files on dev that are not existing on prod
files_to_remove = target_files - source_files
files_to_remove.each_with_index do |file_name, i|
puts "Removing #{i}/#{files_to_remove.size}: #{file_name}"
S3Object.delete(file_name, DEV_BUCKET_NAME)
end
How to copy list of public S3 files to private S3 bucket
1) There's is no sdk feature for an 'internal copy' of public S3 objects to ones private S3 bucket.
2) the below source works, which keeps the same S3 directory structure
vid_file = 'http://example.com.s3.amazonaws.com/assets/videos/abc123.mp4'
vid_response = HTTParty.get(vid_file)
if vid_response.code == 200
uri_path = URI(vid_url).path
uri_path.slice!(0) # slice!(0) removes leading slash, otherwise creates an empty s3 folder
s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
obj = s3.bucket(ENV['S3_BUCKET']).object(uri_path)
obj.put(body: vid_response.body) if !obj.exists?
end
Copy file in a bucket to a paperclip attachment with aws-sdk
I'm copying the file using AWS::S3::S3Object#copy_to(target_obj) and I get target obj by calling #s3_object() on the attachment after setting some column values and saving it:
my_model.some_file_file_name = obj.key
my_model.some_file_file_size = obj.content_length
my_model.some_file_content_type = obj.content_type
my_model.some_file_updated_at = obj.last_modified
my_model.save
obj.copy_to(my_model.some_file.s3_object)
Related Topics
Rails Carrierwave Base64 Image Upload
How Is Each_With_Object Supposed to Work
Is Everything an Object in Ruby
How Does Require Rubygems Help Find Rubygem Files
Ruby: Inject Issue When Turning Array into Hash
Ruby Design Pattern: How to Make an Extensible Factory Class
Directly Accessing an Instance Variable VS. Using an Accessor Method
Populating an Association with Children in Factory_Girl
Reading and Updating Yaml File by Ruby Code
Devise Login with User or Admin Models and Basecamp Style Subdomains
Putting the Results of Pp (Or Anything Outputted to Console) into a String
Safe Navigation Operator (&.) for Nil
Form_For Error Messages in Ruby on Rails
How to Use Params with Slashes with Sinatra
Is There an Equivalent Null Prevention on Chained Attributes of Groovy in Ruby