gmail 0.4.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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