Browse files

prefetch uids for a selected mailbox

  • Loading branch information...
1 parent 3041b38 commit 7f847bbe27f42d2a3c8701be5cdad80bc655e22c @chrisduesing committed Feb 21, 2012
Showing with 39 additions and 30 deletions.
  1. +0 −3 lib/gmail/gmail_base.rb
  2. +20 −10 lib/gmail/mailbox.rb
  3. +19 −17 lib/gmail/message.rb
View
3 lib/gmail/gmail_base.rb
@@ -96,7 +96,6 @@ def in_mailbox(mailbox, &block)
unless @selected == mailbox.name
imap.select(mailbox.name)
@selected = mailbox.name
- @uid_next = imap.status(mailbox.name, ["UIDNEXT"])["UIDNEXT"]
end
value = block.arity == 1 ? block.call(mailbox) : block.call
mailbox_stack.pop
@@ -112,8 +111,6 @@ def in_mailbox(mailbox, &block)
end
alias :in_label :in_mailbox
- attr_accessor :uid_next
-
###########################
# Other...
###########################
View
30 lib/gmail/mailbox.rb
@@ -9,10 +9,13 @@ def to_imap_date
module GmailBase
class Mailbox
attr_reader :name
+ attr_accessor :uid_next
def initialize(gmail, name)
@gmail = gmail
@name = name
+ @uid_next = imap.status(mailbox.name, ["UIDNEXT"])["UIDNEXT"]
+ prefetch
end
def inspect
@@ -23,19 +26,13 @@ def to_s
name
end
- def all
- @gmail.imap.fetch('1:100 FULL').collect do |response| # #{@gmail.uid_next}
- uid = response.attr['UID']
- body = response.attr['BODY']
- messages[uid] ||= Message.new(@gmail, self, uid, body)
- end
- end
-
- def uid_search(key_or_opts = :all, opts={})
+ def search(key_or_opts = :all, opts={})
@gmail.imap.uid_search(search(key_or_opts, opts)).collect { |uid| messages[uid] ||= Message.new(@gmail, self, uid) }
end
- alias :emails :uid_search
+ def emails
+ messages.values
+ end
# Method: emails
# Args: [ :all | :unread | :read ]
@@ -82,5 +79,18 @@ def count(*args)
def messages
@messages ||= {}
end
+
+private
+
+ def prefetch
+ # {@gmail.uid_next}
+ @gmail.imap.fetch('1:100 (body[header.fields (subject)])').collect do |response|
+ uid = response.attr['UID']
+ subject = response.attr['SUBJECT']
+ messages[uid] ||= Message.new(@gmail, self, uid, subject)
+ end
+
+ end
+
end
end
View
36 lib/gmail/message.rb
@@ -1,12 +1,11 @@
module GmailBase
class Message
- def initialize(gmail, mailbox, uid, body=nil)
+
+ def initialize(gmail, mailbox, uid, subject=nil)
@gmail = gmail
@mailbox = mailbox
@uid = uid
- if body
- @message = Mail.new(body)
- end
+ @subject = subject
end
def inspect
@@ -85,30 +84,33 @@ def archive!
move_to('[Gmail]/All Mail')
end
+ # a new message only has a uid, so when listing an inbox full of subjects we don't want to have to download the full headers/body.
+ # this lightens traffic size and serves as a caching mechanism for subjects
def subject
- require 'mail'
- if !@message
- request= '(body[header.fields (subject)])'
- _body = @gmail.in_mailbox(@mailbox) { @gmail.imap.fetch(@uid, request)[0].attr[request] }
- @message = Mail.new(_body)
- elsif !@message.subject
+ if !@subject && !@message && !@message.subject
+ require 'mail'
request= '(body[header.fields (subject)])'
_body = @gmail.in_mailbox(@mailbox) { @gmail.imap.fetch(@uid, request)[0].attr[request] }
tmp = Mail.new(_body)
- @message.subject = tmp.subject
+ @subject = tmp.subject
+ elsif !@subject && @message && @message.subject
+ @subject = @message.subject
end
- @message.subject
+ @subject
end
private
# Parsed MIME message object
def message
- require 'mail'
- request,part = 'RFC822','RFC822'
- request,part = 'BODY.PEEK[]','BODY[]' if @gmail.peek
- _body = @gmail.in_mailbox(@mailbox) { @gmail.imap.uid_fetch(uid, request)[0].attr[part] }
- @message ||= Mail.new(_body)
+ if !@message
+ require 'mail'
+ request,part = 'RFC822','RFC822'
+ request,part = 'BODY.PEEK[]','BODY[]' if @gmail.peek
+ _body = @gmail.in_mailbox(@mailbox) { @gmail.imap.uid_fetch(uid, request)[0].attr[part] }
+ @message = Mail.new(_body)
+ end
+ @message
end
# Delegate all other methods to the Mail message

0 comments on commit 7f847bb

Please sign in to comment.