lib/mail/network/retriever_methods/imap.rb in mail-2.7.0.rc1 vs lib/mail/network/retriever_methods/imap.rb in mail-2.7.0.rc2

- old
+ new

@@ -43,11 +43,12 @@ self.settings = { :address => "localhost", :port => 143, :user_name => nil, :password => nil, :authentication => nil, - :enable_ssl => false }.merge!(values) + :enable_ssl => false, + :enable_starttls => false }.merge!(values) end attr_accessor :settings # Find emails in a IMAP mailbox. Without any options, the 10 last received emails are returned. @@ -65,34 +66,38 @@ # delete_after_find: flag for whether to delete each retreived email after find. Default # is false. Use #find_and_delete if you would like this to default to true. # keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string, # or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list # The default is 'ALL' + # search_charset: charset to pass to IMAP server search. Omitted by default. Example: 'UTF-8' or 'ASCII'. # def find(options={}, &block) options = validate_options(options) start do |imap| options[:read_only] ? imap.examine(options[:mailbox]) : imap.select(options[:mailbox]) - - uids = imap.uid_search(options[:keys]) + uids = imap.uid_search(options[:keys], options[:search_charset]) uids.reverse! if options[:what].to_sym == :last uids = uids.first(options[:count]) if options[:count].is_a?(Integer) uids.reverse! if (options[:what].to_sym == :last && options[:order].to_sym == :asc) || (options[:what].to_sym != :last && options[:order].to_sym == :desc) if block_given? uids.each do |uid| uid = options[:uid].to_i unless options[:uid].nil? - fetchdata = imap.uid_fetch(uid, ['RFC822'])[0] + fetchdata = imap.uid_fetch(uid, ['RFC822', 'FLAGS'])[0] new_message = Mail.new(fetchdata.attr['RFC822']) new_message.mark_for_delete = true if options[:delete_after_find] - if block.arity == 3 + + if block.arity == 4 + yield new_message, imap, uid, fetchdata.attr['FLAGS'] + elsif block.arity == 3 yield new_message, imap, uid else yield new_message end + imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find] && new_message.is_marked_for_delete? break unless options[:uid].nil? end imap.expunge if options[:delete_after_find] else @@ -114,10 +119,11 @@ def delete_all(mailbox='INBOX') mailbox ||= 'INBOX' mailbox = Net::IMAP.encode_utf7(mailbox) start do |imap| + imap.examine(mailbox) imap.uid_search(['ALL']).each do |uid| imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) end imap.expunge end @@ -152,10 +158,17 @@ # Start an IMAP session and ensures that it will be closed in any case. def start(config=Mail::Configuration.instance, &block) raise ArgumentError.new("Mail::Retrievable#imap_start takes a block") unless block_given? + if settings[:enable_starttls] && settings[:enable_ssl] + raise ArgumentError, ":enable_starttls and :enable_ssl are mutually exclusive. Set :enable_ssl if you're on an IMAPS connection. Set :enable_starttls if you're on an IMAP connection and using STARTTLS for secure TLS upgrade." + end + imap = Net::IMAP.new(settings[:address], settings[:port], settings[:enable_ssl], nil, false) + + imap.starttls if settings[:enable_starttls] + if settings[:authentication].nil? imap.login(settings[:user_name], settings[:password]) else # Note that Net::IMAP#authenticate('LOGIN', ...) is not equal with Net::IMAP#login(...)! # (see also http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/net/imap/rdoc/classes/Net/IMAP.html#M000718)