mailr/components/webmail/cdfmail.rb
2009-02-06 01:55:24 +10:00

304 lines
8.5 KiB
Ruby

require 'tmail'
require 'net/smtp'
require 'mail_transform'
class CDF::Mail
include ActionMailer::Quoting
def initialize(senderTempLocation)
@attachments = Array.new
@sender_temp_location = senderTempLocation
@to_contacts = Array.new
end
def customer_id() @customer_id end
def customer_id=(arg) @customer_id = arg end
def from() @from end
def from=(arg) @from = arg end
def to() @to end
def to=(arg) @to = arg end
def to_contacts() @to_contacts end
def to_contacts=(arg) @to_contacts = arg end
def toc=(arg)
@to_contacts = Array.new
arg.split(",").each { |token| @to_contacts << token.to_i unless token == "" or token.strip() == "undefined"} unless arg.nil? or arg == "undefined"
end
def toc
ret = String.new
@to_contacts.each { |contact|
ret << "," unless ret == ""
if contact.kind_of?(Integer)
ret << contact.to_s unless contact.nil? or contact == 0
else
ret << contact.id.to_s unless contact.nil? or contact.id.nil?
end
}
ret
end
def bcc() @bcc end
def bcc=(arg) @bcc = arg end
def cc() @cc end
def cc=(arg) @cc = arg end
def subject() @subject end
def subject=(arg) @subject = arg end
def attachments
@attachments
end
def add_attachment(attachment)
@attachments << attachment
end
def multipart?
@attachments && @attachments.size > 0
end
def delete_attachment(att_filename)
@attachments.each { |att| att.delete_temp_data() if arr.filename == att_filename }
@attachments.delete_if() { |att| att.filename == att_filename }
end
def delete_attachments()
@attachments.each { |att| att.delete_temp_data() }
@attachments = Array.new
end
def body() @body end
def body=(arg) @body = arg end
def content_type() @content_type end
def content_type=(arg) @content_type = arg end
def temp_location() @sender_temp_location end
def send_mail(db_msg_id = 0)
m = TMail::Mail.new
m.from, m.body = self.from, self.body
m.date = Time.now
m.subject, = quote_any_if_necessary("UTF-8", self.subject)
m.to = decode_addresses(self.to)
m.cc, m.bcc = decode_addresses(self.cc), decode_addresses(self.bcc)
if multipart?
m.set_content_type("multipart/mixed")
p = TMail::Mail.new(TMail::StringPort.new(""))
if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!!
prepare_text(p, self.content_type, self.body)
elsif self.content_type.include?("text/html")
prepare_html(p, self.content_type, self.body)
elsif self.content_type.include?("multipart")
prepare_alternative(p, self.body)
end
m.parts << p
else
if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!!
prepare_text(m, self.content_type, self.body)
elsif self.content_type.include?("text/html")
prepare_html(m, self.content_type, self.body)
elsif self.content_type.include?("multipart")
prepare_alternative(m, self.body)
end
end
# attachments
@attachments.each { |a|
m.parts << a.encoded
}
encmail = m.encoded
RAILS_DEFAULT_LOGGER.debug("Sending message \n #{encmail}")
Net::SMTP.start(ActionMailer::Base.smtp_settings[:address], ActionMailer::Base.smtp_settings[:port],
ActionMailer::Base.smtp_settings[:domain], ActionMailer::Base.smtp_settings[:user_name],
ActionMailer::Base.smtp_settings[:password], ActionMailer::Base.smtp_settings[:authentication]) do |smtp|
smtp.sendmail(encmail, m.from, m.destinations)
end
return encmail
end
def forward(tmail, fb)
decoded_subject = mime_encoded?(tmail.subject) ? mime_decode(tmail.subject) : tmail.subject
self.subject = "[Fwd: #{decoded_subject}]"
attachment = CDF::Attachment.new(self)
attachment.body(tmail, fb)
end
def reply(tmail, fb, type)
decoded_subject = mime_encoded?(tmail.subject) ? mime_decode(tmail.subject) : tmail.subject
self.subject = "[Re: #{decoded_subject}]"
tm = tmail.setup_reply(tmail)
self.to = tm.to
footer = ""
msg_id = ""
mt = MailTransform.new
self.body = mt.get_body(tmail, type)
end
private
def delimeter
if self.content_type == "text/plain"
"\n"
else
"<br/>"
end
end
def text2html(str) CGI.escapeHTML(str).gsub("\n", "<br/>") end
def html2text(txt)
clear_html(txt)
end
def prepare_text(msg, ctype, bdy)
msg.set_content_type(ctype, nil, {"charset"=>"utf-8"})
msg.transfer_encoding = "8bit"
msg.body = bdy
end
def prepare_html(msg, ctype, bdy)
msg.set_content_type(ctype, nil, {"charset"=>"utf8"})
msg.transfer_encoding = "8bit"
msg.body = bdy
end
def prepare_alternative(msg, bdy)
bound = ::TMail.new_boundary
msg.set_content_type("multipart/alternative", nil, {"charset"=>"utf8", "boundary"=>bound})
msg.transfer_encoding = "8bit"
ptext = TMail::Mail.new(TMail::StringPort.new(""))
phtml = TMail::Mail.new(TMail::StringPort.new(""))
prepare_text(ptext, "text/plain", html2text(bdy))
prepare_html(phtml, "text/html", bdy)
msg.parts << ptext
msg.parts << phtml
end
def decode_addresses(str)
ret = String.new
str.split(",").each { |addr|
if addr.slice(0,4) == "Grp+"
grp_id = addr.scan(/Grp\+([0-9]*):(.*)/)[0][0]
ContactGroup.find(:first, :conditions=>['customer_id = ? and id = ?', @customer_id, grp_id]).contacts.each { |contact|
ret << "," if not(ret == "")
@to_contacts << contact unless contact.nil?
ret << contact.full_address
ad, = quote_any_address_if_necessary(CDF::CONFIG[:mail_charset], contact.full_address)
ret << ad
}
else
ret << "," if not(ret == "")
ad, = quote_any_address_if_necessary(CDF::CONFIG[:mail_charset], addr) if not(addr.nil? or addr == "")
ret << ad if not(addr.nil? or addr == "")
end
} unless str.nil? or str.strip() == ""
ret
end
end
class CDF::Attachment
def initialize(arg)
@mail = arg
@mail.add_attachment(self)
@index = @mail.attachments.size - 1
end
def filename=(arg)
@filename = arg.tr('\\/:*?"\'<>|', '__________')
end
def filename() @filename end
def temp_filename=(arg) @temp_filename = arg end
def temp_filename() @temp_filename end
def content_type=(arg) @content_type = arg end
def content_type() @content_type end
def delete_temp_data()
File.delete(self.temp_filename)
end
def file
File.open(self.temp_filename, "rb") { |fp| fp.read }
end
def file=(data)
return if data.size == 0
@content_type = data.content_type
self.filename = data.original_filename.scan(/[^\\]*$/).first
self.temp_filename = "#{@mail.temp_location}/#{@filename}"
check_store_path
data.rewind
File.open(@temp_filename, "wb") { |f| f.write(data.read) }
end
def body(data, fb)
@content_type = "message/rfc822"
filename = data.content_type['filename']
self.filename = filename.nil? ? (mime_encoded?(data.subject) ? mime_decode(data.subject) : data.subject) : filename
self.temp_filename = "#{@mail.temp_location}/#{@filename}"
check_store_path
File.open(@temp_filename, "wb") { |f| f.write(fb) }
end
def check_store_path()
path = ""
"#{@mail.temp_location}".split(File::SEPARATOR).each { |p|
path << p
begin
Dir.mkdir(path)
rescue
end
path << File::SEPARATOR
}
end
def encoded
p = TMail::Mail.new(TMail::StringPort.new(""))
data = self.file
p.body = data
if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!!
p.set_content_type(@content_type, nil, {"charset"=>"utf-8"})
p.transfer_encoding = "8bit"
elsif @content_type.include?("text/html")
p.set_content_type(@content_type, nil, {"charset"=>"utf8"})
p.transfer_encoding = "8bit"
elsif @content_type.include?("rfc822")
p.set_content_type(@content_type, nil, {"charset"=>"utf8"})
p.set_disposition("inline;")
p.transfer_encoding = "8bit"
else
p.set_content_type(@content_type, nil, {"name"=>@filename})
p.set_disposition("inline; filename=#{@filename}") unless @filename.nil?
p.set_disposition("inline;") if @filename.nil?
p.transfer_encoding='Base64'
p.body = TMail::Base64.folding_encode(data)
end
return p
end
end