ruby-gmailにて、ある1日のメールを絞り込んで取得するには、
:ONに当該日付を設定する。
:BEFOREや:AFTERに設定してはいけない。
:BEFOREと:AFTERに同一の日付を設定すると、絞り込みが行われなくなる。
厄介な仕様だ(´・д・`)
使い勝手が悪いので、コードを変更。
以下のような処理を挿入。
lib/gmail/mailbox.rb
if opts[:after] === opts[:before]
opts[:on] = opts[:before]
opts[:after] = nil
opts[:before] = nil
end
ダメモトで本家にも、つたない英語で'Pull Request'投げてみたら、通った!!
やってみるもんだ。
次回のバージョンからは反映させるだろう。
なお、コードの全貌は以下。
lib/gmail/mailbox.rb
require 'date'
require 'time'
class Object
def to_imap_date
Date.parse(to_s).strftime("%d-%B-%Y")
end
end
class Gmail
class Mailbox
attr_reader :name
def initialize(gmail, name)
@gmail = gmail
@name = name
end
def inspect
"<#Mailbox name=#{@name}>"
end
def to_s
name
end
# Method: emails
# Args: [ :all | :unread | :read ]
# Opts: {:since => Date.new}
def emails(key_or_opts = :all, opts={})
if key_or_opts.is_a?(Hash) && opts.empty?
search = ['ALL']
opts = key_or_opts
elsif key_or_opts.is_a?(Symbol) && opts.is_a?(Hash)
aliases = {
:all => ['ALL'],
:unread => ['UNSEEN'],
:read => ['SEEN']
}
search = aliases[key_or_opts]
elsif key_or_opts.is_a?(Array) && opts.empty?
search = key_or_opts
else
raise ArgumentError, "Couldn't make sense of arguments to #emails - should be an optional hash of options preceded by an optional read-status bit; OR simply an array of parameters to pass directly to the IMAP uid_search call."
end
if !opts.empty?
if opts[:after] === opts[:before]
opts[:on] = opts[:before]
opts[:after] = nil
opts[:before] = nil
end
# Support for several search macros
# :before => Date, :on => Date, :since => Date, :from => String, :to => String
search.concat ['SINCE', opts[:after].to_imap_date] if opts[:after]
search.concat ['BEFORE', opts[:before].to_imap_date] if opts[:before]
search.concat ['ON', opts[:on].to_imap_date] if opts[:on]
search.concat ['FROM', opts[:from]] if opts[:from]
search.concat ['TO', opts[:to]] if opts[:to]
search.concat ['SUBJECT', opts[:subject]] if opts[:subject]
# Gmail offers us to search the same way we do on the web interface
# https://developers.google.com/gmail/imap_extensions
# example: gmail.emails(gm: 'has:attachment in:unread "who is john galt"')
#
search.concat ['X-GM-RAW', opts[:gm]] if opts[:gm]
end
# puts "Gathering #{(aliases[key] || key).inspect} messages for mailbox '#{name}'..."
@gmail.in_mailbox(self) do
@gmail.imap.uid_search(search).collect { |uid| messages[uid] ||= Message.new(@gmail, self, uid) }
end
end
# This is a convenience method that really probably shouldn't need to exist, but it does make code more readable
# if seriously all you want is the count of messages.
def count(*args)
emails(*args).length
end
def messages
@messages ||= {}
end
end
end