Errno::ENOENT (No such file or directory) in amazon-s3 - ruby-on-rails-3

I have application which is deployed to heroku using amazon s3 posting images to buckets.This works perfectly fine. But when fetching same image it gives error:
Errno::ENOENT (No such file or directory showing path s3.amazonaws.com/bucket_name/app/public/messages/images/000/000/061/thumb/images.jpeg?1362410115)
Same path copying and pasting in browser's url doesn't work. If I am using bucket name as end point it works ie, with following path
/bucket_name.s3.amazonaws.com/app/public/messages/images/000/000/061/thumb/images.jpeg?1362410115.
But I dont know how to configure this url in my model. I am following heroku's way to configure aws-sdk.
https://devcenter.heroku.com/articles/paperclip-s3
Model has_attached_file seems like i am missing something here.For rest of configuration you can check above link.
has_attached_file :image, :styles => { :medium => "100x100>", :thumb => "100x100>" }
Thanks

Including given code in config/initializers/paper_clip.rb resolved my problem.
Paperclip::Attachment.default_options.merge!(
:url => ':s3_domain_url',
:path => 'app/public/:class/:attachment/:id_partition/:style/:filename'
)

Related

best way to process images already on S3 (rails)

I have a set of images on Amazon S3, and I'd like to automatically generate thumbnails for them to serve on my site.
I've considered Cloudinary, but it seems that I'd have to copy over all my images to Cloudinary servers first. I want to keep them on S3.
I've considered Dragonfly, but it seems that Dragonfly only works with files I'd upload after installing Dragonfly. I already have uploaded all my files.
What's a good solution for me? I'm in a Rails environment (rails 3.2).
Thanks!
If it's just a 'set of images' it's not really that well structured. You're better off reorganizing the way you store and manage images.
Try Paperclip.
class ModelName < ActiveRecord::Base
attr_accessible :image #more here
has_attached_file :image, :styles => { :large => "450x450>", :medium => "300x300>", :thumb => "150x150>" },
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => "people/:style/:id/:filename",
:s3_protocol => "https"
def original_image_url
image.url
end
def large_image_url
image.url(:large)
end
def medium_image_url
image.url(:medium)
end
def small_image_url
image.url(:thumb)
end
#etc
end
Then simply do this to assign an existing image to an existing instance through the console:
require 'uri'
#instance.image = open(URI::encode(url))
#instance.save
# s3 will now contain the images in the appropriate sizes in the format specified above.
Since the original will also be saved, I'd advise to then delete the 'set of images' on s3 you started with, otherwise you'll be duplicating them.
I was wrong about Dragonfly. You can use Dragonfly on already-uploaded files. I'm using it on my project and it's working out great.

Paperclip S3 image path issue

