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