Downloading object from S3 through rails not knowing the exact key - ruby-on-rails

I have a simple rails application where a user can upload and download file from S3. For example: in /avatar/caid/uuid, there is only one file named uuid.png which is uploaded by the user. Next, user must be able to download that particular file from S3, however, at this time, he doesn't know the exact name of the file saved in S3. What he knows is the file is save in /avatar/caid/uuid. My question is how can I download the only file from /avatar/caid/uuid folder? I tried the option below:
resp = s3.get_object(
bucket: "xxx",
key: "avatar/123/456/pic.bmp",
)
However, option above assumes that I have to know the exact name of the file which is pic.bmp. May I know how can I download the file pic.bmp by just knowing the
url" "avatar/123/456" ?
Thanks

Related

Rails paperclip upload to S3 returns bucket URL but folder doesn't exist on bucket

For some reason my upload on using Paperclip isn't actually created on my S3 bucket.
#user.update(params.require(:user).permit(:photo))
render json: { photo_url: #user.photo.url(:thumb) } }
s3-us-west-1.amazonaws.com/example123/users/photos/000/000/417/thumb/blob?1496258964
I switched to a new bucket and it works normally. But in my original bucket it doesn't seem to create the user 417 folder or the file.
What should I be looking in relation to bucket permissions to allow Paperclip to create the folder and file for my image upload?
S3 doesn't have directories. It just stores string keys. Your file just has name example123/users/photos/000/000/417/thumb/blob?1496258964. There are some tools that will show you it as directories tree, but these are just names.
I think you should check permissions for that bucket that doesn't work

How to attach files, which were saved in DriveHQ in Rails mailer?

In my application i have a file upload option. The uploaded files used to saved in DriveHQ ftp server. After uploading i want to send a mail to the admin with the uploaded file as attachment.
I tried as follows
uri = URI::FTP.build(['username:password', 'ftp.drivehq.com', nil,"\\My Documents\\#{17}\\Fitness.txt", 'i'])
And in the mailer:
attachments['image'] = {mime_type: 'text/plain',content: File.read(uri)}
But its not working. it was returning error as
bad component(expected relative path component): \My Documents\17\Fitness.txt;type=i
I guess you're using the API in a wrong way.
You need to download the file, and yes you do it by creating an URI to the FTP server, but then you need to download the file to a temporary directory.
After that, in your mailer you read that file.
Remember since File is a subclass of IO and it does not have the read method, when you invoke File.read, you are actually calling IO.read.

MVC: when is a file uploaded?

When uploading files to a server and calling a controller method does a HttpPostedFileBase contain the entire file or just information such as name, path, etc?
What I want to know is if the file is uploaded to the server right away or not until calling SaveAs(path) ?
As the file is part of your request, it is uploaded immediatly. It is just buffered into a tempfile which the system will delete once you send the Response.
If you use SaveAs, you just transfert the file into a permanent location.

Download file on click - Ruby on Rails

My application is using Rails 2 backend, Heroku for hosting, Paperclip for file uploads, and Amazon S3 for file storage.
Right now users can upload files with paperclip + s3 - this works flawlessly. After upload, an icon appears on their dashboard, linked to the file location (in s3 bucket). When the icon is clicked, the browser opens the file in a new window (for most file types - PDF, MP3, img, etc). Instead of opening, I want the file to be automatically downloaded when the user clicks the file's icon (like Gmail attachments). The solution should be able to work for any file type and cross-browser.
Is there a helper to do this in rails, or is javascript needed? I'm really stuck on this one so anything to point me in the right direction would be greatly appreciated. Thanks!
Please try the following:
class Test < ActiveRecord::Base
has_attached_file :testfile,
:storage => :s3,
# All your S3 config
:s3_headers => {"Content-Disposition" => "attachment"}
end
This should tell the Paperclip Gem to set the "Content-Disposition" header to the value "attachment" for newly uploaded files.
Note that you have to manually edit the already uploaded file, e.g. with Cyberduck or another FTP Client.
When you transfer the file, you need to set a Content-Disposition header with a value of attachment; filename=yourfilename.pdf. If it's transfered directly from S3, you'll need to tell S3 to set the Content-Disposition headers as well. Possibly also Content-Type.
Note that if you tell S3 to associate a Content-Disposition header, it will always transmit this header.
FWIW, here's Amazon's documentation on doing a PUT for an Object: http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUT.html

Ruby on rails: Image downloads with Authentication/Authorization/Time outs

I'm having few doubts on implementing file downloads. I'm creating an app where I use attachment_fu with Amazon s3 to upload files. Things are working pretty well so far on uploading side. Now its the time to start the file downloads. Here is what I need, a logged in user search and browse for Images and they should able to add the files in to a download basket (Let's say its a Download Shopping Cart). Finally the user should be able to download these file(s) from S3 probably as a zipped file.
Is there any plugin/gem where I can use for this?
The downside of giving the customer a zip file of all the files is that you'll need to first pull all of the files from S3 back onto your server, then zip them.
You can certainly do that if you want, but it will take a bit of time, you would not want to do it synchronously as part of the browser request. Instead, do it as a background job using delayed_job or similar.
To do the actual zipping, use Zlib::GzipWriter See http://ruby-doc.org/core/classes/Zlib/GzipWriter.html -- it is part of standard Ruby
You could then:
email the user the actual zip file as an attachment
email the user the link to the zip file on your server
or upload the zip file to s3, then email a link to the zip file on s3
Remember to create a clean up task/job to remove the old zip files from your system...
Alternative is to not zip the files together, instead, give the user one or more links to download the files separately.
S3 enables you to create a url to an S3 file that can be used for a set period of time. (The file would be private on S3 so a straight link to it won't work.) Here's how to create it using attachment-fu and aws-s3 gem:
# I added this as a method to my model for the files stored in S3
def authenticated_s3_url
# return a publicly usable url
connect_to_aws # a local method which connects/re-connects to s3
S3Object.url_for(full_filename,
bucket_name,
:expires_in => 60 * 60) # 1 hour
end

Resources