contextio-lite 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,30 @@
1
+ require 'contextio/api/abstract_api'
2
+ require_relative 'url_builder'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class API < ContextIO::API::AbstractAPI
7
+
8
+ VERSION = 'lite'
9
+
10
+ def self.user_agent_string
11
+ "contextio-#{self.version}-ruby-#{ContextIO.version}"
12
+ end
13
+
14
+ # @param [Object] resource The resource you want the URL for.
15
+ #
16
+ # @return [String] The URL for the resource in the API.
17
+ def self.url_for(resource)
18
+ ContextIO::Lite::URLBuilder.url_for(resource)
19
+ end
20
+
21
+ # @param [Object] resource The resource you want the URL for.
22
+ #
23
+ # @return [String] The URL for the resource in the API.
24
+ def url_for(resource)
25
+ ContextIO::Lite::API.url_for(resource)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,48 @@
1
+ require 'contextio/api/resource'
2
+ require 'contextio/api/association_helpers'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class EmailAccount
7
+ include ContextIO::API::Resource
8
+
9
+ self.primary_key = :label
10
+ self.association_name = :email_account
11
+
12
+ has_many :folders
13
+
14
+ lazy_attributes :server, :label, :username, :port, :authentication_type,
15
+ :status, :service_level, :sync_period, :use_ssl, :type
16
+ private :use_ssl
17
+
18
+ # @!attribute [r] use_ssl?
19
+ # @return [Boolean] Whether or not this source uses SSL.
20
+ def use_ssl?
21
+ use_ssl
22
+ end
23
+
24
+ # Updates the email_account.
25
+ #
26
+ # @params [Hash{String, Symbol => String}] options See the Context.IO docs
27
+ # for more details on these fields.
28
+ def update(options={})
29
+ it_worked = api.request(:post, resource_url, options)['success']
30
+
31
+ if it_worked
32
+ options.each do |key, value|
33
+ key = key.to_s.gsub('-', '_')
34
+
35
+ instance_variable_set("@#{key}", value)
36
+ end
37
+ end
38
+
39
+ it_worked
40
+ end
41
+
42
+ def delete
43
+ api.request(:delete, resource_url)['success']
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,44 @@
1
+ require 'contextio/api/resource_collection'
2
+ require_relative 'email_account'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class EmailAccountCollection
7
+ include ContextIO::API::ResourceCollection
8
+
9
+ self.resource_class = ContextIO::Lite::EmailAccount
10
+ self.association_name = :email_accounts
11
+
12
+ belongs_to :user
13
+
14
+ # Creates a new email_account for an user.
15
+ #
16
+ # @param [String] email The email address for the new source.
17
+ # @param [String] server The address of the server for the source.
18
+ # @param [String] username The name for logging into the server. Often the
19
+ # same as the email.
20
+ # @param [Boolean] use_ssl Whether to use SSL for the new source.
21
+ # @param [Numeric, String] port The port to connect on.
22
+ # @param [String] type Currently, only 'IMAP' is supported.
23
+ # @param [Hash{String, Symbol => String}] options Information you can
24
+ # provide at creation. Check out the Context.IO documentation for what's
25
+ # required and what's optional.
26
+ def create(email, server, username, use_ssl, port, type, options={})
27
+ api_args = options.merge(
28
+ :email => email,
29
+ :server => server,
30
+ :username => username,
31
+ :use_ssl => use_ssl ? '1' : '0',
32
+ :port => port.to_s,
33
+ :type => type
34
+ )
35
+
36
+ result_hash = api.request(:post, resource_url, api_args)
37
+
38
+ result_hash.delete('success')
39
+
40
+ resource_class.new(api, result_hash)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ require 'contextio/api/resource'
2
+ require 'contextio/api/association_helpers'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class Folder
7
+ include ContextIO::API::Resource
8
+
9
+ self.primary_key = :name
10
+ self.association_name = :folder
11
+
12
+ has_many :messages
13
+
14
+ lazy_attributes :name, :delimiter, :nb_messages, :nb_unseen_messages
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require 'contextio/api/resource_collection'
2
+ require_relative 'folder'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class FolderCollection
7
+ include ContextIO::API::ResourceCollection
8
+
9
+ self.resource_class = ContextIO::Lite::Folder
10
+ self.association_name = :folders
11
+
12
+ belongs_to :email_account
13
+
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,77 @@
1
+ require 'contextio/api/resource'
2
+ require 'contextio/api/association_helpers'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class Message
7
+ include ContextIO::API::Resource
8
+
9
+ self.primary_key = :message_id
10
+ self.association_name = :message
11
+
12
+ # has_many :body_parts
13
+
14
+ lazy_attributes :sent_at, :addresses, :person_info, :email_message_id, :message_id,
15
+ :attachments, :subject, :folders, :bodies, :references, :in_reply_to,
16
+ :list_headers, :received_headers
17
+
18
+ FLAG_KEYS = %w(seen answered flagged draft deleted)
19
+
20
+ private :sent_at, :bodies, :addresses
21
+
22
+ def sent
23
+ @sent ||= Time.at(sent_at)
24
+ end
25
+
26
+ %w(from to bcc cc reply_to).each do |f|
27
+ define_method(f) do
28
+ addresses[f]
29
+ end
30
+ end
31
+
32
+ def body_plain
33
+ self.body(type:'text/plain').map{|b| b['content']}.join
34
+ end
35
+
36
+ def body_html
37
+ self.body(type:'text/html').map{|b| b['content']}.join
38
+ end
39
+
40
+ def body(options={})
41
+ @body ||= if @with_constraints.has_key?(:include_body) && @with_constraints[:include_body]==1 then
42
+ options.has_key?('type') ?
43
+ self.api_attributes['bodies'].select { |b| b['type']==options['type'] } :
44
+ self.api_attributes['bodies']
45
+ else
46
+ api.request(:get, "#{resource_url}/body", options)['bodies']
47
+ end
48
+ end
49
+
50
+ def flags
51
+ if @with_constraints.has_key?(:include_flags) && @with_constraints[:include_flags]==1
52
+ @flags = self.api_attributes['flags']
53
+ else
54
+ @flags ||= api.request(:get, "#{resource_url}/flags")['flags']
55
+ @flags['seen'] = @flags.delete 'read' if @flags.has_key? 'read'
56
+ @flags = Hash[FLAG_KEYS.map{|f| [f, @flags.include?(f) && @flags[f]]}]
57
+ end
58
+ @flags
59
+ end
60
+
61
+ def headers
62
+ @headers ||= @with_constraints.has_key?(:include_headers) && @with_constraints[:include_headers]==1 ?
63
+ self.api_attributes['headers'] :
64
+ api.request(:get, "#{resource_url}/headers")['headers']
65
+ end
66
+
67
+ def raw
68
+ api.raw_request(:get, "#{resource_url}/raw")
69
+ end
70
+
71
+ def read
72
+ api.request(:post, "#{resource_url}/read")['success']
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,15 @@
1
+ require 'contextio/api/resource_collection'
2
+ require_relative 'message'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class MessageCollection
7
+ include ContextIO::API::ResourceCollection
8
+
9
+ self.resource_class = ContextIO::Lite::Message
10
+ self.association_name = :messages
11
+
12
+ belongs_to :folder
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,95 @@
1
+ require_relative 'email_account_collection'
2
+ require_relative 'folder_collection'
3
+ require_relative 'message_collection'
4
+ require_relative 'user_collection'
5
+ require_relative 'webhook_collection'
6
+
7
+ module ContextIO
8
+ class Lite
9
+ class URLBuilder
10
+ class Error < StandardError; end
11
+
12
+ # Tells you the right URL for a resource to fetch attributes from.
13
+ #
14
+ # @param [Contextio::Resource, Contextio::ResourceCollection] resource The
15
+ # resource or resource collection.
16
+ #
17
+ # @return [String] The path for that resource in the API.
18
+ def self.url_for(resource)
19
+ if (builder = @registered_urls[resource.class])
20
+ builder.call(resource)
21
+ else
22
+ raise Error, "URL could not be built for unregistered Class: #{resource.class}."
23
+ end
24
+ end
25
+
26
+ # Register a block that calculates the URL for a given resource.
27
+ #
28
+ # @param [Class] resource_class The class of the resource you are
29
+ # registering.
30
+ # @param [Block] block The code that will compute the url for the
31
+ # resource. This is actually a path. Start after the version number of
32
+ # the API in the URL. When a URL is being calculated for a specific
33
+ # resource, the resource instance will be yielded to the block.
34
+ #
35
+ # @example For Accounts
36
+ # register_url ContextIO::Account do |account|
37
+ # "accounts/#{account.id}"
38
+ # end
39
+ def self.register_url(resource_class, &block)
40
+ @registered_urls ||= {}
41
+ @registered_urls[resource_class] = block
42
+ end
43
+
44
+ register_url ContextIO::Lite::UserCollection do
45
+ 'users'
46
+ end
47
+
48
+ register_url ContextIO::Lite::User do |user|
49
+ "users/#{user.id}"
50
+ end
51
+
52
+ register_url ContextIO::Lite::EmailAccountCollection do |email_accounts|
53
+ "users/#{email_accounts.user.id}/email_accounts"
54
+ end
55
+
56
+ register_url ContextIO::Lite::EmailAccount do |email_account|
57
+ "users/#{email_account.user.id}/email_accounts/#{email_account.label}"
58
+ end
59
+
60
+ register_url ContextIO::Lite::FolderCollection do |folders|
61
+ "users/#{folders.email_account.user.id}/email_accounts/#{uri_encode folders.email_account.label}/folders"
62
+ end
63
+
64
+ register_url ContextIO::Lite::Folder do |folder|
65
+ "users/#{folder.email_account.user.id}/email_accounts/#{uri_encode folder.email_account.label}/folders/#{uri_encode folder.name}"
66
+ end
67
+
68
+ register_url ContextIO::Lite::MessageCollection do |messages|
69
+ "users/#{messages.folder.email_account.user.id}/email_accounts/#{uri_encode messages.folder.email_account.label}/folders/#{uri_encode messages.folder.name}/messages"
70
+ end
71
+
72
+ register_url ContextIO::Lite::Message do |message|
73
+ "users/#{message.folder.email_account.user.id}/email_accounts/#{uri_encode message.folder.email_account.label}/folders/#{uri_encode message.folder.name}/messages/#{uri_encode message.message_id}"
74
+ end
75
+
76
+
77
+ register_url ContextIO::Lite::WebhookCollection do |webhooks|
78
+ "users/#{webhooks.user.id}/webhooks"
79
+ end
80
+
81
+ register_url ContextIO::Lite::Webhook do |webhook|
82
+ "users/#{webhook.user.id}/webhooks/#{webhook.webhook_id}"
83
+ end
84
+
85
+ def self.uri_encode(param)
86
+ if param.is_a? String
87
+ URI.encode param
88
+ else
89
+ param
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,61 @@
1
+ require 'contextio/api/resource'
2
+ require 'contextio/api/association_helpers'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class User
7
+ include ContextIO::API::Resource
8
+
9
+ self.primary_key = :id
10
+ self.association_name = :user
11
+
12
+ has_many :email_accounts
13
+ has_many :webhooks
14
+
15
+ # @!attribute [r] id
16
+ # @return [String] The id assigned to this account by Context.IO.
17
+ # @!attribute [r] username
18
+ # @return [String] The username assigned to this account by Context.IO.
19
+ # @!attribute [r] first_name
20
+ # @return [String] The account holder's first name.
21
+ # @!attribute [r] last_name
22
+ # @return [String] The account holder's last name.
23
+ lazy_attributes :id, :email_addresses, :username, :created, :first_name, :last_name
24
+ private :created
25
+
26
+ # @!attribute [r] created_at
27
+ # @return [Time] The time this account was created (with Context.IO).
28
+ def created_at
29
+ @created_at ||= Time.at(created)
30
+ end
31
+
32
+ # Updates the account.
33
+ #
34
+ # @param [Hash{String, Symbol => String}] options You can update first_name
35
+ # or last_name (or both).
36
+ def update(options={})
37
+ first_name = options[:first_name] || options['first_name']
38
+ last_name = options[:last_name] || options['last_name']
39
+
40
+ attrs = {}
41
+ attrs[:first_name] = first_name if first_name
42
+ attrs[:last_name] = last_name if last_name
43
+
44
+ return nil if attrs.empty?
45
+
46
+ it_worked = api.request(:post, resource_url, attrs)['success']
47
+
48
+ if it_worked
49
+ @first_name = first_name || @first_name
50
+ @last_name = last_name || @last_name
51
+ end
52
+
53
+ it_worked
54
+ end
55
+
56
+ def delete
57
+ api.request(:delete, resource_url)['success']
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,40 @@
1
+ require 'contextio/api/resource_collection'
2
+ require_relative 'user'
3
+
4
+ module ContextIO
5
+ class Lite
6
+ class UserCollection
7
+ include ContextIO::API::ResourceCollection
8
+
9
+ self.resource_class = ContextIO::Lite::User
10
+ self.association_name = :accounts
11
+
12
+ # Creates a new email account for your Context.IO account.
13
+ #
14
+ # @param [Hash{String, Symbol => String}] options Information you can
15
+ # provide at creation: email, first_name and/or last_name. If the
16
+ # collection isn't already limited by email, then you must provide it.
17
+ #
18
+ # @return [Account] A new email account instance based on the data you
19
+ # input.
20
+ def create(options={})
21
+ email = options.delete(:email) || options.delete('email') ||
22
+ where_constraints[:email] || where_constraints['email']
23
+
24
+ if email.nil?
25
+ raise ArgumentError, 'You must provide an email for new Users.'
26
+ end
27
+
28
+ result_hash = api.request(
29
+ :post,
30
+ resource_url,
31
+ options.merge(email: email)
32
+ )
33
+
34
+ result_hash.delete('success')
35
+
36
+ resource_class.new(api, result_hash)
37
+ end
38
+ end
39
+ end
40
+ end