Permalink
Browse files

* added folder listing for imap

* added download mbox for imap
  • Loading branch information...
1 parent 1586aec commit 7261bc8bb7051b156a213c1d255959f484c3f319 @hone committed Jan 12, 2009
Showing with 147 additions and 4 deletions.
  1. +52 −1 app/models/imap.rb
  2. +78 −0 spec/models/imap_spec.rb
  3. +2 −2 spec/models/pop3_spec.rb
  4. +1 −1 spec/spec.opts
  5. +14 −0 spec/spec_helper.rb
View
@@ -15,13 +15,64 @@ def setup_mailer
else
self.port = DEFAULT_PORT if self.port.nil?
end
+ status = OK_FLAG
if self.old_server != self.server or self.old_port != self.port or self.old_ssl != self.ssl
- @mailer = Net::IMAP.new( self.server, self.port, self.ssl )
+ begin
+ @mailer = Net::IMAP.new( self.server, self.port, self.ssl )
+ @mailer.login( self.username, self.password )
+ rescue Net::IMAP::NoResponseError
+ status = AUTHENTICATION_ERROR_FLAG
+ rescue Errno::ETIMEDOUT
+ status = TIMEOUT_ERROR_FLAG
+ end
end
self.old_server = self.server
self.old_port = self.port
self.old_ssl = self.ssl
+
+ status
+ end
+
+ def close
+ close
+ end
+
+ def folders
+ search_folder( '' )
+ end
+
+ def download_folder( folder, mbox_name )
+ folder_path = "#{TMP_DIR}/#{mbox_name}/#{folder.name.split( folder.delim ).join( "/" )}"
+ FileUtils.mkdir( folder_path ) if folder.attr.include?( :Haschildren )
+ @mailer.examine( folder.name )
+ uids = @mailer.uid_search(['ALL'])
+ # if some uids, download data
+ if uids.length > 0
+ write_mbox( "#{folder_path}.mbox", uids )
+ end
+
+ uids.length
+ end
+
+ def write_mbox( mbox_name, uids )
+ File.open( mbox_name, 'w' ) do |file|
+ @mailer.uid_fetch( uids, ['ENVELOPE'] ) do |msg|
+ file.puts( source.uid_fetch( msg.attr['UID'], ['RFC822'] ).first.attr['RFC822'] )
+ end
+ end
+ end
+
+ private
+ def search_folder( path )
+ list = @mailer.list( path, "%" )
+ list.inject(Array.new) do |folders, item|
+ if item.attr.include?( :Haschildren )
+ folders + [item] + search_folder( item.name )
+ else
+ folders + [item]
+ end
+ end
end
end
View
@@ -34,6 +34,7 @@ def setup_mock_net_imap
it "should set default ssl port if not set" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).once.and_return(@net_imap)
+ @net_imap.should_receive(:login).once
setup_imap( { :port => nil, :ssl => true } )
@imap.port.should == Imap::DEFAULT_SSL_PORT
@@ -42,6 +43,7 @@ def setup_mock_net_imap
it "should keep track of old server" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).twice.and_return(@net_imap)
+ @net_imap.should_receive(:login).twice
setup_imap( {}, false )
@imap.server.should == @valid_attributes[:server]
@imap.old_server.should be_nil
@@ -59,6 +61,7 @@ def setup_mock_net_imap
it "should keep track of old port" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).twice.and_return(@net_imap)
+ @net_imap.should_receive(:login).twice
setup_imap( {}, false )
@imap.port.should == @valid_attributes[:port]
@imap.old_port.should be_nil
@@ -76,6 +79,7 @@ def setup_mock_net_imap
it "should keep track of old ssl" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).twice.and_return(@net_imap)
+ @net_imap.should_receive(:login).twice
setup_imap( {}, false )
@imap.ssl.should == @valid_attributes[:ssl]
@imap.old_ssl.should be_nil
@@ -93,6 +97,7 @@ def setup_mock_net_imap
it "should not create a new Net::IMAP if server or port or ssl hasn't been changed" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).once.and_return(@net_imap)
+ @net_imap.should_receive(:login).once
setup_imap
@imap.setup_mailer
@@ -101,6 +106,7 @@ def setup_mock_net_imap
it "should create a new Net::IMAP object upon server change" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).twice.and_return(@net_imap)
+ @net_imap.should_receive(:login).twice
setup_imap
@imap.server = "pop.dreamhost.com"
@@ -110,6 +116,7 @@ def setup_mock_net_imap
it "should create a new Net::IMAP object upon port change" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).twice.and_return(@net_imap)
+ @net_imap.should_receive(:login).twice
setup_imap
@imap.port = 992
@@ -119,9 +126,80 @@ def setup_mock_net_imap
it "should create a new Net::IMAP object upon ssl change" do
setup_mock_net_imap
Net::IMAP.should_receive(:new).twice.and_return(@net_imap)
+ @net_imap.should_receive(:login).twice
setup_imap
@imap.ssl = !@valid_attributes[:ssl]
@imap.setup_mailer
end
+
+ it "should raise error on login problem" do
+ setup_mock_net_imap
+ Net::IMAP.should_receive(:new).once.and_return(@net_imap)
+ @net_imap.should_receive(:login).and_raise( Net::IMAP::NoResponseError )
+
+ result = setup_imap
+ result.should == RemoteMail::AUTHENTICATION_ERROR_FLAG
+ end
+
+ it "should raise error on timeout" do
+ setup_mock_net_imap
+ Net::IMAP.should_receive(:new).once.and_return(@net_imap)
+ @net_imap.should_receive(:login).and_raise( Errno::ETIMEDOUT )
+
+ result = setup_imap
+ result.should == RemoteMail::TIMEOUT_ERROR_FLAG
+ end
+end
+
+describe Imap, "live connections" do
+ include ImapSpecHelper
+
+ after(:all) do
+ remove_dir( TMP_MBOX_FILE )
+ end
+
+ it "should return all folders" do
+ setup_imap
+
+ folders = ["INBOX", "INBOX.Drafts", "INBOX.Sent", "INBOX.Trash", "INBOX.old-messages"]
+ @imap.folders.collect {|item| item.name }.sort.should == folders.sort
+ end
+
+ it "should download mail in a parent folder" do
+ setup_imap
+ @imap.stub!(:generate_mbox_name).and_return( MBOX_NAME )
+
+ mailbox_folder = Net::IMAP::MailboxList.new( [:Unmarked, :Haschildren], '.', "INBOX" )
+ folder = "#{TMP_MBOX_FILE}/#{mailbox_folder.name}"
+ mbox = "#{folder}.mbox"
+ remove_dir( TMP_MBOX_FILE )
+ FileUtils.mkdir( TMP_MBOX_FILE )
+ @imap.download_folder( mailbox_folder, @imap.generate_mbox_name ).should == 1
+ File.should be_exist( folder )
+ File.should be_directory( folder )
+ File.should be_exist( mbox )
+
+ remove_file( mbox )
+ remove_dir( folder )
+ end
+
+ it "should download mail in a leaf folder" do
+ setup_imap
+ @imap.stub!(:generate_mbox_name).and_return( MBOX_NAME )
+
+ mailbox_folder = Net::IMAP::MailboxList.new( [:Unmarked, :Hasnochildren], '.', "INBOX.Drafts" )
+ parent_dir = "#{TMP_MBOX_FILE}/INBOX"
+ mbox = "#{parent_dir}/Drafts.mbox"
+
+ remove_dir( TMP_MBOX_FILE )
+ FileUtils.mkdir( TMP_MBOX_FILE )
+ FileUtils.mkdir( parent_dir )
+ @imap.download_folder( mailbox_folder, @imap.generate_mbox_name ).should == 1
+ File.should be_exist( mbox )
+ File.should_not be_exist( "#{parent_dir}/Drafts" )
+
+ remove_file( mbox )
+ remove_dir( parent_dir )
+ end
end
View
@@ -164,11 +164,11 @@ def setup_mock_net_pop3
include Pop3SpecHelper
before(:each) do
- remove_file( TMP_MBOX_FILE )
+ remove_dir( TMP_MBOX_FILE )
end
after(:all) do
- remove_file( TMP_MBOX_FILE )
+ remove_dir( TMP_MBOX_FILE )
end
View
@@ -1,4 +1,4 @@
--colour
---format progress
+--format specdoc
--loadby mtime
--reverse
View
@@ -99,3 +99,17 @@ def setup_mock_time
Time.should_receive(:now).once.and_return(@time)
@time.should_receive(:to_s).once.and_return( 'Thu Jan 08 01:22:01 -0500 2009' )
end
+
+def remove_dir( path )
+ if File.exist?( path )
+ if File.directory?( path )
+ Dir[ "#{path}/*" ].each do |file|
+ remove_dir( file )
+ end
+
+ FileUtils.rmdir( path )
+ else
+ FileUtils.rm( path )
+ end
+ end
+end

0 comments on commit 7261bc8

Please sign in to comment.