Alternative to X-Sendfile on Heroku? - ruby-on-rails

I have plans this summer to build an E-commerce app for digital downloads and I usually deploy on Heroku. However, Heroku doesn't support X-Sendfile.
So, what's the alternative?
I've been searching for gems and was thinking this might be a good replacement: https://github.com/marcel/aws-s3 -- but, I'm not sure it's being actively maintained.

You should keep your assets on a CDN like S3/Cloudfront. Then just redirect requests to it as necessary.
I would also use paperclip to manage the file. It could look something like ...
class AssetController < ApplicationController
def show
#asset = Asset.find(params[:id])
redirect_to URI.encode #asset.file.url
end
end
class Asset
has_attached_file :file,
:path => YOUR_PATH,
:storage => :s3,
:s3_credentials => S3_CONFIG,
:bucket => BUCKET_NAME
end
That should get your started. Hope this helps

Related

Amazon S3 only accepting files with no spaces, no numbers in the title?

This is an odd question, but only commensurate with the strange behavior I'm seeing. My app is Rails 3/Paperclip/S3.
Symptoms:
All images are uploading regardless of their title.
When uploading a .pdf or .doc, if the title has no spaces like my_doc.pdf, it uploads fine.
When uploading a .pdf or .doc with spaces, such as My Doc.pdf, it fails, either with error broken pipe or by the file silently failing to upload to S3.
When uploading a .pdf or .doc with numbers, such as mydoc20.pdf, it also fails as above.
I imagine there are two possible solutions to this problem.
Fix the broken pipe error directly (preferred method).
Automatically rename every uploaded file to remove spaces and numbers before it is saved to S3 - while not fixing it at the source, I imagine this would allay the issue.
I would greatly appreciate any help you can give me in fixing 1 and/or 2.
Code
# Upload.rb model
class Upload < ActiveRecord::Base
has_attached_file :document,
:storage => :s3,
:s3_credentials => "#{::Rails.root.to_s}/config/s3.yml",
:path => "/docs/:style/:id/:basename.:extension"
has_attached_file :photo,
:styles => {:medium => "200x300>", :thumb => "100x150>" },
:storage => :s3,
:s3_credentials => "#{::Rails.root.to_s}/config/s3.yml",
:path => "/photos/:style/:id/:basename.:extension"
# s3.yml
development:
bucket: dev_bucket_name
access_key_id: dev_acc_key
secret_access_key: dev_sec_key
production:
bucket: my_production_bucket
access_key_id: my_access_key_id
secret_access_key: my_secret_key
# environment.rb is empty with regard to uploading.
# uploads_controller.rb
def edit
#candidate = Candidate.find(current_user.user_type_id)
render :layout => 'forms'
end
def update
#candidate = Candidate.find(params[:id])
if #candidate.update_attributes(params[:candidate])
flash[:notice] = "Profile updated successfully."
redirect_to :action => "show", :id => params[:id]
else
flash[:notice] = "There was an error updating your profile."
render :action => "edit", :id => params[:id]
end
end
I don't believe there are any methods involved. I almost hope there is something obviously wrong with my approach because that means it'll get fixed :).
For part two this should do it:
#s = "Really Important!*() Document version#123123.newest.pdf"
#s.gsub!(' ','_').downcase! #this will make everything lowercase and replace all spaces with underscores
#s.gsub!(/[^a-zA-Z._]+/,'') #this will remove all numbers and special characters except . and _
puts #s #prints "really_important_document_version.newest.pdf"
Edit: After some more research into paperclip I found the following: http://blog.wyeworks.com/2009/7/13/paperclip-file-rename
Check that link out, I believe it is what you are looking for.
Edit 2: In my initial read of your post I missed the part about pulling out numbers as well, I have modified the regulat expression code to account for that.

Getting a Broken Pipe while uploading an mp3 with paperclip

