carrierwaveuploader / carrierwave

Classier solution for file uploads for Rails, Sinatra and other Ruby web frameworks
https://github.com/carrierwaveuploader/carrierwave
8.78k stars 1.66k forks source link

Wrong MIME when grabbing S3 file after different filetype version #617

Closed geomic closed 12 years ago

geomic commented 12 years ago

In my Uploader Class I've got:

version :thumb do process :resize_to_limit => [200, 200] process :convert =>['png'] def full_filename(for_file = model.file) "thumb.gif" end end

which seems to correctly upload a PNG version of my PDF (converted through RMagick) on S3 (through fog).

It seems, however, that although I'm using process :convert => ['png'], carrierwave still uploads the file with a MIME type of an application/pdf rather than that of a PNG. Is there some way to just set the content type for this specific version?

The bigger picture: I'm trying to allow users to either upload Image files or PDFs. In the former case, the users can download the full image by clicking on the thumbnail (:thumb), in the latter, they can see (:thumb) in the page, but download the PDF. i.e. carrierwave, under the same record, has both the filename.pdf and thumb.png files stored - but when I try the image_tag in HAML, I get an error about the MIME (for the png) being application/pdf.

FGurevich commented 12 years ago

I'm not entirely positive if it's a mime issue when converting to a png or if carrierwave sets a mime column in your db based on the original file but isn't properly overriding it after converting, but try this to set the mime type manually:

require 'carrierwave/processing/mime_types'
class Uploader < CarrierWave::Uploader::Base
  include CarrierWave::MimeTypes

  version :thumb do
    process :resize_to_limit => [200, 200]
    process :convert => ['png']
    process :set_content_type

    def full_filename(for_file = model.file)
      "thumb.gif"
    end
  end
end
trevorturk commented 12 years ago

Good idea @FGurevich -- closing pending response from @geomic.

geomic commented 12 years ago

My apologies for not getting back to you @FGurevich (thank you!) and @trevorturk . I haven't had time to test this - but will definitely report back.

geomic commented 12 years ago

As promised, let me provide some feedback.

The solution didn't quite work as it was. As the original file is a PDF, all that set_content_type did was to set the Mime Type of the PNG to, well, application/pdf.

There was a similar post which suggested:

def set_content_type(*args) self.file.instance_variable_set(:@content_type, "image/png") end

..and since we know what our thumbnail will be already, this works like a charm. Safari previously would not be able to render the thumbnail as it thought it was a PDF, now it's happy with both the original PDF and the converted PNG.

I think: That the same way process :convert => ['png'] would "work" on the 'thumb' version which is just being generated, so should process :set_content_type check this (presumably temporary before it goes to S3 or wherever) file. This way, if different versions (DOC to PDF, DOC to PNG, whatever..) have different mimes, they'd be picked up automatically.

jaybrueder commented 12 years ago

@geomic Big thanks! You saved my project today with you solution.

rogercampos commented 11 years ago

Same issue here, I had to set the mime type the hard way to make it work:

    self.file.instance_variable_set(:@content_type, "image/jpeg")

It seems that it's really difficult to just change the format of a file or version: Add the convert line, deal with the new filename yourself overriding the filename method, and also take care of the correct mime type.