migrate mailr 2.2.2 to 2.3.2
This commit is contained in:
parent
56039cc595
commit
ae789b1d84
23 changed files with 5 additions and 48 deletions
8
lib/webmail/bounced_mail.rb
Normal file
8
lib/webmail/bounced_mail.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
class BouncedMail < ActiveRecord::Base
|
||||
belongs_to :customer
|
||||
belongs_to :contact
|
||||
|
||||
def BouncedMail.find_by_customer_contact(cust_id, contact_id)
|
||||
find_all(["customer_id = ? and contact_id = ?", cust_id, cotact_id], ["msg_date desc"])
|
||||
end
|
||||
end
|
303
lib/webmail/cdfmail.rb
Normal file
303
lib/webmail/cdfmail.rb
Normal file
|
@ -0,0 +1,303 @@
|
|||
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.create_reply
|
||||
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
|
5
lib/webmail/environment.rb
Normal file
5
lib/webmail/environment.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
require 'maildropserializator'
|
||||
Customer.class_eval do
|
||||
include MaildropSerializator
|
||||
has_many :filters, :order => "order_num", :dependent => true
|
||||
end
|
2
lib/webmail/expression.rb
Normal file
2
lib/webmail/expression.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
class Expression < ActiveRecord::Base
|
||||
end
|
3
lib/webmail/filter.rb
Normal file
3
lib/webmail/filter.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Filter < ActiveRecord::Base
|
||||
has_many :expressions
|
||||
end
|
38
lib/webmail/imap_message.rb
Normal file
38
lib/webmail/imap_message.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
require 'mail2screen'
|
||||
class ImapMessage < ActiveRecord::Base
|
||||
include Mail2Screen
|
||||
|
||||
def set_folder(folder)
|
||||
@folder = folder
|
||||
end
|
||||
|
||||
def full_body
|
||||
@folder.mailbox.imap.uid_fetch(uid, "BODY[]").first.attr["BODY[]"]
|
||||
end
|
||||
|
||||
def from_addr=(fa)
|
||||
self.from = fa.to_yaml
|
||||
self.from_flat = short_address(fa)
|
||||
end
|
||||
|
||||
def from_addr
|
||||
begin
|
||||
YAML::load(from)
|
||||
rescue Object
|
||||
from
|
||||
end
|
||||
end
|
||||
|
||||
def to_addr=(ta)
|
||||
self.to = ta.to_yaml
|
||||
self.to_flat = short_address(ta)
|
||||
end
|
||||
|
||||
def to_addr
|
||||
begin
|
||||
YAML::load(to)
|
||||
rescue Object
|
||||
to
|
||||
end
|
||||
end
|
||||
end
|
505
lib/webmail/imapmailbox.rb
Normal file
505
lib/webmail/imapmailbox.rb
Normal file
|
@ -0,0 +1,505 @@
|
|||
# Copyright (c) 2005, Benjamin Stiglitz
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Modifications (c) 2005 by littlegreen
|
||||
#
|
||||
require 'net/imap'
|
||||
|
||||
Net::IMAP.debug = true if CDF::CONFIG[:debug_imap]
|
||||
|
||||
class Net::IMAP
|
||||
class PlainAuthenticator
|
||||
def process(data)
|
||||
return "\0#{@user}\0#{@password}"
|
||||
end
|
||||
|
||||
private
|
||||
def initialize(user, password)
|
||||
@user = user
|
||||
@password = password
|
||||
end
|
||||
end
|
||||
add_authenticator('PLAIN', PlainAuthenticator)
|
||||
|
||||
class Address
|
||||
def to_s
|
||||
if(name)
|
||||
"#{name} #{mailbox}@#{host}"
|
||||
else
|
||||
"#{mailbox}@#{host}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class AuthenticationError < RuntimeError
|
||||
end
|
||||
|
||||
class IMAPMailbox
|
||||
attr_reader :connected
|
||||
attr_accessor :selected_mailbox
|
||||
cattr_accessor :logger
|
||||
|
||||
def initialize
|
||||
@selected_mailbox = ''
|
||||
@folders = {}
|
||||
@connected = false
|
||||
end
|
||||
|
||||
def connect(username, password)
|
||||
unless @connected
|
||||
use_ssl = CDF::CONFIG[:imap_use_ssl] ? true : false
|
||||
port = CDF::CONFIG[:imap_port] || (use_ssl ? 993 : 143)
|
||||
begin
|
||||
@imap = Net::IMAP.new(CDF::CONFIG[:imap_server], port, use_ssl)
|
||||
rescue Net::IMAP::ByeResponseError => bye
|
||||
# make a timeout and retry
|
||||
begin
|
||||
System.sleep(CDF::CONFIG[:imap_bye_timeout_retry_seconds])
|
||||
@imap = Net::IMAP.new(CDF::CONFIG[:imap_server], port, use_ssl)
|
||||
rescue Error => ex
|
||||
logger.error "Error on authentication!"
|
||||
logger.error bye.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
end
|
||||
rescue Net::IMAP::NoResponseError => noresp
|
||||
logger.error "Error on authentication!"
|
||||
logger.error noresp.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
rescue Net::IMAP::BadResponseError => bad
|
||||
logger.error "Error on authentication!"
|
||||
logger.error bad.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
rescue Net::IMAP::ResponseError => resp
|
||||
logger.error "Error on authentication!"
|
||||
logger.error resp.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
end
|
||||
@username = username
|
||||
begin
|
||||
logger.error "IMAP authentication - #{CDF::CONFIG[:imap_auth]}."
|
||||
if CDF::CONFIG[:imap_auth] == 'NOAUTH'
|
||||
@imap.login(username, password)
|
||||
else
|
||||
@imap.authenticate(CDF::CONFIG[:imap_auth], username, password)
|
||||
end
|
||||
@connected = true
|
||||
rescue Exception => ex
|
||||
logger.error "Error on authentication!"
|
||||
logger.error ex.backtrace.join("\n")
|
||||
raise AuthenticationError.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def imap
|
||||
@imap
|
||||
end
|
||||
|
||||
# Function chnage password works only if root has run imap_backend
|
||||
# and users courier-authlib utility authtest - from courier-imap version 4.0.1
|
||||
def change_password(username, password, new_password)
|
||||
ret = ""
|
||||
cin, cout, cerr = Open3.popen3("/usr/sbin/authtest #{username} #{password} #{new_password}")
|
||||
ret << cerr.gets
|
||||
if ret.include?("Password change succeeded.")
|
||||
return true
|
||||
else
|
||||
logger.error "[!] Error on change password! - #{ret}"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def disconnect
|
||||
if @connected
|
||||
@imap.logout
|
||||
#@imap.disconnect
|
||||
@imap = nil
|
||||
@connected = false
|
||||
end
|
||||
end
|
||||
|
||||
def [](mailboxname)
|
||||
@last_folder = IMAPFolderList.new(self, @username)[mailboxname]
|
||||
end
|
||||
|
||||
def folders
|
||||
# reference just to stop GC
|
||||
@folder_list ||= IMAPFolderList.new(self, @username)
|
||||
@folder_list
|
||||
end
|
||||
|
||||
def reload
|
||||
@folder_list.reload if @folder_list
|
||||
end
|
||||
|
||||
def create_folder(name)
|
||||
# begin
|
||||
@imap.create(Net::IMAP.encode_utf7(name))
|
||||
reload
|
||||
# rescue Exception=>e
|
||||
# end
|
||||
end
|
||||
|
||||
def delete_folder(name)
|
||||
begin
|
||||
@imap.delete(folders[name].utf7_name)
|
||||
reload
|
||||
rescue Exception=>e
|
||||
logger.error("Exception on delete #{name} folder #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
def message_sent(message)
|
||||
# ensure we have sent folder
|
||||
begin
|
||||
@imap.create(CDF::CONFIG[:mail_sent])
|
||||
rescue Exception=>e
|
||||
end
|
||||
begin
|
||||
@imap.append(CDF::CONFIG[:mail_sent], message)
|
||||
folders[CDF::CONFIG[:mail_sent]].cached = false if folders[CDF::CONFIG[:mail_sent]]
|
||||
rescue Exception=>e
|
||||
logger.error("Error on append - #{e}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def message_bulk(message)
|
||||
# ensure we have sent folder
|
||||
begin
|
||||
@imap.create(CDF::CONFIG[:mail_bulk_sent])
|
||||
rescue Exception=>e
|
||||
end
|
||||
begin
|
||||
@imap.append(CDF::CONFIG[:mail_bulk_sent], message)
|
||||
folders[CDF::CONFIG[:mail_sent]].cached = false if folders[CDF::CONFIG[:mail_bulk_sent]]
|
||||
rescue Exception=>e
|
||||
logger.error("Error on bulk - #{e}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class IMAPFolderList
|
||||
include Enumerable
|
||||
cattr_accessor :logger
|
||||
|
||||
def initialize(mailbox, username)
|
||||
@mailbox = mailbox
|
||||
@folders = Hash.new
|
||||
@username = username
|
||||
end
|
||||
|
||||
def each
|
||||
refresh if @folders.empty?
|
||||
#@folders.each_value { |folder| yield folder }
|
||||
# We want to allow sorted access; for now only (FIXME)
|
||||
|
||||
@folders.sort.each { |pair| yield pair.last }
|
||||
end
|
||||
|
||||
def reload
|
||||
refresh
|
||||
end
|
||||
|
||||
def [](name)
|
||||
refresh if @folders.empty?
|
||||
@folders[name]
|
||||
end
|
||||
|
||||
private
|
||||
def refresh
|
||||
@folders = {}
|
||||
result = @mailbox.imap.list('', '*')
|
||||
if result
|
||||
result.each do |info|
|
||||
folder = IMAPFolder.new(@mailbox, info.name, @username, info.attr, info.delim)
|
||||
@folders[folder.name] = folder
|
||||
end
|
||||
else
|
||||
# if there are no folders subscribe to INBOX - this is on first use
|
||||
@mailbox.imap.subscribe(CDF::CONFIG[:mail_inbox])
|
||||
# try again to list them - we should find INBOX
|
||||
@mailbox.imap.list('', '*').each do |info|
|
||||
@folders[info.name] = IMAPFolder.new(@mailbox, info.name, @username, info.attr, info.delim)
|
||||
end
|
||||
end
|
||||
@folders
|
||||
end
|
||||
end
|
||||
|
||||
class IMAPFolder
|
||||
attr_reader :mailbox
|
||||
attr_reader :name
|
||||
attr_reader :utf7_name
|
||||
attr_reader :username
|
||||
attr_reader :delim
|
||||
attr_reader :attribs
|
||||
|
||||
attr_writer :cached
|
||||
attr_writer :mcached
|
||||
|
||||
cattr_accessor :logger
|
||||
|
||||
@@fetch_attr = ['ENVELOPE','BODYSTRUCTURE', 'FLAGS', 'UID', 'RFC822.SIZE']
|
||||
|
||||
def initialize(mailbox, utf7_name, username, attribs, delim)
|
||||
@mailbox = mailbox
|
||||
@utf7_name = utf7_name
|
||||
@name = Net::IMAP.decode_utf7 utf7_name
|
||||
@username = username
|
||||
@messages = Array.new
|
||||
@delim = delim
|
||||
@attribs = attribs
|
||||
@cached = false
|
||||
@mcached = false
|
||||
end
|
||||
|
||||
def activate
|
||||
if(@mailbox.selected_mailbox != @name)
|
||||
@mailbox.selected_mailbox = @name
|
||||
@mailbox.imap.select(@utf7_name)
|
||||
load_total_unseen if !@cached
|
||||
end
|
||||
end
|
||||
|
||||
# Just delete message without interaction with Trash folder
|
||||
def delete(message)
|
||||
activate
|
||||
uid = (message.kind_of?(Integer) ? message : message.uid)
|
||||
@mailbox.imap.uid_store(uid, "+FLAGS", :Deleted)
|
||||
@mailbox.imap.expunge
|
||||
# Sync with trash cannot be made - new uid generated - so just delete message from current folder
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid = ?", @username, @name, uid])
|
||||
@cached = false
|
||||
end
|
||||
|
||||
# Deleted messages - move to trash folder
|
||||
def delete_multiple(uids)
|
||||
# ensure we have trash folder
|
||||
begin
|
||||
@mailbox.imap.create(CDF::CONFIG[:mail_trash])
|
||||
rescue
|
||||
end
|
||||
move_multiple(uids, CDF::CONFIG[:mail_trash])
|
||||
end
|
||||
|
||||
def copy(message, dst_folder)
|
||||
uid = (message.kind_of?(Integer) ? message : message.uid)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(uid, dst_folder)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
end
|
||||
|
||||
def copy_multiple(message_uids, dst_folder)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(message_uids, dst_folder)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
end
|
||||
|
||||
def move(message, dst_folder)
|
||||
uid = (message.kind_of?(Integer) ? message : message.uid)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(uid, dst_folder)
|
||||
@mailbox.imap.uid_store(uid, "+FLAGS", :Deleted)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.imap.expunge
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid = ? ", @username, @name, uid])
|
||||
@cached = false
|
||||
@mcached = false
|
||||
end
|
||||
|
||||
def move_multiple(message_uids, dst_folder)
|
||||
activate
|
||||
@mailbox.imap.uid_copy(message_uids, @mailbox.folders[dst_folder].utf7_name)
|
||||
@mailbox.imap.uid_store(message_uids, "+FLAGS", :Deleted)
|
||||
@mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder]
|
||||
@mailbox.imap.expunge
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid in ( ? )", @username, @name, message_uids])
|
||||
@cached = false
|
||||
@mcached = false
|
||||
end
|
||||
|
||||
def mark_read(message_uid)
|
||||
activate
|
||||
cached = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, message_uid])
|
||||
if cached.unread
|
||||
cached.unread = false
|
||||
cached.save
|
||||
@mailbox.imap.select(@name)
|
||||
@mailbox.imap.uid_store(message_uid, "+FLAGS", :Seen)
|
||||
@unseen_messages = @unseen_messages - 1
|
||||
end
|
||||
end
|
||||
|
||||
def mark_unread(message_uid)
|
||||
activate
|
||||
cached = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, message_uid])
|
||||
if !cached.unread
|
||||
cached.unread = true
|
||||
cached.save
|
||||
@mailbox.imap.select(@name)
|
||||
@mailbox.imap.uid_store(message_uid, "-FLAGS", :Seen)
|
||||
@unseen_messages = @unseen_messages + 1
|
||||
end
|
||||
end
|
||||
|
||||
def expunge
|
||||
activate
|
||||
@mailbox.imap.expunge
|
||||
end
|
||||
|
||||
def synchronize_cache
|
||||
startSync = Time.now
|
||||
activate
|
||||
startUidFetch = Time.now
|
||||
server_messages = @mailbox.imap.uid_fetch(1..-1, ['UID', 'FLAGS'])
|
||||
|
||||
startDbFetch = Time.now
|
||||
cached_messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name])
|
||||
|
||||
cached_unread_uids = Array.new
|
||||
cached_read_uids = Array.new
|
||||
uids_to_be_deleted = Array.new
|
||||
|
||||
cached_messages.each { |msg|
|
||||
cached_unread_uids << msg.uid if msg.unread
|
||||
cached_read_uids << msg.uid unless msg.unread
|
||||
uids_to_be_deleted << msg.uid
|
||||
}
|
||||
|
||||
uids_to_be_fetched = Array.new
|
||||
server_msg_uids = Array.new
|
||||
|
||||
uids_unread = Array.new
|
||||
uids_read = Array.new
|
||||
|
||||
server_messages.each { |server_msg|
|
||||
uid, flags = server_msg.attr['UID'], server_msg.attr['FLAGS']
|
||||
server_msg_uids << uid
|
||||
unless uids_to_be_deleted.include?(uid)
|
||||
uids_to_be_fetched << uid
|
||||
else
|
||||
if flags.member?(:Seen) && cached_unread_uids.include?(uid)
|
||||
uids_read << uid
|
||||
elsif !flags.member?(:Seen) && cached_read_uids.include?(uid)
|
||||
uids_unread << uid
|
||||
end
|
||||
end
|
||||
uids_to_be_deleted.delete(uid)
|
||||
} unless server_messages.nil?
|
||||
|
||||
ImapMessage.delete_all(["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_to_be_deleted]) unless uids_to_be_deleted.empty?
|
||||
ImapMessage.update_all('unread = 0', ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_read]) unless uids_read.empty?
|
||||
ImapMessage.update_all('unread = 1', ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_unread]) unless uids_unread.empty?
|
||||
|
||||
|
||||
# fetch and store not cached messages
|
||||
unless uids_to_be_fetched.empty?
|
||||
imapres = @mailbox.imap.uid_fetch(uids_to_be_fetched, @@fetch_attr)
|
||||
imapres.each { |cache|
|
||||
envelope = cache.attr['ENVELOPE'];
|
||||
message = ImapMessage.create( :folder_name => @name,
|
||||
:username => @username,
|
||||
:msg_id => envelope.message_id,
|
||||
:uid => cache.attr['UID'],
|
||||
:from_addr => envelope.from,
|
||||
:to_addr => envelope.to,
|
||||
:subject => envelope.subject,
|
||||
:content_type => cache.attr['BODYSTRUCTURE'].multipart? ? 'multipart' : 'text',
|
||||
:date => envelope.date,
|
||||
:unread => !(cache.attr['FLAGS'].member? :Seen),
|
||||
:size => cache.attr['RFC822.SIZE'])
|
||||
}
|
||||
end
|
||||
@mcached = true
|
||||
logger.debug("Synchonization done for folder #{@name} in #{Time.now - startSync} ms.")
|
||||
end
|
||||
|
||||
def messages(offset = 0, limit = 10, sort = 'date desc')
|
||||
# Synchronize first retrieval time
|
||||
synchronize_cache unless @mcached
|
||||
|
||||
if limit == -1
|
||||
@messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name], :order => sort)
|
||||
else
|
||||
@messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name], :order => sort, :limit => limit, :offset => offset )
|
||||
end
|
||||
end
|
||||
|
||||
def messages_search(query = ["ALL"], sort = 'date desc')
|
||||
activate
|
||||
uids = @mailbox.imap.uid_search(query)
|
||||
if uids.size > 1
|
||||
ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids], :order => sort )
|
||||
elsif uids.size == 1
|
||||
ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ? and uid = ? ", @username, @name, uids.first], :order => sort )
|
||||
else
|
||||
return Array.new
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def message(uid)
|
||||
activate
|
||||
message = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, uid])
|
||||
message.set_folder(self)
|
||||
message
|
||||
end
|
||||
|
||||
def unseen
|
||||
activate
|
||||
load_total_unseen if !@cached
|
||||
@unseen_messages
|
||||
end
|
||||
|
||||
def total
|
||||
activate
|
||||
load_total_unseen if !@cached
|
||||
@total_messages
|
||||
end
|
||||
|
||||
def load_total_unseen
|
||||
stat = @mailbox.imap.status(@utf7_name, ["MESSAGES", "UNSEEN"])
|
||||
@total_messages, @unseen_messages = stat["MESSAGES"], stat['UNSEEN']
|
||||
@cached = true
|
||||
end
|
||||
|
||||
def update_status
|
||||
@status ||= @mailbox.imap.status(@utf7_name, ["MESSAGES"])
|
||||
end
|
||||
|
||||
def subscribe
|
||||
@mailbox.imap.subscribe(@utf7_name)
|
||||
end
|
||||
|
||||
def trash?
|
||||
self.name == CDF::CONFIG[:mail_trash]
|
||||
end
|
||||
end
|
167
lib/webmail/mail2screen.rb
Normal file
167
lib/webmail/mail2screen.rb
Normal file
|
@ -0,0 +1,167 @@
|
|||
require 'cdfutils'
|
||||
module Mail2Screen
|
||||
def mail2html(mail, msg_id)
|
||||
footer = ""
|
||||
parsed_body = create_body(mail, msg_id, footer)
|
||||
|
||||
ret = "<table class='messageheader' border='0' cellpadding='0' cellspacing='0' >\n"
|
||||
ret << "<tbody>\n"
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('From')}:</td><td>#{address(mail.from_addrs, @msg_id)}</td></tr>\n"
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('To')}:</td><td>#{address(mail.to_addrs, @msg_id)}</td></tr>\n"
|
||||
if @mail.cc_addrs
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('CC')}:</td><td>#{address(mail.cc_addrs, @msg_id)}</td></tr>\n"
|
||||
end
|
||||
if @mail.bcc_addrs
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('BCC')}:</td><td>#{address(mail.bcc_addrs, @msg_id)}</td></tr>\n"
|
||||
end
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('Subject')}:</td><td>#{h(mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject)}</dd>\n"
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{_('Date')}:</td><td>#{h message_date(mail.date)}</td></tr>\n"
|
||||
if footer != ''
|
||||
ret << " <tr><td class='label' nowrap='nowrap'>#{image_tag('attachment.png')}</td><td>#{footer}</td></tr>\n"
|
||||
end
|
||||
ret << " </tbody>\n"
|
||||
ret << "</table>\n"
|
||||
|
||||
ret << "<div class='msgpart'>\n"
|
||||
ret << parsed_body
|
||||
ret << "</div>\n"
|
||||
end
|
||||
|
||||
def create_body(mail, msg_id, footer)
|
||||
charset = (mail.charset.nil? ? 'iso-8859-1' : mail.charset)
|
||||
if mail.multipart?
|
||||
ret = ""
|
||||
if mail.content_type == 'multipart/alternative'
|
||||
# take only HTML part
|
||||
mail.parts.each { |part|
|
||||
if part.content_type == "text/html" or part.multipart?
|
||||
ret << create_body(part, msg_id, footer)
|
||||
end
|
||||
}
|
||||
return ret
|
||||
else
|
||||
mail.parts.each { |part|
|
||||
if part.multipart?
|
||||
ret << create_body(part, msg_id, footer)
|
||||
else
|
||||
footer << ", " if footer != ''
|
||||
footer << add_attachment(part.header['content-type'], msg_id)
|
||||
if part.content_type == "text/plain" or part.content_type.nil?
|
||||
charset = (part.charset.nil? ? charset : mail.charset)
|
||||
ret << add_text(part, part.transfer_encoding, charset)
|
||||
elsif part.content_type == "text/html"
|
||||
charset = (part.charset.nil? ? charset : mail.charset)
|
||||
ret << add_html(part, part.transfer_encoding, charset)
|
||||
elsif part.content_type.include?("image/")
|
||||
ctype = part.header['content-type']
|
||||
ret << add_image(ctype, msg_id)
|
||||
elsif part.content_type.include?("message/rfc822")
|
||||
ret << "<br/>#{_('Follows attached message')}:<hr/>" << mail2html(TMail::Mail.parse(part.body), msg_id)
|
||||
end
|
||||
end
|
||||
}
|
||||
return ret
|
||||
end
|
||||
else
|
||||
ret = ""
|
||||
if mail.content_type == "text/plain" or mail.content_type.nil?
|
||||
ret << add_text(mail, mail.transfer_encoding, charset)
|
||||
elsif mail.content_type == "text/html"
|
||||
ret << add_html(mail, mail.transfer_encoding, charset)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
def add_text(part, encoding, charset)
|
||||
CGI.escapeHTML(decode_part_text("#{part}", encoding, charset)).gsub(/\r\n/,"<br/>").gsub(/\r/, "<br/>").gsub(/\n/,"<br/>")
|
||||
end
|
||||
|
||||
def add_html(part, encoding, charset)
|
||||
strip_html(decode_part_text("#{part}", encoding, charset))
|
||||
end
|
||||
|
||||
def decode_part_text(part_str, encoding, charset)
|
||||
# Parse mail
|
||||
header, text = "", ""
|
||||
|
||||
# Get header and body
|
||||
#Content-type: text/plain; charset="ISO-8859-1"
|
||||
#Content-transfer-encoding: quoted-printable
|
||||
isBody = false
|
||||
part_str.each_line { |line|
|
||||
if isBody
|
||||
text << line
|
||||
else
|
||||
if line.strip == ""
|
||||
isBody = true
|
||||
else
|
||||
header << line
|
||||
end
|
||||
end
|
||||
}
|
||||
# Manage encoding
|
||||
if not(encoding.nil?) and encoding.downcase == "quoted-printable"
|
||||
ret = from_qp(text)
|
||||
elsif not(encoding.nil?) and encoding.downcase == "base64"
|
||||
ret = "#{text.unpack("m")}"
|
||||
else
|
||||
ret = text
|
||||
end
|
||||
# manage charset
|
||||
if ret.nil? or charset.nil? or charset.downcase == "utf-8"
|
||||
return ret
|
||||
else
|
||||
begin
|
||||
return Iconv.conv("UTF-8",charset.downcase, ret)
|
||||
rescue Exception => ex
|
||||
RAILS_DEFAULT_LOGGER.debug("Exception occured #{ex}\n#{ex.backtrace.join('\n')}")
|
||||
return ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_attachment(content_type, msg_id)
|
||||
filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name'])
|
||||
if filename == ""
|
||||
""
|
||||
else
|
||||
"<span class='attachment'> <a href='/webmail/download?msg_id=#{msg_id}&ctype=" << CGI.escape(filename) << "'>#{filename}</a></span>"
|
||||
end
|
||||
end
|
||||
|
||||
def add_image(content_type, msg_id)
|
||||
filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name'])
|
||||
"<hr/><span class='attachment'><br/><img src='/webmail/download?msg_id=#{msg_id}&ctype=" << CGI.escape(filename) << "' alt='#{filename}'/></span>"
|
||||
end
|
||||
|
||||
def friendly_address(addr)
|
||||
addr.kind_of?(Net::IMAP::Address) ? ((addr.name.nil? or addr.name.strip == "") ? "#{addr.mailbox}@#{addr.host}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.mailbox}@#{addr.host}>") : ((addr.name.nil? or addr.name.strip == "") ? "#{addr.spec}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.spec}>")
|
||||
end
|
||||
|
||||
def friendly_address_or_name(addr)
|
||||
addr.kind_of?(Net::IMAP::Address) ? ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.mailbox}@#{addr.host}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s)) : ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.spec}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s))
|
||||
end
|
||||
|
||||
def add_to_contact(addr, msg_id)
|
||||
" <a href='/contacts/contact/add_from_mail?cstr=#{CGI.escape(friendly_address(addr))}&retmsg=#{msg_id}'>Add to contacts</a>"
|
||||
end
|
||||
|
||||
def short_address(addresses)
|
||||
ret = ""
|
||||
addresses.each { |addr| #split(/,\s*/)
|
||||
ret << "," unless ret == ""
|
||||
ret << CGI.escapeHTML(friendly_address_or_name(addr))
|
||||
} unless addresses.nil?
|
||||
ret
|
||||
end
|
||||
|
||||
def address(addresses, msg_id)
|
||||
ret = ""
|
||||
addresses.each { |addr| #split(/,\s*/)
|
||||
ret << "," unless ret == ""
|
||||
ret << CGI.escapeHTML(friendly_address_or_name(addr)) << add_to_contact(addr, msg_id)
|
||||
} unless addresses.nil?
|
||||
return ret
|
||||
end
|
||||
end
|
75
lib/webmail/mail_transform.rb
Normal file
75
lib/webmail/mail_transform.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
require 'mail2screen'
|
||||
|
||||
class MailTransform
|
||||
include Mail2Screen
|
||||
|
||||
def get_body(tmail, type)
|
||||
@mail = tmail
|
||||
footer = ""
|
||||
msg_id = ""
|
||||
ret = mail2html(tmail, msg_id)
|
||||
ret = ret.gsub(/<br\/>/,"\n").gsub(/ /, " ").gsub(/</, "<").gsub(/>/, ">").gsub(/&/, "&").gsub(/<hr\/>/, "\n").gsub(/\n/, "\n> ") if type == 'text/plain'
|
||||
ret = ret.gsub(/\r\n/,"<br/>").gsub(/\r/, "<br/>").gsub(/\n/,"<br/>").gsub(/<br\/>/, "<br/>> ") unless type == 'text/plain'
|
||||
return ret
|
||||
end
|
||||
|
||||
def mail2html(mail, msg_id)
|
||||
footer = ""
|
||||
parsed_body = create_body(mail, msg_id, footer)
|
||||
|
||||
ret = "-----Original Message-----\n#{_('From')}:#{address(mail.from_addrs, @msg_id)}\n"
|
||||
ret << "#{_('To')}:#{address(mail.to_addrs, @msg_id)}\n"
|
||||
if @mail.cc_addrs
|
||||
ret << " #{_('CC')}:#{address(mail.cc_addrs, @msg_id)}\n"
|
||||
end
|
||||
if @mail.bcc_addrs
|
||||
ret << "#{_('BCC')}:#{address(mail.bcc_addrs, @msg_id)}\n"
|
||||
end
|
||||
ret << "#{_('Subject')}:#{mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject}\n"
|
||||
ret << "#{_('Date')}:#{message_date(mail.date)}\n"
|
||||
ret << "\n"
|
||||
ret << "\n"
|
||||
ret << parsed_body
|
||||
ret << "\n"
|
||||
end
|
||||
|
||||
def message_date(datestr)
|
||||
t = Time.now
|
||||
begin
|
||||
if datestr.kind_of?(String)
|
||||
d = (Time.rfc2822(datestr) rescue Time.parse(value)).localtime
|
||||
else
|
||||
d = datestr
|
||||
end
|
||||
if d.day == t.day and d.month == t.month and d.year == t.year
|
||||
d.strftime("%H:%M")
|
||||
else
|
||||
d.strftime("%Y-%m-%d")
|
||||
end
|
||||
rescue
|
||||
begin
|
||||
d = imap2time(datestr)
|
||||
if d.day == t.day and d.month == t.month and d.year == t.year
|
||||
d.strftime("%H:%M")
|
||||
else
|
||||
d.strftime("%Y-%m-%d")
|
||||
end
|
||||
rescue
|
||||
datestr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Overwrite some staff
|
||||
def add_to_contact(addr, msg_id)
|
||||
""
|
||||
end
|
||||
def add_attachment(content_type, msg_id)
|
||||
""
|
||||
end
|
||||
|
||||
def add_image(content_type, msg_id)
|
||||
""
|
||||
end
|
||||
|
||||
end
|
51
lib/webmail/maildropserializator.rb
Normal file
51
lib/webmail/maildropserializator.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
module MaildropSerializator
|
||||
def serialize_to_file
|
||||
mail_drop_filter = File.new(self.mail_filter_path, "w")
|
||||
for filter in filters
|
||||
mail_drop_filter << "# filter '#{filter.name}'\n"
|
||||
mail_drop_filter << "if (#{filter_expressions(filter)})\n"
|
||||
mail_drop_filter << "{\n"
|
||||
mail_drop_filter << " exception {\n"
|
||||
mail_drop_filter << " to #{dest_folder(filter)}\n"
|
||||
mail_drop_filter << " }\n"
|
||||
mail_drop_filter << "}\n"
|
||||
end
|
||||
mail_drop_filter.close()
|
||||
end
|
||||
|
||||
private
|
||||
def dest_folder(filter)
|
||||
'$DEFAULT/'<<filter.destination_folder.sub(Regexp.new("(#{CDF::CONFIG[:mail_inbox]})(.*)"), '\2')<<"/"
|
||||
end
|
||||
|
||||
def escape_expr_value(text)
|
||||
text.gsub(".", "\\.").gsub("*", "\\*").gsub("[", "\\[").gsub("]", "\\]").gsub("(", "\\(").gsub(")", "\\)").
|
||||
gsub("?", "\\?")
|
||||
end
|
||||
|
||||
def filter_expressions(filter)
|
||||
fe = ""
|
||||
for exp in filter.expressions
|
||||
post_flag = "h"
|
||||
fe << " && " unless fe == ""
|
||||
if exp.field_name == "^Body"
|
||||
fe << "/"
|
||||
post_flag = "b"
|
||||
else
|
||||
fe << "/#{exp.field_name}:"
|
||||
end
|
||||
if exp.operator == 'contains'
|
||||
fe << ".*(#{escape_expr_value(exp.expr_value)})/"
|
||||
else
|
||||
# starts with
|
||||
fe << "[ ]*(#{escape_expr_value(exp.expr_value)}).*/"
|
||||
end
|
||||
if exp.case_sensitive == 1
|
||||
fe << "D" << post_flag
|
||||
else
|
||||
fe << post_flag
|
||||
end
|
||||
end
|
||||
fe
|
||||
end
|
||||
end
|
4
lib/webmail/routes.rb
Normal file
4
lib/webmail/routes.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Webmail mapping
|
||||
map.connect 'webmail', :controller => 'webmail/webmail', :action => 'messages'
|
||||
|
||||
|
3
lib/webmail/virtual_email.rb
Normal file
3
lib/webmail/virtual_email.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class VirtualEmail < ActiveRecord::Base
|
||||
def self.table_name() "cdf.wm_virtual" end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue