lib/gmail/message.rb in gmail-0.6.0 vs lib/gmail/message.rb in gmail-0.7.0
- old
+ new
@@ -1,207 +1,212 @@
-module Gmail
- class Message
- PREFETCH_ATTRS = ["UID", "ENVELOPE", "BODY.PEEK[]", "FLAGS", "X-GM-LABELS", "X-GM-MSGID", "X-GM-THRID"]
-
- # Raised when given label doesn't exists.
- class NoLabelError < Exception; end
-
- def initialize(mailbox, uid, _attrs = nil)
- @uid = uid
- @mailbox = mailbox
- @gmail = mailbox.instance_variable_get("@gmail") if mailbox # UGLY
- @_attrs = _attrs
- end
-
- def uid
- @uid ||= fetch("UID")
- end
-
- def msg_id
- @msg_id ||= fetch("X-GM-MSGID")
- end
- alias_method :message_id, :msg_id
-
- def thr_id
- @thr_id ||= fetch("X-GM-THRID")
- end
- alias_method :thread_id, :thr_id
-
- def envelope
- @envelope ||= fetch("ENVELOPE")
- end
-
- def message
- @message ||= Mail.new(fetch("BODY[]"))
- end
- alias_method :raw_message, :message
-
- def flags
- @flags ||= fetch("FLAGS")
- end
-
- def labels
- @labels ||= fetch("X-GM-LABELS")
- end
-
- # Mark message with given flag.
- def flag(name)
- !!@gmail.mailbox(@mailbox.name) do
- @gmail.conn.uid_store(uid, "+FLAGS", [name])
- clear_cached_attributes
- end
- end
-
- # Unmark message.
- def unflag(name)
- !!@gmail.mailbox(@mailbox.name) do
- @gmail.conn.uid_store(uid, "-FLAGS", [name])
- clear_cached_attributes
- end
- 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
-
- # Check whether message is read
- def read?
- flags.include?(:Seen)
- end
-
- # Mark as read.
- def read!
- flag(:Seen)
- end
-
- # Mark as unread.
- def unread!
- unflag(:Seen)
- end
-
- # Check whether message is starred
- def starred?
- flags.include?(:Flagged)
- end
-
- # Mark message with star.
- def star!
- flag(:Flagged)
- end
-
- # Remove message from list of starred.
- def unstar!
- unflag(:Flagged)
- end
-
- # Marking as spam is done by adding the `\Spam` label. To undo this,
- # you just re-apply the `\Inbox` label (see `#unspam!`)
- def spam!
- add_label("\\Spam")
- end
-
- # Deleting is done by adding the `\Trash` label. To undo this,
- # you just re-apply the `\Inbox` label (see `#undelete!`)
- def delete!
- add_label("\\Trash")
- end
-
- # Archiving is done by adding the `\Trash` label. To undo this,
- # you just re-apply the `\Inbox` label (see `#unarchive!`)
- def archive!
- remove_label("\\Inbox")
- end
-
- def unarchive!
- 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
- end
- alias_method :move, :move_to
- alias_method :move!, :move_to
- alias_method :move_to!, :move_to
-
- # Use Gmail IMAP Extensions to add a Label to an email
- def add_label(name)
- @gmail.mailbox(@mailbox.name) do
- @gmail.conn.uid_store(uid, "+X-GM-LABELS", [Net::IMAP.encode_utf7(name.to_s)])
- clear_cached_attributes
- end
- end
- alias_method :label, :add_label
- alias_method :label!, :add_label
- alias_method :add_label!, :add_label
-
- # Use Gmail IMAP Extensions to remove a Label from an email
- def remove_label(name)
- @gmail.mailbox(@mailbox.name) do
- @gmail.conn.uid_store(uid, "-X-GM-LABELS", [Net::IMAP.encode_utf7(name.to_s)])
- clear_cached_attributes
- end
- end
- alias_method :remove_label!, :remove_label
-
- def inspect
- "#<Gmail::Message#{'0x%04x' % (object_id << 1)} mailbox=#{@mailbox.name}#{' uid=' + @uid.to_s if @uid}#{' message_id=' + @msg_id.to_s if @msg_id}>"
- end
-
- def method_missing(meth, *args, &block)
- # Delegate rest directly to the message.
- if envelope.respond_to?(meth)
- envelope.send(meth, *args, &block)
- elsif message.respond_to?(meth)
- message.send(meth, *args, &block)
- else
- super(meth, *args, &block)
- end
- end
-
- def respond_to?(meth, *args, &block)
- if envelope.respond_to?(meth)
- return true
- elsif message.respond_to?(meth)
- return true
- else
- super(meth, *args, &block)
- end
- end
-
- private
-
- def clear_cached_attributes
- @_attrs = nil
- @msg_id = nil
- @thr_id = nil
- @envelope = nil
- @message = nil
- @flags = nil
- @labels = nil
- end
-
- def fetch(value)
- @_attrs ||= begin
- @gmail.mailbox(@mailbox.name) do
- @gmail.conn.uid_fetch(uid, PREFETCH_ATTRS)[0]
- end
- end
- @_attrs.attr[value]
- end
- end # Message
-end # Gmail
+module Gmail
+ class Message
+ PREFETCH_ATTRS = ["UID", "ENVELOPE", "BODY.PEEK[]", "FLAGS", "X-GM-LABELS", "X-GM-MSGID", "X-GM-THRID"].freeze
+
+ # Raised when given label doesn't exists.
+ class NoLabelError < RuntimeError; end
+
+ def initialize(mailbox, uid, _attrs = nil)
+ @uid = uid
+ @mailbox = mailbox
+ @gmail = mailbox.instance_variable_get("@gmail") if mailbox # UGLY
+ @_attrs = _attrs
+ end
+
+ def uid
+ @uid ||= fetch("UID")
+ end
+
+ def msg_id
+ @msg_id ||= fetch("X-GM-MSGID")
+ end
+ alias_method :message_id, :msg_id
+
+ def thr_id
+ @thr_id ||= fetch("X-GM-THRID")
+ end
+ alias_method :thread_id, :thr_id
+
+ def envelope
+ @envelope ||= fetch("ENVELOPE")
+ end
+
+ def message
+ @message ||= Mail.new(fetch("BODY[]"))
+ end
+ alias_method :raw_message, :message
+
+ def flags
+ @flags ||= fetch("FLAGS")
+ end
+
+ def labels
+ @labels ||= fetch("X-GM-LABELS")
+ end
+
+ # Mark message with given flag.
+ def flag(name)
+ !!@gmail.mailbox(@mailbox.name) do
+ @gmail.conn.uid_store(uid, "+FLAGS", [name])
+ clear_cached_attributes
+ end
+ end
+
+ # Unmark message.
+ def unflag(name)
+ !!@gmail.mailbox(@mailbox.name) do
+ @gmail.conn.uid_store(uid, "-FLAGS", [name])
+ clear_cached_attributes
+ end
+ 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
+
+ # Check whether message is read
+ def read?
+ flags.include?(:Seen)
+ end
+
+ # Mark as read.
+ def read!
+ flag(:Seen)
+ end
+
+ # Mark as unread.
+ def unread!
+ unflag(:Seen)
+ end
+
+ # Check whether message is starred
+ def starred?
+ flags.include?(:Flagged)
+ end
+
+ # Mark message with star.
+ def star!
+ flag(:Flagged)
+ end
+
+ # Remove message from list of starred.
+ def unstar!
+ unflag(:Flagged)
+ end
+
+ # Marking as spam is done by adding the `\Spam` label. To undo this,
+ # you just re-apply the `\Inbox` label (see `#unspam!`)
+ def spam!
+ add_label("\\Spam")
+ end
+
+ # Deleting is done by adding the `\Trash` label. To undo this,
+ # you just re-apply the `\Inbox` label (see `#undelete!`)
+ def delete!
+ add_label("\\Trash")
+ end
+
+ # 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!
+ @gmail.find(message.message_id).remove_label('\Inbox')
+ end
+
+ def unarchive!
+ @gmail.find(message.message_id).add_label('\Inbox')
+ end
+ alias_method :unspam!, :unarchive!
+ alias_method :undelete!, :unarchive!
+
+ def move_to(name, from = nil)
+ add_label(name)
+ @gmail.find(message.message_id).remove_label(from) if from
+ end
+ alias_method :move, :move_to
+ alias_method :move!, :move_to
+ alias_method :move_to!, :move_to
+
+ # Use Gmail IMAP Extensions to add a Label to an email
+ def add_label(name)
+ @gmail.mailbox(@mailbox.name) do
+ @gmail.conn.uid_store(uid, "+X-GM-LABELS", [Net::IMAP.encode_utf7(name.to_s)])
+ clear_cached_attributes
+ end
+ end
+ alias_method :label, :add_label
+ alias_method :label!, :add_label
+ alias_method :add_label!, :add_label
+
+ # Use Gmail IMAP Extensions to remove a Label from an email
+ def remove_label(name)
+ @gmail.mailbox(@mailbox.name) do
+ @gmail.conn.uid_store(uid, "-X-GM-LABELS", [Net::IMAP.encode_utf7(name.to_s)])
+ clear_cached_attributes
+ end
+ end
+ alias_method :remove_label!, :remove_label
+
+ def inspect
+ "#<Gmail::Message#{'0x%04x' % (object_id << 1)} mailbox=#{@mailbox.name}#{' uid=' + @uid.to_s if @uid}#{' message_id=' + @msg_id.to_s if @msg_id}>"
+ end
+
+ def as_json
+ super(except: ["gmail"])
+ end
+
+ def method_missing(meth, *args, &block)
+ # Delegate rest directly to the message.
+ if envelope.respond_to?(meth)
+ envelope.send(meth, *args, &block)
+ elsif message.respond_to?(meth)
+ message.send(meth, *args, &block)
+ else
+ super
+ end
+ end
+
+ def respond_to?(meth, *args, &block)
+ return true if envelope.respond_to?(meth) || message.respond_to?(meth)
+ super(meth, *args, &block)
+ end
+
+ def respond_to_missing?(meth, include_private = false)
+ envelope.respond_to?(meth) || message.respond_to?(meth) || super
+ end
+
+ private
+
+ def clear_cached_attributes
+ @_attrs = nil
+ @msg_id = nil
+ @thr_id = nil
+ @envelope = nil
+ @message = nil
+ @flags = nil
+ @labels = nil
+ end
+
+ def fetch(value)
+ @_attrs ||= begin
+ @gmail.mailbox(@mailbox.name) do
+ @gmail.conn.uid_fetch(uid, PREFETCH_ATTRS)[0]
+ end
+ end
+ @_attrs.attr[value]
+ end
+ end # Message
+end # Gmail