contextio 0.5.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.document +4 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -0
  5. data/ChangeLog.md +5 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.md +20 -0
  8. data/README.md +62 -22
  9. data/Rakefile +46 -36
  10. data/contextio.gemspec +30 -0
  11. data/lib/contextio.rb +69 -583
  12. data/lib/contextio/account.rb +132 -0
  13. data/lib/contextio/account_collection.rb +57 -0
  14. data/lib/contextio/account_sync_data.rb +22 -0
  15. data/lib/contextio/api.rb +162 -0
  16. data/lib/contextio/api/association_helpers.rb +17 -0
  17. data/lib/contextio/api/resource.rb +230 -0
  18. data/lib/contextio/api/resource_collection.rb +174 -0
  19. data/lib/contextio/api/url_builder.rb +153 -0
  20. data/lib/contextio/body_part.rb +45 -0
  21. data/lib/contextio/body_part_collection.rb +13 -0
  22. data/lib/contextio/connect_token.rb +57 -0
  23. data/lib/contextio/connect_token_collection.rb +44 -0
  24. data/lib/contextio/contact.rb +43 -0
  25. data/lib/contextio/contact_collection.rb +21 -0
  26. data/lib/contextio/email_address.rb +53 -0
  27. data/lib/contextio/email_address_collection.rb +21 -0
  28. data/lib/contextio/email_settings.rb +146 -0
  29. data/lib/contextio/file.rb +92 -0
  30. data/lib/contextio/file_collection.rb +13 -0
  31. data/lib/contextio/folder.rb +56 -0
  32. data/lib/contextio/folder_collection.rb +18 -0
  33. data/lib/contextio/folder_sync_data.rb +32 -0
  34. data/lib/contextio/message.rb +96 -0
  35. data/lib/contextio/message_collection.rb +35 -0
  36. data/lib/contextio/oauth_provider.rb +29 -0
  37. data/lib/contextio/oauth_provider_collection.rb +46 -0
  38. data/lib/contextio/source.rb +55 -0
  39. data/lib/contextio/source_collection.rb +41 -0
  40. data/lib/contextio/source_sync_data.rb +23 -0
  41. data/lib/contextio/thread.rb +15 -0
  42. data/lib/contextio/thread_collection.rb +25 -0
  43. data/lib/contextio/version.rb +11 -0
  44. data/lib/contextio/webhook.rb +39 -0
  45. data/lib/contextio/webhook_collection.rb +26 -0
  46. data/spec/config.yml.example +3 -0
  47. data/spec/contextio/account_collection_spec.rb +78 -0
  48. data/spec/contextio/account_spec.rb +52 -0
  49. data/spec/contextio/api/association_helpers_spec.rb +28 -0
  50. data/spec/contextio/api/resource_collection_spec.rb +286 -0
  51. data/spec/contextio/api/resource_spec.rb +467 -0
  52. data/spec/contextio/api/url_builder_spec.rb +78 -0
  53. data/spec/contextio/api_spec.rb +123 -0
  54. data/spec/contextio/connect_token_collection_spec.rb +74 -0
  55. data/spec/contextio/connect_token_spec.rb +58 -0
  56. data/spec/contextio/email_settings_spec.rb +112 -0
  57. data/spec/contextio/oauth_provider_collection_spec.rb +36 -0
  58. data/spec/contextio/oauth_provider_spec.rb +120 -0
  59. data/spec/contextio/source_collection_spec.rb +57 -0
  60. data/spec/contextio/source_spec.rb +52 -0
  61. data/spec/contextio/version_spec.rb +10 -0
  62. data/spec/contextio_spec.rb +64 -0
  63. data/spec/spec_helper.rb +17 -0
  64. metadata +234 -12
  65. data/README.textile +0 -29
