Paperclip post processing conversion does not update file_name, content_type attributes - ruby-on-rails

I would like to restrict File uploads to images only, and convert them automatically to .png. To do so, I use this class:
class ImageAttachment < ActiveRecord::Base
attr_accessible :file, :file_file_name, :file_content_type, :file_file_size
validates_attachment :file,
:content_type => { :content_type => ["image/jpg", "image/tiff", "image/png"] }
has_attached_file :file,
:styles => { :original => ["100%", :png],
:large => ["500x500", :png],
:medium => ["150x150", :png],
:thumb => ["75x100", :png]
},
:default_url => "/system/missing_thumb.png"
end
As I understand, the :styles => { :original => ["100%", :png], ...} should convert all uploaded files that pass validation to .png files. Therefore, I expect the following things to happen when uploading a file example.tiff:
convert the file to .png
change the file name accordingly to example.png
change the content type accordingly to "image/png"
Here's a spec I use:
it "should convert all image types to .png" do
test_file = File.new(Rails.root + "spec/fixtures/images/test.tiff")
attachment = ImageAttachment.create :file => test_file
attachment.file.url.should == "some/paperclip/path/.../test.png"
attachment.file_file_name.should == "test.png"
attachment.file_content_type.should == "image/png"
end
The first assertion is true, and I can also see ImageMagick output in the terminal,
but attachment.file_file_name still returns example.tiff, and attachment.file_content_type returns "image/tiff".
Is my assumption that paperclip automatically updates the file_file_name and the file_content_type attributes wrong?
If so, how would I best do this on my own?

Related

Paperclip security validation error mp4

I am using Paperclip to upload videos and keep getting a Security Validation error about the content type
The error when saving an mp4 to my model class is "content type discovered from file command: video/mp4. See documentation to allow this combination."
The save looks like this
AssignmentEventVideo.create(video: "https://s3-ap-southeast-2.amazonaws.com/dev/upload/0c857445-09ad-44b6-bbfa-810a9974a501/ScreenCaptureProject4.mp4")
The model class
class AssignmentEventVideo < ActiveRecord::Base
has_attached_file :video, :styles => {
:medium => { :geometry => "640x480", :format => 'mp4' },
:android => { :geometry => "640x480", :format => 'webm'},
:mobile => { :geometry => "300x300", :format => 'png', :time => 2 },
:thumb => { :geometry => "100x100#", :format => 'png', :time => 2 }
}
validates_attachment_content_type :video, content_type: ['video/mp4']
end
If have tried disabling validation all together with the code below but it still throws the error
do_not_validate_attachment_file_type :video
I have confirmed that the file command is return the correct type with
file -b --mime ScreenCaptureProject3.mp4
which returns
video/mp4; charset=binary
The save is working fine for another model class that accepts images and checks content using
validates_attachment_content_type :photo, content_type: /\Aimage\/.*\Z/
I'm not sure where to turn next - except to recreate the class and change the column name to something that doesn't clash with video?
Hope someone can help!
Thanks katafrakt - you got me on the right path.
I was using a presigned_post and uploading to S3 using JQuery FileUploader. This was not setting the Content-Type and I was getting back a binary/octet type that Paperclip didn't know how to deal with.
I set content_type on the presigned post, which stores the right meta data in S3 and all is well.

custom paperclip validation error message

I have this validation for content type:
validates_attachment_content_type :photo, :content_type => /^image\/(jpg|jpeg|pjpeg|png|x-png|gif)$/, :message => 'file type is not allowed (only jpeg/png/gif images)'
I want only the message above to be displayed but instead it says
Photos photo content type file type is not allowed (only jpeg/png/gif images)
because its a photos model and attached file photo.
thanks
> Not a real solution but a Easy one is to skip paperclip validation and
> write custom one
> validate :check_content_type
>
> def check_content_type
> if !['image/jpeg', 'image/gif','image/png'].include?(self.image_content_type)
> errors.add_to_base("File '#{self.image_file_name}' is not a valid image type") # or errors.add
> end
> end
I'm late to this party.
validates_attachment_size :image, :in => 0.megabytes..2.megabytes, message: " is too large, try less than 2mb or for help"
Gets you:
Should get you closer to home, with an output of:
"Image file size is too large, try less than 2mb"
Hello please d validation paperclip avtar image
attr_accessible :avatar
has_attached_file :avatar, :styles => { :small => "60x60>", :thumb => "60x60>" }
validates_attachment :avatar, :presence => true,
:content_type => { :content_type => "image/jpg" },
:size => { :in => 0..1000.kilobytes }

How to set Paperclip style work only if contenttype is image?

