Can't upload image using Paperclip 4.0 Rails 3 - ruby-on-rails

I've installed ImageMagick and I've installed the gem Paperclip (version 4.0). I've added:
Paperclip.options[:command_path] = 'C:\Program Files\ImageMagick-6.8.8-Q16'
to the development.rb
My photo.rb Model has this:
has_attached_file :image
validates_attachment_content_type :image, :content_type => ['image/jpeg', 'image/png', 'image/jpg']
I can choose a file in photos/new.html.erb but once I click on 'Create photo' button, the page reloads with a Paperclip specific error message saying:
1 error prohibited this photo from being saved:
Image translation missing:
en.activerecord.errors.models.photo.attributes.image.spoofed_media_type
Can someone help please?
Thanks

Add this to an initializer to disable spoofing protection:
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end

That message is raised by a validation check for content spoofing.
For Paperclip v.4 this generates a bug https://github.com/thoughtbot/paperclip/issues/1429
While for Paperclip v.3, it seems it just throws a deprecation warning, https://github.com/thoughtbot/paperclip/issues/1423
So I'd wait for Paperclip team to solve this bug before using version 4. At the moment I'd rather keep using version 3.
gem "paperclip", "~> 3.5.3"

This works on Paperclip v3.5.1 (hopefully will still work in V4):
has_attached_file :attachment,
styles: lambda { |a| a.instance.is_image? ? { *** image_styles ***} : { *** video_styles ***},
processors: lambda { |a| a.is_video? ? [ :ffmpeg ] : [ :thumbnail ] }
def is_video?
attachment.instance.attachment_content_type =~ %r(video)
end
def is_image?
attachment.instance.attachment_content_type =~ %r(image)
end

Related

Adding Paperclip Attachment to Spree Orders Table,

I am working on an ecommerce website using Solidus, Rails. The site allows you to order photo frames & prints from a variety of options.
To print a photo a user must upload the jpg file of the photo. So, to allow that I modified the orders table and added a paperclip attachment called 'attachment'
I ran the following command
rails generate paperclip SpreeOrder attachment
Which generated the migrations, then I ran rake db:migrate
Then I created a spree/order_decorator.rb file, and added has_attached_file
module Spree::OrderDecorator
has_attached_file :attachment, styles: {
:medium => {
:geometry => "640x480",
:format => 'jpeg'
},
:thumb => { :geometry => "160x120", :format => 'jpeg', :time => 10}
}, :processors => [:transcoder]
validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\z/
Spree::Order.prepend self
end
After this I ran the server, and ended up getting this error
undefined method `has_attached_file' for Spree::OrderDecorator:Module (NoMethodError)
I have configured solidus for use with paperclip only, so I am really confused as to why I am getting this error, even later I manually went and generated a paperclip.rb file in the config/initializers directory, but still I get the same error.
Please help with this!!
Thank You!!
You should add those paperclip method at class level in the prepended module:
def self.prepended(base)
base.has_attached_file
end

Carrierwave error: version doesn't exist! in Rails

I´m using Carrierwave (2.0.2, 0.11.2) in Rails 5.2.3. and I´m pretty stuck with versions of uploaded images.
Imagemagick is latest version,gems Carrierwave,Rmagick and Minimagick installed.
Everything works as it should with two versions created by default and uncommented in uploaders/image_uploader.rb file:
just like this:
version :large do
process resize_to_fill: [500,500]
end
version :thumb from :large do
process resize_to_fit: [50, 50]
end
version :long do
process resize_to_fill: [500,200]
end
My model looks like this:
class Slide < ApplicationRecord
mount_uploader :image, ImageUploader
before_save :update_image_attributes
after_save :recreate_delayed_versions!
validates :image_title, presence: true
validates :display, presence: true
validates :order, presence: true
validates_presence_of :image
validates_integrity_of :image
validates_processing_of :image
def recreate_delayed_versions!
image.recreate_versions!(:thumb,:large,:long)
end
private
def update_image_attributes
if image.present? && image_changed?
self.image_content_type = image.file.content_type
self.image_file_size = image.file.size
end
end
end
Uploaded images are processed,scaled and saved in :original size,:large and :thumb version in correct folders...all good.
But if I try to create another version,or rename existing one,for example " version :long ",it doesn´t create it and in my views exception is caught as: "Version long doesn't exist!"
I did tried several different version names,amount of versions,name as symbol,in quotation marks,also reading the source code of Carrierwave/versions.rb,reading documentation,but still unable to find any reason for this behaviour.Only those two versions working well,not any other.Could You someone help me with it?
Thanks!
After rename the version or adding new version, you are required to recreate those versions by calling something like this:
User.find_each do |user|
user.avatar.recreate_versions!
end
Full documentation can be found here

Paperclip is not supporting .doc file

In rails 4.0.2, I am using paperclip gem to upload files. But it is not supporting .doc file. Below the file upload field, it is showing an error message as "has an extension that does not match its contents"
In model, the validation for checking the content type is given below :
validates_attachment_content_type :document, :content_type => ['application/txt', 'text/plain',
'application/pdf', 'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.oasis.opendocument.text',
'application/x-vnd.oasis.opendocument.text',
'application/rtf', 'application/x-rtf', 'text/rtf',
'text/richtext', 'application/doc', 'application/docx', 'application/x-soffice', 'application/octet-stream']
Gems which is used right now
rails (4.0.2, 4.0.0, 3.2.13, 3.2.8, 3.0.4, 3.0.3)
paperclip (3.5.2, 2.3.11, 2.3.8)
How can I solve this issue?
add this to an initializer to disable spoofing protection:
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
For centOS
module Paperclip
class MediaTypeSpoofDetector
def type_from_file_command
begin
Paperclip.run("file", "-b --mime :file", :file => #file.path)
rescue Cocaine::CommandLineError
""
end
end
end
end
from https://github.com/thoughtbot/paperclip/issues/1429
It's a bad idea to skip spoofing checking. Because Paperclip adds it for security reason. See this article for details:
http://robots.thoughtbot.com/prevent-spoofing-with-paperclip
The spoof validation checks if file's extension matches it's mime type. For example a txt file's mime type is text/plain, when you upload it to Paperclip everything goes fine. But if you modify the extension to jpg then upload it, the validation fails because jpg file's mime type should be image/jpeg.
Note that this validation is for security checking so there's not a normal way to skip it. Even when you use do_not_validate_attachment_file_type it's not skipped. But for some files Paperclip can't recognize file -> mime type mapping correctly.
In this case the right way is adding content type mapping to Paperclip configuration. Like this:
# Add it to initializer
Paperclip.options[:content_type_mappings] = {
pem: 'text/plain'
}
In this way it works without breaking spoofing validation. If you don't know what mime type a file is, you can use file command:
file -b --mime-type some_file.pdf # -> application/pdf
You can authorize all content types using do_not_validate_attachment_file_type :file
You can enable spoofing using has_attached_file :file,
class Upload
#validate_media_type == false means "authorize spoofing"
has_attached_file :file, validate_media_type: false
#authorize all content types
do_not_validate_attachment_file_type :file_if_content_type_missing
end
The error in the server log means that your OS file command cannot get you the MIME type for a .doc file. This happens for me with ubuntu 12.04.
To get around this, I slightly altered MediaTypeSpoofDetector to use mimetype if file --mime didn't work.
module Paperclip
class MediaTypeSpoofDetector
private
def type_from_file_command
# -- original code removed --
# begin
# Paperclip.run("file", "-b --mime-type :file", :file => #file.path)
# rescue Cocaine::CommandLineError
# ""
# end
# -- new code follows --
file_type = ''
begin
file_type = Paperclip.run('file', '-b --mime-type :file', file: #file.path)
rescue Cocaine::CommandLineError
file_type = ''
end
if file_type == ''
begin
file_type = Paperclip.run('mimetype', '-b :file', file: #file.path)
rescue Cocaine::CommandLineError
file_type = ''
end
end
file_type
end
end
end
Try putting do_not_validate_attachment_file_type :document validation in model.

no validates_attachment_file_name when upgrading to Paperclip 4.1 from 3.5

We have code that looks like run of the mill paper clip:
has_merchants_attached_file :pdf,
storage: :s3,
s3_credentials: Mbc::DataStore.s3_credentials,
s3_permissions: :private,
path: ":identifier_template.pdf",
bucket: Mbc::DataStore.forms_and_templates_bucket_name
validates_attachment_file_name :pdf, :matches => [/pdf\Z/]
Which generates an error:
undefined method `validates_attachment_file_name' for #<Class:0x007fba67d25fe0>
Interestingly enough, when we down grade back to 3.5, we encounter the same issue.
The controller that is generating this is:
def index
#fidelity_templates = FidelityTemplate.order("identifier asc").all
end
Additionally:
def has_merchants_attached_file(attribute, options={})
if Rails.env.test? || Rails.env.development?
has_attached_file attribute,
path: "paperclip_attachments/#{options[:path]}"
else
has_attached_file attribute, options
end
end
Any thoughts on what could be causing this?
You can read about the provided validators here:
https://github.com/thoughtbot/paperclip#validations
The included validators are:
AttachmentContentTypeValidator
AttachmentPresenceValidator
AttachmentSizeValidator
They can be used in either of these ways:
# New style:
validates_with AttachmentPresenceValidator, :attributes => :avatar
# Old style:
validates_attachment_presence :avatar
UPDATE ...
If you read further down the link I've given above you'll get to a section on Security Validations (Thanks Kirti Thorat):
https://github.com/thoughtbot/paperclip#security-validations
They give an example on how to validate the filename format:
# Validate filename
validates_attachment_file_name :avatar, :matches => [/png\Z/, /jpe?g\Z/]
From your code snippet it looks like your validation should work as-is.
However, I've never seen paperclip used with this syntax:
has_merchants_attached_file ...
Perhaps that's the source of your issues? You would usually use the following to attach files to your model:
has_attached_file :pdf ...

multiple paperclip attachements with watermark processor

I'm having a ton of trouble with uploading multiple attachments with paperclip and processing them with a watermark.
I have 2 models, Ad and Photo.
The Ad has_many :photos and the Photo belongs_to :ad.
To be more exact in /models/ad.rb I have:
class Ad < ActiveRecord::Base
has_many :photos, :dependent => :destroy
accepts_nested_attributes_for :photos, :allow_destroy => true
end
and my photo.rb file looks like this:
class Photo < ActiveRecord::Base
belongs_to :ad
has_attached_file :data,
:styles => {
:thumb => "100x100#",
:first => {
:processors => [:watermark],
:geometry => '300x250#',
:watermark_path => ':rails_root/public/images/watermark.png',
:position => 'SouthEast' },
:large => {
:processors => [:watermark],
:geometry => '640x480#',
:watermark_path => ':rails_root/public/images/watermark.png',
:position => 'SouthEast' }
}
end
In my view I use this to add the file fields
<% f.fields_for :photos do |p| %>
<%= p.label :data, 'Poza:' %> <%= p.file_field :data %>
<% end %>
In my controller, in the edit action i use 4.times {#ad.photos.build} to generate the file fields.
It all works fine and dandy if I don't use the watermark processor, if I use a normal has_attached_file declaration, like this:
has_attached_file :data,
:styles => {
:thumb => "100x100#",
:first => '300x250#',
:large => '640x480#'
}
But when I use the watermark processor I always get this error:
NoMethodError in PublicController#update_ad
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
..............................
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:350:in `assign_nested_attributes_for_collection_association'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:345:in `each'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:345:in `assign_nested_attributes_for_collection_association'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/nested_attributes.rb:243:in `photos_attributes='
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2746:in `send'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2746:in `attributes='
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2742:in `each'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2742:in `attributes='
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2628:in `update_attributes'
/home/alexg/Sites/vandmasina/app/controllers/public_controller.rb:217
/home/alexg/Sites/vandmasina/app/controllers/public_controller.rb:216:in `update_ad'
The parameters are ok, as far as I can say
Parameters:
{"commit"=>"Salveaza modificarile",
"ad"=>{"price"=>"6000",
"oras"=>"9",
"photos_attributes"=>{"0"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-b42noe-0>},
"1"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-r0ukcr-0>},
"2"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-mb23ei-0>},
"3"=>{"data"=>#<File:/tmp/RackMultipart20100928-5130-1bpkm3b-0>}},
The Watermark processor /lib/paperclip_processors/watermark.rb looks like this:
module Paperclip
class Watermark < Processor
class InstanceNotGiven < ArgumentError;
end
def initialize(file, options = {},attachment = nil)
super
#file = file
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
#watermark = ':rails_root/public/images/watermark.png'
#current_geometry = Geometry.from_file file # This is pretty slow
#watermark_geometry = watermark_dimensions
end
def watermark_dimensions
return #watermark_dimensions if #watermark_dimensions
#watermark_dimensions = Geometry.from_file #watermark
end
def make
dst = Tempfile.new([#basename, #format].compact.join("."))
watermark = " \\( #{#watermark} -extract #{#current_geometry.width.to_i}x#{#current_geometry.height.to_i}+#{#watermark_geometry.height.to_i /
2}+#{#watermark_geometry.width.to_i / 2} \\) "
command = "-gravity center " + watermark + File.expand_path(#file.path) + " " +File.expand_path(dst.path)
begin
success = Paperclip.run("composite", command.gsub(/\s+/, " "))
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the watermark for #{#basename}" if #whiny_thumbnails
end
dst
end
end
end
I have tried the processor in a normal app, without multiple attachments and it works perfect. It doesn't work with nested_attributes as far as I can tell.
The app is rails 2.3.5 with ruby 1.8.7 and paperclip 2.3.11
If you can provide any help it would be appreciated a lot, since I've been trying to figure this out for 2 days now :)
If you use rails 3 and paperclip > 2.3.3, try https://gist.github.com/843418 source.
Oh, man, that was a tough one!
You have few errors in your code and none is related to nested models. My explanation is for Rails 3 & Paperclip 2.3.3
a) the :rails_root thing doesn't work. This interpolation is used only in url/path and not on custom options. So you should replace it with Rails.root.join("public/images...")
b) you simply ignore the :watermark_path option and you use only hardcoded path (in initialization method). So it doesn't matter what you have in your :styles as it always go for .../images/watermark.png. The :rails_root thingy there again so it cannot work.
c) when you pass a parameter to Paperclip.run("composite", "foo bar there") it actually executes this command:
composite 'foo bar there'
can you see the single quotes? Because of that the composite command see your parameters as one huge parameter and doesn't understand it at all. If you pass it as an array, then every item is enclosed in the quotes, not the array as a whole.
So here is the improved version of watermark processor:
module Paperclip
class Watermark < Processor
class InstanceNotGiven < ArgumentError;
end
def initialize(file, options = {},attachment = nil)
super
#file = file
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
# PAWIEN: use default value only if option is not specified
#watermark = options[:watermark_path] || Rails.root.join('public/images/watermark.png')
#current_geometry = Geometry.from_file file # This is pretty slow
#watermark_geometry = watermark_dimensions
end
def watermark_dimensions
return #watermark_dimensions if #watermark_dimensions
#watermark_dimensions = Geometry.from_file #watermark
end
def make
dst = Tempfile.new([#basename, #format].compact.join("."))
dst.binmode
begin
# PAWIEN: change original "stringy" approach to arrayish approach
# inspired by the thumbnail processor
options = [
"-gravity",
"center",
"#{#watermark}",
"-extract",
"#{#current_geometry.width.to_i}x#{#current_geometry.height.to_i}+#{#watermark_geometry.height.to_i / 2}+#{#watermark_geometry.width.to_i / 2}",
File.expand_path(#file.path),
File.expand_path(dst.path)
].flatten.compact.join(" ").strip.squeeze(" ")
success = Paperclip.run("composite", options)
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the watermark for #{#basename}" if #whiny_thumbnails
end
dst
end
end
end
Hope that helped you!
UPDATE: You need to use latest paperclip gem from github
gem 'paperclip', '>= 2.3.3', :git => "http://github.com/thoughtbot/paperclip.git"
In this version the formats of #run were changed once again so I've updated the code. It really should work as I've created test application and it's doing what supposed.
UPDATE 2: Repo with working example:
git://repo.or.cz/paperclip-mass-example.git
Just from a quick glance it looks like watermark_path should be "#{Rails.root}/..." though it looks like you have a lot going on here.
Also, I don't see your form as in form_for. Make sure you have {:multipart => true}

Resources