require 'net/imap'
require 'mail'
require 'time'
require 'date'
require 'iniparse'
require 'logger'
Mail.defaults do
delivery_method :smtp, {
address: "imap.localhost",
domain: "imap.localhost",
port: 25 }
end
class Imapforwarder
def initialize(server, username, password, log_filename)
@server = server
@username = username
@password = password
@folder = "INBOX"
@keep_days = 30
@logger = Logger.new(log_filename)
@logger.formatter = proc do |severity, datetime, progname, msg|
"#{datetime}: #{msg}\n"
end
@imap = connect()
fetch_mails(['UNSEEN'])
end
def idle_loop()
loop do
begin
@imap.select(@folder)
@imap.idle do |resp|
if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS" then
@imap.idle_done
end
end
fetch_mails(['UNSEEN'])
delete_date = (Date.today() - @keep_days).strftime("%d-%b-%Y")
delete_oldmails(["BEFORE", delete_date])
rescue SignalException => e
@logger.error("#{e.class}. #{e.message}")
@imap.idle_done
@imap.logout unless @imap.disconnected?
@imap.disconnect
exit(0)
rescue Net::IMAP::Error => e
@logger.error("Net::IMAP::Error #{e.class}. #{e.message}")
@imap = connect(@server, @username, @password)
@logger.error("reconnected to server: #{server}")
rescue Exception => e
@logger.error("Something went wrong #{e.class}. #{e.message}")
@imap = connect(@server, @username, @password)
@logger.error("reconnected to server: #{server}")
end
end
end
def connect()
@logger.debug("Connecting to server " + @server)
imap = Net::IMAP.new(@server)
unless imap.capability.include? "IDLE"
@logger.error("'IDLE' IMAP capability not available in server: #{server}")
imap.disconnect()
end
@logger.debug("Login " + @username)
imap.authenticate('PLAIN', @username, @password)
return imap
end
def fetch_mails(search_filter)
@imap.select(@folder)
message_ids = @imap.search(search_filter)
if not message_ids.empty? then
@logger.debug("Fetching " + message_ids.count.to_s + " mails")
message_ids.each do |message_id|
msg = @imap.fetch(message_id,'RFC822')[0].attr['RFC822']
mail = Mail.read_from_string msg
@logger.info(mail.from[0] + " - " + mail.subject)
@imap.store(message_id, "+FLAGS", [:Seen])
mail.deliver
end
end
end
def delete_oldmails(search_filter)
@imap.select(@folder)
message_ids = @imap.search(search_filter)
if not message_ids.empty? then
@logger.debug("Deleting " + message_ids.count.to_s + " mails")
message_ids.each do |message_id|
@imap.store(message_id, "+FLAGS", [:Deleted])
end
@imap.expunge()
end
end
def disconnect()
imap.disconnect()
end
end
config_file = File.read('config.ini')
config = IniParse.parse(config_file)
config.each do |section|
log_filename = section.key + ".log"
username = section['username']
password = section['password']
server = section['server']
Thread.new(log_filename, username, password, server) {
imapforwarder = Imapforwarder.new(server, username, password, log_filename)
imapforwarder.idle_loop()
}
end
sleep