I am using the following:
has_attached_file :file,:styles => { :thumbnail => '320x240!'},:url => "/images/:attachment/:id/:style/:basename.:extension",:path => ":rails_root/public/images/:attachment/:id/:style/:basename.:extension"
validates_attachment_content_type :file, :content_type => [ 'image/gif', 'image/png', 'image/x-png', 'image/jpeg', 'image/pjpeg', 'image/jpg' ]
To upload both images and video. If I use :style =>{} then image does not upload. I want to use :style method only if content type of file is image.
You can use condition inside of lambda, sorry about ugly formatting:
has_attached_file :file, :styles => lambda
{ |a|
if a.instance.is_image?
{:thumbnail => "320x240!"}
end
}
def is_image?
return false unless asset.content_type
['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg'].include?(asset.content_type)
end
Update 2016:
Most upvoted answer still works, but you need to return an empty hash if it's not of the expected type (eg. a PDF that you don't want to process instead of an image), else you'll run into TypeError - can't dup NilClass issues.
Sample using a ternary for terseness:
has_attached_file :file, :styles => lambda { |a| a.instance.is_image? ? {:thumbnail => "320x240!"} : {} }

Can't resize uploaded image

I'm using paperclip gem for uploading and resizing images. This setup works fine. I'm able to display the uploaded images. The problem comes when I try to resize the uploaded image.
Here is snippet from the model file
has_attached_file :photo,
:size => {:small => "150x150>"}
When I try to upload the image I get this error.
Photo /var/folders/gm/gm-SegRMHuOkSlYtTMkO8U+++TI/-Tmp-/file.jpg is not recognized by the 'identify' command.
I'm sure that the file is jpg. Here is the output of the file command
file.jpg: JPEG image data, JFIF standard 1.01, comment: "CREATOR: gd-jpeg v1.0 (using IJ"
I'm not sure but in our application we do the same thing and it works. Our code looks like this:
has_attached_file :image,
:styles => {:small => "280x173#", :medium => "635x393#"},
:convert_options => {:all => "-quality 80"},#,
:default_style => :medium,
:default_url => "/images/study/nophoto.jpg"
validates_attachment_size :image, :less_than => 10.megabyte
validates_attachment_content_type :image, :content_type => ['image/gif', 'image/png', 'image/x-png', 'image/jpeg', 'image/pjpeg', 'image/jpg']
The difference I see, is that you might have to provide convert_options to be able to resize.
Have you tried any other jpg file, maybe with a simpler path also?

Paperclip: PDF thumbnail has wrong content_type on S3

I'm using Paperclip 2.3.5 within a Rails app to store PDF documents on Amazon S3. For every PDF a JPG thumbnail is generated by ImageMagick. Im' using this configuration in the model:
has_attached_file :file,
:styles => { :thumb => { :geometry => "200x200>",
:format => :jpg
} },
:whiny => false,
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:s3_permissions => 'authenticated-read',
:s3_headers => { 'Expires' => 1.year.from_now.httpdate },
:url => "s3.amazonaws.com",
:path => "documents/:id/:style/:basename.:extension",
:bucket => 'mybucket'
But there is problem: The generated thumbnail is uploaded to S3 with the content_type "application/pdf", which is WRONG, because it's a JPG (you can see the content_type of a file on S3 with a S3 exploring tool like Cyberduck). For the original PDF file this content_type is correct, but not for the thumbnail. This causes trouble in some browsers (e.g. Chrome or Safari) which don't show the thumbnail inline.
Beware: The content_type stored in my database (field "file_content_type") is "application/pdf", which is still correct, because it's the content_type for the original file.
How can I override the content_type for a thumbnail if it should be different from the original file?
This is how we fixed it on brighterplanet.com/research, which has pdf documents and png previews:
has_attached :pdf_document,
:storage => :s3,
# [... other settings ...]
# PDFs work better in Windows 7 / IE if you give them content-type: attachment
:s3_headers => { 'Content-Disposition' => 'attachment' },
:styles => { :preview => { :geometry => '135', :format => :png } }
after_save :fix_thumbnail
def fix_thumbnail(force = false)
# application/pdf and application/x-pdf have both been seen...
return unless force or pdf_document_content_type.include?('pdf')
# set content type and disposition
s3 = AWS::S3.new(YAML.load(File.read("#{RAILS_ROOT}/config/aws_s3.yml")))
t = s3.buckets[PAPERCLIP_BUCKET].objects[pdf_document.path(:thumbnail)]
content = t.read
t.write(:data => content, :content_type => 'image/png', :content_disposition => 'inline', :acl => :public_read)
nil
end
I had to overcome this, not the most elegant solution but I forked Paperclip and hold the patch in my own git repo - https://github.com/svetzal/paperclip
It is a direct replacement for Paperclip, just put in your environment.rb
gem 'twm_paperclip', :lib => 'paperclip'
This is fixed in paperclip >= 2.7, as you can see here:
https://github.com/thoughtbot/paperclip/blob/v2.7/lib/paperclip/storage/s3.rb#L290
the mime-type of the file that is written to S3 is determined specifically before uploading.

Resources