Upload files using attachment_fu and swfupload on rails

Uploading files in ruby on rails application seems trivial task using attachment_fu plugin but it become non-trivial when you need to display upload progress.Recently we had requirements from client to show the progress bar while uploading the image/video files. We could show the file upload progress only when we upload with flash. We found swfupload a reliable solution for this and decided to use it. We were using attachment_fu plugin for the attachment and there is no easier way to integrate it with swfupload. attachment_fu saves the files using the mime type of the file and when swfupload is used for uploading the file, it set mimetype of files to application/octet-stream. It become difficult to detect the difference between image/video or other formated files. So we come up with a solution which first convert the convert the file data in same format which is expected by attachment_fu plugin and later detect the mimetype of the file.

Conversion of file data to attachment_fu format

Using attachment_fu plugin we were expecting the file data in params[:ASSET_DATA] but with swfupload data was coming as params[:Filedata]. So we wrapped the Filedata from swfupload and put that in the desired format

 data = {"uploaded_data" =>params[:Filedata]}

Setting mimetype of the file

Attachment_fu requires the mimetype to be set correctly before it will accept the files. Matt Aimonetti wrote mimetype-fu to help attachment_fu properly set the mimetype.

We override the uploaded_data of attachment_fu in our model object.

 #override attachment_fu plugin
  def uploaded_data=(file_data)
    return nil if file_data.nil? || file_data.size == 0
    self.filename = file_data.original_filename if respond_to?(:filename)
    extension = file_data.original_filename.slice(/.w+$/)
    # Map file extensions to mime types.  Thanks to bug in Flash 8
    # the content type is always set to application/octet-stream.
    mime = MIME::Types.type_for(self.filename)[0]
    self.content_type = mime.blank? ? file_data.content_type : mime.content_type
    #Custom name of the file
    self.filename  = "xxxx_" + Digest::SHA1.hexdigest(Time.now.to_s) + extension
    if file_data.is_a?(StringIO)
      file_data.rewind
      self.temp_data = file_data.read
    else
      self.temp_path = file_data.path
    end
     #callback after attachment is uploaded
    after_attachment_uploaded
  end

Please let us know if you have any issues using above code or have any questions.

References

Leave a Comment

Scroll to Top