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.
@@ -1,164 +1,166 @@
1
- require 'mime/message'
2
-
3
- module Gmail
4
- class Message
5
- # Raised when given label doesn't exists.
6
- class NoLabelError < Exception; end
7
-
8
- attr_reader :uid
9
-
10
- def initialize(mailbox, uid)
11
- @uid = uid
12
- @mailbox = mailbox
13
- @gmail = mailbox.instance_variable_get("@gmail") if mailbox
14
- end
15
-
16
- def uid
17
- @uid ||= @gmail.conn.uid_search(['HEADER', 'Message-ID', message_id])[0]
18
- end
19
-
20
- # Mark message with given flag.
21
- def flag(name)
22
- !!@gmail.mailbox(@mailbox.name) { @gmail.conn.uid_store(uid, "+FLAGS", [name]) }
23
- end
24
-
25
- # Unmark message.
26
- def unflag(name)
27
- !!@gmail.mailbox(@mailbox.name) { @gmail.conn.uid_store(uid, "-FLAGS", [name]) }
28
- end
29
-
30
- # Do commonly used operations on message.
31
- def mark(flag)
32
- case flag
33
- when :read then read!
34
- when :unread then unread!
35
- when :deleted then delete!
36
- when :spam then spam!
37
- else
38
- flag(flag)
39
- end
40
- end
41
-
42
- # Mark this message as a spam.
43
- def spam!
44
- move_to('[Gmail]/Spam')
45
- end
46
-
47
- # Mark as read.
48
- def read!
49
- flag(:Seen)
50
- end
51
-
52
- # Mark as unread.
53
- def unread!
54
- unflag(:Seen)
55
- end
56
-
57
- # Mark message with star.
58
- def star!
59
- flag('[Gmail]/Starred')
60
- end
61
-
62
- # Remove message from list of starred.
63
- def unstar!
64
- unflag('[Gmail]/Starred')
65
- end
66
-
67
- # Move to trash / bin.
68
- def delete!
69
- @mailbox.messages.delete(uid)
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)
75
- end
76
-
77
- # Archive this message.
78
- def archive!
79
- move_to('[Gmail]/All Mail')
80
- end
81
-
82
- # Move to given box and delete from others.
83
- def move_to(name, from=nil)
84
- label(name, from)
85
- delete! if !%w[[Gmail]/Bin [Gmail]/Trash].include?(name)
86
- end
87
- alias :move :move_to
88
-
89
- # Move message to given and delete from others. When given mailbox doesn't
90
- # exist then it will be automaticaly created.
91
- def move_to!(name, from=nil)
92
- label!(name, from) && delete!
93
- end
94
- alias :move! :move_to!
95
-
96
- # Mark this message with given label. When given label doesn't exist then
97
- # it will raise <tt>NoLabelError</tt>.
98
- #
99
- # See also <tt>Gmail::Message#label!</tt>.
100
- def label(name, from=nil)
101
- @gmail.mailbox(Net::IMAP.encode_utf7(from || @mailbox.external_name)) { @gmail.conn.uid_copy(uid, Net::IMAP.encode_utf7(name)) }
102
- rescue Net::IMAP::NoResponseError
103
- raise NoLabelError, "Label '#{name}' doesn't exist!"
104
- end
105
-
106
- # Mark this message with given label. When given label doesn't exist then
107
- # it will be automaticaly created.
108
- #
109
- # See also <tt>Gmail::Message#label</tt>.
110
- def label!(name, from=nil)
111
- label(name, from)
112
- rescue NoLabelError
113
- @gmail.labels.add(Net::IMAP.encode_utf7(name))
114
- label(name, from)
115
- end
116
- alias :add_label :label!
117
- alias :add_label! :label!
118
-
119
- # Remove given label from this message.
120
- def remove_label!(name)
121
- move_to('[Gmail]/All Mail', name)
122
- end
123
- alias :delete_label! :remove_label!
124
-
125
- def inspect
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}>"
127
- end
128
-
129
- def method_missing(meth, *args, &block)
130
- # Delegate rest directly to the message.
131
- if envelope.respond_to?(meth)
132
- envelope.send(meth, *args, &block)
133
- elsif message.respond_to?(meth)
134
- message.send(meth, *args, &block)
135
- else
136
- super(meth, *args, &block)
137
- end
138
- end
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
-
150
- def envelope
151
- @envelope ||= @gmail.mailbox(@mailbox.name) {
152
- @gmail.conn.uid_fetch(uid, "ENVELOPE")[0].attr["ENVELOPE"]
153
- }
154
- end
155
-
156
- def message
157
- @message ||= Mail.new(@gmail.mailbox(@mailbox.name) {
158
- @gmail.conn.uid_fetch(uid, "RFC822")[0].attr["RFC822"] # RFC822
159
- })
160
- end
161
- alias_method :raw_message, :message
162
-
163
- end # Message
164
- end # Gmail
1
+ module Gmail
2
+ class Message
3
+ # Raised when given label doesn't exists.
4
+ class NoLabelError < Exception; end
5
+
6
+ attr_reader :uid
7
+
8
+ def initialize(mailbox, uid)
9
+ @uid = uid
10
+ @mailbox = mailbox
11
+ @gmail = mailbox.instance_variable_get("@gmail") if mailbox
12
+ end
13
+
14
+ def labels
15
+ @gmail.conn.uid_fetch(uid, "X-GM-LABELS")[0].attr["X-GM-LABELS"]
16
+ end
17
+
18
+ def uid
19
+ @uid ||= @gmail.conn.uid_search(['HEADER', 'Message-ID', message_id])[0]
20
+ end
21
+
22
+ # Mark message with given flag.
23
+ def flag(name)
24
+ !!@gmail.mailbox(@mailbox.name) { @gmail.conn.uid_store(uid, "+FLAGS", [name]) }
25
+ end
26
+
27
+ # Unmark message.
28
+ def unflag(name)
29
+ !!@gmail.mailbox(@mailbox.name) { @gmail.conn.uid_store(uid, "-FLAGS", [name]) }
30
+ end
31
+
32
+ # Do commonly used operations on message.
33
+ def mark(flag)
34
+ case flag
35
+ when :read then read!
36
+ when :unread then unread!
37
+ when :deleted then delete!
38
+ when :spam then spam!
39
+ else
40
+ flag(flag)
41
+ end
42
+ end
43
+
44
+ # Mark this message as a spam.
45
+ def spam!
46
+ move_to('[Gmail]/Spam')
47
+ end
48
+
49
+ # Mark as read.
50
+ def read!
51
+ flag(:Seen)
52
+ end
53
+
54
+ # Mark as unread.
55
+ def unread!
56
+ unflag(:Seen)
57
+ end
58
+
59
+ # Mark message with star.
60
+ def star!
61
+ flag('[Gmail]/Starred')
62
+ end
63
+
64
+ # Remove message from list of starred.
65
+ def unstar!
66
+ unflag('[Gmail]/Starred')
67
+ end
68
+
69
+ # Move to trash / bin.
70
+ def delete!
71
+ @mailbox.messages.delete(uid)
72
+ flag(:deleted)
73
+
74
+ # For some, it's called "Trash", for others, it's called "Bin". Support both.
75
+ trash = @gmail.labels.exist?('[Gmail]/Bin') ? '[Gmail]/Bin' : '[Gmail]/Trash'
76
+ move_to(trash) unless %w[[Gmail]/Spam [Gmail]/Bin [Gmail]/Trash].include?(@mailbox.name)
77
+ end
78
+
79
+ # Archive this message.
80
+ def archive!
81
+ move_to('[Gmail]/All Mail')
82
+ end
83
+
84
+ # Move to given box and delete from others.
85
+ def move_to(name, from=nil)
86
+ label(name, from)
87
+ delete! if !%w[[Gmail]/Bin [Gmail]/Trash].include?(name)
88
+ end
89
+ alias :move :move_to
90
+
91
+ # Move message to given and delete from others. When given mailbox doesn't
92
+ # exist then it will be automaticaly created.
93
+ def move_to!(name, from=nil)
94
+ label!(name, from) && delete!
95
+ end
96
+ alias :move! :move_to!
97
+
98
+ # Mark this message with given label. When given label doesn't exist then
99
+ # it will raise <tt>NoLabelError</tt>.
100
+ #
101
+ # See also <tt>Gmail::Message#label!</tt>.
102
+ def label(name, from=nil)
103
+ @gmail.mailbox(Net::IMAP.encode_utf7(from || @mailbox.external_name)) { @gmail.conn.uid_copy(uid, Net::IMAP.encode_utf7(name)) }
104
+ rescue Net::IMAP::NoResponseError
105
+ raise NoLabelError, "Label '#{name}' doesn't exist!"
106
+ end
107
+
108
+ # Mark this message with given label. When given label doesn't exist then
109
+ # it will be automaticaly created.
110
+ #
111
+ # See also <tt>Gmail::Message#label</tt>.
112
+ def label!(name, from=nil)
113
+ label(name, from)
114
+ rescue NoLabelError
115
+ @gmail.labels.add(Net::IMAP.encode_utf7(name))
116
+ label(name, from)
117
+ end
118
+ alias :add_label :label!
119
+ alias :add_label! :label!
120
+
121
+ # Remove given label from this message.
122
+ def remove_label!(name)
123
+ move_to('[Gmail]/All Mail', name)
124
+ end
125
+ alias :delete_label! :remove_label!
126
+
127
+ def inspect
128
+ "#<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}>"
129
+ end
130
+
131
+ def method_missing(meth, *args, &block)
132
+ # Delegate rest directly to the message.
133
+ if envelope.respond_to?(meth)
134
+ envelope.send(meth, *args, &block)
135
+ elsif message.respond_to?(meth)
136
+ message.send(meth, *args, &block)
137
+ else
138
+ super(meth, *args, &block)
139
+ end
140
+ end
141
+
142
+ def respond_to?(meth, *args, &block)
143
+ if envelope.respond_to?(meth)
144
+ return true
145
+ elsif message.respond_to?(meth)
146
+ return true
147
+ else
148
+ super(meth, *args, &block)
149
+ end
150
+ end
151
+
152
+ def envelope
153
+ @envelope ||= @gmail.mailbox(@mailbox.name) {
154
+ @gmail.conn.uid_fetch(uid, "ENVELOPE")[0].attr["ENVELOPE"]
155
+ }
156
+ end
157
+
158
+ def message
159
+ @message ||= Mail.new(@gmail.mailbox(@mailbox.name) {
160
+ @gmail.conn.uid_fetch(uid, "RFC822")[0].attr["RFC822"] # RFC822
161
+ })
162
+ end
163
+ alias_method :raw_message, :message
164
+
165
+ end # Message
166
+ end # Gmail
@@ -1,12 +1,3 @@
1
- module Gmail
2
- class Version #:nodoc:
3
- MAJOR = 0
4
- MINOR = 4
5
- PATCH = 0
6
- STRING = [MAJOR, MINOR, PATCH].join('.')
7
- end # Version
8
-
9
- def self.version # :nodoc:
10
- Version::STRING
11
- end
12
- end # Gmail
1
+ module Gmail
2
+ VERSION = "0.4.2"
3
+ end # Gmail
@@ -1,2 +1,2 @@
1
- - "test@gmail.com"
1
+ - "test@gmail.com"
2
2
  - "test"
@@ -1,173 +1,178 @@
1
- require 'spec_helper'
2
-
3
- describe "Gmail client (Plain)" do
4
- subject { Gmail::Client::Plain }
5
-
6
- context "on initialize" do
7
- it "should set username, password and options" do
8
- client = subject.new("test@gmail.com", "pass", :foo => :bar)
9
- client.username.should == "test@gmail.com"
10
- client.password.should == "pass"
11
- client.options[:foo].should == :bar
12
- end
13
-
14
- it "should convert simple name to gmail email" do
15
- client = subject.new("test", "pass")
16
- client.username.should == "test@gmail.com"
17
- end
18
- end
19
-
20
- context "instance" do
21
- def mock_client(&block)
22
- client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
23
- if block_given?
24
- client.connect
25
- yield client
26
- client.logout
27
- end
28
- client
29
- end
30
-
31
- it "should connect to GMail IMAP service" do
32
- lambda {
33
- client = mock_client
34
- client.connect!.should be_true
35
- }.should_not raise_error(Gmail::Client::ConnectionError)
36
- end
37
-
38
- it "should properly login to valid GMail account" do
39
- client = mock_client
40
- client.connect.should be_true
41
- client.login.should be_true
42
- client.should be_logged_in
43
- client.logout
44
- end
45
-
46
- it "should raise error when given GMail account is invalid and errors enabled" do
47
- lambda {
48
- client = Gmail::Client::Plain.new("foo", "bar")
49
- client.connect.should be_true
50
- client.login!.should_not be_true
51
- }.should raise_error(Gmail::Client::AuthorizationError)
52
- end
53
-
54
- it "shouldn't login when given GMail account is invalid" do
55
- lambda {
56
- client = Gmail::Client::Plain.new("foo", "bar")
57
- client.connect.should be_true
58
- client.login.should_not be_true
59
- }.should_not raise_error(Gmail::Client::AuthorizationError)
60
- end
61
-
62
- it "should properly logout from GMail" do
63
- client = mock_client
64
- client.connect
65
- client.login.should be_true
66
- client.logout.should be_true
67
- client.should_not be_logged_in
68
- end
69
-
70
- it "#connection should automatically log in to GMail account when it's called" do
71
- mock_client do |client|
72
- client.expects(:login).once.returns(false)
73
- client.connection.should_not be_nil
74
- end
75
- end
76
-
77
- it "should properly compose message" do
78
- mail = mock_client.compose do
79
- from "test@gmail.com"
80
- to "friend@gmail.com"
81
- subject "Hello world!"
82
- end
83
- mail.from.should == ["test@gmail.com"]
84
- mail.to.should == ["friend@gmail.com"]
85
- mail.subject.should == "Hello world!"
86
- end
87
-
88
- it "#compose should automatically add `from` header when it is not specified" do
89
- mail = mock_client.compose
90
- mail.from.should == [TEST_ACCOUNT[0]]
91
- mail = mock_client.compose(Mail.new)
92
- mail.from.should == [TEST_ACCOUNT[0]]
93
- mail = mock_client.compose {}
94
- mail.from.should == [TEST_ACCOUNT[0]]
95
- end
96
-
97
- it "should deliver inline composed email" do
98
- mock_client do |client|
99
- client.deliver do
100
- to TEST_ACCOUNT[0]
101
- subject "Hello world!"
102
- body "Yeah, hello there!"
103
- end.should be_true
104
- end
105
- end
106
-
107
- it "should not raise error when mail can't be delivered and errors are disabled" do
108
- lambda {
109
- client = mock_client
110
- client.deliver(Mail.new {}).should be_false
111
- }.should_not raise_error(Gmail::Client::DeliveryError)
112
- end
113
-
114
- it "should raise error when mail can't be delivered and errors are disabled" do
115
- lambda {
116
- client = mock_client
117
- client.deliver!(Mail.new {})
118
- }.should raise_error(Gmail::Client::DeliveryError)
119
- end
120
-
121
- it "should properly switch to given mailbox" do
122
- mock_client do |client|
123
- mailbox = client.mailbox("TEST")
124
- mailbox.should be_kind_of(Gmail::Mailbox)
125
- mailbox.name.should == "TEST"
126
- end
127
- end
128
-
129
- it "should properly switch to given mailbox using block style" do
130
- mock_client do |client|
131
- client.mailbox("TEST") do |mailbox|
132
- mailbox.should be_kind_of(Gmail::Mailbox)
133
- mailbox.name.should == "TEST"
134
- end
135
- end
136
- end
137
-
138
- context "labels" do
139
- subject {
140
- client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
141
- client.connect
142
- client.labels
143
- }
144
-
145
- it "should get list of all available labels" do
146
- labels = subject
147
- labels.all.should include("TEST", "INBOX")
148
- end
149
-
150
- it "should be able to check if there is given label defined" do
151
- labels = subject
152
- labels.exists?("TEST").should be_true
153
- labels.exists?("FOOBAR").should be_false
154
- end
155
-
156
- it "should be able to create given label" do
157
- labels = subject
158
- labels.create("MYLABEL")
159
- labels.exists?("MYLABEL").should be_true
160
- labels.create("MYLABEL").should be_false
161
- labels.delete("MYLABEL")
162
- end
163
-
164
- it "should be able to remove existing label" do
165
- labels = subject
166
- labels.create("MYLABEL")
167
- labels.delete("MYLABEL").should be_true
168
- labels.exists?("MYLABEL").should be_false
169
- labels.delete("MYLABEL").should be_false
170
- end
171
- end
172
- end
173
- end
1
+ require 'spec_helper'
2
+
3
+ describe "Gmail client (Plain)" do
4
+ subject { Gmail::Client::Plain }
5
+
6
+ context "on initialize" do
7
+ it "should set username, password and options" do
8
+ client = subject.new("test@gmail.com", "pass", :foo => :bar)
9
+ client.username.should == "test@gmail.com"
10
+ client.password.should == "pass"
11
+ client.options[:foo].should == :bar
12
+ end
13
+
14
+ it "should convert simple name to gmail email" do
15
+ client = subject.new("test", "pass")
16
+ client.username.should == "test@gmail.com"
17
+ end
18
+ end
19
+
20
+ context "instance" do
21
+ def mock_client(&block)
22
+ client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
23
+ if block_given?
24
+ client.connect
25
+ yield client
26
+ client.logout
27
+ end
28
+ client
29
+ end
30
+
31
+ it "should connect to GMail IMAP service" do
32
+ client = mock_client
33
+ client.connect!.should be_true
34
+ end
35
+
36
+ it "should properly login to valid GMail account" do
37
+ client = mock_client
38
+ client.connect.should be_true
39
+ client.login.should be_true
40
+ client.should be_logged_in
41
+ client.logout
42
+ end
43
+
44
+ it "should raise error when given GMail account is invalid and errors enabled" do
45
+ lambda {
46
+ client = Gmail::Client::Plain.new("foo", "bar")
47
+ client.connect.should be_true
48
+ client.login!.should_not be_nil
49
+ }.should raise_error
50
+ ### FIX: can someone dig to the bottom of this? We are getting NoMethodError instead of Gmail::Client::AuthorizationError in 1.9
51
+ end
52
+
53
+ it "shouldn't raise error even though GMail account is invalid" do
54
+ lambda {
55
+ client = Gmail::Client::Plain.new("foo", "bar")
56
+ client.connect.should be_true
57
+ expect(client.login).to_not be_true
58
+ }.should_not raise_error
59
+ end
60
+
61
+ it "shouldn't login when given GMail account is invalid" do
62
+ client = Gmail::Client::Plain.new("foo", "bar")
63
+ client.connect.should be_true
64
+ client.login.should be_false
65
+ end
66
+
67
+ it "should properly logout from GMail" do
68
+ client = mock_client
69
+ client.connect
70
+ client.login.should be_true
71
+ client.logout.should be_true
72
+ client.should_not be_logged_in
73
+ end
74
+
75
+ it "#connection should automatically log in to GMail account when it's called" do
76
+ mock_client do |client|
77
+ client.expects(:login).once.returns(false)
78
+ client.connection.should_not be_nil
79
+ end
80
+ end
81
+
82
+ it "should properly compose message" do
83
+ mail = mock_client.compose do
84
+ from "test@gmail.com"
85
+ to "friend@gmail.com"
86
+ subject "Hello world!"
87
+ end
88
+ mail.from.should == ["test@gmail.com"]
89
+ mail.to.should == ["friend@gmail.com"]
90
+ mail.subject.should == "Hello world!"
91
+ end
92
+
93
+ it "#compose should automatically add `from` header when it is not specified" do
94
+ mail = mock_client.compose
95
+ mail.from.should == [TEST_ACCOUNT[0]]
96
+ mail = mock_client.compose(Mail.new)
97
+ mail.from.should == [TEST_ACCOUNT[0]]
98
+ mail = mock_client.compose {}
99
+ mail.from.should == [TEST_ACCOUNT[0]]
100
+ end
101
+
102
+ it "should deliver inline composed email" do
103
+ mock_client do |client|
104
+ client.deliver do
105
+ to TEST_ACCOUNT[0]
106
+ subject "Hello world!"
107
+ body "Yeah, hello there!"
108
+ end.should be_true
109
+ end
110
+ end
111
+
112
+ it "should not raise error when mail can't be delivered and errors are disabled" do
113
+ lambda {
114
+ client = mock_client
115
+ client.deliver(Mail.new {}).should be_false
116
+ }.should_not raise_error
117
+ end
118
+
119
+ it "should raise error when mail can't be delivered and errors are disabled" do
120
+ lambda {
121
+ client = mock_client
122
+ client.deliver!(Mail.new {})
123
+ }.should raise_error(Gmail::Client::DeliveryError)
124
+ end
125
+
126
+ it "should properly switch to given mailbox" do
127
+ mock_client do |client|
128
+ mailbox = client.mailbox("INBOX")
129
+ mailbox.should be_kind_of(Gmail::Mailbox)
130
+ mailbox.name.should == "INBOX"
131
+ end
132
+ end
133
+
134
+ it "should properly switch to given mailbox using block style" do
135
+ mock_client do |client|
136
+ client.mailbox("INBOX") do |mailbox|
137
+ mailbox.should be_kind_of(Gmail::Mailbox)
138
+ mailbox.name.should == "INBOX"
139
+ end
140
+ end
141
+ end
142
+
143
+ context "labels" do
144
+ subject {
145
+ client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
146
+ client.connect
147
+ client.labels
148
+ }
149
+
150
+ it "should get list of all available labels" do
151
+ labels = subject
152
+ labels.all.should include("INBOX")
153
+ end
154
+
155
+ it "should be able to check if there is given label defined" do
156
+ labels = subject
157
+ labels.exists?("INBOX").should be_true
158
+ labels.exists?("FOOBAR").should be_false
159
+ end
160
+
161
+ it "should be able to create given label" do
162
+ labels = subject
163
+ labels.create("MYLABEL")
164
+ labels.exists?("MYLABEL").should be_true
165
+ labels.create("MYLABEL").should be_false
166
+ labels.delete("MYLABEL")
167
+ end
168
+
169
+ it "should be able to remove existing label" do
170
+ labels = subject
171
+ labels.create("MYLABEL")
172
+ labels.delete("MYLABEL").should be_true
173
+ labels.exists?("MYLABEL").should be_false
174
+ labels.delete("MYLABEL").should be_false
175
+ end
176
+ end
177
+ end
178
+ end