Keep getting a broken pipe after uploading a mp3 with paperclip to S3. What did i do wrong?
Model
has_attached_file :mp3,
:storage => :s3,
:path => 'mp3/:class/:id/:style.:extension',
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:bucket => 'cobras-production',
:url => ':s3_domain_url'
Controller
def create
#track = Track.new(params[:track])
if #track.save
redirect_to(#track, :notice => 'Track was successfully created.')
else
render :action => "new"
end
end
I think there may be an issue with non us bucket locations.
I have 2 applications set up to run on heroku, and was running into the issue you mention. When i changed my bucket location to US the paperclip lib worked perfectly with exact same file.
Where you using singapore or tokyo as your bucket locaiton.
https://github.com/marcel/aws-s3/issues/#issue/4
this explains the issue better
In my case it was because I chose a new (as of now) AWS region 'Oregon'.
When I switched back to US Standard for my bucket, I had no problems.
It might be worth pointing out that buckets are not created automatically on-demand - you have to create them yourself. If you're using the aws-s3 gem, the command for that is
AWS::S3::Bucket.create("cobras-production")
For future googlers: I had the same issue, the reason was in wrong time on my computer, which was included in request. Amazon's server compared my time and their, which caused an error.

AWS::S3::MissingAccessKey in Paperclip but I've defined both

I'm on Heroku, and this is a portfolio thing which I'm putting up on github for potential employers to look at, so obviously I don't want to stick my keys in a S3.yml file. I've exported S3_KEY and S3_SECRET to my environment both on Heroku and my machine and ruby can access them. But when I try and upload, it gives me the following error:
AWS::S3::MissingAccessKey in Portfolio itemsController#update
You did not provide both required access keys. Please provide the access_key_id and the secret_access_key.
The trace is irrelevant except for my controller line #, which works fine until I try and upload a file. Here's what I have:
class Asset < ActiveRecord::Base
attr_accessible :image, :image_file_name, :image_content_type, :image_file_size, :portfolio_item_id, :order
has_attached_file :image,
:styles => {
:thumb => "100x100#",
:small => "300x300",
:large => "600x600>"
},
:storage => :s3,
:s3_credentials => {
:access_key_id => ENV["S3_KEY"],
:secret_access_key => ENV["S3_SECRET"]
},
:bucket => "bucketybucket",
:path => "portfolio"
end
Anyone know what's going on here? How am I constructing this hash wrong?
Oh, and I've followed this thread, no dice: Paperclip and Amazon S3 Issue
same problem...
seems like that ENV const doesn't load before loading the module. solve by using file argument
like this
:s3_credentials => Rails.root.join('config/amazon_s3.yml')
and in amazon_s3.yml
access_key_id: 'your_key'
secret_access_key: 'your_sec_key'
bucket: 'somebucket'
furthermore, you can set environment variable by using heroku config:add command, which is describe in Heroku DevCenter
The problem is because the Enviroment variable in heroku is different that the enviroment variable in your system, so it may happen that the application works just in one enviroment

Paperclip S3 download remote images

How I can download a remote image (http protocol, the url is in the image_remote_url attribute) and save it as an attachment to S3 via Paperclip ?
class Product < ActiveRecord::Base
require 'open-uri'
attr_accessor :image_remote_url
has_attached_file :photo,
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":class/:id/:style.:extension",
:bucket => "my_bucket",
:styles => {
:icon => "32x32#",
}
def fetch_image
# how should this method look ?
end
end
How should the method "fetch_image" look ?
Here's a link to a page that explains exactly what you need.
http://trevorturk.wordpress.com/2008/12/11/easy-upload-via-url-with-paperclip/
I've implemented it successfully on my own site.
I'm not sure this is still useful for you or not, but in a pull request to paperclip just a few hours ago, I've managed to make this super easy.
def set_photo
self.photo = URI.parse(self.image_remote_url)
end
This should do the job now on paperclip (version > 3.1.3) (not 3.1.3 but whatever comes after).

Ruby on Rails / Paperclip / AWS::S3::NoSuchBucket error

I installed the paperclip plugin and was able to use it locally. When I configured it to work with amazon S3 I keep getting the NoSuchBucket (The specified bucket does not exist) error. Paperclip documentation states that the bucket will be created if it doesn't exist but clearly
something is going wrong in my case.
I first insalled aws-s3 gem (v0.6.2)
then also installed right_aws gem (v1.9.0)
both have corresponding
config.gem "aws-s3", :lib => "aws/s3"
config.gem 'right_aws', :version => '1.9.0'
lines in environment.rb file
The code for the image.rb file with paperclip is as follows:
class Image < ActiveRecord::Base
belongs_to :work
has_attached_file :photo, :styles => {:big => "612x1224>", :small => "180X360>", :thumb => "36x36#"},
:storage => 's3',
:s3_credentials => YAML.load_file("#{RAILS_ROOT}/config/s3.yml")[RAILS_ENV],
:path => ":attachment/:id/:style/:basename.:extension",
:bucket => 'my-unique-image-bucket'
attr_protected :photo_file_name, :photo_content_type, :photo_size
validates_attachment_presence :photo
validates_attachment_size :photo, :less_than => 3.megabytes
validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/png', 'image/gif']
end
I'm not entirely sure this is it, but your loading of the s3_credentials is different than what I'm using on my production sites.
My config line is:
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml"
Instead of
:s3_credentials => YAML.load_file("#{RAILS_ROOT}/config/s3.yml")[RAILS_ENV]
it should create but the bucket but this was a bug at one point :
http://groups.google.com/group/paperclip-plugin/browse_thread/thread/42f148cee71a0477
i recently had this problem and it turned out to be the servers time was hugely off and s3 wouldnt allow any updates "that far in the future" or similar but the rails error was NoSuchBucket...confusing
..
I have installed the s3fox plugin for firefox and created the bucket with the plugin. Now Paperclip works fine with S3 as the bucket identified is already created.
But I am still curious about paperclip's inability to create new buckets with the code above.
In case anyone winds up here via google: I saw this same error when I mistakenly switched the order of the 2nd and 3rd parameters I was passing to AWS::S3::S3Object.store.
It's not your case, but AWS doesn't allow upper case letters in bucket name and paperclip doesn't check that, failing in create_bucket.

Resources