require 'mime/message'
module Gmail
class Message
# Raised when given label doesn't exists.
class NoLabelError < Exception; end
attr_reader :uid
def initialize(mailbox, uid)
@uid = uid
@mailbox = mailbox
@gmail = mailbox.instance_variable_get("@gmail") if mailbox
end
def uid
@uid ||= @gmail.conn.uid_search(['HEADER', 'Message-ID', message_id])[0]
end
# Mark message with given flag.
def flag(name)
!!@gmail.mailbox(@mailbox.name) { @gmail.conn.uid_store(uid, "+FLAGS", [name]) }
end
# Unmark message.
def unflag(name)
!!@gmail.mailbox(@mailbox.name) { @gmail.conn.uid_store(uid, "-FLAGS", [name]) }
end
# Do commonly used operations on message.
def mark(flag)
case flag
when :read then read!
when :unread then unread!
when :deleted then delete!
when :spam then spam!
else
flag(flag)
end
end
# Mark this message as a spam.
def spam!
move_to('[Gmail]/Spam')
end
# Mark as read.
def read!
flag(:Seen)
end
# Mark as unread.
def unread!
unflag(:Seen)
end
# Mark message with star.
def star!
flag('[Gmail]/Starred')
end
# Remove message from list of starred.
def unstar!
unflag('[Gmail]/Starred')
end
# Move to trash / bin.
def delete!
@mailbox.messages.delete(uid)
flag(:deleted)
# For some, it's called "Trash", for others, it's called "Bin". Support both.
trash = @gmail.labels.exist?('[Gmail]/Bin') ? '[Gmail]/Bin' : '[Gmail]/Trash'
move_to(trash) unless %w[[Gmail]/Spam [Gmail]/Bin [Gmail]/Trash].include?(@mailbox.name)
end
# Archive this message.
def archive!
move_to('[Gmail]/All Mail')
end
# Move to given box and delete from others.
def move_to(name, from=nil)
label(name, from)
delete! if !%w[[Gmail]/Bin [Gmail]/Trash].include?(name)
end
alias :move :move_to
# Move message to given and delete from others. When given mailbox doesn't
# exist then it will be automaticaly created.
def move_to!(name, from=nil)
label!(name, from) && delete!
end
alias :move! :move_to!
# Mark this message with given label. When given label doesn't exist then
# it will raise NoLabelError.
#
# See also Gmail::Message#label!.
def label(name, from=nil)
@gmail.mailbox(Net::IMAP.encode_utf7(from || @mailbox.external_name)) { @gmail.conn.uid_copy(uid, Net::IMAP.encode_utf7(name)) }
rescue Net::IMAP::NoResponseError
raise NoLabelError, "Label '#{name}' doesn't exist!"
end
# Mark this message with given label. When given label doesn't exist then
# it will be automaticaly created.
#
# See also Gmail::Message#label.
def label!(name, from=nil)
label(name, from)
rescue NoLabelError
@gmail.labels.add(Net::IMAP.encode_utf7(name))
label(name, from)
end
alias :add_label :label!
alias :add_label! :label!
# Remove given label from this message.
def remove_label!(name)
move_to('[Gmail]/All Mail', name)
end
alias :delete_label! :remove_label!
def inspect
"#