groups

Link to this snippet:


Download to Code Collector

language: Ruby
licence: GPL 2

Send multipart mail

options: send to code collectorview all greg's snippets
require 'rubygems'
require 'tmail'
require 'mime/types'
require 'net/smtp'

class SendMail
  class Body
  end
  
  class Attachment
  end
  
  def initialize( hOpts = {} )
    @options = {
      :server   => "localhost",
      :port     => 25,
      :domain   => "localhost.localdomain",
      :user     => nil,
      :password => nil,
      :auth     => nil
    }
    
    @mail = TMail::Mail.new
    @mail.date = Time.now
    
    @attachment = []
    @body       = []
    
    hOpts.each do |k, v|
      if @options.keys.include?( k.to_sym )
        @options[k.to_sym] = v 
      else
        warn "Option #{k.to_sym} unknown!"
      end
    end
  end
  
  def method_missing( idName, *args, &block ) #:nodoc:
    xName = idName.id2name
    @mail.send xName.to_sym, *args
  end
  
  def to_s
    compose.to_s
  end
  
  def body
    @body
  end
  
  def attachment
    @attachment
  end
  
  def send
    m = compose
    Net::SMTP.new(@options[:server], @options[:port]).start(@options[:domain], @options[:user], @options[:password], @options[:auth]) do |smtp|
      smtp.send_message m.to_s, m.from, m.destinations
    end
  end
  
  private
  def compose
    _mail = @mail.clone
    
    if @attachment.size == 0
      if @body.size == 1
        _body = @body[0].clone      
        _mail.body = _body.delete( :content )
        type_str, type_sub = _body.delete( :type ).split( /\// )
        _mail.set_content_type(type_str, type_sub, _body)
      elsif @body.size == 2
        @body.each do |b|
          _body = b.clone
          _body_part = TMail::Mail.new
          _body_part.body = _body.delete( :content )
          type_str, type_sub = _body.delete( :type ).split( /\// )
          _body_part.set_content_type(type_str, type_sub, _body)
          _mail.parts.push( _body_part )
        end
        _mail.set_content_type('multipart', 'alternative') 
      else
        raise ArgumentError, "Can't generate email body!" if @body.size > 2
      end
    else
      if @body.size == 1
        _body = @body[0].clone
        _body_part = TMail::Mail.new
        _body_part.body = _body.delete( :content )
        type_str, type_sub = _body.delete( :type ).split( /\// )
        _body_part.set_content_type(type_str, type_sub, _body)
        _mail.parts.push( _body_part )
      elsif @body.size == 2
        __body_parts = TMail::Mail.new
        
        @body.each do |b|
          _body = b.clone
          _body_part = TMail::Mail.new
          _body_part.body = _body.delete( :content )
          type_str, type_sub = _body.delete( :type ).split( /\// )
          _body_part.set_content_type(type_str, type_sub, _body)
          __body_parts.parts.push( _body_part )
        end
        
        __body_parts.set_content_type('multipart', 'alternative') 
        _mail.parts.push( __body_parts )
      else
        raise ArgumentError, "Can't generate email body!" if @body.size > 2
      end
      
      @attachment.each do |a|
        _attachment = TMail::Mail.new
        _attachment.transfer_encoding = "base64"
        type = (MIME::Types.type_for(a)[0] || 'text/plain').to_s
        _attachment.set_content_type(type, nil, 'name' => a.split( /\// )[-1])
        _attachment.set_content_disposition("attachment", "filename" => a.split( /\// )[-1])
        _attachment.body = TMail::Base64.folding_encode( open( a ).read )
        _mail.parts.push( _attachment )
      end
      
      _mail.set_content_type('multipart', 'mixed')
    end
    
    _mail
  end
end

if $0 == __FILE__
  m = SendMail.new( )
  m.from = "you@yourdomain.com"
  m.to = ["your.friend@domain.com", "your.other.friend@domain.fr"]
  m.cc = "toto@domain.fr"
  m.subject = "Test de SendMail"

  m.body << {
    :type => "text/plain",
    :charset => "utf-8",
    :format => "flowed",
    :content => "Ceci est un test de SendMail..."
  }

  m.body << {
    :type => "text/html",
    :charset => "utf-8",
    :format => "flowed",
    :content => "<html><body>Ceci est un <b>test de SendMail</b>...</body></html>"  
  }

  m.attachment << "sendmail.rb"
  m.attachment << "maya/Rakefile"

  m.send
end