@@ -0,0 +1,4 @@
1
+ lib/**/*.rb
2
+ README.rdoc
3
+ ChangeLog.rdoc
4
+ LICENSE.txt
@@ -0,0 +1,8 @@
1
+ Gemfile.lock
2
+ html/
3
+ pkg/
4
+ doc/
5
+ .yardoc/
6
+ vendor/cache/*.gem
7
+ test_script.rb
8
+ spec/config.yml
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format progress
@@ -0,0 +1 @@
1
+ --no-private --markup markdown --no-cache - README.md LICENSE.md ChangeLog.md
@@ -0,0 +1,5 @@
1
+ # Changes
2
+
3
+ ## 0.5.0 / 2012-08-18
4
+
5
+ * Major Refactor of all code.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Context.IO
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,35 +1,75 @@
1
- Context.IO Gem Source
2
- =====================
1
+ # Context.IO
3
2
 
4
- This repository contains the source for the Context.IO gem.
3
+ * [Homepage](https://github.com/benhamill/contextio#readme)
4
+ * [API Documentation](http://context.io/docs/2.0/)
5
+ * [Sign Up](http://context.io)
5
6
 
6
- If all you want is to use the gem can install it with the following command:
7
+ ## Description
7
8
 
8
- gem install contextio
9
+ Provides a Ruby interface to [Context.IO](http://context.io). The general design
10
+ was inspired by the wonderful [aws-sdk](https://github.com/aws/aws-sdk-ruby)
11
+ gem. You start with an object that represents your account with Context.IO and
12
+ then you deal with collections within that going forward. Check out the example.
9
13
 
10
- You can get more information at [http://context.io](http://context.io). Complete API documentation is available at [http://context.io/docs/2.0/](http://context.io/docs/2.0/).
14
+ If you're looking at the Context.IO docs, it is important to note that there are
15
+ some attributes that've been renamed to be a bit more Ruby-friendly. In general,
16
+ if the API returns a number meant to be seconds-from-epoch, then it's been
17
+ converted to return a `Time` (e.g. `updated` has changed to `updated_at`) and a
18
+ boolean has converted to something with a `?` at the end (e.g. `HasChildren` and
19
+ `initial_import_finished` are `has_children?` and `initial_import_finished?`,
20
+ respectively).
11
21
 
12
- An example
13
- ----------
22
+ ## Example
14
23
 
15
- require 'contextio'
16
- require 'json'
24
+ ```ruby
25
+ require 'contextio'
17
26
 
18
- key = 'the key you get in your developer console'
19
- secret = ' the secret you get in your developer console'
20
- account = 'your account id'
27
+ contextio = ContextIO.new('your_api_key', 'your_api_secret')
21
28
 
22
- connection = ContextIO::Connection.new(key, secret)
23
- messages = connection.list_messages(:account => account, :since => (Time.now - 24 * 60 * 60 * 5))
24
- puts JSON.parse(messages.body).first['subject']
29
+ account = contextio.accounts.where(email: 'some@email.com').first
25
30
 
26
- LICENSE
27
- -------
31
+ account.email_addresses # ['some@email.com', 'another@email.com']
32
+ account.first_name # 'Bruno'
33
+ account.suspended? # False
28
34
 
29
- Copyright (C) 2011 DokDok Inc.
35
+ account.messages.where(folder: '\Drafts').each do |m|
36
+ puts m.subject
37
+ end
38
+ ```
30
39
 
31
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
40
+ ## Install
32
41
 
33
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
42
+ $ gem install contextio
34
43
 
35
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44
+ Or, of course, put this in your Gemfile:
45
+
46
+ gem contextio
47
+
48
+ ## Version Numbers
49
+
50
+ This gem adheres to [SemVer](http://semver.org/). So you should be pretty safe
51
+ upgrading from 1.0.0 to 1.9.9. Whatever as long as the major version doesn't
52
+ bump. When the major version bumps, be warned; upgrading will take some kind of
53
+ effort.
54
+
55
+ ## Contributing
56
+
57
+ Help is gladly welcomed. If you have a feature you'd like to add, it's much more
58
+ likely to get in (or get in faster) the closer you stick to these steps:
59
+
60
+ 1. Open an Issue to talk about it. We can discuss whether it's the right
61
+ direction or maybe help track down a bug, etc.
62
+ 1. Fork the project, and make a branch to work on your feature/fix. Master is
63
+ where you'll want to start from.
64
+ 1. Turn the Issue into a Pull Request. There are several ways to do this, but
65
+ [hub](https://github.com/defunkt/hub) is probably the easiest.
66
+ 1. Make sure your Pull Request includes tests.
67
+
68
+ If you don't know how to fix something, even just a Pull Request that includes a
69
+ failing test can be helpful. If in doubt, make an Issue to discuss.
70
+
71
+ ## Copyright
72
+
73
+ Copyright (c) 2012 Context.IO
74
+
75
+ See LICENSE.md for details.
data/Rakefile CHANGED
@@ -1,46 +1,56 @@
1
- require 'rubygems'
2
- require 'rubygems/specification'
3
- require 'rake'
4
- require 'rake/gempackagetask'
1
+ # encoding: utf-8
5
2
 
6
- GEM = "contextio"
7
- GEM_VERSION = "0.4.0"
8
- SUMMARY = "Provides interface for Context.IO email"
9
- AUTHOR = "Dominik Gehl"
10
- EMAIL = "dominik@context.io"
11
- HOMEPAGE = "http://context.io/"
12
-
13
- task :default => [:test]
3
+ require 'rubygems'
14
4
 
15
- task :test do
16
- ruby "spec/contextio_spec.rb"
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit e.status_code
17
11
  end
18
12
 
19
- spec = Gem::Specification.new do |s|
20
- s.name = GEM
21
- s.version = GEM_VERSION
22
- s.platform = Gem::Platform::RUBY
23
- s.summary = SUMMARY
24
- s.require_paths = ['lib']
25
- s.files = FileList['app_generators/**/*', 'bin/*', 'lib/**/*.rb', '[A-Z]*'].to_a
26
-
27
- s.author = AUTHOR
28
- s.email = EMAIL
29
- s.homepage = HOMEPAGE
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
30
19
  end
