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