So here I was, lost on a windows box, looking for a way to get supplies
that were badly needed. And what do you know, but Dan Weinand came to the rescue. Dan had written a plug-in for rails that "does" fetching of a IMAP server.
Dan Weinand site: http://www.danweinand.com/
In my application, I wanted my "clients" existing email infrastructure which consisted of Exchange 2003 soon to be exchange 2007. Just wanted to fetch a "email" address from the existing server.
So after asking permision we enable IMAP on exchange. And I pulled in the "fetcher"
into the application. Of course I wanted it to run as a "service" on windows. The original was designed for Linux. So I converted to a windows service. In addition
I found that the "standard" authentications in the fetcher for IMAP needed a "tweak" to do a "login" at the IMAP level, rather than "authorize".
So I added "dumb" authentication to the code.
The imap.rb in vendors/plugins/fetcher/lib needed the two patches
1. Added dumb authentication
2. Fixed the "recovery" so it would not cause a exception on a empty mailbox
--- imap.rb ---
module Fetcher
class Imap < Base
protected
# Additional Options:
# * :authentication - authentication type to use, defaults to DUMB
def initialize(options={})
@authentication = options.delete(:authentication) || 'DUMB'
super(options)
end
# Open connection and login to server
def establish_connection
@connection = Net::IMAP.new(@server)
if (@authentication == "DUMB")
@connection.login(@username,@password)
elsif
@connection.authenticate(@authentication, @username, @password)
end
end
# Retrieve messages from server
def get_messages
@connection.select('INBOX')
@connection.search(['ALL']).each do |message_id|
msg = @connection.fetch(message_id,'RFC822')[0].attr['RFC822']
begin
process_message(msg)
rescue
# handle_bogus_message(msg)
end
# Mark message as deleted
@connection.store(message_id, "+FLAGS", [:Deleted])
end
end
The Fetcher is designed with a bit of "meta" programming so it can "submit" the email to the activerecord model.
-- script/AirFetchservice.rb
require 'rubygems'
require 'win32/service'
require 'logger'
require 'net/imap'
require 'net/pop'
include Win32
Dir.chdir("\\projects\\ror\\AirCenter")
require File.dirname(__FILE__) + '/../config/environment.rb'
SERVICE_NAME = 'AirFetchService'
SERVICE_DISPLAYNAME = 'AirCenterEmailFetcherService'
$logger = Logger.new("c:\\projects\\ror\\AirCenter\\log\\AirFetchService.log")
class Mailman < ActionMailer::Base
def receive(email)
sender = email.from.to_s()
subject = email.subject.to_s()
body = email.body.to_s()
subjectparts = subject.split(/ /)
classname = subjectparts[0]
$logger.info("Mailman: Sender = #{sender} Class = #{classname} Subject = #{subject}")
myclass = Object.const_get(classname)
if myclass
myclass.ReceiveEmail(sender,subject,subjectparts,body)
else $logger.warn("Mailman: Invalid class #{classname}")
end
end
end
if ARGV[0] == "register"
#Start The Service
svc = Service.new
svc.create_service do |s|
s.service_name = SERVICE_NAME
s.display_name = SERVICE_DISPLAYNAME
s.binary_path_name = "c:\\ruby\\bin\\ruby.exe c:\\projects\\ror\\AirCenter\\script\\AirFetchService.rb"
# + File.expand_path($0)
s.dependencies = []
end
svc.close
puts "Registered Service - " + SERVICE_DISPLAYNAME
elsif ARGV[0] == "test"
$logger.info "Service Starting"
$logger.info "Loading EMAIL Config"
@config = YAML.load_file("#{RAILS_ROOT}/config/mail.yml")
$logger.info "Setting up config"
@config = @config[RAILS_ENV].to_options
$logger.info "Setting up sleep time"
@sleep_time = @config.delete(:sleep_time) || 60
$logger.info "Service Init Complete"
$logger.info "AirFetchService Establish mail processor"
# Add your own receiver object below
@fetcher = Fetcher.create({:receiver => Mailman}.merge(@config))
@fetcher.fetch
exit
elsif ARGV[0] == "delete"
if Service.status(SERVICE_NAME).current_state == "running"
Service.stop(SERVICE_NAME)
end
Service.delete(SERVICE_NAME)
else
if ENV["HOMEDRIVE"] !=nil
puts "Usage: ruby airfetchservice.rb [options]"
puts " where options are: register or delete"
exit
end
$stderr = $logger
$stdout = $logger
class MyDaemon < Win32::Daemon
def service_init
sleep 1
$logger.info "Service Starting"
$logger.info "Loading EMAIL Config"
@config = YAML.load_file("#{RAILS_ROOT}/config/mail.yml")
$logger.info "Setting up config"
@config = @config[RAILS_ENV].to_options
$logger.info "Setting up sleep time"
@sleep_time = @config.delete(:sleep_time) || 60
$logger.info "Service Init Complete"
$logger.info "AirFetchService Establish mail processor"
# Add your own receiver object below
@fetcher = Fetcher.create({:receiver => Mailman.receive}.merge(@config))
end
def service_stop
$logger.info "AirFetchService Stopped"
end
def service_main
$logger.info "AirFetchService: Service in Running State"
while state == RUNNING
@fetcher.fetch
sleep(@sleep_time)
end
end
end
d = MyDaemon.new
d.mainloop
end
Friday, September 28, 2007
My Life On Rails
I've been looking for a "idea" environment to do "applications".
I used to do alot of VB6, and felt that Microsoft "messed" things up
after that. My apps didnt move, and my mind was even less willing to
face the "explosion" of technology and "false" starts that Microsoft
offered in the way of programming.
My background covers C,assembler,Cobol,VB, PL1 and a variety of others.
I found Python about a year and a half ago, and did lots of small backend
projects with it for "backend" processes. Everything from colecting router
logs to database conversion, and realtime "interconnect" between legacy
applications. Python could not be beat. My problem was doing a "gui". The
gui must connect to a "database" and our database of choice is Oracle. In addition it should connect to a variety of others. As well as have libraries for everything else.
Enter "Stage-left" ruby and its framework ruby-on-rails.
Now I can develop a variety of applications with lovely "web" based gui in no time flat.
My technology stack:
active-scaffold
This take care of all the java-script for me. :)
tabnav/widgets
ruby-on-rails
activerecord - Manages the database
activemailer - Handles outgoing and incoming mail
ruby
Supporting cast:
Oracle (10g, Oracle XE)
win32-service - Lets me make my background rails functions run
as windows services
I used to do alot of VB6, and felt that Microsoft "messed" things up
after that. My apps didnt move, and my mind was even less willing to
face the "explosion" of technology and "false" starts that Microsoft
offered in the way of programming.
My background covers C,assembler,Cobol,VB, PL1 and a variety of others.
I found Python about a year and a half ago, and did lots of small backend
projects with it for "backend" processes. Everything from colecting router
logs to database conversion, and realtime "interconnect" between legacy
applications. Python could not be beat. My problem was doing a "gui". The
gui must connect to a "database" and our database of choice is Oracle. In addition it should connect to a variety of others. As well as have libraries for everything else.
Enter "Stage-left" ruby and its framework ruby-on-rails.
Now I can develop a variety of applications with lovely "web" based gui in no time flat.
My technology stack:
active-scaffold
This take care of all the java-script for me. :)
tabnav/widgets
ruby-on-rails
activerecord - Manages the database
activemailer - Handles outgoing and incoming mail
ruby
Supporting cast:
Oracle (10g, Oracle XE)
win32-service - Lets me make my background rails functions run
as windows services
Subscribe to:
Posts (Atom)