Skip to content

Instantly share code, notes, and snippets.

@airblade
Created October 27, 2022 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save airblade/aa4c7738089be459db1134f512e548fd to your computer and use it in GitHub Desktop.
Save airblade/aa4c7738089be459db1134f512e548fd to your computer and use it in GitHub Desktop.
Adds IMAP move to Mail
require 'mail'
require 'net/imap'
# Add IMAP move to Mail.
module Mail
# In addition to the options supported by the IMAP class:
#
# move: mailbox to which to move emails. This makes the :delete_after_find flag irrelevant.
#
# https://github.com/mikel/mail/blob/f5801f2a1437a2625c929bf129e995f7ff829a5c/lib/mail/network/retriever_methods/imap.rb
class IMAPWithMove < IMAP
def find(options=nil, &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], 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', 'FLAGS'])[0]
new_message = Mail.new(fetchdata.attr['RFC822'])
new_message.mark_for_delete = true if options[:delete_after_find]
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
if options[:move]
imap.uid_move(uid, options[:move])
else
imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find] && new_message.is_marked_for_delete?
end
break unless options[:uid].nil?
end
imap.expunge if options[:delete_after_find]
else
emails = []
uids.each do |uid|
uid = options[:uid].to_i unless options[:uid].nil?
fetchdata = imap.uid_fetch(uid, ['RFC822'])[0]
emails << Mail.new(fetchdata.attr['RFC822'])
if options[:move]
imap.uid_move(uid, options[:move])
else
imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find]
end
break unless options[:uid].nil?
end
imap.expunge if options[:delete_after_find]
emails.size == 1 && options[:count] == 1 ? emails.first : emails
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment