gmail 0.6.0 → 0.7.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.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +27 -27
- data/.rspec +1 -1
- data/.rubocop.yml +53 -13
- data/.rubocop_todo.yml +299 -239
- data/.travis.yml +19 -19
- data/CHANGELOG.md +152 -145
- data/Gemfile +5 -3
- data/LICENSE +21 -21
- data/README.md +380 -355
- data/Rakefile +44 -46
- data/gmail.gemspec +32 -34
- data/lib/gmail.rb +72 -78
- data/lib/gmail/client.rb +35 -34
- data/lib/gmail/client/base.rb +244 -229
- data/lib/gmail/client/plain.rb +24 -24
- data/lib/gmail/client/xoauth.rb +67 -68
- data/lib/gmail/client/xoauth2.rb +39 -39
- data/lib/gmail/imap_extensions.rb +156 -159
- data/lib/gmail/labels.rb +80 -79
- data/lib/gmail/mailbox.rb +178 -175
- data/lib/gmail/message.rb +212 -207
- data/lib/gmail/version.rb +3 -3
- data/spec/account.yml.example +1 -1
- data/spec/account.yml.obfus +2 -2
- data/spec/gmail/client/base_spec.rb +5 -5
- data/spec/gmail/client/plain_spec.rb +169 -169
- data/spec/gmail/client/xoauth2_spec.rb +186 -186
- data/spec/gmail/client/xoauth_spec.rb +5 -5
- data/spec/gmail/client_spec.rb +5 -5
- data/spec/gmail/imap_extensions_spec.rb +47 -47
- data/spec/gmail/labels_spec.rb +27 -27
- data/spec/gmail/mailbox_spec.rb +84 -84
- data/spec/gmail/message_spec.rb +181 -181
- data/spec/gmail_spec.rb +40 -39
- data/spec/recordings/gmail/_new_connects_with_client_and_give_it_context_when_block_given.yml +61 -28
- data/spec/recordings/gmail/_new_connects_with_gmail_service_and_return_valid_connection_object.yml +43 -28
- data/spec/recordings/gmail/_new_does_not_raise_error_when_couldn_t_connect_with_given_account.yml +21 -13
- data/spec/recordings/gmail/_new_raises_error_when_couldn_t_connect_with_given_account.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/delivers_inline_composed_email.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/does_not_raise_error_even_though_gmail_account_is_invalid.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/labels/checks_if_there_is_given_label_defined.yml +409 -196
- data/spec/recordings/gmail_client_plain/instance/labels/creates_given_label.yml +280 -151
- data/spec/recordings/gmail_client_plain/instance/labels/removes_existing_label.yml +271 -146
- data/spec/recordings/gmail_client_plain/instance/labels/returns_list_of_all_available_labels.yml +227 -113
- data/spec/recordings/gmail_client_plain/instance/properly_logs_in_to_valid_gmail_account.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/properly_logs_out_from_gmail.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox.yml +164 -109
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox_using_block_style.yml +164 -109
- data/spec/recordings/gmail_client_plain/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +21 -13
- data/spec/recordings/gmail_client_xo_auth2/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +24 -13
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/checks_if_there_is_given_label_defined.yml +39 -27
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/creates_given_label.yml +52 -39
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/removes_existing_label.yml +52 -39
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/returns_list_of_all_available_labels.yml +39 -27
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_in_to_valid_gmail_account.yml +26 -15
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_out_from_gmail.yml +26 -15
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox.yml +63 -40
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox_using_block_style.yml +63 -40
- data/spec/recordings/gmail_client_xo_auth2/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +24 -13
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/all/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/and_the_mailbox_does_not_exist/returns_the_mailbox_name_as_a_string.yml +229 -110
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/drafts/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/flagged/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/important/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/inbox/localizes_into_the_appropriate_label.yml +61 -42
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/junk/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/sent/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/trash/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_mailbox/instance/counts_all_emails.yml +595 -277
- data/spec/recordings/gmail_mailbox/instance/finds_messages.yml +1049 -586
- data/spec/recordings/gmail_mailbox/instance/waits_once.yml +191 -136
- data/spec/recordings/gmail_mailbox/instance/waits_repeatedly.yml +217 -141
- data/spec/recordings/gmail_mailbox/instance/waits_with_29-minute_re-issue.yml +188 -136
- data/spec/recordings/gmail_mailbox/instance/waits_with_an_unblocked_connection.yml +644 -207
- data/spec/recordings/gmail_mailbox/on_initialize/sets_client_and_name.yml +61 -42
- data/spec/recordings/gmail_mailbox/on_initialize/works_in_inbox_by_default.yml +61 -42
- data/spec/recordings/gmail_message/initialize/sets_prefetch_attrs.yml +1068 -578
- data/spec/recordings/gmail_message/initialize/sets_uid_and_mailbox.yml +1068 -580
- data/spec/recordings/gmail_message/instance_methods/deletes_itself.yml +1084 -637
- data/spec/recordings/gmail_message/instance_methods/marks_itself_read.yml +1137 -682
- data/spec/recordings/gmail_message/instance_methods/marks_itself_unread.yml +1153 -686
- data/spec/recordings/gmail_message/instance_methods/moves_from_one_tag_to_other.yml +1447 -862
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label.yml +1288 -776
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label_with_old_method.yml +1288 -776
- data/spec/recordings/gmail_message/instance_methods/sets_given_label.yml +1165 -690
- data/spec/recordings/gmail_message/instance_methods/sets_given_label_with_old_method.yml +1157 -691
- data/spec/spec_helper.rb +56 -53
- data/spec/support/imap_mock.rb +181 -181
- data/spec/support/obfuscation.rb +49 -52
- metadata +21 -90
- data/spec/recordings/gmail_client_plain/instance/_connection_automatically_logs_in_to_gmail_account_when_it_s_called.yml +0 -42
data/lib/gmail/labels.rb
CHANGED
@@ -1,79 +1,80 @@
|
|
1
|
-
module Gmail
|
2
|
-
class Labels
|
3
|
-
include Enumerable
|
4
|
-
attr_reader :connection
|
5
|
-
alias :conn :connection
|
6
|
-
|
7
|
-
def initialize(connection)
|
8
|
-
@connection = connection
|
9
|
-
end
|
10
|
-
|
11
|
-
# Get list of all defined labels.
|
12
|
-
def all
|
13
|
-
@list = []
|
14
|
-
|
15
|
-
## check each item in list for subfolders
|
16
|
-
conn.list("", "%").each { |l| sublabels_or_label(l) }
|
17
|
-
|
18
|
-
@list.inject([]) do |labels, label|
|
19
|
-
label[:name].each_line { |l| labels << Net::IMAP.decode_utf7(l) }
|
20
|
-
labels
|
21
|
-
end
|
22
|
-
end
|
23
|
-
alias :list :all
|
24
|
-
alias :to_a :all
|
25
|
-
|
26
|
-
def sublabels_or_label(label)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
alias :
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
#
|
66
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
@mailboxes
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end #
|
1
|
+
module Gmail
|
2
|
+
class Labels
|
3
|
+
include Enumerable
|
4
|
+
attr_reader :connection
|
5
|
+
alias :conn :connection
|
6
|
+
|
7
|
+
def initialize(connection)
|
8
|
+
@connection = connection
|
9
|
+
end
|
10
|
+
|
11
|
+
# Get list of all defined labels.
|
12
|
+
def all
|
13
|
+
@list = []
|
14
|
+
|
15
|
+
## check each item in list for subfolders
|
16
|
+
conn.list("", "%").each { |l| sublabels_or_label(l) }
|
17
|
+
|
18
|
+
@list.inject([]) do |labels, label|
|
19
|
+
label[:name].each_line { |l| labels << Net::IMAP.decode_utf7(l) }
|
20
|
+
labels
|
21
|
+
end
|
22
|
+
end
|
23
|
+
alias :list :all
|
24
|
+
alias :to_a :all
|
25
|
+
|
26
|
+
def sublabels_or_label(label)
|
27
|
+
@list << label
|
28
|
+
return if label.attr.include? :Hasnochildren
|
29
|
+
conn.list("#{label.name}/", "%").each { |l| sublabels_or_label(l) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def each(*args, &block)
|
33
|
+
all.each(*args, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns +true+ when given label defined.
|
37
|
+
def exists?(label)
|
38
|
+
all.include?(label)
|
39
|
+
end
|
40
|
+
alias :exist? :exists?
|
41
|
+
|
42
|
+
# Creates given label in your account.
|
43
|
+
def create(label)
|
44
|
+
!!conn.create(Net::IMAP.encode_utf7(label))
|
45
|
+
rescue StandardError
|
46
|
+
false
|
47
|
+
end
|
48
|
+
alias :new :create
|
49
|
+
alias :add :create
|
50
|
+
|
51
|
+
# Deletes given label from your account.
|
52
|
+
def delete(label)
|
53
|
+
!!conn.delete(Net::IMAP.encode_utf7(label))
|
54
|
+
rescue StandardError
|
55
|
+
false
|
56
|
+
end
|
57
|
+
alias :remove :delete
|
58
|
+
|
59
|
+
def inspect
|
60
|
+
"#<Gmail::Labels#{'0x%04x' % (object_id << 1)}>"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Localizes a specific label flag into a label name
|
64
|
+
|
65
|
+
# Accepts standard mailbox flags returned by LIST's special-use extension:
|
66
|
+
# :Inbox, :All, :Drafts, :Sent, :Trash, :Important, :Junk, :Flagged
|
67
|
+
# and their string equivalents. Capitalization agnostic.
|
68
|
+
def localize(label)
|
69
|
+
type = label.to_sym.capitalize
|
70
|
+
if [:All, :Drafts, :Sent, :Trash, :Important, :Junk, :Flagged].include? type
|
71
|
+
@mailboxes ||= connection.list("", "*")
|
72
|
+
@mailboxes.select { |box| box.attr.include? type }.collect(&:name).compact.uniq.first || label.to_s
|
73
|
+
elsif type == :Inbox
|
74
|
+
'INBOX'
|
75
|
+
else
|
76
|
+
label
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end # Labels
|
80
|
+
end # Gmail
|
data/lib/gmail/mailbox.rb
CHANGED
@@ -1,175 +1,178 @@
|
|
1
|
-
module Gmail
|
2
|
-
class Mailbox
|
3
|
-
MAILBOX_ALIASES = {
|
4
|
-
:all => ['ALL'],
|
5
|
-
:seen => ['SEEN'],
|
6
|
-
:unseen => ['UNSEEN'],
|
7
|
-
:read => ['SEEN'],
|
8
|
-
:unread => ['UNSEEN'],
|
9
|
-
:flagged => ['FLAGGED'],
|
10
|
-
:unflagged => ['UNFLAGGED'],
|
11
|
-
:starred => ['FLAGGED'],
|
12
|
-
:unstarred => ['UNFLAGGED'],
|
13
|
-
:deleted => ['DELETED'],
|
14
|
-
:undeleted => ['UNDELETED'],
|
15
|
-
:draft => ['DRAFT'],
|
16
|
-
:undrafted => ['UNDRAFT']
|
17
|
-
}
|
18
|
-
|
19
|
-
attr_reader :name
|
20
|
-
attr_reader :encoded_name
|
21
|
-
|
22
|
-
def initialize(gmail, name = "INBOX")
|
23
|
-
@name = Net::IMAP.decode_utf7(name)
|
24
|
-
@encoded_name = Net::IMAP.encode_utf7(name)
|
25
|
-
@gmail = gmail
|
26
|
-
end
|
27
|
-
|
28
|
-
def fetch_uids(*args)
|
29
|
-
args << :all if args.
|
30
|
-
|
31
|
-
if args.first.is_a?(Symbol)
|
32
|
-
search = MAILBOX_ALIASES[args.shift].dup
|
33
|
-
opts = args.first.is_a?(Hash) ? args.first : {}
|
34
|
-
|
35
|
-
opts[:after] and search.concat ['SINCE', opts[:after]
|
36
|
-
opts[:before] and search.concat ['BEFORE', opts[:before]
|
37
|
-
opts[:on] and search.concat ['ON', opts[:on].to_imap_date]
|
38
|
-
opts[:from] and search.concat ['FROM', opts[:from]]
|
39
|
-
opts[:to] and search.concat ['TO', opts[:to]]
|
40
|
-
opts[:subject] and search.concat ['SUBJECT', opts[:subject]]
|
41
|
-
opts[:label] and search.concat ['LABEL', opts[:label]]
|
42
|
-
opts[:attachment] and search.concat ['HAS', 'attachment']
|
43
|
-
opts[:search] and search.concat ['BODY', opts[:search]]
|
44
|
-
opts[:body] and search.concat ['BODY', opts[:body]]
|
45
|
-
opts[:uid] and search.concat ['UID', opts[:uid]]
|
46
|
-
opts[:gm] and search.concat ['X-GM-RAW', opts[:gm]]
|
47
|
-
opts[:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
# gmail.inbox.emails(:
|
65
|
-
# gmail.inbox.emails(:
|
66
|
-
# gmail.
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
# box.emails(:
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
message
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
alias :
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
#
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
#
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
end
|
1
|
+
module Gmail
|
2
|
+
class Mailbox
|
3
|
+
MAILBOX_ALIASES = {
|
4
|
+
:all => ['ALL'],
|
5
|
+
:seen => ['SEEN'],
|
6
|
+
:unseen => ['UNSEEN'],
|
7
|
+
:read => ['SEEN'],
|
8
|
+
:unread => ['UNSEEN'],
|
9
|
+
:flagged => ['FLAGGED'],
|
10
|
+
:unflagged => ['UNFLAGGED'],
|
11
|
+
:starred => ['FLAGGED'],
|
12
|
+
:unstarred => ['UNFLAGGED'],
|
13
|
+
:deleted => ['DELETED'],
|
14
|
+
:undeleted => ['UNDELETED'],
|
15
|
+
:draft => ['DRAFT'],
|
16
|
+
:undrafted => ['UNDRAFT']
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
attr_reader :name
|
20
|
+
attr_reader :encoded_name
|
21
|
+
|
22
|
+
def initialize(gmail, name = "INBOX")
|
23
|
+
@name = Net::IMAP.decode_utf7(name)
|
24
|
+
@encoded_name = Net::IMAP.encode_utf7(name)
|
25
|
+
@gmail = gmail
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch_uids(*args)
|
29
|
+
args << :all if args.empty?
|
30
|
+
|
31
|
+
if args.first.is_a?(Symbol)
|
32
|
+
search = MAILBOX_ALIASES[args.shift].dup
|
33
|
+
opts = args.first.is_a?(Hash) ? args.first : {}
|
34
|
+
|
35
|
+
opts[:after] and search.concat ['SINCE', Net::IMAP.format_date(opts[:after])]
|
36
|
+
opts[:before] and search.concat ['BEFORE', Net::IMAP.format_date(opts[:before])]
|
37
|
+
opts[:on] and search.concat ['ON', opts[:on].to_imap_date]
|
38
|
+
opts[:from] and search.concat ['FROM', opts[:from]]
|
39
|
+
opts[:to] and search.concat ['TO', opts[:to]]
|
40
|
+
opts[:subject] and search.concat ['SUBJECT', opts[:subject]]
|
41
|
+
opts[:label] and search.concat ['LABEL', opts[:label]]
|
42
|
+
opts[:attachment] and search.concat ['HAS', 'attachment']
|
43
|
+
opts[:search] and search.concat ['BODY', opts[:search]]
|
44
|
+
opts[:body] and search.concat ['BODY', opts[:body]]
|
45
|
+
opts[:uid] and search.concat ['UID', opts[:uid]]
|
46
|
+
opts[:gm] and search.concat ['X-GM-RAW', opts[:gm]]
|
47
|
+
opts[:message_id] and search.concat ['X-GM-MSGID', opts[:message_id].to_s]
|
48
|
+
opts[:query] and search.concat opts[:query]
|
49
|
+
|
50
|
+
@gmail.mailbox(name) do
|
51
|
+
@gmail.conn.uid_search(search)
|
52
|
+
end
|
53
|
+
elsif args.first.is_a?(Hash)
|
54
|
+
fetch_uids(:all, args.first)
|
55
|
+
else
|
56
|
+
raise ArgumentError, "Invalid search criteria"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns list of emails which meets given criteria.
|
61
|
+
#
|
62
|
+
# ==== Examples
|
63
|
+
#
|
64
|
+
# gmail.inbox.emails(:all)
|
65
|
+
# gmail.inbox.emails(:unread, :from => "friend@gmail.com")
|
66
|
+
# gmail.inbox.emails(:all, :after => Time.now-(20*24*3600))
|
67
|
+
# gmail.mailbox("Test").emails(:read)
|
68
|
+
#
|
69
|
+
# gmail.mailbox("Test") do |box|
|
70
|
+
# box.emails(:read)
|
71
|
+
# box.emails(:unread) do |email|
|
72
|
+
# ... do something with each email...
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
def emails(*args, &block)
|
76
|
+
fetch_uids(*args).collect do |uid|
|
77
|
+
message = Message.new(self, uid)
|
78
|
+
yield(message) if block_given?
|
79
|
+
message
|
80
|
+
end
|
81
|
+
end
|
82
|
+
alias :search :emails
|
83
|
+
alias :find :emails
|
84
|
+
|
85
|
+
def emails_in_batches(*args, &block)
|
86
|
+
return [] unless uids.is_a?(Array) && uids.any?
|
87
|
+
|
88
|
+
uids.each_slice(100).flat_map do |slice|
|
89
|
+
find_for_slice(slice, &block)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
alias :search_in_batches :emails_in_batches
|
94
|
+
alias :find_in_batches :emails_in_batches
|
95
|
+
|
96
|
+
# This is a convenience method that really probably shouldn't need to exist,
|
97
|
+
# but it does make code more readable, if seriously all you want is the count
|
98
|
+
# of messages.
|
99
|
+
#
|
100
|
+
# ==== Examples
|
101
|
+
#
|
102
|
+
# gmail.inbox.count(:all)
|
103
|
+
# gmail.inbox.count(:unread, :from => "friend@gmail.com")
|
104
|
+
# gmail.mailbox("Test").count(:all, :after => Time.now-(20*24*3600))
|
105
|
+
def count(*args)
|
106
|
+
emails(*args).size
|
107
|
+
end
|
108
|
+
|
109
|
+
# This permanently removes messages which are marked as deleted
|
110
|
+
def expunge
|
111
|
+
@gmail.mailbox(name) { @gmail.conn.expunge }
|
112
|
+
end
|
113
|
+
|
114
|
+
def wait(options = {}, &block)
|
115
|
+
loop do
|
116
|
+
wait_once(options, &block)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def wait_once(options = {})
|
121
|
+
options[:idle_timeout] ||= 29 * 60
|
122
|
+
|
123
|
+
response = nil
|
124
|
+
loop do
|
125
|
+
complete_cond = @gmail.conn.new_cond
|
126
|
+
complete_now = false
|
127
|
+
|
128
|
+
@gmail.conn.idle do |resp|
|
129
|
+
if resp.is_a?(Net::IMAP::ContinuationRequest) && resp.data.text == 'idling'
|
130
|
+
Thread.new do
|
131
|
+
@gmail.conn.synchronize do
|
132
|
+
complete_cond.wait(options[:idle_timeout]) unless complete_now
|
133
|
+
@gmail.conn.idle_done
|
134
|
+
end
|
135
|
+
end
|
136
|
+
elsif resp.is_a?(Net::IMAP::UntaggedResponse) && resp.name == 'EXISTS'
|
137
|
+
response = resp
|
138
|
+
|
139
|
+
@gmail.conn.synchronize do
|
140
|
+
complete_now = true
|
141
|
+
complete_cond.signal
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
break if response
|
147
|
+
end
|
148
|
+
|
149
|
+
yield response if block_given?
|
150
|
+
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
|
154
|
+
def inspect
|
155
|
+
"#<Gmail::Mailbox#{'0x%04x' % (object_id << 1)} name=#{name}>"
|
156
|
+
end
|
157
|
+
|
158
|
+
def to_s
|
159
|
+
name
|
160
|
+
end
|
161
|
+
|
162
|
+
MAILBOX_ALIASES.each_key do |mailbox|
|
163
|
+
define_method(mailbox) do |*args, &block|
|
164
|
+
emails(mailbox, *args, &block)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
|
170
|
+
def find_for_slice(slice, &block)
|
171
|
+
@gmail.conn.uid_fetch(slice, Message::PREFETCH_ATTRS).map do |data|
|
172
|
+
message = Message.new(self, nil, data)
|
173
|
+
yield(message) if block_given?
|
174
|
+
message
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end # Message
|
178
|
+
end # Gmail
|