gmail 0.3.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +6 -0
- data/README.md +3 -0
- data/TODO.md +2 -1
- data/gmail.gemspec +5 -4
- data/lib/gmail.rb +46 -11
- data/lib/gmail/client.rb +9 -208
- data/lib/gmail/client/base.rb +220 -0
- data/lib/gmail/client/plain.rb +18 -0
- data/lib/gmail/client/xoauth.rb +49 -0
- data/lib/gmail/labels.rb +4 -4
- data/lib/gmail/mailbox.rb +7 -3
- data/lib/gmail/message.rb +27 -13
- data/lib/gmail/version.rb +2 -2
- data/spec/client_spec.rb +6 -6
- data/spec/gmail_spec.rb +2 -2
- data/spec/mailbox_spec.rb +11 -0
- metadata +33 -7
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -14,6 +14,9 @@ API, is well tested, better documented and have many other improvements. | |
| 14 14 |  | 
| 15 15 | 
             
            Extra thanks for specific feature contributions from:
         | 
| 16 16 |  | 
| 17 | 
            +
            * [Nicolas Fouché](http://github.com/nfo)
         | 
| 18 | 
            +
            * [Stefano Bernardi](http://github.com/stefanobernardi)
         | 
| 19 | 
            +
            * [Benjamin Bock](http://github.com/bb)
         | 
| 17 20 | 
             
            * [Arthur Chiu](http://github.com/achiu)
         | 
| 18 21 | 
             
            * [Justin Perkins](http://github.com/justinperkins)
         | 
| 19 22 | 
             
            * [Mikkel Malmberg](http://github.com/mikker)
         | 
    
        data/TODO.md
    CHANGED
    
    
    
        data/gmail.gemspec
    CHANGED
    
    | @@ -15,8 +15,9 @@ Gem::Specification.new do |s| | |
| 15 15 | 
             
              s.require_paths    = %w[lib]
         | 
| 16 16 | 
             
              s.extra_rdoc_files = %w[LICENSE README.md CHANGELOG.md TODO.md]
         | 
| 17 17 |  | 
| 18 | 
            -
              s.add_runtime_dependency     'mime', | 
| 19 | 
            -
              s.add_runtime_dependency     'mail', | 
| 20 | 
            -
              s. | 
| 21 | 
            -
              s.add_development_dependency ' | 
| 18 | 
            +
              s.add_runtime_dependency     'mime', '>= 0.1'
         | 
| 19 | 
            +
              s.add_runtime_dependency     'mail', '>= 2.2.1'
         | 
| 20 | 
            +
              s.add_runtime_dependency     'gmail_xoauth', '>= 0.3.0'
         | 
| 21 | 
            +
              s.add_development_dependency 'rspec', '~> 2.0'
         | 
| 22 | 
            +
              s.add_development_dependency 'mocha', '>= 0.9'
         | 
| 22 23 | 
             
            end
         | 
    
        data/lib/gmail.rb
    CHANGED
    
    | @@ -22,26 +22,61 @@ module Gmail | |
| 22 22 | 
             
              autoload :Message, "gmail/message"
         | 
| 23 23 |  | 
| 24 24 | 
             
              class << self
         | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 25 | 
            +
             | 
| 26 | 
            +
                # Creates new Gmail connection using given authorization options.
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                # ==== Examples
         | 
| 29 | 
            +
                #
         | 
| 30 | 
            +
                #   Gmail.new(:plain, "foo@gmail.com", "password")
         | 
| 31 | 
            +
                #   Gmail.new(:xoauth, "foo@gmail.com", 
         | 
| 32 | 
            +
                #     :consumer_key => "",
         | 
| 33 | 
            +
                #     :consumer_secret => "",
         | 
| 34 | 
            +
                #     :token => "",
         | 
| 35 | 
            +
                #     :secret => "")
         | 
| 36 | 
            +
                #
         | 
| 37 | 
            +
                # To use plain authentication mehod you can also call:
         | 
| 38 | 
            +
                #
         | 
| 39 | 
            +
                #   Gmail.new("foo@gmail.com", "password")
         | 
| 40 | 
            +
                #
         | 
| 41 | 
            +
                # You can also use block-style call:
         | 
| 42 | 
            +
                #
         | 
| 43 | 
            +
                #   Gmail.new("foo@gmail.com", "password") do |client|
         | 
| 44 | 
            +
                #     # ...
         | 
| 45 | 
            +
                #   end
         | 
| 46 | 
            +
                #
         | 
| 47 | 
            +
                def new(*args, &block)
         | 
| 48 | 
            +
                  client = connect_with_proper_client(*args)
         | 
| 27 49 | 
             
                  client.connect and client.login
         | 
| 28 | 
            -
                   | 
| 29 | 
            -
                    yield client
         | 
| 30 | 
            -
                    client.logout
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
                  client
         | 
| 50 | 
            +
                  perform_block(client, &block)
         | 
| 33 51 | 
             
                end
         | 
| 34 52 | 
             
                alias :connect :new
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                def new!( | 
| 37 | 
            -
                  client =  | 
| 53 | 
            +
             | 
| 54 | 
            +
                def new!(*args, &block)
         | 
| 55 | 
            +
                  client = connect_with_proper_client(*args)
         | 
| 38 56 | 
             
                  client.connect! and client.login!
         | 
| 57 | 
            +
                  perform_block(client, &block)
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
                alias :connect! :new!
         | 
| 60 | 
            +
                
         | 
| 61 | 
            +
                protected
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                def connect_with_proper_client(*args)
         | 
| 64 | 
            +
                  if args.first.is_a?(Symbol)        
         | 
| 65 | 
            +
                    login_method = args.shift  
         | 
| 66 | 
            +
                  else
         | 
| 67 | 
            +
                    login_method ||= :plain
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  Client.send("new_#{login_method}", *args)
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                def perform_block(client, &block)
         | 
| 39 74 | 
             
                  if block_given?
         | 
| 40 75 | 
             
                    yield client
         | 
| 41 76 | 
             
                    client.logout
         | 
| 42 77 | 
             
                  end
         | 
| 43 78 | 
             
                  client
         | 
| 44 79 | 
             
                end
         | 
| 45 | 
            -
             | 
| 80 | 
            +
             | 
| 46 81 | 
             
              end # << self
         | 
| 47 82 | 
             
            end # Gmail
         | 
    
        data/lib/gmail/client.rb
    CHANGED
    
    | @@ -1,221 +1,22 @@ | |
| 1 1 | 
             
            module Gmail
         | 
| 2 | 
            -
               | 
| 2 | 
            +
              module Client
         | 
| 3 3 | 
             
                # Raised when connection with GMail IMAP service couldn't be established. 
         | 
| 4 4 | 
             
                class ConnectionError < SocketError; end
         | 
| 5 5 | 
             
                # Raised when given username or password are invalid.
         | 
| 6 6 | 
             
                class AuthorizationError < Net::IMAP::NoResponseError; end
         | 
| 7 7 | 
             
                # Raised when delivered email is invalid. 
         | 
| 8 8 | 
             
                class DeliveryError < ArgumentError; end
         | 
| 9 | 
            -
              
         | 
| 10 | 
            -
                # GMail IMAP defaults
         | 
| 11 | 
            -
                GMAIL_IMAP_HOST = 'imap.gmail.com'
         | 
| 12 | 
            -
                GMAIL_IMAP_PORT = 993
         | 
| 13 9 |  | 
| 14 | 
            -
                 | 
| 15 | 
            -
                 | 
| 16 | 
            -
                 | 
| 17 | 
            -
              
         | 
| 18 | 
            -
                attr_reader :username
         | 
| 19 | 
            -
                attr_reader :password
         | 
| 20 | 
            -
                attr_reader :options
         | 
| 21 | 
            -
              
         | 
| 22 | 
            -
                def initialize(username, password, options={})
         | 
| 23 | 
            -
                  defaults  = {}
         | 
| 24 | 
            -
                  @username = fill_username(username)
         | 
| 25 | 
            -
                  @password = password
         | 
| 26 | 
            -
                  @options  = defaults.merge(options)
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
                
         | 
| 29 | 
            -
                # Connect to gmail service. 
         | 
| 30 | 
            -
                def connect(raise_errors=false)
         | 
| 31 | 
            -
                  @imap = Net::IMAP.new(GMAIL_IMAP_HOST, GMAIL_IMAP_PORT, true, nil, false)
         | 
| 32 | 
            -
                rescue SocketError
         | 
| 33 | 
            -
                  raise_errors and raise ConnectionError, "Couldn't establish connection with GMail IMAP service"
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
                
         | 
| 36 | 
            -
                # This version of connect will raise error on failure...
         | 
| 37 | 
            -
                def connect!
         | 
| 38 | 
            -
                  connect(true)
         | 
| 39 | 
            -
                end
         | 
| 40 | 
            -
                
         | 
| 41 | 
            -
                # Return current connection. Log in automaticaly to specified account if 
         | 
| 42 | 
            -
                # it is necessary.
         | 
| 43 | 
            -
                def connection
         | 
| 44 | 
            -
                  login and at_exit { logout } unless logged_in?
         | 
| 45 | 
            -
                  @imap
         | 
| 46 | 
            -
                end
         | 
| 47 | 
            -
                alias :conn :connection
         | 
| 48 | 
            -
                
         | 
| 49 | 
            -
                # Login to specified account.
         | 
| 50 | 
            -
                def login(raise_errors=false)
         | 
| 51 | 
            -
                  @imap and @logged_in = (login = @imap.login(username, password)) && login.name == 'OK'
         | 
| 52 | 
            -
                rescue Net::IMAP::NoResponseError
         | 
| 53 | 
            -
                  raise_errors and raise AuthorizationError, "Couldn't login to given GMail account: #{username}"
         | 
| 54 | 
            -
                end
         | 
| 55 | 
            -
                alias :sign_in :login
         | 
| 56 | 
            -
                
         | 
| 57 | 
            -
                # This version of login will raise error on failure...
         | 
| 58 | 
            -
                def login!
         | 
| 59 | 
            -
                  login(true)
         | 
| 60 | 
            -
                end
         | 
| 61 | 
            -
                alias :sign_in! :login!
         | 
| 62 | 
            -
                
         | 
| 63 | 
            -
                # Returns +true+ when you are logged in to specified account.
         | 
| 64 | 
            -
                def logged_in?
         | 
| 65 | 
            -
                  !!@logged_in
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
                alias :signed_in? :logged_in?
         | 
| 68 | 
            -
                
         | 
| 69 | 
            -
                # Logout from GMail service. 
         | 
| 70 | 
            -
                def logout
         | 
| 71 | 
            -
                  @imap && logged_in? and @imap.logout
         | 
| 72 | 
            -
                ensure
         | 
| 73 | 
            -
                  @logged_in = false
         | 
| 74 | 
            -
                end
         | 
| 75 | 
            -
                alias :sign_out :logout
         | 
| 76 | 
            -
                
         | 
| 77 | 
            -
                # Return labels object, which helps you with managing your GMail labels.
         | 
| 78 | 
            -
                # See <tt>Gmail::Labels</tt> for details.
         | 
| 79 | 
            -
                def labels
         | 
| 80 | 
            -
                  @labels ||= Labels.new(conn)
         | 
| 81 | 
            -
                end
         | 
| 82 | 
            -
                
         | 
| 83 | 
            -
                # Compose new e-mail.
         | 
| 84 | 
            -
                #
         | 
| 85 | 
            -
                # ==== Examples
         | 
| 86 | 
            -
                #   
         | 
| 87 | 
            -
                #   mail = gmail.compose
         | 
| 88 | 
            -
                #   mail.from "test@gmail.org"
         | 
| 89 | 
            -
                #   mail.to "friend@gmail.com"
         | 
| 90 | 
            -
                #
         | 
| 91 | 
            -
                # ... or block style:
         | 
| 92 | 
            -
                #  
         | 
| 93 | 
            -
                #   mail = gmail.compose do 
         | 
| 94 | 
            -
                #     from "test@gmail.org"
         | 
| 95 | 
            -
                #     to "friend@gmail.com"
         | 
| 96 | 
            -
                #     subject "Hello!"
         | 
| 97 | 
            -
                #     body "Hello my friend! long time..."
         | 
| 98 | 
            -
                #   end
         | 
| 99 | 
            -
                #
         | 
| 100 | 
            -
                # Now you can deliver your mail:
         | 
| 101 | 
            -
                #
         | 
| 102 | 
            -
                #   gmail.deliver(mail)
         | 
| 103 | 
            -
                def compose(mail=nil, &block)
         | 
| 104 | 
            -
                  if block_given?
         | 
| 105 | 
            -
                    mail = Mail.new(&block)
         | 
| 106 | 
            -
                  elsif !mail 
         | 
| 107 | 
            -
                    mail = Mail.new
         | 
| 108 | 
            -
                  end 
         | 
| 109 | 
            -
                  mail.delivery_method(*smtp_settings)
         | 
| 110 | 
            -
                  mail.from = username unless mail.from
         | 
| 111 | 
            -
                  mail
         | 
| 112 | 
            -
                end
         | 
| 113 | 
            -
                alias :message :compose
         | 
| 114 | 
            -
                
         | 
| 115 | 
            -
                # Compose (optionaly) and send given email. 
         | 
| 116 | 
            -
                #
         | 
| 117 | 
            -
                # ==== Examples
         | 
| 118 | 
            -
                #
         | 
| 119 | 
            -
                #   gmail.deliver do 
         | 
| 120 | 
            -
                #     to "friend@gmail.com"
         | 
| 121 | 
            -
                #     subject "Hello friend!"
         | 
| 122 | 
            -
                #     body "Hi! How are you?"
         | 
| 123 | 
            -
                #   end
         | 
| 124 | 
            -
                #
         | 
| 125 | 
            -
                # ... or with already created message:
         | 
| 126 | 
            -
                #
         | 
| 127 | 
            -
                #   mail = Mail.new { ... }
         | 
| 128 | 
            -
                #   gmail.deliver(mail)
         | 
| 129 | 
            -
                #
         | 
| 130 | 
            -
                #   mail = gmail.compose { ... }
         | 
| 131 | 
            -
                #   gmail.deliver(mail)
         | 
| 132 | 
            -
                def deliver(mail=nil, raise_errors=false, &block)
         | 
| 133 | 
            -
                  mail = compose(mail, &block) if block_given?
         | 
| 134 | 
            -
                  mail.deliver!
         | 
| 135 | 
            -
                rescue Object => ex
         | 
| 136 | 
            -
                  raise_errors and raise DeliveryError, "Couldn't deliver email: #{ex.to_s}"
         | 
| 137 | 
            -
                end
         | 
| 138 | 
            -
                
         | 
| 139 | 
            -
                # This version of deliver will raise error on failure...
         | 
| 140 | 
            -
                def deliver!(mail=nil, &block)
         | 
| 141 | 
            -
                  deliver(mail, true, &block)
         | 
| 142 | 
            -
                end
         | 
| 143 | 
            -
                
         | 
| 144 | 
            -
                # Do something with given mailbox or within it context. 
         | 
| 145 | 
            -
                #
         | 
| 146 | 
            -
                # ==== Examples
         | 
| 147 | 
            -
                #
         | 
| 148 | 
            -
                #   mailbox = gmail.mailbox("INBOX")
         | 
| 149 | 
            -
                #   mailbox.emails(:all)
         | 
| 150 | 
            -
                #   mailbox.count(:unread, :before => Time.now-(20*24*3600))
         | 
| 151 | 
            -
                #
         | 
| 152 | 
            -
                # ... or block style:
         | 
| 153 | 
            -
                #
         | 
| 154 | 
            -
                #   gmail.label("Work") do |mailbox|
         | 
| 155 | 
            -
                #     mailbox.emails(:unread)
         | 
| 156 | 
            -
                #     mailbox.count(:all)
         | 
| 157 | 
            -
                #     ...
         | 
| 158 | 
            -
                #   end
         | 
| 159 | 
            -
                def mailbox(name, &block)
         | 
| 160 | 
            -
                  name = name.to_s
         | 
| 161 | 
            -
                  mailbox = (mailboxes[name] ||= Mailbox.new(self, name))
         | 
| 162 | 
            -
                  switch_to_mailbox(name) if @current_mailbox != name
         | 
| 163 | 
            -
                  if block_given?
         | 
| 164 | 
            -
                    mailbox_stack << @current_mailbox
         | 
| 165 | 
            -
                    result = block.arity == 1 ? block.call(mailbox) : block.call
         | 
| 166 | 
            -
                    mailbox_stack.pop
         | 
| 167 | 
            -
                    switch_to_mailbox(mailbox_stack.last)
         | 
| 168 | 
            -
                    return result
         | 
| 169 | 
            -
                  end
         | 
| 170 | 
            -
                  mailbox
         | 
| 171 | 
            -
                end
         | 
| 172 | 
            -
                alias :in_mailbox :mailbox
         | 
| 173 | 
            -
                alias :in_label :mailbox
         | 
| 174 | 
            -
                alias :label :mailbox
         | 
| 175 | 
            -
                
         | 
| 176 | 
            -
                # Alias for <tt>mailbox("INBOX")</tt>. See <tt>Gmail::Client#mailbox</tt>
         | 
| 177 | 
            -
                # for details.
         | 
| 178 | 
            -
                def inbox
         | 
| 179 | 
            -
                  mailbox("INBOX")
         | 
| 180 | 
            -
                end
         | 
| 181 | 
            -
                
         | 
| 182 | 
            -
                def mailboxes
         | 
| 183 | 
            -
                  @mailboxes ||= {}
         | 
| 184 | 
            -
                end
         | 
| 185 | 
            -
                
         | 
| 186 | 
            -
                def inspect
         | 
| 187 | 
            -
                  "#<Gmail::Client#{'0x%04x' % (object_id << 1)} (#{username}) #{'dis' if !logged_in?}connected>"
         | 
| 188 | 
            -
                end
         | 
| 189 | 
            -
                
         | 
| 190 | 
            -
                def fill_username(username)
         | 
| 191 | 
            -
                  username =~ /@/ ? username : "#{username}@gmail.com"
         | 
| 192 | 
            -
                end
         | 
| 10 | 
            +
                autoload :Base,   'gmail/client/base'
         | 
| 11 | 
            +
                autoload :Plain,  'gmail/client/plain'
         | 
| 12 | 
            +
                autoload :XOAuth, 'gmail/client/xoauth'
         | 
| 193 13 |  | 
| 194 | 
            -
                def  | 
| 195 | 
            -
                   | 
| 196 | 
            -
                end
         | 
| 197 | 
            -
                
         | 
| 198 | 
            -
                private
         | 
| 199 | 
            -
                
         | 
| 200 | 
            -
                def switch_to_mailbox(mailbox)
         | 
| 201 | 
            -
                  conn.select(mailbox) if mailbox
         | 
| 202 | 
            -
                  @current_mailbox = mailbox
         | 
| 203 | 
            -
                end
         | 
| 204 | 
            -
                
         | 
| 205 | 
            -
                def mailbox_stack
         | 
| 206 | 
            -
                  @mailbox_stack ||= []
         | 
| 14 | 
            +
                def self.new_plain(*args)
         | 
| 15 | 
            +
                  Gmail::Client::Plain.new(*args)
         | 
| 207 16 | 
             
                end
         | 
| 208 | 
            -
             | 
| 209 | 
            -
                def  | 
| 210 | 
            -
                   | 
| 211 | 
            -
                    :address => GMAIL_SMTP_HOST,
         | 
| 212 | 
            -
                    :port => GMAIL_SMTP_PORT,
         | 
| 213 | 
            -
                    :domain => mail_domain,
         | 
| 214 | 
            -
                    :user_name => username,
         | 
| 215 | 
            -
                    :password => password,
         | 
| 216 | 
            -
                    :authentication => 'plain',
         | 
| 217 | 
            -
                    :enable_starttls_auto => true
         | 
| 218 | 
            -
                  }]
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def self.new_xoauth(*args)
         | 
| 19 | 
            +
                  Gmail::Client::XOAuth.new(*args)
         | 
| 219 20 | 
             
                end
         | 
| 220 21 | 
             
              end # Client
         | 
| 221 22 | 
             
            end # Gmail
         | 
| @@ -0,0 +1,220 @@ | |
| 1 | 
            +
            require 'thread'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Gmail
         | 
| 4 | 
            +
              module Client
         | 
| 5 | 
            +
                class Base
         | 
| 6 | 
            +
                  # GMail IMAP defaults
         | 
| 7 | 
            +
                  GMAIL_IMAP_HOST = 'imap.gmail.com'
         | 
| 8 | 
            +
                  GMAIL_IMAP_PORT = 993
         | 
| 9 | 
            +
                  
         | 
| 10 | 
            +
                  # GMail SMTP defaults
         | 
| 11 | 
            +
                  GMAIL_SMTP_HOST = "smtp.gmail.com"
         | 
| 12 | 
            +
                  GMAIL_SMTP_PORT = 587
         | 
| 13 | 
            +
                  
         | 
| 14 | 
            +
                  attr_reader :username
         | 
| 15 | 
            +
                  attr_reader :options
         | 
| 16 | 
            +
                  
         | 
| 17 | 
            +
                  def initialize(username, options={})
         | 
| 18 | 
            +
                    defaults       = {}
         | 
| 19 | 
            +
                    @username      = fill_username(username)
         | 
| 20 | 
            +
                    @options       = defaults.merge(options)
         | 
| 21 | 
            +
                    @mailbox_mutex = Mutex.new
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                  
         | 
| 24 | 
            +
                  # Connect to gmail service. 
         | 
| 25 | 
            +
                  def connect(raise_errors=false)
         | 
| 26 | 
            +
                    @imap = Net::IMAP.new(GMAIL_IMAP_HOST, GMAIL_IMAP_PORT, true, nil, false)
         | 
| 27 | 
            +
                  rescue SocketError
         | 
| 28 | 
            +
                    raise_errors and raise ConnectionError, "Couldn't establish connection with GMail IMAP service"
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                  
         | 
| 31 | 
            +
                  # This version of connect will raise error on failure...
         | 
| 32 | 
            +
                  def connect!
         | 
| 33 | 
            +
                    connect(true)
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                  
         | 
| 36 | 
            +
                  # Return current connection. Log in automaticaly to specified account if 
         | 
| 37 | 
            +
                  # it is necessary.
         | 
| 38 | 
            +
                  def connection
         | 
| 39 | 
            +
                    login and at_exit { logout } unless logged_in?
         | 
| 40 | 
            +
                    @imap
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                  alias :conn :connection
         | 
| 43 | 
            +
                  
         | 
| 44 | 
            +
                  # Login to specified account.
         | 
| 45 | 
            +
                  def login(*args)
         | 
| 46 | 
            +
                    raise NotImplementedError, "The `#{self.class.name}#login` method is not implemented."
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                  alias :sign_in :login
         | 
| 49 | 
            +
                  
         | 
| 50 | 
            +
                  # This version of login will raise error on failure...
         | 
| 51 | 
            +
                  def login!
         | 
| 52 | 
            +
                    login(true)
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                  alias :sign_in! :login!
         | 
| 55 | 
            +
                  
         | 
| 56 | 
            +
                  # Returns +true+ when you are logged in to specified account.
         | 
| 57 | 
            +
                  def logged_in?
         | 
| 58 | 
            +
                    !!@logged_in
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                  alias :signed_in? :logged_in?
         | 
| 61 | 
            +
                  
         | 
| 62 | 
            +
                  # Logout from GMail service. 
         | 
| 63 | 
            +
                  def logout
         | 
| 64 | 
            +
                    @imap && logged_in? and @imap.logout
         | 
| 65 | 
            +
                  ensure
         | 
| 66 | 
            +
                    @logged_in = false
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  alias :sign_out :logout
         | 
| 69 | 
            +
                  
         | 
| 70 | 
            +
                  # Return labels object, which helps you with managing your GMail labels.
         | 
| 71 | 
            +
                  # See <tt>Gmail::Labels</tt> for details.
         | 
| 72 | 
            +
                  def labels
         | 
| 73 | 
            +
                    @labels ||= Labels.new(conn)
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                  
         | 
| 76 | 
            +
                  # Compose new e-mail.
         | 
| 77 | 
            +
                  #
         | 
| 78 | 
            +
                  # ==== Examples
         | 
| 79 | 
            +
                  #   
         | 
| 80 | 
            +
                  #   mail = gmail.compose
         | 
| 81 | 
            +
                  #   mail.from "test@gmail.org"
         | 
| 82 | 
            +
                  #   mail.to "friend@gmail.com"
         | 
| 83 | 
            +
                  #
         | 
| 84 | 
            +
                  # ... or block style:
         | 
| 85 | 
            +
                  #  
         | 
| 86 | 
            +
                  #   mail = gmail.compose do 
         | 
| 87 | 
            +
                  #     from "test@gmail.org"
         | 
| 88 | 
            +
                  #     to "friend@gmail.com"
         | 
| 89 | 
            +
                  #     subject "Hello!"
         | 
| 90 | 
            +
                  #     body "Hello my friend! long time..."
         | 
| 91 | 
            +
                  #   end
         | 
| 92 | 
            +
                  #
         | 
| 93 | 
            +
                  # Now you can deliver your mail:
         | 
| 94 | 
            +
                  #
         | 
| 95 | 
            +
                  #   gmail.deliver(mail)
         | 
| 96 | 
            +
                  def compose(mail=nil, &block)
         | 
| 97 | 
            +
                    if block_given?
         | 
| 98 | 
            +
                      mail = Mail.new(&block)
         | 
| 99 | 
            +
                    elsif !mail 
         | 
| 100 | 
            +
                      mail = Mail.new
         | 
| 101 | 
            +
                    end 
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    mail.delivery_method(*smtp_settings)
         | 
| 104 | 
            +
                    mail.from = username unless mail.from
         | 
| 105 | 
            +
                    mail
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
                  alias :message :compose
         | 
| 108 | 
            +
                  
         | 
| 109 | 
            +
                  # Compose (optionaly) and send given email. 
         | 
| 110 | 
            +
                  #
         | 
| 111 | 
            +
                  # ==== Examples
         | 
| 112 | 
            +
                  #
         | 
| 113 | 
            +
                  #   gmail.deliver do 
         | 
| 114 | 
            +
                  #     to "friend@gmail.com"
         | 
| 115 | 
            +
                  #     subject "Hello friend!"
         | 
| 116 | 
            +
                  #     body "Hi! How are you?"
         | 
| 117 | 
            +
                  #   end
         | 
| 118 | 
            +
                  #
         | 
| 119 | 
            +
                  # ... or with already created message:
         | 
| 120 | 
            +
                  #
         | 
| 121 | 
            +
                  #   mail = Mail.new { ... }
         | 
| 122 | 
            +
                  #   gmail.deliver(mail)
         | 
| 123 | 
            +
                  #
         | 
| 124 | 
            +
                  #   mail = gmail.compose { ... }
         | 
| 125 | 
            +
                  #   gmail.deliver(mail)
         | 
| 126 | 
            +
                  def deliver(mail=nil, raise_errors=false, &block)
         | 
| 127 | 
            +
                    mail = compose(mail, &block) if block_given?
         | 
| 128 | 
            +
                    mail.deliver!
         | 
| 129 | 
            +
                  rescue Object => ex
         | 
| 130 | 
            +
                    raise_errors and raise DeliveryError, "Couldn't deliver email: #{ex.to_s}"
         | 
| 131 | 
            +
                  end
         | 
| 132 | 
            +
                  
         | 
| 133 | 
            +
                  # This version of deliver will raise error on failure...
         | 
| 134 | 
            +
                  def deliver!(mail=nil, &block)
         | 
| 135 | 
            +
                    deliver(mail, true, &block)
         | 
| 136 | 
            +
                  end
         | 
| 137 | 
            +
                  
         | 
| 138 | 
            +
                  # Do something with given mailbox or within it context. 
         | 
| 139 | 
            +
                  #
         | 
| 140 | 
            +
                  # ==== Examples
         | 
| 141 | 
            +
                  #
         | 
| 142 | 
            +
                  #   mailbox = gmail.mailbox("INBOX")
         | 
| 143 | 
            +
                  #   mailbox.emails(:all)
         | 
| 144 | 
            +
                  #   mailbox.count(:unread, :before => Time.now-(20*24*3600))
         | 
| 145 | 
            +
                  #
         | 
| 146 | 
            +
                  # ... or block style:
         | 
| 147 | 
            +
                  #
         | 
| 148 | 
            +
                  #   gmail.label("Work") do |mailbox|
         | 
| 149 | 
            +
                  #     mailbox.emails(:unread)
         | 
| 150 | 
            +
                  #     mailbox.count(:all)
         | 
| 151 | 
            +
                  #     ...
         | 
| 152 | 
            +
                  #   end
         | 
| 153 | 
            +
                  def mailbox(name, &block)
         | 
| 154 | 
            +
                    @mailbox_mutex.synchronize do
         | 
| 155 | 
            +
                      name = Net::IMAP.encode_utf7(name.to_s)
         | 
| 156 | 
            +
                      mailbox = (mailboxes[name] ||= Mailbox.new(self, name))
         | 
| 157 | 
            +
                      switch_to_mailbox(name) if @current_mailbox != name
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                      if block_given?
         | 
| 160 | 
            +
                        mailbox_stack << @current_mailbox
         | 
| 161 | 
            +
                        result = block.arity == 1 ? block.call(mailbox) : block.call
         | 
| 162 | 
            +
                        mailbox_stack.pop
         | 
| 163 | 
            +
                        switch_to_mailbox(mailbox_stack.last)
         | 
| 164 | 
            +
                        return result
         | 
| 165 | 
            +
                      end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                      return mailbox
         | 
| 168 | 
            +
                    end
         | 
| 169 | 
            +
                  end
         | 
| 170 | 
            +
                  alias :in_mailbox :mailbox
         | 
| 171 | 
            +
                  alias :in_label :mailbox
         | 
| 172 | 
            +
                  alias :label :mailbox
         | 
| 173 | 
            +
                  
         | 
| 174 | 
            +
                  # Alias for <tt>mailbox("INBOX")</tt>. See <tt>Gmail::Client#mailbox</tt>
         | 
| 175 | 
            +
                  # for details.
         | 
| 176 | 
            +
                  def inbox
         | 
| 177 | 
            +
                    mailbox("INBOX")
         | 
| 178 | 
            +
                  end
         | 
| 179 | 
            +
                  
         | 
| 180 | 
            +
                  def mailboxes
         | 
| 181 | 
            +
                    @mailboxes ||= {}
         | 
| 182 | 
            +
                  end
         | 
| 183 | 
            +
                  
         | 
| 184 | 
            +
                  def inspect
         | 
| 185 | 
            +
                    "#<Gmail::Client#{'0x%04x' % (object_id << 1)} (#{username}) #{'dis' if !logged_in?}connected>"
         | 
| 186 | 
            +
                  end
         | 
| 187 | 
            +
                  
         | 
| 188 | 
            +
                  def fill_username(username)
         | 
| 189 | 
            +
                    username =~ /@/ ? username : "#{username}@gmail.com"
         | 
| 190 | 
            +
                  end
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                  def mail_domain
         | 
| 193 | 
            +
                    username.split('@')[0]
         | 
| 194 | 
            +
                  end
         | 
| 195 | 
            +
                  
         | 
| 196 | 
            +
                  private
         | 
| 197 | 
            +
                  
         | 
| 198 | 
            +
                  def switch_to_mailbox(mailbox)
         | 
| 199 | 
            +
                    conn.select(mailbox) if mailbox
         | 
| 200 | 
            +
                    @current_mailbox = mailbox
         | 
| 201 | 
            +
                  end
         | 
| 202 | 
            +
                  
         | 
| 203 | 
            +
                  def mailbox_stack
         | 
| 204 | 
            +
                    @mailbox_stack ||= []
         | 
| 205 | 
            +
                  end
         | 
| 206 | 
            +
                  
         | 
| 207 | 
            +
                  def smtp_settings
         | 
| 208 | 
            +
                    [:smtp, {
         | 
| 209 | 
            +
                      :address => GMAIL_SMTP_HOST,
         | 
| 210 | 
            +
                      :port => GMAIL_SMTP_PORT,
         | 
| 211 | 
            +
                      :domain => mail_domain,
         | 
| 212 | 
            +
                      :user_name => username,
         | 
| 213 | 
            +
                      :password => password,
         | 
| 214 | 
            +
                      :authentication => 'plain',
         | 
| 215 | 
            +
                      :enable_starttls_auto => true
         | 
| 216 | 
            +
                    }]
         | 
| 217 | 
            +
                  end
         | 
| 218 | 
            +
                end # Base
         | 
| 219 | 
            +
              end # Client
         | 
| 220 | 
            +
            end # Gmail
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module Gmail
         | 
| 2 | 
            +
              module Client
         | 
| 3 | 
            +
                class Plain < Base
         | 
| 4 | 
            +
                  attr_reader :password
         | 
| 5 | 
            +
                  
         | 
| 6 | 
            +
                  def initialize(username, password, options={})
         | 
| 7 | 
            +
                    @password = password
         | 
| 8 | 
            +
                    super(username, options)
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def login(raise_errors=false)
         | 
| 12 | 
            +
                    @imap and @logged_in = (login = @imap.login(username, password)) && login.name == 'OK'
         | 
| 13 | 
            +
                  rescue Net::IMAP::NoResponseError
         | 
| 14 | 
            +
                    raise_errors and raise AuthorizationError, "Couldn't login to given GMail account: #{username}"
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end # Plain
         | 
| 17 | 
            +
              end # Client
         | 
| 18 | 
            +
            end # Gmail
         | 
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            require 'gmail_xoauth'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Gmail
         | 
| 4 | 
            +
              module Client
         | 
| 5 | 
            +
                class XOAuth < Base
         | 
| 6 | 
            +
                  attr_reader :token
         | 
| 7 | 
            +
                  attr_reader :secret
         | 
| 8 | 
            +
                  attr_reader :consumer_key
         | 
| 9 | 
            +
                  attr_reader :consumer_secret
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def initialize(username, options={})
         | 
| 12 | 
            +
                    @token           = options.delete(:token)
         | 
| 13 | 
            +
                    @secret          = options.delete(:secret)
         | 
| 14 | 
            +
                    @consumer_key    = options.delete(:consumer_key)
         | 
| 15 | 
            +
                    @consumer_secret = options.delete(:consumer_secret)
         | 
| 16 | 
            +
                   
         | 
| 17 | 
            +
                    super(username, options)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def login(raise_errors=false)
         | 
| 21 | 
            +
                    @imap and @logged_in = (login = @imap.authenticate('XOAUTH', username,
         | 
| 22 | 
            +
                      :consumer_key    => consumer_key,
         | 
| 23 | 
            +
                      :consumer_secret => consumer_secret,
         | 
| 24 | 
            +
                      :token           => token,
         | 
| 25 | 
            +
                      :token_secret    => secret
         | 
| 26 | 
            +
                    )) && login.name == 'OK'
         | 
| 27 | 
            +
                  rescue
         | 
| 28 | 
            +
                    raise_errors and raise AuthorizationError, "Couldn't login to given GMail account: #{username}"        
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def smtp_settings
         | 
| 32 | 
            +
                    [:smtp, {
         | 
| 33 | 
            +
                       :address => GMAIL_SMTP_HOST,
         | 
| 34 | 
            +
                       :port => GMAIL_SMTP_PORT,
         | 
| 35 | 
            +
                       :domain => mail_domain,
         | 
| 36 | 
            +
                       :user_name => username,
         | 
| 37 | 
            +
                       :password => secret = {
         | 
| 38 | 
            +
                         :consumer_key    => consumer_key,
         | 
| 39 | 
            +
                         :consumer_secret => consumer_secret,
         | 
| 40 | 
            +
                         :token           => token,
         | 
| 41 | 
            +
                         :token_secret    => token_secret
         | 
| 42 | 
            +
                       },
         | 
| 43 | 
            +
                       :authentication => :xoauth,
         | 
| 44 | 
            +
                       :enable_starttls_auto => true
         | 
| 45 | 
            +
                     }]
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end # XOAuth
         | 
| 48 | 
            +
              end # Client
         | 
| 49 | 
            +
            end # Gmail
         | 
    
        data/lib/gmail/labels.rb
    CHANGED
    
    | @@ -11,7 +11,7 @@ module Gmail | |
| 11 11 | 
             
                # Get list of all defined labels.
         | 
| 12 12 | 
             
                def all
         | 
| 13 13 | 
             
                  (conn.list("", "%")+conn.list("[Gmail]/", "%")).inject([]) do |labels,label|
         | 
| 14 | 
            -
                    label[:name].each_line {|l| labels << l }
         | 
| 14 | 
            +
                    label[:name].each_line {|l| labels << Net::IMAP.decode_utf7(l) }
         | 
| 15 15 | 
             
                    labels 
         | 
| 16 16 | 
             
                  end
         | 
| 17 17 | 
             
                end
         | 
| @@ -24,20 +24,20 @@ module Gmail | |
| 24 24 |  | 
| 25 25 | 
             
                # Returns +true+ when given label defined. 
         | 
| 26 26 | 
             
                def exists?(label)
         | 
| 27 | 
            -
                  all.include?(label)
         | 
| 27 | 
            +
                  all.include?(Net::IMAP.encode_utf7(label))
         | 
| 28 28 | 
             
                end
         | 
| 29 29 | 
             
                alias :exist? :exists?
         | 
| 30 30 |  | 
| 31 31 | 
             
                # Creates given label in your account.
         | 
| 32 32 | 
             
                def create(label)
         | 
| 33 | 
            -
                  !!conn.create(label) rescue false
         | 
| 33 | 
            +
                  !!conn.create(Net::IMAP.encode_utf7(label)) rescue false
         | 
| 34 34 | 
             
                end
         | 
| 35 35 | 
             
                alias :new :create
         | 
| 36 36 | 
             
                alias :add :create
         | 
| 37 37 |  | 
| 38 38 | 
             
                # Deletes given label from your account. 
         | 
| 39 39 | 
             
                def delete(label)
         | 
| 40 | 
            -
                  !!conn.delete(label) rescue false
         | 
| 40 | 
            +
                  !!conn.delete(Net::IMAP.encode_utf7(label)) rescue false
         | 
| 41 41 | 
             
                end
         | 
| 42 42 | 
             
                alias :remove :delete
         | 
| 43 43 |  | 
    
        data/lib/gmail/mailbox.rb
    CHANGED
    
    | @@ -17,9 +17,11 @@ module Gmail | |
| 17 17 | 
             
                }
         | 
| 18 18 |  | 
| 19 19 | 
             
                attr_reader :name
         | 
| 20 | 
            +
                attr_reader :external_name
         | 
| 20 21 |  | 
| 21 22 | 
             
                def initialize(gmail, name="INBOX")
         | 
| 22 23 | 
             
                  @name  = name
         | 
| 24 | 
            +
                  @external_name = Net::IMAP.decode_utf7(name)
         | 
| 23 25 | 
             
                  @gmail = gmail
         | 
| 24 26 | 
             
                end
         | 
| 25 27 |  | 
| @@ -53,8 +55,10 @@ module Gmail | |
| 53 55 | 
             
                    opts[:subject]    and search.concat ['SUBJECT', opts[:subject]]
         | 
| 54 56 | 
             
                    opts[:label]      and search.concat ['LABEL', opts[:label]]
         | 
| 55 57 | 
             
                    opts[:attachment] and search.concat ['HAS', 'attachment']
         | 
| 56 | 
            -
                    opts[:search]     and search.concat [opts[:search]]
         | 
| 57 | 
            -
                    
         | 
| 58 | 
            +
                    opts[:search]     and search.concat ['BODY', opts[:search]]
         | 
| 59 | 
            +
                    opts[:body]       and search.concat ['BODY', opts[:body]]
         | 
| 60 | 
            +
                    opts[:query]      and search.concat opts[:query]
         | 
| 61 | 
            +
             | 
| 58 62 | 
             
                    @gmail.mailbox(name) do
         | 
| 59 63 | 
             
                      @gmail.conn.uid_search(search).collect do |uid| 
         | 
| 60 64 | 
             
                        message = (messages[uid] ||= Message.new(self, uid))
         | 
| @@ -97,7 +101,7 @@ module Gmail | |
| 97 101 | 
             
                end
         | 
| 98 102 |  | 
| 99 103 | 
             
                def inspect
         | 
| 100 | 
            -
                  "#<Gmail::Mailbox#{'0x%04x' % (object_id << 1)} name=#{ | 
| 104 | 
            +
                  "#<Gmail::Mailbox#{'0x%04x' % (object_id << 1)} name=#{external_name}>"
         | 
| 101 105 | 
             
                end
         | 
| 102 106 |  | 
| 103 107 | 
             
                def to_s
         | 
    
        data/lib/gmail/message.rb
    CHANGED
    
    | @@ -64,11 +64,14 @@ module Gmail | |
| 64 64 | 
             
                  unflag('[Gmail]/Starred')
         | 
| 65 65 | 
             
                end
         | 
| 66 66 |  | 
| 67 | 
            -
                # Move to trash.
         | 
| 67 | 
            +
                # Move to trash / bin.
         | 
| 68 68 | 
             
                def delete!
         | 
| 69 69 | 
             
                  @mailbox.messages.delete(uid)
         | 
| 70 | 
            -
                  flag(: | 
| 71 | 
            -
             | 
| 70 | 
            +
                  flag(:deleted)
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  # For some, it's called "Trash", for others, it's called "Bin". Support both.
         | 
| 73 | 
            +
                  trash =  @gmail.labels.exist?('[Gmail]/Bin') ? '[Gmail]/Bin' : '[Gmail]/Trash'
         | 
| 74 | 
            +
                  move_to(trash) unless %w[[Gmail]/Spam [Gmail]/Bin [Gmail]/Trash].include?(@mailbox.name)
         | 
| 72 75 | 
             
                end
         | 
| 73 76 |  | 
| 74 77 | 
             
                # Archive this message.
         | 
| @@ -78,7 +81,8 @@ module Gmail | |
| 78 81 |  | 
| 79 82 | 
             
                # Move to given box and delete from others.  
         | 
| 80 83 | 
             
                def move_to(name, from=nil)
         | 
| 81 | 
            -
                  label(name, from) | 
| 84 | 
            +
                  label(name, from)
         | 
| 85 | 
            +
                  delete! if !%w[[Gmail]/Bin [Gmail]/Trash].include?(name)
         | 
| 82 86 | 
             
                end
         | 
| 83 87 | 
             
                alias :move :move_to
         | 
| 84 88 |  | 
| @@ -94,11 +98,10 @@ module Gmail | |
| 94 98 | 
             
                #
         | 
| 95 99 | 
             
                # See also <tt>Gmail::Message#label!</tt>.
         | 
| 96 100 | 
             
                def label(name, from=nil)
         | 
| 97 | 
            -
                  @gmail.mailbox(from || @mailbox. | 
| 101 | 
            +
                  @gmail.mailbox(Net::IMAP.encode_utf7(from || @mailbox.external_name)) { @gmail.conn.uid_copy(uid, Net::IMAP.encode_utf7(name)) }
         | 
| 98 102 | 
             
                rescue Net::IMAP::NoResponseError
         | 
| 99 103 | 
             
                  raise NoLabelError, "Label '#{name}' doesn't exist!"
         | 
| 100 104 | 
             
                end
         | 
| 101 | 
            -
                alias :add_label :label
         | 
| 102 105 |  | 
| 103 106 | 
             
                # Mark this message with given label. When given label doesn't exist then
         | 
| 104 107 | 
             
                # it will be automaticaly created. 
         | 
| @@ -107,10 +110,11 @@ module Gmail | |
| 107 110 | 
             
                def label!(name, from=nil)
         | 
| 108 111 | 
             
                  label(name, from) 
         | 
| 109 112 | 
             
                rescue NoLabelError
         | 
| 110 | 
            -
                  @gmail.labels.add(name)
         | 
| 111 | 
            -
                  label | 
| 113 | 
            +
                  @gmail.labels.add(Net::IMAP.encode_utf7(name))
         | 
| 114 | 
            +
                  label(name, from)
         | 
| 112 115 | 
             
                end
         | 
| 113 | 
            -
                alias :add_label | 
| 116 | 
            +
                alias :add_label :label!
         | 
| 117 | 
            +
                alias :add_label! :label!
         | 
| 114 118 |  | 
| 115 119 | 
             
                # Remove given label from this message. 
         | 
| 116 120 | 
             
                def remove_label!(name)
         | 
| @@ -119,7 +123,7 @@ module Gmail | |
| 119 123 | 
             
                alias :delete_label! :remove_label!
         | 
| 120 124 |  | 
| 121 125 | 
             
                def inspect
         | 
| 122 | 
            -
                  "#<Gmail::Message#{'0x%04x' % (object_id << 1)} mailbox=#{@mailbox. | 
| 126 | 
            +
                  "#<Gmail::Message#{'0x%04x' % (object_id << 1)} mailbox=#{@mailbox.external_name}#{' uid='+@uid.to_s if @uid}#{' message_id='+@message_id.to_s if @message_id}>"
         | 
| 123 127 | 
             
                end
         | 
| 124 128 |  | 
| 125 129 | 
             
                def method_missing(meth, *args, &block)
         | 
| @@ -132,19 +136,29 @@ module Gmail | |
| 132 136 | 
             
                    super(meth, *args, &block)
         | 
| 133 137 | 
             
                  end
         | 
| 134 138 | 
             
                end
         | 
| 135 | 
            -
             | 
| 139 | 
            +
             | 
| 140 | 
            +
                def respond_to?(meth, *args, &block)
         | 
| 141 | 
            +
                  if envelope.respond_to?(meth)
         | 
| 142 | 
            +
                    return true
         | 
| 143 | 
            +
                  elsif message.respond_to?(meth)
         | 
| 144 | 
            +
                    return true
         | 
| 145 | 
            +
                  else
         | 
| 146 | 
            +
                    super(meth, *args, &block)
         | 
| 147 | 
            +
                  end
         | 
| 148 | 
            +
                end
         | 
| 149 | 
            +
             | 
| 136 150 | 
             
                def envelope
         | 
| 137 151 | 
             
                  @envelope ||= @gmail.mailbox(@mailbox.name) {
         | 
| 138 152 | 
             
                    @gmail.conn.uid_fetch(uid, "ENVELOPE")[0].attr["ENVELOPE"]
         | 
| 139 153 | 
             
                  }
         | 
| 140 154 | 
             
                end
         | 
| 141 | 
            -
             | 
| 142 | 
            -
                private
         | 
| 143 155 |  | 
| 144 156 | 
             
                def message
         | 
| 145 157 | 
             
                  @message ||= Mail.new(@gmail.mailbox(@mailbox.name) { 
         | 
| 146 158 | 
             
                    @gmail.conn.uid_fetch(uid, "RFC822")[0].attr["RFC822"] # RFC822
         | 
| 147 159 | 
             
                  })
         | 
| 148 160 | 
             
                end
         | 
| 161 | 
            +
                alias_method :raw_message, :message
         | 
| 162 | 
            +
             | 
| 149 163 | 
             
              end # Message
         | 
| 150 164 | 
             
            end # Gmail
         | 
    
        data/lib/gmail/version.rb
    CHANGED
    
    
    
        data/spec/client_spec.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 | 
            -
            describe "Gmail client" do
         | 
| 4 | 
            -
              subject { Gmail::Client }
         | 
| 3 | 
            +
            describe "Gmail client (Plain)" do
         | 
| 4 | 
            +
              subject { Gmail::Client::Plain }
         | 
| 5 5 |  | 
| 6 6 | 
             
              context "on initialize" do
         | 
| 7 7 | 
             
                it "should set username, password and options" do
         | 
| @@ -19,7 +19,7 @@ describe "Gmail client" do | |
| 19 19 |  | 
| 20 20 | 
             
              context "instance" do
         | 
| 21 21 | 
             
                def mock_client(&block) 
         | 
| 22 | 
            -
                  client = Gmail::Client.new(*TEST_ACCOUNT)
         | 
| 22 | 
            +
                  client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
         | 
| 23 23 | 
             
                  if block_given?
         | 
| 24 24 | 
             
                    client.connect
         | 
| 25 25 | 
             
                    yield client
         | 
| @@ -45,7 +45,7 @@ describe "Gmail client" do | |
| 45 45 |  | 
| 46 46 | 
             
                it "should raise error when given GMail account is invalid and errors enabled" do
         | 
| 47 47 | 
             
                  lambda {
         | 
| 48 | 
            -
                    client = Gmail::Client.new("foo", "bar")
         | 
| 48 | 
            +
                    client = Gmail::Client::Plain.new("foo", "bar")
         | 
| 49 49 | 
             
                    client.connect.should be_true
         | 
| 50 50 | 
             
                    client.login!.should_not be_true
         | 
| 51 51 | 
             
                  }.should raise_error(Gmail::Client::AuthorizationError)
         | 
| @@ -53,7 +53,7 @@ describe "Gmail client" do | |
| 53 53 |  | 
| 54 54 | 
             
                it "shouldn't login when given GMail account is invalid" do
         | 
| 55 55 | 
             
                  lambda {
         | 
| 56 | 
            -
                    client = Gmail::Client.new("foo", "bar")
         | 
| 56 | 
            +
                    client = Gmail::Client::Plain.new("foo", "bar")
         | 
| 57 57 | 
             
                    client.connect.should be_true
         | 
| 58 58 | 
             
                    client.login.should_not be_true
         | 
| 59 59 | 
             
                  }.should_not raise_error(Gmail::Client::AuthorizationError)
         | 
| @@ -137,7 +137,7 @@ describe "Gmail client" do | |
| 137 137 |  | 
| 138 138 | 
             
                context "labels" do
         | 
| 139 139 | 
             
                  subject { 
         | 
| 140 | 
            -
                    client = Gmail::Client.new(*TEST_ACCOUNT)
         | 
| 140 | 
            +
                    client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
         | 
| 141 141 | 
             
                    client.connect
         | 
| 142 142 | 
             
                    client.labels
         | 
| 143 143 | 
             
                  }
         | 
    
        data/spec/gmail_spec.rb
    CHANGED
    
    | @@ -8,14 +8,14 @@ describe "Any object" do | |
| 8 8 | 
             
              %w[new new!].each do |method|
         | 
| 9 9 | 
             
                it "##{method} should properly connect with GMail service and return valid connection object" do
         | 
| 10 10 | 
             
                  gmail = Gmail.send(method, *TEST_ACCOUNT)
         | 
| 11 | 
            -
                  gmail.should be_kind_of(Gmail::Client)
         | 
| 11 | 
            +
                  gmail.should be_kind_of(Gmail::Client::Plain)
         | 
| 12 12 | 
             
                  gmail.connection.should_not be_nil
         | 
| 13 13 | 
             
                  gmail.should be_logged_in
         | 
| 14 14 | 
             
                end
         | 
| 15 15 |  | 
| 16 16 | 
             
                it "##{method} should connect with client and give it context when block given" do
         | 
| 17 17 | 
             
                  Gmail.send(method, *TEST_ACCOUNT) do |gmail|
         | 
| 18 | 
            -
                    gmail.should be_kind_of(Gmail::Client)
         | 
| 18 | 
            +
                    gmail.should be_kind_of(Gmail::Client::Plain)
         | 
| 19 19 | 
             
                    gmail.connection.should_not be_nil
         | 
| 20 20 | 
             
                    gmail.should be_logged_in
         | 
| 21 21 | 
             
                  end
         | 
    
        data/spec/mailbox_spec.rb
    CHANGED
    
    | @@ -34,5 +34,16 @@ describe "A Gmail mailbox" do | |
| 34 34 | 
             
                    mailbox.emails(:all, :from => message.from.first.name) == message.from.first.name
         | 
| 35 35 | 
             
                  end
         | 
| 36 36 | 
             
                end
         | 
| 37 | 
            +
                
         | 
| 38 | 
            +
                it "should be able to do a full text search of message bodies" do
         | 
| 39 | 
            +
                  pending "This can wait..."
         | 
| 40 | 
            +
                  #mock_mailbox do |mailbox|
         | 
| 41 | 
            +
                  #  message = mailbox.emails.first
         | 
| 42 | 
            +
                  #  body = message.parts.blank? ? message.body.decoded : message.parts[0].body.decoded
         | 
| 43 | 
            +
                  #  emails = mailbox.emails(:search => body.split(' ').first)
         | 
| 44 | 
            +
                  #  emails.size.should > 0
         | 
| 45 | 
            +
                  #end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
                
         | 
| 37 48 | 
             
              end
         | 
| 38 49 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,12 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: gmail
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              hash: 15
         | 
| 4 5 | 
             
              prerelease: false
         | 
| 5 6 | 
             
              segments: 
         | 
| 6 7 | 
             
              - 0
         | 
| 7 | 
            -
              - 3
         | 
| 8 8 | 
             
              - 4
         | 
| 9 | 
            -
               | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 0.4.0
         | 
| 10 11 | 
             
            platform: ruby
         | 
| 11 12 | 
             
            authors: 
         | 
| 12 13 | 
             
            - BehindLogic
         | 
| @@ -15,7 +16,7 @@ autorequire: | |
| 15 16 | 
             
            bindir: bin
         | 
| 16 17 | 
             
            cert_chain: []
         | 
| 17 18 |  | 
| 18 | 
            -
            date:  | 
| 19 | 
            +
            date: 2011-01-13 00:00:00 +01:00
         | 
| 19 20 | 
             
            default_executable: 
         | 
| 20 21 | 
             
            dependencies: 
         | 
| 21 22 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -26,6 +27,7 @@ dependencies: | |
| 26 27 | 
             
                requirements: 
         | 
| 27 28 | 
             
                - - ">="
         | 
| 28 29 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 30 | 
            +
                    hash: 9
         | 
| 29 31 | 
             
                    segments: 
         | 
| 30 32 | 
             
                    - 0
         | 
| 31 33 | 
             
                    - 1
         | 
| @@ -40,6 +42,7 @@ dependencies: | |
| 40 42 | 
             
                requirements: 
         | 
| 41 43 | 
             
                - - ">="
         | 
| 42 44 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 45 | 
            +
                    hash: 5
         | 
| 43 46 | 
             
                    segments: 
         | 
| 44 47 | 
             
                    - 2
         | 
| 45 48 | 
             
                    - 2
         | 
| @@ -48,33 +51,51 @@ dependencies: | |
| 48 51 | 
             
              type: :runtime
         | 
| 49 52 | 
             
              version_requirements: *id002
         | 
| 50 53 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 51 | 
            -
              name:  | 
| 54 | 
            +
              name: gmail_xoauth
         | 
| 52 55 | 
             
              prerelease: false
         | 
| 53 56 | 
             
              requirement: &id003 !ruby/object:Gem::Requirement 
         | 
| 57 | 
            +
                none: false
         | 
| 58 | 
            +
                requirements: 
         | 
| 59 | 
            +
                - - ">="
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 61 | 
            +
                    hash: 19
         | 
| 62 | 
            +
                    segments: 
         | 
| 63 | 
            +
                    - 0
         | 
| 64 | 
            +
                    - 3
         | 
| 65 | 
            +
                    - 0
         | 
| 66 | 
            +
                    version: 0.3.0
         | 
| 67 | 
            +
              type: :runtime
         | 
| 68 | 
            +
              version_requirements: *id003
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 70 | 
            +
              name: rspec
         | 
| 71 | 
            +
              prerelease: false
         | 
| 72 | 
            +
              requirement: &id004 !ruby/object:Gem::Requirement 
         | 
| 54 73 | 
             
                none: false
         | 
| 55 74 | 
             
                requirements: 
         | 
| 56 75 | 
             
                - - ~>
         | 
| 57 76 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 77 | 
            +
                    hash: 3
         | 
| 58 78 | 
             
                    segments: 
         | 
| 59 79 | 
             
                    - 2
         | 
| 60 80 | 
             
                    - 0
         | 
| 61 81 | 
             
                    version: "2.0"
         | 
| 62 82 | 
             
              type: :development
         | 
| 63 | 
            -
              version_requirements: * | 
| 83 | 
            +
              version_requirements: *id004
         | 
| 64 84 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 65 85 | 
             
              name: mocha
         | 
| 66 86 | 
             
              prerelease: false
         | 
| 67 | 
            -
              requirement: & | 
| 87 | 
            +
              requirement: &id005 !ruby/object:Gem::Requirement 
         | 
| 68 88 | 
             
                none: false
         | 
| 69 89 | 
             
                requirements: 
         | 
| 70 90 | 
             
                - - ">="
         | 
| 71 91 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 92 | 
            +
                    hash: 25
         | 
| 72 93 | 
             
                    segments: 
         | 
| 73 94 | 
             
                    - 0
         | 
| 74 95 | 
             
                    - 9
         | 
| 75 96 | 
             
                    version: "0.9"
         | 
| 76 97 | 
             
              type: :development
         | 
| 77 | 
            -
              version_requirements: * | 
| 98 | 
            +
              version_requirements: *id005
         | 
| 78 99 | 
             
            description: A Rubyesque interface to Gmail, with all the tools you will need. Search, read and send multipart emails; archive, mark as read/unread, delete emails; and manage labels.
         | 
| 79 100 | 
             
            email: 
         | 
| 80 101 | 
             
            - chris@nu7hat.ch
         | 
| @@ -97,6 +118,9 @@ files: | |
| 97 118 | 
             
            - gmail.gemspec
         | 
| 98 119 | 
             
            - lib/gmail.rb
         | 
| 99 120 | 
             
            - lib/gmail/client.rb
         | 
| 121 | 
            +
            - lib/gmail/client/base.rb
         | 
| 122 | 
            +
            - lib/gmail/client/plain.rb
         | 
| 123 | 
            +
            - lib/gmail/client/xoauth.rb
         | 
| 100 124 | 
             
            - lib/gmail/labels.rb
         | 
| 101 125 | 
             
            - lib/gmail/mailbox.rb
         | 
| 102 126 | 
             
            - lib/gmail/message.rb
         | 
| @@ -121,6 +145,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 121 145 | 
             
              requirements: 
         | 
| 122 146 | 
             
              - - ">="
         | 
| 123 147 | 
             
                - !ruby/object:Gem::Version 
         | 
| 148 | 
            +
                  hash: 3
         | 
| 124 149 | 
             
                  segments: 
         | 
| 125 150 | 
             
                  - 0
         | 
| 126 151 | 
             
                  version: "0"
         | 
| @@ -129,6 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 129 154 | 
             
              requirements: 
         | 
| 130 155 | 
             
              - - ">="
         | 
| 131 156 | 
             
                - !ruby/object:Gem::Version 
         | 
| 157 | 
            +
                  hash: 3
         | 
| 132 158 | 
             
                  segments: 
         | 
| 133 159 | 
             
                  - 0
         | 
| 134 160 | 
             
                  version: "0"
         |