How to set Paperclip style work only if contenttype is image? - ruby-on-rails

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!"} : {} }

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.

Paperclip post processing conversion does not update file_name, content_type attributes

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?

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 }

Paperclip - get attachment.url in active record query

I have an Inventory.find(id) and it returns all the data I need including the icons uploaded
using paperclip. However, the result is returned like this after format.json
"icon_content_type": "image/jpeg",
"icon_file_name": "images_(2).jpeg",
"icon_file_size": 994,
"icon_updated_at": "2012-09-21T05:00:22Z",
how do I include the "icon.url" so it will say something like
"icon_content_type": "image/jpeg",
"icon_file_name": "images_(2).jpeg",
"icon_file_size": 994,
"icon_updated_at": "2012-09-21T05:00:22Z",
"icon_url":"http://s3.amazonaws.com/*********/icons/000/000/130/original/images_(2).jpeg?1348203622"
here is my model
has_attached_file :icon, :presence => false, :default_url => "/assets/logo.png"
validates_attachment :icon,
:content_type => { :content_type => ["image/jpg","image/png","image/jpeg"] },
:size => { :in => 0..50.kilobytes }
See doc, you can add whatever you need to the json:
your_object.to_json(:methods => :icon_url)
For more complex situations, you'd rather use a json builder.

How do I get Paperclip to recognize custom processors instead of just pushing styles through to thumbnail?

I am not having any problem getting the custom processor to load, however when I try to call it from has_attached_file, paperclip ignores it, and instead just runs thumbnail.
model
has_attached_file :file,
:styles => { :web => "some input" },
:processors => [ :custom ],
:url => ":class/:id/:style/:basename.:extension",
:path => ":class/:id/:style/:basename.:extension"
:storage => :s3
As simple a processor as can be made just to show that the processor has been run
processor.rb
module Paperclip
class Custom < Processor
attr_accessor :input
def initialize(file, options = {}, attachment = nil)
super
#basename = File.basename(file.path, File.extname(file.path))
end
def make
dst = Tempfile.new([ #basename, 'jpg' ].compact.join("."))
dst
end
end
end
But instead when I check the saved record it returns instance variables from thumbnail
>record.file.styles
{:web=>
#<Paperclip::Style:0x00000102f185d0
#attachment=
http://s3.amazonaws.com/bucket/model/id/base_name/file_name.jpg,
#format=nil,
#geometry="some_input",
#name=:web,
#other_args={}>}
I must be missing something in either writing the processor or calling it. Any idea what is going on here?
Have you tried something like this?
has_attached_file :file,
:styles => {
:my_super_style => {:geometry => "100x100#", :foo => "bar", :processors => [:custom]}
},
Have you put in the right place?
lib/paperclip_processors/custom.rb
:styles => { :web => "some input" },
:processors => [ :custom ],
should be:
:styles => {
:web => {:geometry => "some input", :processors => [:custom]},

Resources