31
20
 
32
- Rake::GemPackageTask.new(spec) do |pkg|
33
- pkg.gem_spec = spec
34
- end
21
+ require 'rake'
35
22
 
36
- desc "Install the gem locally"
37
- task :install => [:package] do
38
- sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
39
- end
23
+ require 'rspec/core/rake_task'
24
+ RSpec::Core::RakeTask.new
40
25
 
41
- desc "Create a gemspec file"
42
- task :make_spec do
43
- File.open("#{GEM}.gemspec", "w") do |file|
44
- file.puts spec.to_ruby
26
+ task :test => :spec
27
+ task :default => :spec
28
+
29
+ require 'yard'
30
+ YARD::Rake::YardocTask.new
31
+ task :doc => :yard
32
+
33
+ desc "Fire up an interactive terminal to play with"
34
+ task :console do
35
+ require 'pry'
36
+ require File.expand_path(File.dirname(__FILE__) + '/lib/contextio')
37
+
38
+ config = YAML.load_file File.expand_path(File.dirname(__FILE__) + '/spec/config.yml')
39
+ @api = ContextIO.new(config['key'], config['secret'])
40
+
41
+ # add ability to reload console
42
+ def reload
43
+ reload_msg = '# Reloading the console...'
44
+ puts CodeRay.scan(reload_msg, :ruby).term
45
+ Pry.save_history
46
+ exec('rake console')
45
47
  end
48
+
49
+ welcome = <<-EOS
50
+ Welcome to the Context.IO developer console. If you put your API credentials in
51
+ /spec/config.yml, you'll have a handle on the API named `@api` to play with.
52
+ EOS
53
+
54
+ puts welcome
55
+ Pry.start
46
56
  end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/contextio/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "contextio"
