3

I'm using Rails 3 with Paperclip + Rails:

Gemfile
  gem "paperclip"
  gem "mongoid-paperclip", require: 'mongoid_paperclip'

Everything works fine unless a user uploads a photo with a filename with non-alphanumeric characters like so:

thing 1/2/3/.PNG

I've tried handling this with before_post_process before_validation :

  def strip_strange_characters_from_attachments
    # Set the clean Attachment File Title
    self.attachment.instance.meta['file_name'] = "test.png"
  end

However Rails is erring beforehand and files are not uploading. Error below. Any ideas?

[2014-06-10 13:54:47] INFO    Command :: identify -format %wx%h '/var/folders/g_/kythn1dx4fbbry5npb4jx1cr0000gn/T/thing 1:2:3:20140610-41978-ksy5e9.PNG[0]'
[2014-06-10 13:54:47] INFO    [paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: /var/folders/g_/kythn1dx4fbbry5npb4jx1cr0000gn/T/thing 1:2:3:20140610-41978-ksy5e9.PNG is not recognized by the 'identify' command.>
[2014-06-10 13:54:47] INFO    Command :: identify -format %wx%h '/var/folders/g_/kythn1dx4fbbry5npb4jx1cr0000gn/T/thing 1:2:3:20140610-41978-ksy5e9.PNG[0]'
[2014-06-10 13:54:47] INFO    [paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: /var/folders/g_/kythn1dx4fbbry5npb4jx1cr0000gn/T/thing 1:2:3:20140610-41978-ksy5e9.PNG is not recognized by the 'identify' command.>
[2014-06-10 13:54:47] INFO    Command :: identify -format %wx%h '/var/folders/g_/kythn1dx4fbbry5npb4jx1cr0000gn/T/thing 1:2:3:20140610-41978-ksy5e9.PNG[0]'
[2014-06-10 13:54:47] INFO    Completed 422 Unprocessable Entity in 120.0ms
[2014-06-10 13:54:48] INFO    Mongo: (1.5333ms) | Query count: 3
[2014-06-10 13:54:48] FATAL   
Mongoid::Errors::Validations - 
Problem:
  Validation of Mongo::Attachment failed.
Summary:
  The following errors were found: Attachment /var/folders/g_/kythn1dx4fbbry5npb4jx1cr0000gn/T/thing 1:2:3:20140610-41978-ksy5e9.PNG is not recognized by the 'identify' command., Attachment /var/folders/g_/kythn1dx4fbbry5npb4jx1cr0000gn/T/thing 1:2:3:20140610-41978-ksy5e9.PNG is not recognized by the 'identify' command.
Resolution:

Any ideas / suggestions on handling this error?

halfer
  • 19,824
  • 17
  • 99
  • 186
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012
  • 1
    What's your version of paperclip? The newer ones have a `cleanup_filename` method in there by default to deal with this. See [here](http://stackoverflow.com/questions/7328423/does-paperclip-automatically-clean-up-filenames). – tirdadc Jun 11 '14 at 04:36
  • It appears that the mongo paperclip gem doesn't support cleanup_filename - https://github.com/meskyanichi/mongoid-paperclip/search?q=restricted_characters – AnApprentice Jun 11 '14 at 15:46
  • May be use obfuscation? https://github.com/thoughtbot/paperclip#uri-obfuscation – Vakiliy Jun 13 '14 at 14:58
  • Thanks but obfuscating filenames isn't good as the end user won't be happy with download filenames they don't recognize. – AnApprentice Jun 13 '14 at 20:22
  • But original file name stored in the database, or you do not provide information from db for users? – Vakiliy Jun 13 '14 at 21:08

4 Answers4

7

The mongoid-paperclip gem just hands down all given options to paperclip (see source) so you need to clean the filename, just like you would when using plain paperclip.

There are two options to accomplish this, and here are the default values:

 :restricted_characters => /[&$+,\/:;=?@<>\[\]\{\}\|\\\^~%# ]/, 
 :filename_cleaner => nil,

Normally whitespace is perfectly fine in a filename, but you could try to add it to the :restricted_characters. The restricted-characters are used to initialise a PaperClip::FilenameCleaner.

has_mongoid_attached_file :image, restricted_characters: /[\s&$+,\/:;=?@<>\[\]\{\}\|\\\^~%# ]/ 

You could be more explicit and specify a filename cleaner as follows (but not sure if that is relevant).

has_mongoid_attached_file :image, filename_cleaner: Paperclip::FilenameCleaner.new(/[\s&$+,\/:;=?@<>\[\]\{\}\|\\\^~%# ]/)

This is exactly the same as specifying the restricted_characters option. However, you could use this option and hand it your own version of a FilenameClear. It should have a call method and will receive the filename as parameter (see source)

nathanvda
  • 49,707
  • 13
  • 117
  • 139
1

Looking at the error you're getting, it appears that the filename is getting fixed. The /'s are being replaced with :'s.

Doing some searching around, and it looks like the most common cause for that error is Paperclip not being able to find ImageMagick. Setting Paperclip.options[:command_path] should fix that. It can also be caused by various gem version mismatches.

Take a look at rails paperclip and passenger `is not recognized by the 'identify' command` for a bunch of (hopefully) helpful things to try.

Community
  • 1
  • 1
James Mason
  • 4,246
  • 1
  • 21
  • 26
1

I had to do something similar and handled it with before_create and before_update, but this was with the regular Paperclip gem. The randomize_file_name method isn't shown, but you get the idea.

before_create :randomize_attachment_name
before_update :randomize_attachment_name

def randomize_attachment_name
  if document_file_name
    random_name = randomize_file_name(document_file_name)
    self.document.instance_write(:file_name, random_name)
  end
end
furman87
  • 928
  • 13
  • 20
-2

Why not just change path with something like this ?

path: '/:class/:attachment/:id_partition/:style/:id.:extension'
BGuimberteau
  • 249
  • 1
  • 8