attachment_fu custom processor and s3: file seems to be converted ok, but isn't saved

41 views Asked by At

Setup:

ruby 1.8.6
rails 2.2.2
attachment_fu - not sure (it's vendorized), but last entry in CHANGELOG is "Apr 17 2008"
aws-s3 (0.6.3)
aws-sdk (2.1.13)
aws-sdk-core (2.1.13)
aws-sdk-resources (2.1.13)

I have a model which uses attachment_fu like so:

has_attachment :storage => :s3, 
               :path_prefix => "vip_uploads#{("_"+RAILS_ENV) if RAILS_ENV != "production"}",
               :max_size => 100.megabytes,
               :processor => :mp3

The s3 stuff is all set up fine - if i remove the processor option then the upload to s3 works.

My mp3 processor, which converts wav files to mp3s, looks like this:

module Technoweenie # :nodoc:
  module AttachmentFu # :nodoc:
    module Processors
      module Mp3Processor
        def self.included(base)
          base.send :extend, ClassMethods
          base.alias_method_chain :process_attachment, :processing
        end

        module ClassMethods
        end

      protected
        def process_attachment_with_processing
          self.convert_to_mp3
        end

        # Convert to mp3 and set some metadata
        def convert_to_mp3(options={})            
          #do the conversion with ffmpeg
          mp3_temp_path = "#{self.temp_path}.mp3"

          cmd = "ffmpeg -i #{self.temp_path} -metadata title=\"#{self.filename.gsub("\.wav","")}\" -metadata artist=\"Vip Studio Sessions\" -metadata album=\"Uploads\" -vn -ar 44100 -ac 2 -ab 320k -f mp3 #{mp3_temp_path}"

          `#{cmd}`

          #copy this file back into temp_data
          self.copy_to_temp_file(mp3_temp_path)

          #update attributes
          self.filename = self.filename.gsub(/\.wav$/,".mp3")
          self.content_type = "audio/mpeg"
          self.set_size_from_temp_path
        end
      end
    end
  end
end

All of the conversion stuff seems to be working, in that it makes a new mp3 file in the tmp folder, with the filename saved in mp3_temp_path, and it makes a record in the database. But for some reason, the resulting file isn't then pushed up to s3. I've got a feeling i just need to set some accessor to do with temp_data or temp_file or something. I've tried this

self.temp_path = mp3_temp_path

and

self.temp_data = File.read(mp3_temp_path)

and

self.temp_path = write_to_temp_file(File.read(mp3_temp_path))

Currently, as you can see in my code, i'm trying this:

self.copy_to_temp_file(mp3_temp_path)

but none of them work. These attempts were based on looking in the pre-existing processors, eg for rmagick, and seeing what they do. They seem to do the same thing as me, but since all of them are about thumbnailing it's easy to lose something in the translation.

Can anyone see what i'm missing? thanks, Max

1

There are 1 answers

0
Max Williams On

Ok, answering my own question - it's amazing what a new day can bring. It suddenly occurred to me to look more closely at the attachment_fu source code, in which i noticed this...

    def after_process_attachment
      if @saved_attachment
        if respond_to?(:process_attachment_with_processing) && thumbnailable? && !attachment_options[:thumbnails].blank? && parent_id.nil?
          temp_file = temp_path || create_temp_file
          attachment_options[:thumbnails].each { |suffix, size| create_or_update_thumbnail(temp_file, suffix, *size) }
        end
        save_to_storage
        @temp_paths.clear
        @saved_attachment = nil
        callback :after_attachment_saved
      end
    end

I hadn't set this instance variable @saved_attachment to true (or truthy), so it was not going ahead with save_to_storage. It kind of fails silently - the record is still happily saved to the database , it just doesn't store the file.

in summary, the answer was that, if i'm happy with the resulting mp3 (ie it was an mp3 in the first place, or I successfully convert it to an mp3), then i need to set @saved_attachment = true in my processor.