I've just upgraded from Rails 3.1 to Rails 3.2.6 and my paperclip photo paths are now broken on production.
photo.rb
if Rails.env == "production"
has_attached_file :image,
:storage => :s3,
:s3_credentials => S3_CREDENTIALS,
:url => "/app/public/system/images/:id/:style/:basename.:extension",
I need the resulting path to be like so: http://s3.amazonaws.com/photoramblr/app/public/system/images/5/thumb_large/image.jpg
but instead the above url settings result in: http://s3.amazonaws.com/photoramblr/app/public/app/public/system/images/5/thumb_large/image.jpg
I've also tried setting the paperclip url to :url => "/system/images/:id/:style/:basename.:extension" but that resulted in this url: http://s3.amazonaws.com/photoramblr/images/5/thumb_large/image.jpg
Any thoughts on how I can set this properly?
UPDATE: Well, I still don't understand how it's working, but I 'fixed' this by just moving the files to the location it was looking in.
Try adding a path parameter replacing the url parameter and specifying the path under the bucket name where your file will be stored and the URL will be constructed from the bucket and the path supplied. Here is a link to paperclip s3 docs for further details. If you supply a url parameter, it is treated relative to your "app/public". That explains why you're resulting image path doubles "app/public". Ryan Bate's paperclip tutorial also explains this behaviour.
In your case your code will be as shown below;
if Rails.env.production?
has_attached_file :image,
:storage => :s3,
:s3_credentials => S3_CREDENTIALS,
:path => "app/public/system/images/:id/:style/:basename.:extension",
Your resulting link will be (I'm assuming your bucket name is photorambler from your link); s3.amazonaws.com/photorambler/app/public/system/images/5/thumb_large/image.jpg

rails paperclip: How to access the url of the a

I am new to rails and paperclip plugin - so I apologize if this is as a silly question.
I am trying to upload a file and later access the url for the file url. In dev, the file gets stored locally while in prod, the file is pushed to s3.
Once the model is stored in the db, how to I get the url later on to display the link?
When you specify a paperclip association in a model you do :
class ModelName < ActiveRecord::Base
has_attached_file :thumbnail, :styles => { :medium => "300x300#", :thumb => "100x100#"} , :default_url => '/images/default/missing.png'
end
To get the url, you have to do :
#model.thumbnail.url(:original)
Where :original is the file format, it can be :medium, :thumb...

Errors::SignatureDoesNotMatch, AWS-SDK gem for S3 support on paperclip 3.0.1 and rails 3.2

I'm migrating my app from Rails 3.0.9 to 3.2.3 and ruby 1.9.3. I was using paperclip(2.3.11) with aws-s3 gem to store my pictures.
Now I want to use the last version of paperclip(3.0.1) and then I have to use aws-sdk gem.
I've set my aws.yml file as:
development: &development
bucket: bucket_name_for_dev
access_key_id: *****
secret_access_key: *******
staging:
<<: *development
bucket: bucket_name_for_staging
production:
<<: *development
bucket: bucket_name_for_prod
my model contains :
has_attached_file :picture, :styles => { :medium => "300x300>", :thumb => "50x50>" }, :default_url => 'picture_missing.png',
:storage => :s3,
:bucket => "bucket_name_for_dev",
:s3_credentials => Rails.root.join("config/aws.yml"),
:path => "/presentation_pictures/:id/:style/:filename",
:url => ":s3_eu_url"
attr_accessible :picture
attr_accessor :picture_url
When trying to upload a file, I get the error:
AWS::S3::Errors::SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your key and signing method.
I verified that my keys are accessible and set to the right value.
Here is also what I get from console:
[paperclip] Saving attachments.
[paperclip] saving /presentation_pictures/43/original/Image_1.png
[AWS S3 200 0.813272 0 retries] put_object(:acl=>:public_read,:bucket_name=>"*******_dev",:content_type=>"image/png",:data=>#<Paperclip::UploadedFileAdapter:0x2e144b4 #target=#<ActionDispatch::Http::UploadedFile:0x2dbb1fc #original_filename="Image 1.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"presentation_picture[picture]\"; filename=\"Image 1.png\"\r\nContent-Type: image/png\r\n", #tempfile=#<File:/var/folders/tb/tbmv4LE9EwGNPr1QqU2S0E+++TI/-Tmp-/RackMultipart20120407-33502-1gajfe9>>, #tempfile=#<File:/var/folders/tb/tbmv4LE9EwGNPr1QqU2S0E+++TI/-Tmp-/Image 1.png20120407-33502-an4dcy>>,:key=>"presentation_pictures/43/original/Image_1.png")
Do you have any idea from where could come this problem?
Thx
I had the same issue. It turned out I was using the correct access key id but my secret key was copied incorrectly.
Double checking my secret key and correcting it fixed it for me.
My mistake was taking the root access key instead of the user access key. AWS changed it recently so you must create an individual AIM user for yourself, and then use that user's access key (not root)
Seems like you cannot access your aws the right way. You have to specify your host name, especially when using buckets in a non US region. Try using
:s3_host_name => 's3-eu-west-1.amazonaws.com'
in your has_attached_file options.
If you've configured your S3 to use https also add
:s3_protocol => 'https'
if not, just ignore it.
And if your bucket is a private one, add
:s3_permissions => :private
You also don't need to explicitly configure your bucket in the options parameter, as you've already declared it in your aws.yml and set it via :s3_credentials => Rails.root.join("config/aws.yml").
Hope this helps.

How to store prawn PDF files into Amazon S3

I have a problem with the path. In my model I have following setup:
class Pdffiles < ActiveRecord::Base
belongs_to :user
has_attached_file :invoice_file,
:path => ":rails_root/public/pdffiles/:user_id/:style/:basename.:extension",
:url => "/pdffiles/:user_id/:style/:basename.:extension",
:storage => :s3,
:bucket => '...',
:s3_credentials => {
:access_key_id => '...',
:secret_access_key => '...'
}
end
and in a controller looks my action this:
pdf = Prawn::Document.new
pdf.move_down 70
pdf.text("Prawn Rocks")
pdf.render_file('prawn.pdf')
pdf_file = File.open('prawn.pdf')
pdff = Pdffile.new()
pdff.pdffile_file = pdf_file
pdff.user_id = todays_user.id
pdff.save
And my problem is, that this PDF file is stored to the S3 server, but on the bad place. Instead the directory app/public/pdff/id_of_a_user/file_name_of_pdf_file is the file saved to
Users/my_name/my_ruby_root_directory/name_of_my_project/public/pdffiles/id_of_a_user/file_name_of_pdf_file.
I am not totally sure, if I use the prawn for saving PDF files right, but I think the problem could be in the controller, where I have set up the place, where the created file have to be saved...
I would like to ask you, what I should change for saving PDF files into the right directory in S3... All helps will be appreciated!
Manny thanks, Sep
You could use something like CarrierWave ( https://github.com/jnicklas/carrierwave ) -- it makes uploading to S3 extremely easy with the FOG library https://github.com/jnicklas/carrierwave
The Users/my_name/my_ruby_root_directory/name_of_my_project/public portion of the path came from :rails_root/public portion of the path you configured in paperclip. So if you really want the s3 "directory" to be app/public/pdff/id_of_a_user/file_name_of_pdf_file you need to give paperclip the following path: app/public/pdffiles/:user_id/:style/:basename.:extension
Also, according to your model, you should use pdff.invoice_file = pdf_file instead of pdff.pdffile_file = pdf_file
I hope this helps.