7
+ gem.version = ContextIO.version
8
+ gem.summary = 'Provides interface to Context.IO'
9
+ gem.description = 'Provides Ruby interface to Context.IO'
10
+ gem.license = 'MIT'
11
+ gem.authors = ['Ben Hamill']
12
+ gem.email = %w(ben@benhamill.com)
13
+ gem.homepage = 'https://github.com/contextio/contextio-ruby#readme'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency 'oauth', '~> 0.4.5'
21
+
22
+ gem.add_development_dependency 'bundler'
23
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
24
+ gem.add_development_dependency 'rspec', '~> 2.4'
25
+ gem.add_development_dependency 'rake'
26
+ gem.add_development_dependency 'yard'
27
+ gem.add_development_dependency 'redcarpet'
28
+ gem.add_development_dependency 'pry-doc'
29
+ gem.add_development_dependency 'fakeweb'
30
+ end
@@ -1,589 +1,75 @@
1
- require 'oauth'
2
- require 'net/http'
3
-
4
- warn("WARNING: You're using the contextio gem from the dev_2.0 in an old repository. As of the 18th of June, 2013 this repository may vanish. Please use a released version of the gem (this branch was released as-is as version 0.5.0).")
5
-
6
- module ContextIO
7
- VERSION = "2.0"
8
-
9
- class ContextIO::Connection
10
- def initialize(key='', secret='', server='https://api.context.io')
11
- @consumer = OAuth::Consumer.new(key, secret, {:site => server, :sheme => :header})
12
- @token = OAuth::AccessToken.new @consumer
13
- end
14
-
15
- def discovery(options)
16
- get 'discovery', {:source_type => 'imap'}.merge(options)
17
- end
18
-
19
- def list_connect_tokens()
20
- get 'connect_tokens'
21
- end
22
-
23
- def get_connect_token(options)
24
- if ! options.has_key?(:token) then
25
- raise ArgumentError, "missing required argument token", caller
26
- end
27
- get "connect_tokens/#{options[:token]}"
28
- end
29
-
30
- def add_connect_token(options)
31
- if ! options.has_key?(:callback_url) then
32
- raise ArgumentError, "missing required argument callback_url", caller
33
- end
34
- post "connect_tokens", options
35
- end
36
-
37
- def delete_connect_token(options)
38
- if ! options.has_key?(:token) then
39
- raise ArgumentError, "missing required argument token", caller
40
- end
41
- delete "connect_tokens/#{options[:token]}"
42
- end
43
-
44
- def list_oauth_providers
45
- get 'oauth_providers'
46
- end
47
-
48
- def get_oauth_provider(options)
49
- if ! options.has_key?(:provider_consumer_key) then
50
- raise ArgumentError, "missing required argument provider_consumer_key", caller
51
- end
52
- get "oauth_providers/#{options[:provider_consumer_key]}"
53
- end
54
-
55
- def add_oauth_provider(options)
56
- if ! options.has_key?(:provider_consumer_key) then
57
- raise ArgumentError, "missing required argument provider_consumer_key", caller
58
- end
59
- if ! options.has_key?(:type) then
60
- raise ArgumentError, "missing required argument type", caller
61
- end
62
- if ! options.has_key?(:provider_consumer_secret) then
63
- raise ArgumentError, "missing required argument provider_consumer_secret", caller
64
- end
65
- post "oauth_providers/", options
66
- end
67
-
68
- def delete_oauth_provider(options)
69
- if ! options.has_key?(:provider_consumer_key) then
70
- raise ArgumentError, "missing required argument provider_consumer_key", caller
71
- end
72
- delete "oauth_providers/#{options[:provider_consumer_key]}"
73
- end
74
-
75
- def list_contacts(options)
76
- if ! options.has_key?(:account) then
77
- raise ArgumentError, "missing required argument account", caller
78
- end
79
- account = options.delete(:account)
80
- get "accounts/#{account}/contacts", options
81
- end
82
-
83
- def get_contact(options)
84
- if ! options.has_key?(:account) then
85
- raise ArgumentError, "missing required argument account", caller
86
- end
87
- if ! options.has_key?(:email) then
88
- raise ArgumentError, "missing required argument email", caller
89
- end
90
- get "accounts/#{options[:account]}/contacts/#{URI.escape options[:email]}"
91
- end
92
-
93
- def list_contact_files(options)
94
- if ! options.has_key?(:account) then
95
- raise ArgumentError, "missing required argument account", caller
96
- end
97
- if ! options.has_key?(:email) then
98
- raise ArgumentError, "missing required argument email", caller
99
- end
100
- account = options.delete(:account)
101
- email = URI.escape(options.delete(:email))
102
- get "accounts/#{account}/contacts/#{email}/files", options
103
- end
104
-
105
- def list_contact_messages(options)
106
- if ! options.has_key?(:account) then
107
- raise ArgumentError, "missing required argument account", caller
108
- end
109
- if ! options.has_key?(:email) then
110
- raise ArgumentError, "missing required argument email", caller
111
- end
112
- account = options.delete(:account)
113
- email = URI.escape(options.delete(:email))
114
- get "accounts/#{account}/contacts/#{email}/messages", options
115
- end
116
-
117
- def list_contact_threads(options)
118
- if ! options.has_key?(:account) then
119
- raise ArgumentError, "missing required argument account", caller
120
- end
121
- if ! options.has_key?(:email) then
122
- raise ArgumentError, "missing required argument email", caller
123
- end
124
- account = options.delete(:account)
125
- email = URI.escape(options.delete(:email))
126
- get "accounts/#{account}/contacts/#{email}/threads", options
127
- end
128
-
129
- def list_files(options)
130
- if ! options.has_key?(:account) then
131
- raise ArgumentError, "missing required argument account", caller
132
- end
133
- account = options.delete(:account)
134
- get "accounts/#{account}/files", options
135
- end
136
-
137
- def get_file(options)
138
- if ! options.has_key?(:account) then
139
- raise ArgumentError, "missing required argument account", caller
140
- end
141
- if ! options.has_key?(:file_id) then
142
- raise ArgumentError, "missing required argument file_id", caller
143
- end
144
- get "accounts/#{options[:account]}/files/#{options[:file_id]}"
145
- end
146
-
147
- def get_file_content(options)
148
- if ! options.has_key?(:account) then
149
- raise ArgumentError, "missing required argument account", caller
150
- end
151
- if ! options.has_key?(:file_id) then
152
- raise ArgumentError, "missing required argument file_id", caller
153
- end
154
- if ! options.has_key?(:as_link) then
155
- get "accounts/#{options[:account]}/files/#{options[:file_id]}/content"
156
- else
157
- get "accounts/#{options[:account]}/files/#{options[:file_id]}/content?as_link=#{options[:as_link]}"
158
- end
159
- end
160
-
161
- def get_file_changes(options)
162
- if ! options.has_key?(:account) then
163
- raise ArgumentError, "missing required argument account", caller
164
- end
165
- if ! options.has_key?(:file_id) then
166
- raise ArgumentError, "missing required argument file_id", caller
167
- end
168
- account = options.delete(:account)
169
- file_id = options.delete(:file_id)
170
- get "accounts/#{account}/files/#{file_id}/changes", options
171
- end
172
-
173
- def list_file_revisions(options)
174
- if ! options.has_key?(:account) then
175
- raise ArgumentError, "missing required argument account", caller
176
- end
177
- if ! options.has_key?(:file_id) then
178
- raise ArgumentError, "missing required argument file_id", caller
179
- end
180
- account = options.delete(:account)
181
- file_id = options.delete(:file_id)
182
- get "accounts/#{account}/files/#{file_id}/revisions", options
183
- end
184
-
185
- def list_file_related(options)
186
- if ! options.has_key?(:account) then
187
- raise ArgumentError, "missing required argument account", caller
188
- end
189
- if ! options.has_key?(:file_id) then
190
- raise ArgumentError, "missing required argument file_id", caller
191
- end
192
- account = options.delete(:account)
193
- file_id = options.delete(:file_id)
194
- get "accounts/#{account}/files/#{file_id}/related", options
195
- end
196
-
197
- def list_messages(options)
198
- if ! options.has_key?(:account) then
199
- raise ArgumentError, "missing required argument account", caller
200
- end
201
- account = options.delete(:account)
202
- get "accounts/#{account}/messages", options
203
- end
204
-
205
- def get_message(options)
206
- if ! options.has_key?(:account) then
207
- raise ArgumentError, "missing required argument account", caller
208
- end
209
-
210
- account = options.delete(:account)
211
- if options.has_key?(:email_message_id) then
212
- email_message_id = URI.escape(options.delete(:email_message_id))
213
- get "accounts/#{account}/messages/#{email_message_id}"
214
- elsif options.has_key?(:message_id) then
215
- message_id = options.delete(:message_id)
216
- get "accounts/#{account}/messages/#{message_id}"
217
- elsif options.has_key?(:gmail_message_id) then
218
- gmail_message_id = options.delete(:gmail_message_id)
219
- if options[:gmail_message_id].start_with?('gm-') then
220
- get "accounts/#{account}/messages/#{gmail_message_id}"
221
- else
222
- get "accounts/#{account}/messages/gm-#{gmail_message_id}"
223
- end
224
- end
225
- end
226
-
227
- def get_message_headers(options)
228
- if ! options.has_key?(:account) then
229
- raise ArgumentError, "missing required argument account", caller
230
- end
231
-
232
- account = options.delete(:account)
233
- if options.has_key?(:email_message_id) then
234
- email_message_id = URI.escape(options.delete(:email_message_id))
235
- get "accounts/#{account}/messages/#{email_message_id}/headers"
236
- elsif options.has_key?(:message_id) then
237
- message_id = options.delete(:message_id)
238
- get "accounts/#{account}/messages/#{message_id}/headers"
239
- elsif options.has_key?(:gmail_message_id) then
240
- gmail_message_id = options.delete(:gmail_message_id)
241
- if options[:gmail_message_id].start_with?('gm-') then
242
- get "accounts/#{account}/messages/#{gmail_message_id}/headers"
243
- else
244
- get "accounts/#{account}/messages/gm-#{gmail_message_id}/headers"
245
- end
246
- end
247
- end
248
-
249
- def get_message_flags(options)
250
- if ! options.has_key?(:account) then
251
- raise ArgumentError, "missing required argument account", caller
252
- end
253
-
254
- account = options.delete(:account)
255
- if options.has_key?(:email_message_id) then
256
- email_message_id = URI.escape(options.delete(:email_message_id))
257
- get "accounts/#{account}/messages/#{email_message_id}/flags"
258
- elsif options.has_key?(:message_id) then
259
- message_id = options.delete(:message_id)
260
- get "accounts/#{account}/messages/#{message_id}/flags"
261
- elsif options.has_key?(:gmail_message_id) then
262
- gmail_message_id = options.delete(:gmail_message_id)
263
- if options[:gmail_message_id].start_with?('gm-') then
264
- get "accounts/#{account}/messages/#{gmail_message_id}/flags"
265
- else
266
- get "accounts/#{account}/messages/gm-#{gmail_message_id}/flags"
267
- end
268
- end
269
- end
270
-
271
- def get_message_body(options)
272
- if ! options.has_key?(:account) then
273
- raise ArgumentError, "missing required argument account", caller
274
- end
275
-
276
- account = options.delete(:account)
277
- if options.has_key?(:email_message_id) then
278
- email_message_id = URI.escape(options.delete(:email_message_id))
279
- get "accounts/#{account}/messages/#{email_message_id}/body"
280
- elsif options.has_key?(:message_id) then
281
- message_id = options.delete(:message_id)
282
- get "accounts/#{account}/messages/#{message_id}/body"
283
- elsif options.has_key?(:gmail_message_id) then
284
- gmail_message_id = options.delete(:gmail_message_id)
285
- if options[:gmail_message_id].start_with?('gm-') then
286
- get "accounts/#{account}/messages/#{gmail_message_id}/body"
287
- else
288
- get "accounts/#{account}/messages/gm-#{gmail_message_id}/body"
289
- end
290
- end
291
- end
292
-
293
- def get_message_thread(options)
294
- if ! options.has_key?(:account) then
295
- raise ArgumentError, "missing required argument account", caller
296
- end
297
-
298
- if options.has_key?(:email_message_id) then
299
- get "accounts/#{options[:account]}/messages/#{URI.escape options[:email_message_id]}/thread"
300
- elsif options.has_key?(:message_id) then
301
- get "accounts/#{options[:account]}/messages/#{options[:message_id]}/thread"
302
- elsif options.has_key?(:gmail_message_id) then
303
- if options[:gmail_message_id].start_with?('gm-') then
304
- get "accounts/#{options[:account]}/messages/#{options[:gmail_message_id]}/thread"
305
- else
306
- get "accounts/#{options[:account]}/messages/gm-#{options[:gmail_message_id]}/thread"
307
- end
308
- end
309
- end
310
-
311
- def list_threads(options)
312
- if ! options.has_key?(:account) then
313
- raise ArgumentError, "missing required argument account", caller
314
- end
315
- account = options.delete(:account)
316
- get "accounts/#{account}/threads", options
317
- end
318
-
319
- def get_thread(options)
320
- if ! options.has_key?(:account) then
321
- raise ArgumentError, "missing required argument account", caller
322
- end
323
-
324
- if options.has_key?(:email_message_id) then
325
- get "accounts/#{options[:account]}/messages/#{URI.escape options[:email_message_id]}/thread"
326
- elsif options.has_key?(:message_id) then
327
- get "accounts/#{options[:account]}/messages/#{options[:message_id]}/thread"
328
- elsif options.has_key?(:gmail_message_id) then
329
- if options[:gmail_message_id].start_with?('gm-') then
330
- get "accounts/#{options[:account]}/messages/#{options[:gmail_message_id]}/thread"
331
- else
332
- get "accounts/#{options[:account]}/messages/gm-#{options[:gmail_message_id]}/thread"
333
- end
334
- elsif options.has_key?(:gmail_thread_id) then
335
- if options[:gmail_thread_id].start_with?('gm-') then
336
- get "accounts/#{options[:account]}/threads/#{options[:gmail_thread_id]}"
337
- else
338
- get "accounts/#{options[:account]}/threads/gm-#{options[:gmail_thread_id]}"
339
- end
340
- end
341
- end
342
-
343
- def add_account(options)
344
- if ! options.has_key?(:email) then
345
- raise ArgumentError, "missing required argument email", caller
346
- end
347
- post "accounts", options
348
- end
349
-
350
- def modify_account(options)
351
- if ! options.has_key?(:account) then
352
- raise ArgumentError, "missing required argument account", caller
353
- end
354
- account = options.delete(:account)
355
- post "accounts/#{account}", options
356
- end
357
-
358
- def get_account(options)
359
- if ! options.has_key?(:account) then
360
- raise ArgumentError, "missing required argument account", caller
361
- end
362
- account = options.delete(:account)
363
- get "accounts/#{account}"
364
- end
365
-
366
- def delete_account(options)
367
- if ! options.has_key?(:account) then
368
- raise ArgumentError, "missing required argument account", caller
369
- end
370
- account = options.delete(:account)
371
- delete "accounts/#{account}"
372
- end
373
-
374
- def list_account_email_addresses(options)
375
- if ! options.has_key?(:account) then
376
- raise ArgumentError, "missing required argument account", caller
377
- end
378
- get "accounts/#{options[:account]}/email_addresses"
379
- end
380
-
381
- def delete_email_address_from_account(options)
382
- if ! options.has_key?(:account) then
383
- raise ArgumentError, "missing required argument account", caller
384
- end
385
- if ! options.has_key?(:email_address) then
386
- raise ArgumentError, "missing required argument account", caller
387
- end
388
- delete "accounts/#{account}/email_addresses/#{options[:email_address]}"
389
- end
390
-
391
- def set_primary_email_address_for_account(options)
392
- if ! options.has_key?(:account) then
393
- raise ArgumentError, "missing required argument account", caller
394
- end
395
- if ! options.has_key?(:email_address) then
396
- raise ArgumentError, "missing required argument account", caller
397
- end
398
- post "accounts/#{account}/email_addresses/#{options[:email_address]}", {:primary => 1}
399
- end
400
-
401
- def add_email_address_to_account(options)
402
- if ! options.has_key?(:account) then
403
- raise ArgumentError, "missing required argument account", caller
404
- end
405
- if ! options.has_key?(:email_address) then
406
- raise ArgumentError, "missing required argument account", caller
407
- end
408
- account = options.delete(:account)
409
- post "accounts/#{account}/email_addresses", options
410
- end
411
-
412
- def list_accounts(options)
413
- get "accounts", options
414
- end
415
-
416
- def modify_source(options)
417
- if ! options.has_key?(:account) then
418
- raise ArgumentError, "missing required argument account", caller
419
- end
420
- if ! options.has_key?(:label) then
421
- raise ArgumentError, "missing required argument label", caller
422
- end
423
- account = options.delete(:account)
424
- label = URI.escape(options.delete(:label))
425
- post "accounts/#{account}/sources/#{label}", options
426
- end
427
-
428
- def reset_source_status(options)
429
- if ! options.has_key?(:account) then
430
- raise ArgumentError, "missing required argument account", caller
431
- end
432
- if ! options.has_key?(:label) then
433
- raise ArgumentError, "missing required argument label", caller
434
- end
435
- post "accounts/#{options[:account]}/sources/#{URI.escape options[:label]}", { :status => 1 }
436
- end
437
-
438
- def list_sources(options)
439
- if ! options.has_key?(:account) then
440
- raise ArgumentError, "missing required argument account", caller
441
- end
442
- get "accounts/#{options[:account]}/sources"
443
- end
444
-
445
- def get_source(options)
446
- if ! options.has_key?(:account) then
447
- raise ArgumentError, "missing required argument account", caller
448
- end
449
- if ! options.has_key?(:label) then
450
- raise ArgumentError, "missing required argument label", caller
451
- end
452
- get "accounts/#{options[:account]}/sources/#{URI.escape options[:label]}"
453
- end
454
-
455
- def add_source(options)
456
- if ! options.has_key?(:account) then
457
- raise ArgumentError, "missing required argument account", caller
458
- end
459
- if ! options.has_key?(:type) then
460
- options[:type] = 'imap'
461
- end
462
- account = options.delete(:account)
463
- post "accounts/#{account}/sources", options
464
- end
465
-
466
- def delete_source(options)
467
- if ! options.has_key?(:account) then
468
- raise ArgumentError, "missing required argument account", caller
469
- end
470
- if ! options.has_key?(:label) then
471
- raise ArgumentError, "missing required argument label", caller
472
- end
473
- delete "accounts/#{options[:account]}/sources/#{URI.escape options[:label]}"
474
- end
475
-
476
- def sync_source(options)
477
- if ! options.has_key?(:account) then
478
- raise ArgumentError, "missing required argument account", caller
479
- end
480
- if ! options.has_key?(:label) then
481
- post "accounts/#{options[:account]}/sync"
482
- else
483
- post "accounts/#{options[:account]}/sources/#{URI.escape options[:label]}/sync"
484
- end
485
- end
486
-
487
- def get_sync(options)
488
- if ! options.has_key?(:account) then
489
- raise ArgumentError, "missing required argument account", caller
490
- end
491
- if ! options.has_key?(:label) then
492
- get "accounts/#{options[:account]}/sync"
493
- else
494
- get "accounts/#{options[:account]}/sources/#{URI.escape options[:label]}/sync"
495
- end
496
- end
497
-
498
- def add_folder_to_source(options)
499
- if ! options.has_key?(:account) then
500
- raise ArgumentError, "missing required argument account", caller
501
- end
502
- if ! options.has_key?(:label) then
503
- raise ArgumentError, "missing required argument label", caller
504
- end
505
- put "accounts/#{options[:account]}/sources/#{URI.escape options[:label]}/folders/#{URI.escape options[:folder]}"
506
- end
507
-
508
- def list_source_folders(options)
509
- if ! options.has_key?(:account) then
510
- raise ArgumentError, "missing required argument account", caller
511
- end
512
- if ! options.has_key?(:label) then
513
- raise ArgumentError, "missing required argument label", caller
514
- end
515
- get "accounts/#{options[:account]}/sources/#{URI.escape options[:label]}/folders"
516
- end
517
-
518
- def list_webhooks(options)
519
- if ! options.has_key?(:account) then
520
- raise ArgumentError, "missing required argument account", caller
521
- end
522
- get "accounts/#{options[:account]}/webhooks"
523
- end
524
-
525
- def get_webhook(options)
526
- if ! options.has_key?(:account) then
527
- raise ArgumentError, "missing required argument account", caller
528
- end
529
- if ! options.has_key?(:webhook_id) then
530
- raise ArgumentError, "missing required argument webhook_id", caller
531
- end
532
- get "accounts/#{options[:account]}/webhooks/#{options[:webhook_id]}"
533
- end
534
-
535
- def add_webhook(options)
536
- if ! options.has_key?(:account) then
537
- raise ArgumentError, "missing required argument account", caller
538
- end
539
- account = options.delete(:account)
540
- post "accounts/#{account}/webhooks", options
541
- end
542
-
543
- def delete_webhook(options)
544
- if ! options.has_key?(:account) then
545
- raise ArgumentError, "missing required argument account", caller
546
- end
547
- if ! options.has_key?(:webhook_id) then
548
- raise ArgumentError, "missing required argument webhook_id", caller
549
- end
550
- delete "accounts/#{options[:account]}/webhooks/#{options[:webhook_id]}"
551
- end
552
-
553
- private
554
-
555
- def url(*args)
556
- if args.length == 1
557
- "/#{ContextIO::VERSION}/#{args[0]}"
558
- else
559
- "/#{ContextIO::VERSION}/#{args.shift.to_s}?#{parametrize args.last}"
560
- end
561
- end
562
-
563
- def get(*args)
564
- @token.get(url(*args), { 'Accept' => 'application/json' })
565
- end
1
+ # Provides an object-oriented interface for the Context.IO API.
2
+ #
3
+ # To use it, you have to [sign up for an account](http://context.io).
4
+ #
5
+ # Once you have an account, you can create a new `ContextIO` object and interact
6
+ # with the API using the methods on that object as a starting point.
7
+ class ContextIO
8
+ # @private
9
+ # Handle for the `API` instance. For internal use only.
10
+ attr_reader :api
11
+
12
+ # Creates a new `ContextIO` instance and makes a new handle for the API.
13
+ # This is your entry point to your Context.IO account. For a web app, you
14
+ # probably want to instantiate this in some kind of initializer and keep it
15
+ # around for the life of the process.
16
+ #
17
+ # @param [String] key Your OAuth consumer key for your Context.IO account
18
+ # @param [String] secret Your OAuth consumer secret for your Context.IO
19
+ # account
20
+ def initialize(key, secret)
21
+ @api = API.new(key, secret)
22
+ end
566
23
 
