gmail 0.4.0 → 0.4.2

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/Rakefile CHANGED
@@ -1,45 +1,35 @@
1
- # -*- ruby -*-
2
- $:.unshift(File.expand_path('../lib', __FILE__))
3
- require 'gmail/version'
4
- require 'rspec/core/rake_task'
5
- require 'rake/rdoctask'
6
-
7
- RSpec::Core::RakeTask.new(:spec) do |t|
8
- t.pattern = 'spec/**/*_spec.rb'
9
- t.rspec_opts = %q[-c -b]
10
- end
11
-
12
- RSpec::Core::RakeTask.new(:rcov) do |t|
13
- t.rcov = true
14
- t.rspec_opts = %q[-c -b]
15
- t.rcov_opts = %q[-T -x "spec"]
16
- end
17
-
18
- Rake::RDocTask.new do |rdoc|
19
- rdoc.rdoc_dir = 'rdoc'
20
- rdoc.title = "Gmail #{Gmail.version}"
21
- rdoc.rdoc_files.include('README*')
22
- rdoc.rdoc_files.include('lib/**/*.rb')
23
- end
24
-
25
- task :default => :spec
26
-
27
- desc "Build current version as a rubygem"
28
- task :build do
29
- `gem build gmail.gemspec`
30
- `mkdir -p pkg`
31
- `mv gmail-*.gem pkg/`
32
- end
33
-
34
- desc "Relase current version to rubygems.org"
35
- task :release => :build do
36
- `git tag -am "Version bump to #{Gmail.version}" v#{Gmail.version}`
37
- `git push origin master`
38
- `git push origin master --tags`
39
- `gem push pkg/gmail-#{Gmail.version}.gem`
40
- end
41
-
42
- desc "Perform installation via rubygems"
43
- task :install => :build do
44
- `gem install pkg/gmail-#{Gmail.version}.gem`
45
- end
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ begin
10
+ require 'rdoc/task'
11
+ rescue LoadError
12
+ require 'rdoc/rdoc'
13
+ require 'rake/rdoctask'
14
+ RDoc::Task = Rake::RDocTask
15
+ end
16
+
17
+ RDoc::Task.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = "Gmail for Ruby #{Gmail::VERSION}"
20
+ rdoc.rdoc_files.include('README*')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+ Bundler::GemHelper.install_tasks
25
+
26
+ begin
27
+ require 'rspec/core/rake_task'
28
+ RSpec::Core::RakeTask.new(:spec)
29
+ rescue LoadError
30
+ task :spec do
31
+ abort 'Run `gem install rspec` to install RSpec'
32
+ end
33
+ end
34
+
35
+ task :default => :spec
data/TODO.md CHANGED
@@ -1,7 +1,12 @@
1
- # TODO
2
-
3
- * Info about xoauth and plain authentication in readme
4
- * Specs for xoauth
5
- * Specs for message operations
6
- * Specs for filters in mailbox
7
- * Non-English accounts
1
+ # TODO
2
+
3
+ * Specs for xoauth
4
+ * Specs for message operations
5
+ * Specs for filters in mailbox
6
+ * Specs for current [Gmail IMAP extensions](http://code.google.com/apis/gmail/imap/)
7
+ * Non-English accounts
8
+ * Further implement [Gmail IMAP extensions](http://code.google.com/apis/gmail/imap/)
9
+ * add custom search (X-GM-RAW)
10
+ * add thread id (X-GM-THRID)
11
+ * Export/Import to mbox format
12
+ * Integration with [contacts](http://rubygems.org/gems/contacts) gem
@@ -1,23 +1,34 @@
1
- # -*- ruby -*-
2
- $:.unshift(File.expand_path('../lib', __FILE__))
3
- require 'gmail/version'
4
-
5
- Gem::Specification.new do |s|
6
- s.name = 'gmail'
7
- s.version = Gmail.version
8
- s.homepage = 'http://github.com/nu7hatch/gmail'
9
- s.email = ['chris@nu7hat.ch']
10
- s.authors = ['BehindLogic', 'Chris Kowalik']
11
- s.summary = %q{A Rubyesque interface to Gmail, with all the tools you will need.}
12
- s.description = %q{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.}
13
- s.files = `git ls-files`.split("\n")
14
- s.test_files = `git ls-files -- {spec}/*`.split("\n")
15
- s.require_paths = %w[lib]
16
- s.extra_rdoc_files = %w[LICENSE README.md CHANGELOG.md TODO.md]
17
-
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'
23
- end
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path('../lib', __FILE__)
4
+ require 'gmail/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "gmail"
8
+ s.summary = "A Rubyesque interface to Gmail, with all the tools you will need."
9
+ s.description = "A Rubyesque interface to Gmail, with all the tools you will need.
10
+ Search, read and send multipart emails; archive, mark as read/unread,
11
+ delete emails; and manage labels.
12
+ "
13
+ s.version = Gmail::VERSION
14
+ s.platform = Gem::Platform::RUBY
15
+ s.authors = ["Chris Kowalik"]
16
+ s.email = ["chris@nu7hat.ch"]
17
+ s.homepage = "http://github.com/nu7hatch/gmail"
18
+
19
+ # runtime dependencies
20
+ s.add_dependency "mime", ">= 0.1"
21
+ s.add_dependency "mail", ">= 2.2.1"
22
+ s.add_dependency "gmail_xoauth", ">= 0.3.0"
23
+
24
+ # development dependencies
25
+ s.add_development_dependency "rake"
26
+ s.add_development_dependency "rspec", "~> 2.0"
27
+ s.add_development_dependency "mocha", ">= 0.9"
28
+ s.add_development_dependency "gem-release"
29
+
30
+ s.files = `git ls-files`.split("\n")
31
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
32
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
33
+ s.require_paths = ["lib"]
34
+ end
@@ -1,82 +1,65 @@
1
- require 'net/imap'
2
- require 'net/smtp'
3
- require 'mail'
4
- require 'date'
5
- require 'time'
6
-
7
- if RUBY_VERSION < "1.8.7"
8
- require "smtp_tls"
9
- end
10
-
11
- class Object
12
- def to_imap_date
13
- Date.parse(to_s).strftime("%d-%B-%Y")
14
- end
15
- end
16
-
17
- module Gmail
18
- autoload :Version, "gmail/version"
19
- autoload :Client, "gmail/client"
20
- autoload :Labels, "gmail/labels"
21
- autoload :Mailbox, "gmail/mailbox"
22
- autoload :Message, "gmail/message"
23
-
24
- class << self
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)
49
- client.connect and client.login
50
- perform_block(client, &block)
51
- end
52
- alias :connect :new
53
-
54
- def new!(*args, &block)
55
- client = connect_with_proper_client(*args)
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)
74
- if block_given?
75
- yield client
76
- client.logout
77
- end
78
- client
79
- end
80
-
81
- end # << self
82
- end # Gmail
1
+ require 'net/imap'
2
+ require 'net/smtp'
3
+ require 'mail'
4
+ require 'date'
5
+ require 'time'
6
+
7
+ if RUBY_VERSION < "1.8.7"
8
+ require "smtp_tls"
9
+ end
10
+
11
+ class Object
12
+ def to_imap_date
13
+ Date.parse(to_s).strftime("%d-%B-%Y")
14
+ end
15
+ end
16
+
17
+ module Gmail
18
+ autoload :Version, "gmail/version"
19
+ autoload :Client, "gmail/client"
20
+ autoload :Labels, "gmail/labels"
21
+ autoload :Mailbox, "gmail/mailbox"
22
+ autoload :Message, "gmail/message"
23
+
24
+ class << self
25
+ # Creates new Gmail connection using given authorization options.
26
+ #
27
+ # ==== Examples
28
+ #
29
+ # Gmail.new(:plain, "foo@gmail.com", "password")
30
+ # Gmail.new(:xoauth, "foo@gmail.com",
31
+ # :consumer_key => "",
32
+ # :consumer_secret => "",
33
+ # :token => "",
34
+ # :secret => "")
35
+ #
36
+ # To use plain authentication mehod you can also call:
37
+ #
38
+ # Gmail.new("foo@gmail.com", "password")
39
+ #
40
+ # You can also use block-style call:
41
+ #
42
+ # Gmail.new("foo@gmail.com", "password") do |client|
43
+ # # ...
44
+ # end
45
+ #
46
+
47
+ ['', '!'].each { |kind|
48
+ define_method("new#{kind}") do |*args, &block| # def new(*args, &block)
49
+ args.unshift(:plain) unless args.first.is_a?(Symbol) # args.unshift(:plain) unless args.first.is_a?(Symbol)
50
+ client = Gmail::Client.new(*args) # client = Gmail::Client.new(*args)
51
+ client.send("connect#{kind}") and client.send("login#{kind}") # client.connect and client.login
52
+ #
53
+ if block_given? # if block_given?
54
+ yield client # yield client
55
+ client.logout # client.logout
56
+ end # end
57
+ #
58
+ client # client
59
+ end # end
60
+ }
61
+
62
+ alias :connect :new
63
+ alias :connect! :new!
64
+ end # << self
65
+ end # Gmail
@@ -1,22 +1,30 @@
1
- module Gmail
2
- module Client
3
- # Raised when connection with GMail IMAP service couldn't be established.
4
- class ConnectionError < SocketError; end
5
- # Raised when given username or password are invalid.
6
- class AuthorizationError < Net::IMAP::NoResponseError; end
7
- # Raised when delivered email is invalid.
8
- class DeliveryError < ArgumentError; end
9
-
10
- autoload :Base, 'gmail/client/base'
11
- autoload :Plain, 'gmail/client/plain'
12
- autoload :XOAuth, 'gmail/client/xoauth'
13
-
14
- def self.new_plain(*args)
15
- Gmail::Client::Plain.new(*args)
16
- end
17
-
18
- def self.new_xoauth(*args)
19
- Gmail::Client::XOAuth.new(*args)
20
- end
21
- end # Client
22
- end # Gmail
1
+ module Gmail
2
+ module Client
3
+ # Raised when connection with GMail IMAP service couldn't be established.
4
+ class ConnectionError < SocketError; end
5
+ # Raised when given username or password are invalid.
6
+ class AuthorizationError < Net::IMAP::NoResponseError; end
7
+ # Raised when delivered email is invalid.
8
+ class DeliveryError < ArgumentError; end
9
+ # Raised when given client is not registered
10
+ class UnknownClient < ArgumentError; end
11
+
12
+ def self.register(name, klass)
13
+ @clients ||= {}
14
+ @clients[name] = klass
15
+ end
16
+
17
+ def self.new(name, *args)
18
+ if client = @clients[name]
19
+ client.new(*args)
20
+ else
21
+ raise UnknownClient, "No such client: #{name}"
22
+ end
23
+ end
24
+
25
+ require 'gmail/client/imap_extensions'
26
+ require 'gmail/client/base'
27
+ require 'gmail/client/plain'
28
+ require 'gmail/client/xoauth'
29
+ end # Client
30
+ end # Gmail
@@ -1,220 +1,225 @@
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
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
+ GmailImapExtensions.patch_net_imap_response_parser
28
+ @imap
29
+ rescue SocketError
30
+ raise_errors and raise ConnectionError, "Couldn't establish connection with GMail IMAP service"
31
+ end
32
+
33
+ # This version of connect will raise error on failure...
34
+ def connect!
35
+ connect(true)
36
+ end
37
+
38
+ # Return current connection. Log in automaticaly to specified account if
39
+ # it is necessary.
40
+ def connection
41
+ login and at_exit { logout } unless logged_in?
42
+ @imap
43
+ end
44
+ alias :conn :connection
45
+
46
+ # Login to specified account.
47
+ def login(*args)
48
+ raise NotImplementedError, "The `#{self.class.name}#login` method is not implemented."
49
+ end
50
+ alias :sign_in :login
51
+
52
+ # This version of login will raise error on failure...
53
+ def login!
54
+ login(true)
55
+ end
56
+ alias :sign_in! :login!
57
+
58
+ # Returns +true+ when you are logged in to specified account.
59
+ def logged_in?
60
+ !!@logged_in
61
+ end
62
+ alias :signed_in? :logged_in?
63
+
64
+ # Logout from GMail service.
65
+ def logout
66
+ @imap && logged_in? and @imap.logout
67
+ ensure
68
+ @logged_in = false
69
+ end
70
+ alias :sign_out :logout
71
+
72
+ # Return labels object, which helps you with managing your GMail labels.
73
+ # See <tt>Gmail::Labels</tt> for details.
74
+ def labels
75
+ @labels ||= Labels.new(conn)
76
+ end
77
+
78
+ # Compose new e-mail.
79
+ #
80
+ # ==== Examples
81
+ #
82
+ # mail = gmail.compose
83
+ # mail.from "test@gmail.org"
84
+ # mail.to "friend@gmail.com"
85
+ #
86
+ # ... or block style:
87
+ #
88
+ # mail = gmail.compose do
89
+ # from "test@gmail.org"
90
+ # to "friend@gmail.com"
91
+ # subject "Hello!"
92
+ # body "Hello my friend! long time..."
93
+ # end
94
+ #
95
+ # Now you can deliver your mail:
96
+ #
97
+ # gmail.deliver(mail)
98
+ def compose(mail=nil, &block)
99
+ if block_given?
100
+ mail = Mail.new(&block)
101
+ elsif !mail
102
+ mail = Mail.new
103
+ end
104
+
105
+ mail.delivery_method(*smtp_settings)
106
+ mail.from = username unless mail.from
107
+ mail
108
+ end
109
+ alias :message :compose
110
+
111
+ # Compose (optionaly) and send given email.
112
+ #
113
+ # ==== Examples
114
+ #
115
+ # gmail.deliver do
116
+ # to "friend@gmail.com"
117
+ # subject "Hello friend!"
118
+ # body "Hi! How are you?"
119
+ # end
120
+ #
121
+ # ... or with already created message:
122
+ #
123
+ # mail = Mail.new { ... }
124
+ # gmail.deliver(mail)
125
+ #
126
+ # mail = gmail.compose { ... }
127
+ # gmail.deliver(mail)
128
+ def deliver(mail=nil, raise_errors=false, &block)
129
+ mail = compose(mail, &block) if block_given?
130
+ mail.deliver!
131
+ rescue Object => ex
132
+ raise_errors and raise DeliveryError, "Couldn't deliver email: #{ex.to_s}"
133
+ end
134
+
135
+ # This version of deliver will raise error on failure...
136
+ def deliver!(mail=nil, &block)
137
+ deliver(mail, true, &block)
138
+ end
139
+
140
+ # Do something with given mailbox or within it context.
141
+ #
142
+ # ==== Examples
143
+ #
144
+ # mailbox = gmail.mailbox("INBOX")
145
+ # mailbox.emails(:all)
146
+ # mailbox.count(:unread, :before => Time.now-(20*24*3600))
147
+ #
148
+ # ... or block style:
149
+ #
150
+ # gmail.label("Work") do |mailbox|
151
+ # mailbox.emails(:unread)
152
+ # mailbox.count(:all)
153
+ # ...
154
+ # end
155
+ def mailbox(name, &block)
156
+ @mailbox_mutex.synchronize do
157
+ name = name.to_s
158
+ mailbox = (mailboxes[name] ||= Mailbox.new(self, name))
159
+ switch_to_mailbox(name) if @current_mailbox != name
160
+
161
+ if block_given?
162
+ mailbox_stack << @current_mailbox
163
+ result = block.arity == 1 ? block.call(mailbox) : block.call
164
+ mailbox_stack.pop
165
+ switch_to_mailbox(mailbox_stack.last)
166
+ return result
167
+ end
168
+
169
+ return mailbox
170
+ end
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
193
+
194
+ def mail_domain
195
+ username.split('@').last
196
+ end
197
+
198
+ private
199
+
200
+ def switch_to_mailbox(mailbox)
201
+ if mailbox
202
+ mailbox = Net::IMAP.encode_utf7(mailbox)
203
+ conn.select(mailbox)
204
+ end
205
+ @current_mailbox = mailbox
206
+ end
207
+
208
+ def mailbox_stack
209
+ @mailbox_stack ||= []
210
+ end
211
+
212
+ def smtp_settings
213
+ [:smtp, {
214
+ :address => GMAIL_SMTP_HOST,
215
+ :port => GMAIL_SMTP_PORT,
216
+ :domain => mail_domain,
217
+ :user_name => username,
218
+ :password => password,
219
+ :authentication => 'plain',
220
+ :enable_starttls_auto => true
221
+ }]
222
+ end
223
+ end # Base
224
+ end # Client
225
+ end # Gmail