lib/mail/attachments_list.rb



module Mail
  class AttachmentsList < Array
    
    def initialize(parts_list)
      @parts_list = parts_list
      parts_list.map { |p|
        if p.parts.empty?
          p if p.attachment?
        else
          p.attachments
        end
      }.flatten.compact.each { |a| self << a }
      self
    end
    
    # Returns the attachment by filename or at index.
    # 
    # mail.attachments['test.png'] = File.read('test.png')
    # mail.attachments['test.jpg'] = File.read('test.jpg')
    # 
    # mail.attachments['test.png'].filename #=> 'test.png'
    # mail.attachments[1].filename          #=> 'test.jpg'
    def [](index_value)
      if index_value.is_a?(Fixnum)
        self.fetch(index_value)
      else
        self.select { |a| a.filename == index_value }.first
      end
    end

    def []=(name, value)
      default_values = { :content_type => "#{set_mime_type(name)}; filename=\"#{name}\"",
                         :content_transfer_encoding => 'Base64',
                         :content_disposition => "attachment; filename=\"#{name}\"" }

      if value.is_a?(Hash)

        default_values[:body] = value.delete(:content) if value[:content]

        default_values[:body] = value.delete(:data) if value[:data]

        # Only force encode base64 if the user has not specified an encoding
        if value[:transfer_encoding]
          default_values[:content_transfer_encoding] = value.delete(:transfer_encoding)
        elsif value[:encoding]
          default_values[:content_transfer_encoding] = value.delete(:encoding)
        else
          default_values[:body] = Mail::Encodings::Base64.encode(default_values[:body])
        end

        if value[:mime_type]
          default_values[:content_type] = value.delete(:mime_type)
        end

        hash = default_values.merge(value)
      else
        default_values[:body] = Mail::Encodings::Base64.encode(value)
        hash = default_values
      end

      @parts_list << Part.new(hash)
    end
    
    def set_mime_type(filename)
      # Have to do this because MIME::Types is not Ruby 1.9 safe yet
      if RUBY_VERSION >= '1.9'
        new_file = String.new(filename).force_encoding(Encoding::BINARY)
        ext = new_file.split('.'.force_encoding(Encoding::BINARY)).last
        filename = "file.#{ext}".force_encoding('US-ASCII')
      end
      @mime_type = MIME::Types.type_for(filename).first
    end
    
  end
end