module MultiMail::Receiver::Base::ClassMethods

Public Instance Methods

add_file_arguments(attachment) click to toggle source

ActionDispatch::Http::Request subclasses Rack::Request and turns attachment hashes into instances of ActionDispatch::Http::UploadedFile in Rails 3 and 4 and instances of ActionController::UploadedFile in Rails 2.3, both of which have the same interface.

@param [ActionDispatch::Http::UploadedFile,ActionController::UploadedFile,Hash] attachment an attachment @return [Hash] arguments for `Mail::Message#add_file`

# File lib/multi_mail/receiver/base.rb, line 69
def add_file_arguments(attachment)
  if Hash === attachment
    {:filename => attachment[:filename], :content => attachment[:tempfile].read}
  else
    {:filename => attachment.original_filename, :content => attachment.read}
  end
end
condense(message) click to toggle source

Condenses a message's HTML parts to a single HTML part.

@example

flat = self.class.condense(message.dup)

@param [Mail::Message] message a message with zero or more HTML parts @return [Mail::Message] the message with a single HTML part

# File lib/multi_mail/receiver/base.rb, line 154
def condense(message)
  if message.multipart? && message.parts.any?(&:multipart?)
    # Get the message parts as a flat array.
    result = flatten(Mail.new, message.parts.dup)

    # Rebuild the message's parts.
    message.parts.clear

    # Merge non-attachments with the same content type.
    (result.parts - result.attachments).group_by(&:content_type).each do |content_type,group|
      body = group.map{|part| part.body.decoded}.join

      # Make content types match across all APIs.
      if content_type == 'text/plain; charset=us-ascii'
        # `text/plain; charset=us-ascii` is the default content type.
        content_type = 'text/plain'
      elsif content_type == 'text/html; charset=us-ascii'
        content_type = 'text/html; charset=UTF-8'
        body = body.encode('UTF-8') if body.respond_to?(:encode)
      end

      message.parts << Mail::Part.new({
        :content_type => content_type,
        :body => body,
      })
    end

    # Add attachments last.
    result.attachments.each do |part|
      message.parts << part
    end
  end

  message
end
flatten(message, parts) click to toggle source

Flattens a hierarchy of message parts.

@example

flat = self.class.flatten(Mail.new, parts.dup)

@param [Mail::Message] message a message @param [Mail::PartsList] parts parts to add to the message @return [Mail::Message] the message with all the parts

# File lib/multi_mail/receiver/base.rb, line 198
def flatten(message, parts)
  parts.each do |part|
    if part.multipart?
      flatten(message, part.parts)
    else
      message.parts << part
    end
  end
  message
end
multimap(object) click to toggle source

Converts a hash or array to a multimap.

@param [Hash,Array] object a hash or array @return [Multimap] a multimap

# File lib/multi_mail/receiver/base.rb, line 81
def multimap(object)
  multimap = Multimap.new
  object.each do |key,value|
    if Array === value
      value.each do |v|
        multimap[key] = v
      end
    else
      multimap[key] = value
    end
  end
  multimap
end
parse(raw) click to toggle source

Parses raw POST data into a params hash.

@param [String,Hash] raw raw POST data or a params hash @raise [ArgumentError] if the argument is not a string or a hash

# File lib/multi_mail/receiver/base.rb, line 99
def parse(raw)
  case raw
  when String
    begin
      JSON.load(raw)
    rescue JSON::ParserError
      params = CGI.parse(raw)

      # Flatten the parameters.
      params.each do |key,value|
        if Array === value && value.size == 1
          params[key] = value.first
        end
      end

      params
    end
  when Array
    params = {}

    # Collect the values for each key.
    map = Multimap.new
    raw.each do |key,value|
      map[key] = value
    end

    # Flatten the parameters.
    map.each_pair do |key,value|
      if Array === value && value.size == 1
        params[key] = value.first
      else
        params[key] = value
      end
    end

    params
  when Rack::Request
    env = raw.env.dup
    env.delete('rack.input')
    env.delete('rack.errors')
    {'env' => env}.merge(raw.params)
  when Hash
    raw
  else
    raise ArgumentError, "Can't handle #{raw.class.name} input"
  end
end