Class: Gmail::Mailbox

Inherits:
Object
  • Object
show all
Defined in:
lib/gmail/mailbox.rb

Constant Summary collapse

MAILBOX_ALIASES =
{
  :all       => ['ALL'],
  :seen      => ['SEEN'],
  :unseen    => ['UNSEEN'],
  :read      => ['SEEN'],
  :unread    => ['UNSEEN'],
  :flagged   => ['FLAGGED'],
  :unflagged => ['UNFLAGGED'],
  :starred   => ['FLAGGED'],
  :unstarred => ['UNFLAGGED'],
  :deleted   => ['DELETED'],
  :undeleted => ['UNDELETED'],
  :draft     => ['DRAFT'],
  :undrafted => ['UNDRAFT']
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(gmail, name = "INBOX") ⇒ Mailbox

Returns a new instance of Mailbox.



22
23
24
25
26
# File 'lib/gmail/mailbox.rb', line 22

def initialize(gmail, name = "INBOX")
  @name = Net::IMAP.decode_utf7(name)
  @encoded_name = Net::IMAP.encode_utf7(name)
  @gmail = gmail
end

Instance Attribute Details

#encoded_nameObject (readonly)

Returns the value of attribute encoded_name.



20
21
22
# File 'lib/gmail/mailbox.rb', line 20

def encoded_name
  @encoded_name
end

#nameObject (readonly)

Returns the value of attribute name.



19
20
21
# File 'lib/gmail/mailbox.rb', line 19

def name
  @name
end

Instance Method Details

#count(*args) ⇒ Object

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.

Examples

gmail.inbox.count(:all)
gmail.inbox.count(:unread, :from => "[email protected]")
gmail.mailbox("Test").count(:all, :after => Time.now-(20*24*3600))


105
106
107
# File 'lib/gmail/mailbox.rb', line 105

def count(*args)
  emails(*args).size
end

#emails(*args, &block) ⇒ Object Also known as: search, find

Returns list of emails which meets given criteria.

Examples

gmail.inbox.emails(:all)
gmail.inbox.emails(:unread, :from => "[email protected]")
gmail.inbox.emails(:all, :after => Time.now-(20*24*3600))
gmail.mailbox("Test").emails(:read)

gmail.mailbox("Test") do |box|
  box.emails(:read)
  box.emails(:unread) do |email|
    ... do something with each email...
  end
end


75
76
77
78
79
80
81
# File 'lib/gmail/mailbox.rb', line 75

def emails(*args, &block)
  fetch_uids(*args).collect do |uid|
    message = Message.new(self, uid)
    yield(message) if block_given?
    message
  end
end

#emails_in_batches(*args, &block) ⇒ Object Also known as: search_in_batches, find_in_batches



85
86
87
88
89
90
91
# File 'lib/gmail/mailbox.rb', line 85

def emails_in_batches(*args, &block)
  return [] unless uids.is_a?(Array) && uids.any?

  uids.each_slice(100).flat_map do |slice|
    find_for_slice(slice, &block)
  end
end

#expungeObject

This permanently removes messages which are marked as deleted



110
111
112
# File 'lib/gmail/mailbox.rb', line 110

def expunge
  @gmail.mailbox(name) { @gmail.conn.expunge }
end

#fetch_uids(*args) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/gmail/mailbox.rb', line 28

def fetch_uids(*args)
  args << :all if args.empty?

  if args.first.is_a?(Symbol)
    search = MAILBOX_ALIASES[args.shift].dup
    opts = args.first.is_a?(Hash) ? args.first : {}

    opts[:after]      and search.concat ['SINCE', Net::IMAP.format_date(opts[:after])]
    opts[:before]     and search.concat ['BEFORE', Net::IMAP.format_date(opts[:before])]
    opts[:on]         and search.concat ['ON', Net::IMAP.format_date(opts[:on])]
    opts[:from]       and search.concat ['FROM', opts[:from]]
    opts[:to]         and search.concat ['TO', opts[:to]]
    opts[:subject]    and search.concat ['SUBJECT', opts[:subject]]
    opts[:label]      and search.concat ['LABEL', opts[:label]]
    opts[:attachment] and search.concat ['HAS', 'attachment']
    opts[:search]     and search.concat ['BODY', opts[:search]]
    opts[:body]       and search.concat ['BODY', opts[:body]]
    opts[:uid]        and search.concat ['UID', opts[:uid]]
    opts[:gm]         and search.concat ['X-GM-RAW', opts[:gm]]
    opts[:message_id] and search.concat ['X-GM-MSGID', opts[:message_id].to_s]
    opts[:query]      and search.concat opts[:query]

    @gmail.mailbox(name) do
      @gmail.conn.uid_search(search)
    end
  elsif args.first.is_a?(Hash)
    fetch_uids(:all, args.first)
  else
    raise ArgumentError, "Invalid search criteria"
  end
end

#inspectObject



154
155
156
# File 'lib/gmail/mailbox.rb', line 154

def inspect
  "#<Gmail::Mailbox#{'0x%04x' % (object_id << 1)} name=#{name}>"
end

#to_sObject



158
159
160
# File 'lib/gmail/mailbox.rb', line 158

def to_s
  name
end

#wait(options = {}, &block) ⇒ Object



114
115
116
117
118
# File 'lib/gmail/mailbox.rb', line 114

def wait(options = {}, &block)
  loop do
    wait_once(options, &block)
  end
end

#wait_once(options = {}) {|response| ... } ⇒ Object

Yields:

  • (response)


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/gmail/mailbox.rb', line 120

def wait_once(options = {})
  options[:idle_timeout] ||= 29 * 60

  response = nil
  loop do
    complete_cond = @gmail.conn.new_cond
    complete_now = false

    @gmail.conn.idle do |resp|
      if resp.is_a?(Net::IMAP::ContinuationRequest) && resp.data.text == 'idling'
        Thread.new do
          @gmail.conn.synchronize do
            complete_cond.wait(options[:idle_timeout]) unless complete_now
            @gmail.conn.idle_done
          end
        end
      elsif resp.is_a?(Net::IMAP::UntaggedResponse) && resp.name == 'EXISTS'
        response = resp

        @gmail.conn.synchronize do
          complete_now = true
          complete_cond.signal
        end
      end
    end

    break if response
  end

  yield response if block_given?

  nil
end