gmail 0.4.2 → 0.5.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/.gitignore +1 -0
- data/.rubocop.yml +13 -0
- data/.rubocop_todo.yml +239 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +75 -18
- data/Gemfile +1 -1
- data/README.md +214 -131
- data/Rakefile +11 -0
- data/gmail.gemspec +8 -8
- data/lib/gmail.rb +31 -18
- data/lib/gmail/client.rb +11 -7
- data/lib/gmail/client/base.rb +52 -48
- data/lib/gmail/client/plain.rb +9 -5
- data/lib/gmail/client/xoauth.rb +23 -6
- data/lib/gmail/client/xoauth2.rb +39 -0
- data/lib/gmail/imap_extensions.rb +150 -0
- data/lib/gmail/labels.rb +33 -16
- data/lib/gmail/mailbox.rb +60 -42
- data/lib/gmail/message.rb +142 -101
- data/lib/gmail/version.rb +2 -2
- data/spec/account.yml.obfus +2 -0
- data/spec/gmail/client/base_spec.rb +5 -0
- data/spec/gmail/client/plain_spec.rb +168 -0
- data/spec/gmail/client/xoauth2_spec.rb +186 -0
- data/spec/gmail/client/xoauth_spec.rb +5 -0
- data/spec/gmail/client_spec.rb +5 -0
- data/spec/gmail/imap_extensions_spec.rb +12 -0
- data/spec/gmail/labels_spec.rb +18 -0
- data/spec/{mailbox_spec.rb → gmail/mailbox_spec.rb} +14 -14
- data/spec/gmail/message_spec.rb +181 -0
- data/spec/gmail_spec.rb +21 -21
- data/spec/recordings/gmail/_new_connects_with_client_and_give_it_context_when_block_given.yml +28 -0
- data/spec/recordings/gmail/_new_connects_with_gmail_service_and_return_valid_connection_object.yml +28 -0
- data/spec/recordings/gmail/_new_does_not_raise_error_when_couldn_t_connect_with_given_account.yml +13 -0
- data/spec/recordings/gmail/_new_raises_error_when_couldn_t_connect_with_given_account.yml +13 -0
- data/spec/recordings/gmail_client_plain/instance/_connection_automatically_logs_in_to_gmail_account_when_it_s_called.yml +42 -0
- data/spec/recordings/gmail_client_plain/instance/delivers_inline_composed_email.yml +42 -0
- data/spec/recordings/gmail_client_plain/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +13 -0
- data/spec/recordings/gmail_client_plain/instance/does_not_raise_error_even_though_gmail_account_is_invalid.yml +13 -0
- data/spec/recordings/gmail_client_plain/instance/labels/checks_if_there_is_given_label_defined.yml +196 -0
- data/spec/recordings/gmail_client_plain/instance/labels/creates_given_label.yml +151 -0
- data/spec/recordings/gmail_client_plain/instance/labels/removes_existing_label.yml +146 -0
- data/spec/recordings/gmail_client_plain/instance/labels/returns_list_of_all_available_labels.yml +113 -0
- data/spec/recordings/gmail_client_plain/instance/properly_logs_in_to_valid_gmail_account.yml +42 -0
- data/spec/recordings/gmail_client_plain/instance/properly_logs_out_from_gmail.yml +42 -0
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox.yml +109 -0
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox_using_block_style.yml +109 -0
- data/spec/recordings/gmail_client_plain/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +13 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +13 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/checks_if_there_is_given_label_defined.yml +27 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/creates_given_label.yml +39 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/removes_existing_label.yml +39 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/returns_list_of_all_available_labels.yml +27 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_in_to_valid_gmail_account.yml +15 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_out_from_gmail.yml +15 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox.yml +40 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox_using_block_style.yml +40 -0
- data/spec/recordings/gmail_client_xo_auth2/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +13 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/all/localizes_into_the_appropriate_label.yml +116 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/drafts/localizes_into_the_appropriate_label.yml +116 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/flagged/localizes_into_the_appropriate_label.yml +116 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/important/localizes_into_the_appropriate_label.yml +116 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/inbox/localizes_into_the_appropriate_label.yml +42 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/junk/localizes_into_the_appropriate_label.yml +116 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/sent/localizes_into_the_appropriate_label.yml +116 -0
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/trash/localizes_into_the_appropriate_label.yml +116 -0
- data/spec/recordings/gmail_mailbox/instance/counts_all_emails.yml +277 -0
- data/spec/recordings/gmail_mailbox/instance/finds_messages.yml +586 -0
- data/spec/recordings/gmail_mailbox/on_initialize/sets_client_and_name.yml +42 -0
- data/spec/recordings/gmail_mailbox/on_initialize/works_in_inbox_by_default.yml +42 -0
- data/spec/recordings/gmail_message/initialize/sets_prefetch_attrs.yml +578 -0
- data/spec/recordings/gmail_message/initialize/sets_uid_and_mailbox.yml +580 -0
- data/spec/recordings/gmail_message/instance_methods/deletes_itself.yml +637 -0
- data/spec/recordings/gmail_message/instance_methods/marks_itself_read.yml +682 -0
- data/spec/recordings/gmail_message/instance_methods/marks_itself_unread.yml +686 -0
- data/spec/recordings/gmail_message/instance_methods/moves_from_one_tag_to_other.yml +862 -0
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label.yml +776 -0
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label_with_old_method.yml +776 -0
- data/spec/recordings/gmail_message/instance_methods/sets_given_label.yml +690 -0
- data/spec/recordings/gmail_message/instance_methods/sets_given_label_with_old_method.yml +691 -0
- data/spec/spec_helper.rb +34 -10
- data/spec/support/imap_mock.rb +129 -0
- data/spec/support/obfuscation.rb +52 -0
- metadata +79 -30
- data/TODO.md +0 -12
- data/lib/gmail/client/imap_extensions.rb +0 -54
- data/spec/client_spec.rb +0 -178
- data/spec/message_spec.rb +0 -51
data/spec/spec_helper.rb
CHANGED
@@ -1,29 +1,53 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
2
|
|
4
3
|
require 'rubygems'
|
5
4
|
require 'rspec'
|
6
|
-
require 'mocha'
|
7
5
|
require 'yaml'
|
8
6
|
require 'gmail'
|
9
7
|
|
10
|
-
|
11
|
-
|
8
|
+
# require_support_files
|
9
|
+
Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each { |f| require f }
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
Spec::ImapMock.configure_rspec!(config)
|
12
13
|
end
|
13
14
|
|
14
15
|
def within_gmail(&block)
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
Gmail.connect!(*TEST_ACCOUNT) do |gmail|
|
17
|
+
yield(gmail)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def mock_client(&block)
|
22
|
+
client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
|
23
|
+
client.connect
|
24
|
+
|
25
|
+
if block_given?
|
26
|
+
client.login
|
27
|
+
yield client
|
28
|
+
client.logout
|
29
|
+
end
|
30
|
+
|
31
|
+
client
|
18
32
|
end
|
19
33
|
|
20
|
-
def mock_mailbox(box="INBOX", &block)
|
34
|
+
def mock_mailbox(box = "INBOX", &block)
|
21
35
|
within_gmail do |gmail|
|
22
|
-
mailbox =
|
36
|
+
mailbox = gmail.mailbox(box)
|
23
37
|
yield(mailbox) if block_given?
|
24
38
|
mailbox
|
25
39
|
end
|
26
40
|
end
|
27
41
|
|
42
|
+
# TODO: move this to it's own dir; get rid of global variable
|
28
43
|
# Run test by creating your own test account with credentials in account.yml
|
29
|
-
|
44
|
+
# Otherwise default credentials from an obfuscated file are used.
|
45
|
+
clear_file = File.join(File.dirname(__FILE__), 'account.yml')
|
46
|
+
obfus_file = File.join(File.dirname(__FILE__), 'account.yml.obfus')
|
47
|
+
if File.exist?(clear_file)
|
48
|
+
TEST_ACCOUNT = YAML.load_file(clear_file)
|
49
|
+
elsif File.exist?(obfus_file)
|
50
|
+
TEST_ACCOUNT = Spec::Obfuscation.decrypt_file(obfus_file)
|
51
|
+
else
|
52
|
+
raise 'account.yml file not found'
|
53
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Net
|
2
|
+
class IMAP
|
3
|
+
class << self
|
4
|
+
def recordings=(value)
|
5
|
+
@replaying = !value.nil?
|
6
|
+
@recordings = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def recordings
|
10
|
+
@recordings ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def replaying?
|
14
|
+
@replaying
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
alias_method :_send_command, :send_command
|
21
|
+
|
22
|
+
def self.force_utf8(data)
|
23
|
+
case data.class.to_s
|
24
|
+
when /String/
|
25
|
+
data.force_encoding('utf-8')
|
26
|
+
when /Hash/
|
27
|
+
data.each { |k, v| data[k] = force_utf8(v) }
|
28
|
+
when /Array/
|
29
|
+
data.map { |s| force_utf8(s) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def send_command(cmd, *args, &block)
|
34
|
+
# In Ruby 1.9.x, strings default to binary which causes the digest to be
|
35
|
+
# different.
|
36
|
+
clean_args = args.dup.each do |s|
|
37
|
+
Net::IMAP.force_utf8(s)
|
38
|
+
end
|
39
|
+
|
40
|
+
yaml_dump = YAML.dump([cmd] + clean_args)
|
41
|
+
|
42
|
+
if RUBY_VERSION =~ /^(1.9|2.0)/
|
43
|
+
# From 1.9 to 2.0 to 2.1, the way YAML encodes special characters changed.
|
44
|
+
# Here's what each returns for: YAML.dump(["", "%"])
|
45
|
+
# 1.9.x: "---\n- ''\n- ! '%'\n"
|
46
|
+
# 2.0.x: "---\n- ''\n- '%'\n"
|
47
|
+
# 2.1.x: "---\n- ''\n- \"%\"\n"
|
48
|
+
# The `gsub` here converts the older format into the 2.1.x.
|
49
|
+
yaml_dump.gsub!(/(?:! )?'(.+)'/, '"\1"')
|
50
|
+
|
51
|
+
# In 1.9 and 2.0 strings starting with `+` or `-` are not escaped in quotes, but
|
52
|
+
# they are in 2.1+. This addresses that.
|
53
|
+
yaml_dump.gsub!(/ ([+-](?:X-GM-\w+|FLAGS))/, ' "\1"')
|
54
|
+
|
55
|
+
# In 1.9 and 2.0 strings starting with `\` are not escaped in quotes, but
|
56
|
+
# they are in 2.1+. This addresses that. Yes we need all those backslashes :|
|
57
|
+
yaml_dump.gsub!(/ \\(\w+)/, ' "\\\\\\\\\1"')
|
58
|
+
end
|
59
|
+
|
60
|
+
digest = "#{cmd}-#{Digest::MD5.hexdigest(yaml_dump)}"
|
61
|
+
|
62
|
+
if Net::IMAP.replaying?
|
63
|
+
recordings = Net::IMAP.recordings[digest] || []
|
64
|
+
if recordings.empty?
|
65
|
+
# Be lenient if LOGOUT is called but wasn't explicitly recorded. This
|
66
|
+
# comes up often when called from `at_exit`.
|
67
|
+
cmd == 'LOGOUT' ? return : raise('Could not find recording')
|
68
|
+
end
|
69
|
+
|
70
|
+
action, response, @responses = recordings.shift
|
71
|
+
else
|
72
|
+
action = :return
|
73
|
+
begin
|
74
|
+
response = _send_command(cmd, *args, &block)
|
75
|
+
rescue => e
|
76
|
+
action = :raise
|
77
|
+
response = e
|
78
|
+
end
|
79
|
+
|
80
|
+
# @responses (the third argument here) contains untagged responses captured
|
81
|
+
# via the Net::IMAP#record_response method.
|
82
|
+
Net::IMAP.recordings[digest] ||= []
|
83
|
+
Net::IMAP.recordings[digest] << [action, response.dup, @responses ? @responses.dup : nil]
|
84
|
+
end
|
85
|
+
|
86
|
+
raise(response) if action == :raise
|
87
|
+
|
88
|
+
response
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
module Spec
|
94
|
+
module ImapMock
|
95
|
+
# Configures RSpec with an around(:each) block to use IMAP mocks
|
96
|
+
def self.configure_rspec!(config)
|
97
|
+
config.around(:each) do |example|
|
98
|
+
Spec::ImapMock.run_rspec_example(example)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Run an RSpec example using IMAP mocks
|
103
|
+
def self.run_rspec_example(example)
|
104
|
+
# The path is determined by the rspec `describe`s and `context`s
|
105
|
+
mock_path = example.example_group.to_s
|
106
|
+
.gsub(/RSpec::ExampleGroups::/, '')
|
107
|
+
.gsub(/(\w)([A-Z])/, '\1_\2')
|
108
|
+
.gsub(/::/, '/')
|
109
|
+
.downcase
|
110
|
+
|
111
|
+
# The name is determined by the description of the example.
|
112
|
+
mock_name = example.description.gsub(/[^\w\-\/]+/, '_').downcase
|
113
|
+
|
114
|
+
filename = File.join('spec/recordings/', mock_path, "#{mock_name}.yml")
|
115
|
+
|
116
|
+
# If we've already recorded this spec load the recordings
|
117
|
+
Net::IMAP.recordings = File.exist?(filename) ? YAML.load_file(filename) : nil
|
118
|
+
|
119
|
+
example.run
|
120
|
+
|
121
|
+
# If we haven't yet recorded the spec and there were some recordings,
|
122
|
+
# write them to a file.
|
123
|
+
unless File.exist?(filename) or Net::IMAP.recordings.empty?
|
124
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
125
|
+
File.open(filename, 'w') { |f| YAML.dump(Net::IMAP.recordings, f) }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
# Lightweight obfuscation wrapper used to obfuscate account.yml file.
|
5
|
+
#
|
6
|
+
# CAUTION; this is not intended to be a robust security mechanism. It is simple
|
7
|
+
# obfuscation (security through obscurity). There's no strong reason why we couldn't
|
8
|
+
# store the credentials in clear text, but just taking an extra step to prevent trouble.
|
9
|
+
|
10
|
+
module Spec
|
11
|
+
module Obfuscation
|
12
|
+
def encrypt(data)
|
13
|
+
rot13(Base64.encode64(data))
|
14
|
+
end
|
15
|
+
|
16
|
+
def decrypt(data)
|
17
|
+
Base64.decode64(rot13(data))
|
18
|
+
end
|
19
|
+
|
20
|
+
def rot13(data)
|
21
|
+
data.tr!("A-Za-z", "N-ZA-Mn-za-m")
|
22
|
+
end
|
23
|
+
|
24
|
+
def encrypt_file(file)
|
25
|
+
data = read_if_exist!(file)
|
26
|
+
begin
|
27
|
+
File.open("#{file}.obfus", 'w') { |file| file.write(encrypt(data)) }
|
28
|
+
rescue Exception => e
|
29
|
+
raise "Unable to encrypt #{file}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def decrypt_file(file)
|
34
|
+
data = read_if_exist!(file)
|
35
|
+
begin
|
36
|
+
return ::YAML::load(decrypt(data))
|
37
|
+
rescue Exception => e
|
38
|
+
raise "Unable to decrypt #{file}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_if_exist!(file)
|
43
|
+
if File.exist?(file)
|
44
|
+
IO.read(file)
|
45
|
+
else
|
46
|
+
raise "File not found #{file}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
extend self
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Kowalik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: mime
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.1'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.1'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: mail
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,30 +56,30 @@ dependencies:
|
|
70
56
|
name: rspec
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - "
|
59
|
+
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '3.1'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - "
|
66
|
+
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
68
|
+
version: '3.1'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: rubocop
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
75
|
+
version: '0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
80
|
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
82
|
+
version: '0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: gem-release
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,31 +105,93 @@ extra_rdoc_files: []
|
|
119
105
|
files:
|
120
106
|
- ".gitignore"
|
121
107
|
- ".rspec"
|
108
|
+
- ".rubocop.yml"
|
109
|
+
- ".rubocop_todo.yml"
|
110
|
+
- ".travis.yml"
|
122
111
|
- CHANGELOG.md
|
123
112
|
- Gemfile
|
124
113
|
- LICENSE
|
125
114
|
- README.md
|
126
115
|
- Rakefile
|
127
|
-
- TODO.md
|
128
116
|
- gmail.gemspec
|
129
117
|
- lib/gmail.rb
|
130
118
|
- lib/gmail/client.rb
|
131
119
|
- lib/gmail/client/base.rb
|
132
|
-
- lib/gmail/client/imap_extensions.rb
|
133
120
|
- lib/gmail/client/plain.rb
|
134
121
|
- lib/gmail/client/xoauth.rb
|
122
|
+
- lib/gmail/client/xoauth2.rb
|
123
|
+
- lib/gmail/imap_extensions.rb
|
135
124
|
- lib/gmail/labels.rb
|
136
125
|
- lib/gmail/mailbox.rb
|
137
126
|
- lib/gmail/message.rb
|
138
127
|
- lib/gmail/version.rb
|
139
128
|
- spec/account.yml.example
|
140
|
-
- spec/
|
129
|
+
- spec/account.yml.obfus
|
130
|
+
- spec/gmail/client/base_spec.rb
|
131
|
+
- spec/gmail/client/plain_spec.rb
|
132
|
+
- spec/gmail/client/xoauth2_spec.rb
|
133
|
+
- spec/gmail/client/xoauth_spec.rb
|
134
|
+
- spec/gmail/client_spec.rb
|
135
|
+
- spec/gmail/imap_extensions_spec.rb
|
136
|
+
- spec/gmail/labels_spec.rb
|
137
|
+
- spec/gmail/mailbox_spec.rb
|
138
|
+
- spec/gmail/message_spec.rb
|
141
139
|
- spec/gmail_spec.rb
|
142
|
-
- spec/
|
143
|
-
- spec/
|
140
|
+
- spec/recordings/gmail/_new_connects_with_client_and_give_it_context_when_block_given.yml
|
141
|
+
- spec/recordings/gmail/_new_connects_with_gmail_service_and_return_valid_connection_object.yml
|
142
|
+
- spec/recordings/gmail/_new_does_not_raise_error_when_couldn_t_connect_with_given_account.yml
|
143
|
+
- spec/recordings/gmail/_new_raises_error_when_couldn_t_connect_with_given_account.yml
|
144
|
+
- spec/recordings/gmail_client_plain/instance/_connection_automatically_logs_in_to_gmail_account_when_it_s_called.yml
|
145
|
+
- spec/recordings/gmail_client_plain/instance/delivers_inline_composed_email.yml
|
146
|
+
- spec/recordings/gmail_client_plain/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml
|
147
|
+
- spec/recordings/gmail_client_plain/instance/does_not_raise_error_even_though_gmail_account_is_invalid.yml
|
148
|
+
- spec/recordings/gmail_client_plain/instance/labels/checks_if_there_is_given_label_defined.yml
|
149
|
+
- spec/recordings/gmail_client_plain/instance/labels/creates_given_label.yml
|
150
|
+
- spec/recordings/gmail_client_plain/instance/labels/removes_existing_label.yml
|
151
|
+
- spec/recordings/gmail_client_plain/instance/labels/returns_list_of_all_available_labels.yml
|
152
|
+
- spec/recordings/gmail_client_plain/instance/properly_logs_in_to_valid_gmail_account.yml
|
153
|
+
- spec/recordings/gmail_client_plain/instance/properly_logs_out_from_gmail.yml
|
154
|
+
- spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox.yml
|
155
|
+
- spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox_using_block_style.yml
|
156
|
+
- spec/recordings/gmail_client_plain/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml
|
157
|
+
- spec/recordings/gmail_client_xo_auth2/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml
|
158
|
+
- spec/recordings/gmail_client_xo_auth2/instance/labels/checks_if_there_is_given_label_defined.yml
|
159
|
+
- spec/recordings/gmail_client_xo_auth2/instance/labels/creates_given_label.yml
|
160
|
+
- spec/recordings/gmail_client_xo_auth2/instance/labels/removes_existing_label.yml
|
161
|
+
- spec/recordings/gmail_client_xo_auth2/instance/labels/returns_list_of_all_available_labels.yml
|
162
|
+
- spec/recordings/gmail_client_xo_auth2/instance/properly_logs_in_to_valid_gmail_account.yml
|
163
|
+
- spec/recordings/gmail_client_xo_auth2/instance/properly_logs_out_from_gmail.yml
|
164
|
+
- spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox.yml
|
165
|
+
- spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox_using_block_style.yml
|
166
|
+
- spec/recordings/gmail_client_xo_auth2/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml
|
167
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/all/localizes_into_the_appropriate_label.yml
|
168
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/drafts/localizes_into_the_appropriate_label.yml
|
169
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/flagged/localizes_into_the_appropriate_label.yml
|
170
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/important/localizes_into_the_appropriate_label.yml
|
171
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/inbox/localizes_into_the_appropriate_label.yml
|
172
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/junk/localizes_into_the_appropriate_label.yml
|
173
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/sent/localizes_into_the_appropriate_label.yml
|
174
|
+
- spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/trash/localizes_into_the_appropriate_label.yml
|
175
|
+
- spec/recordings/gmail_mailbox/instance/counts_all_emails.yml
|
176
|
+
- spec/recordings/gmail_mailbox/instance/finds_messages.yml
|
177
|
+
- spec/recordings/gmail_mailbox/on_initialize/sets_client_and_name.yml
|
178
|
+
- spec/recordings/gmail_mailbox/on_initialize/works_in_inbox_by_default.yml
|
179
|
+
- spec/recordings/gmail_message/initialize/sets_prefetch_attrs.yml
|
180
|
+
- spec/recordings/gmail_message/initialize/sets_uid_and_mailbox.yml
|
181
|
+
- spec/recordings/gmail_message/instance_methods/deletes_itself.yml
|
182
|
+
- spec/recordings/gmail_message/instance_methods/marks_itself_read.yml
|
183
|
+
- spec/recordings/gmail_message/instance_methods/marks_itself_unread.yml
|
184
|
+
- spec/recordings/gmail_message/instance_methods/moves_from_one_tag_to_other.yml
|
185
|
+
- spec/recordings/gmail_message/instance_methods/removes_a_given_label.yml
|
186
|
+
- spec/recordings/gmail_message/instance_methods/removes_a_given_label_with_old_method.yml
|
187
|
+
- spec/recordings/gmail_message/instance_methods/sets_given_label.yml
|
188
|
+
- spec/recordings/gmail_message/instance_methods/sets_given_label_with_old_method.yml
|
144
189
|
- spec/spec_helper.rb
|
145
|
-
|
146
|
-
|
190
|
+
- spec/support/imap_mock.rb
|
191
|
+
- spec/support/obfuscation.rb
|
192
|
+
homepage: http://github.com/gmailgem/gmail
|
193
|
+
licenses:
|
194
|
+
- MIT
|
147
195
|
metadata: {}
|
148
196
|
post_install_message:
|
149
197
|
rdoc_options: []
|
@@ -166,3 +214,4 @@ signing_key:
|
|
166
214
|
specification_version: 4
|
167
215
|
summary: A Rubyesque interface to Gmail, with all the tools you will need.
|
168
216
|
test_files: []
|
217
|
+
has_rdoc:
|
data/TODO.md
DELETED
@@ -1,12 +0,0 @@
|
|
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,54 +0,0 @@
|
|
1
|
-
# Taken from https://github.com/oxos/gmail-oauth-thread-stats/blob/master/gmail_imap_extensions_compatibility.rb
|
2
|
-
|
3
|
-
module GmailImapExtensions
|
4
|
-
|
5
|
-
def self.patch_net_imap_response_parser(klass = Net::IMAP::ResponseParser)
|
6
|
-
klass.class_eval do
|
7
|
-
def msg_att
|
8
|
-
match(Net::IMAP::ResponseParser::T_LPAR)
|
9
|
-
attr = {}
|
10
|
-
while true
|
11
|
-
token = lookahead
|
12
|
-
case token.symbol
|
13
|
-
when Net::IMAP::ResponseParser::T_RPAR
|
14
|
-
shift_token
|
15
|
-
break
|
16
|
-
when Net::IMAP::ResponseParser::T_SPACE
|
17
|
-
shift_token
|
18
|
-
token = lookahead
|
19
|
-
end
|
20
|
-
case token.value
|
21
|
-
when /\A(?:ENVELOPE)\z/ni
|
22
|
-
name, val = envelope_data
|
23
|
-
when /\A(?:FLAGS)\z/ni
|
24
|
-
name, val = flags_data
|
25
|
-
when /\A(?:INTERNALDATE)\z/ni
|
26
|
-
name, val = internaldate_data
|
27
|
-
when /\A(?:RFC822(?:\.HEADER|\.TEXT)?)\z/ni
|
28
|
-
name, val = rfc822_text
|
29
|
-
when /\A(?:RFC822\.SIZE)\z/ni
|
30
|
-
name, val = rfc822_size
|
31
|
-
when /\A(?:BODY(?:STRUCTURE)?)\z/ni
|
32
|
-
name, val = body_data
|
33
|
-
when /\A(?:UID)\z/ni
|
34
|
-
name, val = uid_data
|
35
|
-
|
36
|
-
# Gmail extension additions.
|
37
|
-
# Cargo-Cult code warning: # I have no idea why the regexp - just copying a pattern
|
38
|
-
when /\A(?:X-GM-LABELS)\z/ni
|
39
|
-
name, val = flags_data
|
40
|
-
when /\A(?:X-GM-MSGID)\z/ni
|
41
|
-
name, val = uid_data
|
42
|
-
when /\A(?:X-GM-THRID)\z/ni
|
43
|
-
name, val = uid_data
|
44
|
-
else
|
45
|
-
parse_error("unknown attribute `%s'", token.value)
|
46
|
-
end
|
47
|
-
attr[name] = val
|
48
|
-
end
|
49
|
-
return attr
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|