Serve audio file from GCS with Rails - ruby-on-rails

I have audio files located on a private GCS bucket. I want to serve these audio files for users to listen to.
I cant use Active Storage for this as these files are created/deleted outside of my Rails application.
I could download files using google-cloud-storage gem. It would cover authentication, file download. But if I understand correctly I can only serve files from the public directory? So do I need to download those to Rails.public_path?
Furthermore, I really don't want to manage these files after downloading them - caching, deleting them after some time, etc.
What would be the best way to achieve this?

The best option in my opinion would be to use the google-cloud-storage gem,
since both Google::Cloud::Storage::Bucket and Google::Cloud::Storage::File have the #signed_url method. This way you can find the relevant file(s) that you need and create a temporary url, send the url to the client, which will be in charge of downloading the file directly.
If you don't want the client do download the file directly from Google Cloud you can just download the file from GC yourself, and use #send_data or #send_file in the controller.

Related

Download File from Dropbox folder in Rails application

I am trying and failing to download a single file from a "open for public" dropbox folder which a 3rd party created for others to use. I am trying to use this within my Ruby On Rails Application (file is changing but folder stays the same all the time).
I want to:
List all files in that public folder
Make sure that there is only this one file
... and this file has the appropriate filename (ending in .xlsx in my case -> an Excel file)
Download the file (e.g. using RestClient gem)
Save as an attachment to a new database record (Record is existing already and is used inside the app)
Thanks for any hints on how to proceed here! I Than plan to update the file with a cron-job daily.
Its kind of an API to the public :-)
Thought there must be a simple gem to interact with dropbox folders but couldnt't find any.
I used Rest-Client to open the dropbox folder and Nokogiri to parse the content but cant work through the glibberish produced. I gave up after an hour of work and decided to ask here!
Dropbox does offer a public Dropbox API, but it doesn't offer an official SDK for Ruby in particular, but you can either use the Dropbox API HTTPS endpoints directly, or via a third party library if there is one that works for your use case.
Exactly how you would accomplish this would depend on the specifics of the scenario so you may want to read through some guides first to get started, e.g.: Getting Started and File Access.
For instance, depending on how you have access to the content (e.g., directly via a folder in a connected account, or via a shared link, etc.) some of the following endpoints may be useful:
https://www.dropbox.com/developers/documentation/http/documentation#files-download
https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder
https://www.dropbox.com/developers/documentation/http/documentation#files-list_folder-continue
https://www.dropbox.com/developers/documentation/http/documentation#sharing-get_shared_link_metadata
https://www.dropbox.com/developers/documentation/http/documentation#sharing-get_shared_link_file
The Dropbox API v2 Explorer can also be a useful tool for trying out Dropbox API calls.

Storing assets in cloud and read them securely

I am developing an iOS app that uses a large amount of images that are needed for animations for short videos. I want to save my application assets as static files in cloud and once they are needed download them using secure API call (either JSON, XML or any other alternative for that matter).
What is the best option for that. I have checked Parse, Dropbox, iCloud, Google Drive, but I am puzzled since I see only instructions for dynamic data that lets users access content they have created and not static assets.
What would be best option for that?
If you just want an easy way to serve static files I would take a look at Amazon S3. You can just upload files through the online console and then get the public URL to those files to use in your app. You can also use the S3 API to upload files through your web service or iOS app.
Hope this helps!
I'd go for Parse (basically because it is fast to learn and develop), you can create a table with the images and change the writing permissions if you are afraid somebody could modify the table.
Another option that you can check it's the special Config table so you can upload custom files (zip files i.e.) and download them in demand.

Upload file directly to S3 without need to use forms in Rails

For my Rails application, I download a bunch of files from a remote URL to my application. I would like to directly upload them to Amazon S3, without needing a form to do the upload, since I will temporarily cache the file I downloaded on the EC2 instance.
I would also like to retain the links to the files I uploaded so I can download them later.
I am essentially reposting the files I downloaded.
I looked around, but most of the solution seem to involve form uploading to S3 with a user.
Is there s direct upload solution?
You can upload directly to S3 using the AWS SDK for Ruby. The easiest way is:
require 'aws-sdk'
s3 = Aws::S3::Resource.new(region:'us-west-2')
obj = s3.bucket('bucket-name').object('key')
obj.upload_file('/path/to/source/file')
Or you can find a couple other options here.
You can simply use EvaporateJS to achieve this. You can also take advantage of sending ajax request to update file name to the database after each file upload. Though javascript exposes few details your bucket is not vulnerable to hack as S3 service provide a bucket policy.
Just set the <AllowedOrigin>*</AllowedOrigin> to <AllowedOrigin>specificwebsite.com</AllowedOrigin> in production mode.

MongoDB's GridFS, Rails 3, X-Sendfile, and ACL's, HOW-TO?

I have a Rails 3 project that does file upload/download, with access rights (User has many Files, and can only read/write his own files).
If I store my files on classic filesystem, I can check the access to the file in my rails app and then use X-Sendfile header to redirect to the file, if user has access. In this way, a user can never access a file without permission, and the download is fast.
Can I make file download from GridFS as fast as X-Sendfile, and skip the hassle of piping them trough rails/rack ?
Piping them trough rails/rack would be horribly slow ?
Can I make file download from GridFS as fast as X-Sendfile, and skip the hassle of piping them trough rails/rack, AND ALSO have the ability to enforce access rights ?
Up until now I've found and thought of to possible solutions:
Use something like gridfs-fuse to mount the GFS to local FS and use X-Sendfile just as allways.
Use something like nginx-gridfs which is c-fast and out-of-rails (does not block my app's req-resp cycle while downloading). The downside is that it's server specific

How do I generate files and then zip/compress with Heroku?

I sort of want to do the reverse of this.
Instead of unzipping and adding the collection files to S3 I want to
On user's request:
generate a bunch of xml files
zip the xml files with some images (pre-existing images hosted on s3)
download zip
Does anybody know agood way of doing this? I think I could manage this no problem on a normal machine but Heroku complicates things somewhat in that it has a read-only filesystem.
From the heroku documentation on the read-only filesystem:
There are two directories that are writeable: ./tmp and ./log (under your application root). If you wish to drop a file temporarily for the duration of the request, you can write to a filename like #{RAILS_ROOT}/tmp/myfile_#{Process.pid}. There is no guarantee that this file will be there on subsequent requests (although it might be), so this should not be used for any kind of permanent storage.
You should be able to pretty easily write your generated xml files to tmp/ and keep track of the names, download and write the s3 files to the same directory, and (maybe?) invoke a zip command as long as the output is in tmp/, then serve the file to the browser with the correct mime type to prompt a download. I would only be concerned with how big the filesize is and if heroku has an undocumented limit on what they'll allow in the tmp directory. Especially since you are only performing this action for a one-time download in the duration of a single request, I think you have a good chance of being able to do it.
Edit: Looking around a bit, you might be able to use something like RubyZip to create your zip file if you want to avoid calling system commands.

Resources