Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'geoffyoungs-master' into adimircolen-master

  • Loading branch information...
commit 0dc36128015128548ed8dd6510dfa930864395ab 2 parents 5ca0d69 + 0950d55
@adimircolen adimircolen authored
Showing with 89 additions and 11 deletions.
  1. +5 −5 lib/gmail.rb
  2. +63 −2 lib/gmail/mailbox.rb
  3. +21 −4 lib/gmail/message.rb
View
10 lib/gmail.rb
@@ -88,17 +88,17 @@ def @imap.xlist(refname, mailbox)
@xlist_result ||= @imap.xlist('', '*')
end
- def self.special_labels
+ def self.gmail_label_types
[:Inbox, :Allmail, :Spam, :Trash, :Drafts, :Important, :Starred, :Sent]
end
- def special_labels
- self.class.special_labels
+ def gmail_label_types
+ self.class.gmail_label_types
end
def normal_labels
imap_xlist.reject { |label|
- label.attr.include?(:Noselect) or label.attr.any? { |flag| special_labels.include?(flag) }
+ label.attr.include?(:Noselect) or label.attr.any? { |flag| gmail_label_types.include?(flag) }
}.map { |label|
label.name
}
@@ -114,7 +114,7 @@ def label_of_type(type)
info && info.name || nil
end
- special_labels.each do |label|
+ gmail_label_types.each do |label|
module_eval <<-EOL
def #{label.to_s.downcase} &block
in_label(#{label.to_s.downcase}_label, &block)
View
65 lib/gmail/mailbox.rb
@@ -126,18 +126,79 @@ def emails(key_or_opts = :all, opts={})
@gmail.in_mailbox(self) do
uids = @gmail.imap.uid_search(search)
list = uids.collect { |uid| messages[uid] ||= Message.new(@gmail, self, uid) }
+
if fetch
missing = list.reject { |message| message.loaded? }.map { |message| message.uid }
- @gmail.imap.uid_fetch(missing, 'RFC822').each do |info|
+ @gmail.imap.uid_fetch(missing, ['ENVELOPE', 'RFC822']).each do |info|
message = messages[info.attr['UID']]
+ message.envelope = info.attr['ENVELOPE']
message.set_body(info.attr['RFC822'])
end
+ else
+ missing = list.reject { |message| message.message_id? }.map { |message| message.uid }
+ @gmail.imap.uid_fetch(missing, ['ENVELOPE']).each do |info|
+ message = messages[info.attr['UID']]
+ message.envelope = info.attr['ENVELOPE']
+ message.message_id = info.attr['ENVELOPE'].message_id
+ end
end
end
- list
+ MessageList.new(@gmail, list)
end
+ class MessageList
+ include Enumerable
+ attr_reader :list
+ def initialize(gmail, list)
+ @gmail = gmail
+ @list = list
+ end
+ def size
+ @list.size
+ end
+ def each(&block)
+ @list.each(&block)
+ end
+ def with_label(label)
+ label = label.is_a?(String) ? @gmail.label(label) : label
+ @gmail.in_label(label) do |mbox|
+
+ # Search for message ids in named folder
+ search = []
+ @list.each_with_index do |m, index|
+ search.unshift "OR" unless index.zero?#.empty?
+ search << "HEADER" << "Message-ID" << m.message_id
+ end
+ uids = @gmail.imap.uid_search(search)
+
+ # Fetch envelopes for uids
+ message_ids = []
+
+ missing_uids = uids.collect { |uid|
+ mbox.messages[uid] ||= Message.new(@gmail, mbox, uid)
+ }.reject { |message|
+ if message.loaded? or message.message_id?
+ message_ids << message.message_id
+ true
+ else
+ false
+ end
+ }.map { |message|
+ message.uid
+ }
+
+ message_ids += @gmail.imap.uid_fetch(missing_uids, ['ENVELOPE']).map do |info|
+ message = mbox.messages[info.attr['UID']]
+ message.envelope ||= info.attr['ENVELOPE']
+ info.attr['ENVELOPE'].message_id
+ end
+
+ MessageList.new(@gmail, @list.select { |m| message_ids.include?(m.message_id) })
+ end
+ 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)
View
25 lib/gmail/message.rb
@@ -28,8 +28,25 @@ def unflag(flg)
end ? true : false
end
+ attr_writer :message_id
+ attr_writer :envelope
+ def message_id?
+ !! (@envelope || @message_id || @message)
+ end
def message_id
- @message_id ||= self.header['Message-ID'].value
+ @message_id ||= @envelope ? @envelope.message_id : self.header['Message-ID'].value
+ end
+ def envelope
+ @envelope ||= @gmail.in_mailbox(@mailbox) { @gmail.imap.uid_fetch(uid, "ENVELOPE")[0].attr["ENVELOPE"] }
+ end
+ def subject
+ @envelope ? @envelope.subject : self.header['Subject'].value
+ end
+ def from
+ @envelope ? @envelope.from : self.header['From'].value
+ end
+ def to
+ @envelope ? @envelope.to : self.header['To'].value
end
def has_label?(label)
@@ -111,8 +128,6 @@ def label!(name)
end
end
- # We're not sure of any 'labels' except the 'mailbox' we're in at the moment.
- # Research whether we can find flags that tell which other labels this email is a part of.
def remove_label(label)
return false if label.downcase == @gmail.allmail_label.downcase
@@ -132,8 +147,10 @@ def move_to(name)
label(name) && delete!
end
+ # Archive, in the gmail sense, means remove label Inbox,
+ # rather than simply remove current label
def archive!
- move_to(@gmail.allmail_label)
+ remove_label(@gmail.inbox_label)
end
def save_attachments_to(path=nil)
Please sign in to comment.
Something went wrong with that request. Please try again.