567
- def delete(*args)
568
- @token.delete(url(*args), { 'Accept' => 'application/json' })
569
- end
24
+ # Your entry point for dealing with oauth providers.
25
+ #
26
+ # @return [OAuthProviderCollection] Allows you to work with the providers for
27
+ # your account as a group.
28
+ def oauth_providers
29
+ OAuthProviderCollection.new(api)
30
+ end
570
31
 
571
- def put(action, args=nil)
572
- @token.put(url(action), args, { 'Accept' => 'application/json' })
573
- end
32
+ # Your entry point for dealing with connect tokens.
33
+ #
34
+ # @return [ConnectTokenCollection] Allows you to work with the tokens for
35
+ # your account as a group.
36
+ def connect_tokens
37
+ ConnectTokenCollection.new(api)
38
+ end
574
39
 
575
- def post(action, args=nil)
576
- @token.post(url(action), args, { 'Accept' => 'application/json' })
577
- end
40
+ # Your entry point for dealing with accounts.
41
+ #
42
+ # @return [AccountCollection] Allows you to work with the email accounts for
43
+ # your account as a group.
44
+ def accounts
45
+ AccountCollection.new(api)
46
+ end
578
47
 
579
- def parametrize(options)
580
- URI.escape(options.collect do |k,v|
581
- v = v.to_i if k == :since
582
- v = v.join(',') if v.instance_of?(Array)
583
- k = k.to_s
584
- #k = k.to_s.gsub('_', '')
585
- "#{k}=#{v}"
586
- end.join('&'))
587
- end
48
+ # Discover the IMAP settings for an email account.
49
+ #
50
+ # @param [String] email_address The email address in question.
51
+ # @param [String] source_type The only source type currently supported by the
52
+ # API is 'IMAP'.
53
+ #
54
+ # @return [EmailSettings] Allows you to inspec the settings for an account's
55
+ # IMAP server.
56
+ def email_settings_for(email_address, source_type = 'IMAP')
57
+ EmailSettings.new(api, email_address, source_type)
588
58
  end
589
59
  end
60
+
61
+ require_relative 'contextio/version'
62
+
63
+ require_relative 'contextio/api'
64
+
65
+ require_relative 'contextio/oauth_provider_collection'
66
+ require_relative 'contextio/email_settings'
67
+ require_relative 'contextio/connect_token_collection'
68
+ require_relative 'contextio/account_collection'
69
+ require_relative 'contextio/source_collection'
70
+ require_relative 'contextio/folder_collection'
71
+ require_relative 'contextio/message_collection'
72
+ require_relative 'contextio/body_part_collection'
73
+ require_relative 'contextio/thread_collection'
74
+ require_relative 'contextio/webhook_collection'
75
+ require_relative 'contextio/contact_collection'