Download a Carrierwave upload from S3
Thanks apneadiving. It was as easy as:
image = MiniMagick::Image::open(card.image.to_s)
image.write(somepath)
Carrierwave & Amazon S3 file downloading/uploading
Looks like you want to upload to S3, but have not-public URLs. Instead of downloading the file from S3 and using send_file, you can redirect the user to the S3 authenticated URL. This URL will expire and only be valid for a little while (for the user to download).
Check out this thread: http://groups.google.com/group/carrierwave/browse_thread/thread/2f727c77864ac923
Since you're already setting fog_public to false, do you get an authenticated (i.e. signed) url when calling resource.upload_url
Downloading an image from S3 using carrierwave (without open)
I can suggest you use JavaScript to download a data(file/image) anything.
You can do ajax call to server to get an url.
#removed: target: '_self' no need it anymore
#added: remote: true
<%= link_to download_media_partnership_path(@partner, m: m.id), remote: true, data: {disable_with: "<i class='fa fa-spinner fa-spin media-icon'></i>"}
<i class="fa fa-download media-icon download" id=""></i>
<% end %>
def download_media
@media = TeamMedia.find(params[:m])
@url = @media.attachment.url
respond_to do |format|
format.js {}
end
end
Check this Link and implement into your javascript assets.Do not forget to create download_media.js.erb
file.
#download_media.js.erb
downloadFile("<%= @url %>");
Downloading and zipping files that were uploaded to S3 with CarrierWave
I've managed to solve the problem with help from @ffoeg
The solution offered by @ffoeg didn't work quite so well for me since I was dealing with zip files > 500 MB which caused me problems on Heroku. I've therefor moved the zipping to a background process using resque:
app/workers/photo_zipper.rb:
require 'zip/zip'
require 'zip/zipfilesystem'
require 'open-uri'
class PhotoZipper
@queue = :photozip_queue
#I pass
def self.perform(id_of_object_with_images, id_of_user_to_be_notified)
user_mail = User.where(:id => id_of_user_to_be_notified).pluck(:email)
export = PhotoZipper.generate_zip(id_of_object_with_images, id_of_user_to_be_notified)
Notifications.zip_ready(export.archive_url, user_mail).deliver
end
# Zipfile generator
def self.generate_zip(id_of_object_with_images, id_of_user_to_be_notified)
object = ObjectWithImages.find(id_of_object_with_images)
photos = object.images
# base temp dir
temp_dir = Dir.mktmpdir
# path for zip we are about to create, I find that ruby zip needs to write to a real file
# This assumes the ObjectWithImages object has an attribute title which is a string.
zip_path = File.join(temp_dir, "#{object.title}_#{Date.today.to_s}.zip")
Zip::ZipOutputStream.open(zip_path) do |zos|
photos.each do |photo|
path = photo.photo.path
zos.put_next_entry(path)
zos.write photo.photo.file.read
end
end
#Find the user that made the request
user = User.find(id_of_user_to_be_notified)
#Create an export object associated to the user
export = user.exports.build
#Associate the created zip to the export
export.archive = File.open(zip_path)
#Upload the archive
export.save!
#return the export object
export
ensure
# clean up the tempdir now!
FileUtils.rm_rf temp_dir if temp_dir
end
end
app/controllers/photos_controller.rb: format.zip do
#pick the last ObjectWithImages.. ofcourse you should include your own logic here
id_of_object_with_images = ObjectWithImages.last.id
#enqueue the Photozipper task
Resque.enqueue(PhotoZipper, id_of_object_with_images, current_user.id)
#don't keep the user waiting and flash a message with information about what's happening behind the scenes
redirect_to some_path, :notice => "Your zip is being created, you will receive an e-mail once this process is complete"
end
Many thanks to @ffoeg for helping me out. If your zips are smaller you could try @ffoeg's solution. How do I dynamically generate a download link for file uploaded to S3 with Carrierwave?
CarrierWave allows you to set the fog_public
and fog_authenticated_url_expiration
options both for every uploader (through an initializer) or on a specific uploader. In the latter case you just place self.fog_public = false
and self.fog_authenticated_url_expiration = 123
inside your uploader class definition. With these two options set, any calls to model.uploader.url
will return a specially built URL that will expire after the set amount of time.
How do I open a CSV file that I uploaded with Carrierwave and Fog to Amazon S3?
I tried Jared Beck's idea and it's working now, basically I added this condition to my BG job:
if Rails.env.production? || Rails.env.staging?
url = cbf.billing_file_name.url
cbf.billing_file_name.download!(url)
end
So the final code looks like this:def self.perform(client_billing_file_id, email)
cbf = ClientBillingFile.find(client_billing_file_id)
if Rails.env.production? || Rails.env.staging?
url = cbf.billing_file_name.url
cbf.billing_file_name.download!(url)
end
filepath = cbf.billing_file_name.current_path
csv_file = CSV.read(filepath, headers: true)
.
.
.
end
how to direct upload to s3 using carrierwave rails
You can use "fog-aws" gem if you want to upload to S3 using carrierwave
.
Here's a link. Scroll down to Using Amazon S3
section for details.
Also, you can take a look at this question. It explains how to use fog
to generate pre-signed URLs for direct uploads.
Related Topics
How to Avoid Circular Creation of Associated Models in Factory_Girl
Clean Install Osx 10.9.1 Returns "Undefined Method 'Path2Class'" When Trying to Install Gems
Recommended Way to Generate a Presigned Url to S3 Bucket in Ruby
Why Am I Getting "Unable to Autoload Constant" with Rails and Grape
Functional Testing of a Restful Post in Ruby on Rails
How to Reference a Local Gem from a Ruby Script
How to Validate This Hash Parameter
Activemodel::Validations on Anonymous Class
How to Use The "Self" Keyword in Rails
How to Properly Manage The Rails Tmp Directory
Using Update_Columns in Rails 3
Indent Multiline String in Erb
How to Convert Ruby Formatted JSON String to JSON Hash in Ruby
Ruby 1.9 How to Convert Array to String Without Brackets