Skip to content

Commit

Permalink
Faster archiving methods (#234)
Browse files Browse the repository at this point in the history
mailbox('[Gmail]/All Mail') can be deadly slow when you have full of emails.
This will fix that by
- create a temp folder (label)
- put the target email in it
- archive it or unarchive it
- delete the temp folder
  • Loading branch information
github0013 authored and johnnyshields committed Jul 16, 2018
1 parent 0c445c3 commit bdd5983
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
2 changes: 2 additions & 0 deletions lib/gmail/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class AuthorizationError < Net::IMAP::NoResponseError; end
class DeliveryError < ArgumentError; end
# Raised when given client is not registered
class UnknownClient < ArgumentError; end
# Raised when email not found
class EmailNotFound < ArgumentError; end

def self.clients
@clients ||= {}
Expand Down
17 changes: 17 additions & 0 deletions lib/gmail/client/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,23 @@ def inbox
mailbox("INBOX")
end

# Functionality like rails #find method
# https://support.google.com/mail/answer/7190?hl=en
# Messages with a certain message-id header
# Rfc822msgid:
# Example: rfc822msgid:200503292@example.com
def find(rfc822msgid)
message = :message_before_built

mailbox(:all) do |mailbox|
uid = conn.uid_search(['X-GM-RAW', "rfc822msgid:#{rfc822msgid.to_s.strip}"]).first
raise EmailNotFound, "Can't find message with ID #{rfc822msgid}" unless uid
message = Message.new(mailbox, uid)
end

message
end

def mailboxes
@mailboxes ||= {}
end
Expand Down
18 changes: 10 additions & 8 deletions lib/gmail/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,26 @@ def delete!

# Archiving is done by adding the `\All Mail` label. To undo this,
# you just re-apply the `\Inbox` label (see `#unarchive!`)
#
# IMAP's fetch('1:100', (X-GM-LABELS)) function does not fetch inbox, just emails labeled important?
# http://stackoverflow.com/a/28973760
# In my testing the currently selected mailbox is always excluded from the X-GM-LABELS results.
# When you called conn.select() it implicitly selected 'INBOX', therefore excluding 'Inbox'
# from the list of labels.
# If you selected a different mailbox then you would see '\\\\Inbox' in your results:
def archive!
remove_label("\\Inbox")
@gmail.find(message.message_id).remove_label('\Inbox')
end

def unarchive!
add_label("\\Inbox")
@gmail.find(message.message_id).add_label('\Inbox')
end
alias_method :unspam!, :unarchive!
alias_method :undelete!, :unarchive!

# Move to given box and delete from others.
# Apply a given label and optionally remove one.
# TODO: We should probably deprecate this method. It doesn't really add a lot
# of value, especially since the concept of "moving" a message from one
# label to another doesn't totally make sense in the Gmail world.
def move_to(name, from = nil)
add_label(name)
remove_label(from) if from
@gmail.find(message.message_id).remove_label(from) if from
end
alias_method :move, :move_to
alias_method :move!, :move_to
Expand Down

0 comments on commit bdd5983

Please sign in to comment.