class ImapGuard::Guard

Guard allows you to process your mailboxes.

Constants

OPTIONAL_SETTINGS

List of optional settings

REQUIRED_SETTINGS

List of required settings

Attributes

debug[RW]

@return [Proc, nil] Matched emails are passed to this debug lambda if present

mailbox[R]

@return [String, nil] Currently selected mailbox

settings[R]

@note The settings are frozen @return [OpenStruct] ImapGuard settings

Public Class Methods

new(settings) click to toggle source
# File lib/imap_guard/guard.rb, line 30
def initialize(settings)
  self.settings = settings
end

Public Instance Methods

close() click to toggle source

Sends a CLOSE command to close the currently selected mailbox. The CLOSE command permanently removes from the mailbox all messages that have the Deleted flag set. @return [void]

# File lib/imap_guard/guard.rb, line 117
def close
  @imap.close unless @settings.read_only
end
delete(query, &filter) click to toggle source

Deletes messages matching the query and filter block @param query IMAP query @param filter Optional filter block @return [void]

# File lib/imap_guard/guard.rb, line 75
def delete(query, &filter)
  operation = lambda do |message_id|
    @imap.store(message_id, "+FLAGS", [Net::IMAP::DELETED]) unless @settings.read_only

    "deleted".red
  end
  process query, operation, &filter
end
disconnect() click to toggle source

Disconnects from the server. @return [void]

# File lib/imap_guard/guard.rb, line 123
def disconnect
  @imap.disconnect
end
each(query) { |message_id| ... } click to toggle source

Runs operation on messages matching the query @param query IMAP query @param opration Lambda to call on each message @return [void]

# File lib/imap_guard/guard.rb, line 88
def each(query)
  operation = ->(message_id) { yield message_id }
  process query, operation
end
expunge() click to toggle source

Sends a EXPUNGE command to permanently remove from the currently selected mailbox all messages that have the Deleted flag set. @return [void]

# File lib/imap_guard/guard.rb, line 109
def expunge
  @imap.expunge unless @settings.read_only
end
fetch_mail(message_id) click to toggle source

Fetches a message from its UID @return [Mail] @note We use “BODY.PEEK[]” to avoid setting the Seen flag.

# File lib/imap_guard/guard.rb, line 96
def fetch_mail(message_id)
  msg = @imap.fetch(message_id, "BODY.PEEK[]").first.attr["BODY[]"]
  Mail.read_from_string msg
end
list() click to toggle source

@return [Array<String>] Sorted list of all mailboxes

# File lib/imap_guard/guard.rb, line 102
def list
  @imap.list("", "*").map(&:name).sort
end
login() click to toggle source

Authenticates to the given IMAP server @see www.ruby-doc.org/stdlib-1.9.3/libdoc/net/imap/rdoc/Net/IMAP.html#method-c-new @return [void]

# File lib/imap_guard/guard.rb, line 37
def login
  @imap = Net::IMAP.new(@settings.host, @settings.port, true, nil, false)
  @imap.login(@settings.username, @settings.password)
  verbose.puts "Logged in successfully"
end
move(query, mailbox, &filter) click to toggle source

Moves messages matching the query and filter block @param query IMAP query @param mailbox Destination mailbox @param filter Optional filter block @return [void]

# File lib/imap_guard/guard.rb, line 59
def move(query, mailbox, &filter)
  operation = lambda do |message_id|
    unless @settings.read_only
      @imap.copy(message_id, mailbox)
      @imap.store(message_id, "+FLAGS", [Net::IMAP::DELETED])
    end

    "moved to #{mailbox}".yellow
  end
  process query, operation, &filter
end
select(mailbox) click to toggle source

Selects a mailbox (folder) @return [void]

# File lib/imap_guard/guard.rb, line 45
def select(mailbox)
  if @settings.read_only
    @imap.examine(mailbox) # open in read-only
  else
    @imap.select(mailbox) # open in read-write
  end
  @mailbox = mailbox
end

Private Instance Methods

method_missing(*) click to toggle source
# File lib/imap_guard/guard.rb, line 169
def method_missing(*); nil end
process(query, operation) { |mail| ... } click to toggle source
# File lib/imap_guard/guard.rb, line 129
def process(query, operation)
  message_ids = search query
  count = message_ids.size

  message_ids.each_with_index do |message_id, index|
    print "Processing UID #{message_id} (#{index.succ}/#{count}): "

    result = true
    if block_given? || debug
      mail = fetch_mail message_id

      debug.call(mail) if debug

      if block_given?
        result = yield(mail)
        verbose.print "(given filter result: #{result.inspect}) "
      end
    end

    puts result ? operation.call(message_id) : "ignored".green
  end
ensure
  expunge
end
settings=(settings) click to toggle source
# File lib/imap_guard/guard.rb, line 174
def settings=(settings)
  missing = REQUIRED_SETTINGS - settings.keys
  raise ArgumentError, "Missing settings: #{missing}" unless missing.empty?

  unknown = settings.keys - REQUIRED_SETTINGS - OPTIONAL_SETTINGS
  raise ArgumentError, "Unknown settings: #{unknown}" unless unknown.empty?

  @settings = OpenStruct.new(settings).freeze
  puts "DRY-RUN MODE ENABLED".yellow.bold.negative if @settings.read_only
end
verbose() click to toggle source
# File lib/imap_guard/guard.rb, line 163
def verbose
  @verbose ||= if @settings.verbose
                 $stdout
               else
                 # anonymous null object
                 # rubocop:disable all
                 Class.new do def method_missing(*); nil end end.new
                 # rubocop:enable all
               end
end