redbooth-ruby 0.0.3 → 0.0.4
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 +11 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.md +429 -0
- data/Rakefile +8 -0
- data/lib/redbooth-ruby/base.rb +43 -0
- data/lib/redbooth-ruby/client.rb +85 -0
- data/lib/redbooth-ruby/conversation.rb +20 -0
- data/lib/redbooth-ruby/me.rb +16 -0
- data/lib/redbooth-ruby/membership.rb +17 -0
- data/lib/redbooth-ruby/operations/base.rb +47 -0
- data/lib/redbooth-ruby/operations/create.rb +25 -0
- data/lib/redbooth-ruby/operations/delete.rb +26 -0
- data/lib/redbooth-ruby/operations/index.rb +49 -0
- data/lib/redbooth-ruby/operations/meta.rb +15 -0
- data/lib/redbooth-ruby/operations/show.rb +25 -0
- data/lib/redbooth-ruby/operations/update.rb +26 -0
- data/lib/redbooth-ruby/organization.rb +34 -0
- data/lib/redbooth-ruby/person.rb +23 -0
- data/lib/redbooth-ruby/project.rb +26 -0
- data/lib/redbooth-ruby/request/base.rb +41 -0
- data/lib/redbooth-ruby/request/collection.rb +105 -0
- data/lib/redbooth-ruby/request/connection.rb +140 -0
- data/lib/redbooth-ruby/request/helpers.rb +36 -0
- data/lib/redbooth-ruby/request/info.rb +41 -0
- data/lib/redbooth-ruby/request/response.rb +34 -0
- data/lib/redbooth-ruby/request/validator.rb +85 -0
- data/lib/redbooth-ruby/session.rb +46 -0
- data/lib/redbooth-ruby/task.rb +37 -0
- data/lib/redbooth-ruby/user.rb +13 -0
- data/lib/redbooth-ruby/version.rb +3 -0
- data/lib/redbooth-ruby.rb +113 -0
- data/redbooth-ruby.gemspec +30 -0
- metadata +37 -2
@@ -0,0 +1,34 @@
|
|
1
|
+
module RedboothRuby
|
2
|
+
module Request
|
3
|
+
# Wraps the API response parsing the json body and keeping interesting headers
|
4
|
+
#
|
5
|
+
class Response
|
6
|
+
attr_accessor :body, :headers, :data, :status
|
7
|
+
|
8
|
+
def initialize(attrs={})
|
9
|
+
@body = attrs[:body]
|
10
|
+
@headers = attrs[:headers]
|
11
|
+
@status = attrs[:status]
|
12
|
+
initialize_data
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
# initializes the json data with the request body
|
18
|
+
# or empty array if not
|
19
|
+
def initialize_data
|
20
|
+
@data = parse_body || {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Parses the json body if is a json valid string
|
24
|
+
#
|
25
|
+
def parse_body
|
26
|
+
return unless body.is_a?(String)
|
27
|
+
JSON.parse(body)
|
28
|
+
rescue
|
29
|
+
# not a valid json body
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module RedboothRuby
|
2
|
+
module Request
|
3
|
+
class Validator
|
4
|
+
attr_reader :info
|
5
|
+
attr_accessor :raw_response, :response
|
6
|
+
|
7
|
+
def initialize(info)
|
8
|
+
@info = info
|
9
|
+
end
|
10
|
+
|
11
|
+
# Validates the given http response creating a response object or
|
12
|
+
# failing with an error and description
|
13
|
+
#
|
14
|
+
# param incoming_response [] http response object
|
15
|
+
# return [RedboothRuby::Request::Response]
|
16
|
+
def validated_response_for(incoming_response)
|
17
|
+
self.raw_response = incoming_response
|
18
|
+
@response = RedboothRuby::Request::Response.new(headers: raw_response.headers,
|
19
|
+
body: raw_response.body,
|
20
|
+
status: raw_response.status.to_i)
|
21
|
+
verify_response_code
|
22
|
+
info.data = response.data
|
23
|
+
validate_response_data
|
24
|
+
response
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
# Verifies the response status code in case it fails with the dessired error
|
30
|
+
# and message
|
31
|
+
#
|
32
|
+
def verify_response_code
|
33
|
+
status = raw_response.status.to_i
|
34
|
+
case
|
35
|
+
when status == 401
|
36
|
+
verify_authentication_header
|
37
|
+
fail AuthenticationError
|
38
|
+
when status >= 500
|
39
|
+
fail APIError
|
40
|
+
when status >= 404
|
41
|
+
fail NotFound
|
42
|
+
when [102, 202].include?(status)
|
43
|
+
fail Processing, response
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Checks the authetication header to ensure wich is the best error to throw
|
48
|
+
#
|
49
|
+
def verify_authentication_header
|
50
|
+
case raw_response.headers['WWW-Authenticate']
|
51
|
+
when /error\=\"invalid_token\".*expired/
|
52
|
+
fail OauhtTokenExpired
|
53
|
+
when /error\=\"invalid_token\".*revoked/
|
54
|
+
fail OauhtTokenRevoked
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Validates the body data returned in the response in case there is
|
59
|
+
# an embed error it will fail with the dessired error and message
|
60
|
+
#
|
61
|
+
def validate_response_data
|
62
|
+
if response.data.is_a?(Hash)
|
63
|
+
if response.data['error']
|
64
|
+
handle_api_error(response.data['error']['code'], response.data['error']['message'])
|
65
|
+
elsif response.data['errors']
|
66
|
+
response.data['errors'].each do |error|
|
67
|
+
handle_api_error(error['code'], error['message'])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def handle_api_error(code, message)
|
74
|
+
error = case code
|
75
|
+
when 1021, 1024 then ObjectNotFound.new(message)
|
76
|
+
when 1300, 1303 then BadRequest.new(message)
|
77
|
+
when 2000 then AuthenticationError.new(message)
|
78
|
+
else
|
79
|
+
APIError.new(message)
|
80
|
+
end
|
81
|
+
fail error
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
|
3
|
+
module RedboothRuby
|
4
|
+
class Session
|
5
|
+
|
6
|
+
attr_accessor :token, :refresh_token, :access_token
|
7
|
+
attr_accessor :consumer_key, :consumer_secret
|
8
|
+
attr_accessor :oauth_verifier, :oauth_token
|
9
|
+
|
10
|
+
OAUTH_URLS = {
|
11
|
+
:site => 'https://redbooth.com/api/3',
|
12
|
+
:authorize_url => 'https://redbooth.com/oauth2/authorize',
|
13
|
+
:token_url => 'https://redbooth.com/oauth2/token'
|
14
|
+
}
|
15
|
+
|
16
|
+
def initialize(opts = {})
|
17
|
+
@token = opts[:token]
|
18
|
+
@consumer_key = opts[:consumer_key] || RedboothRuby.configuration[:consumer_key]
|
19
|
+
@consumer_secret = opts[:consumer_secret] || RedboothRuby.configuration[:consumer_secret]
|
20
|
+
@oauth_verifier = opts[:oauth_verifier]
|
21
|
+
@oauth_token = opts[:oauth_token]
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid?
|
25
|
+
return false unless token
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def client
|
30
|
+
@client ||= OAuth2::Client.new(consumer_key, consumer_secret, OAUTH_URLS)
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_access_token_url
|
34
|
+
url = OAUTH_URLS[:request_token_url]
|
35
|
+
url += "?oauth_verifier=#{oauth_verifier}" if oauth_verifier
|
36
|
+
url += "&oauth_token=#{oauth_token}" if oauth_token
|
37
|
+
end
|
38
|
+
|
39
|
+
def access_token
|
40
|
+
@access_token ||= OAuth2::AccessToken.new(client, token)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module RedboothRuby
|
2
|
+
class Task < Base
|
3
|
+
include RedboothRuby::Operations::Index
|
4
|
+
include RedboothRuby::Operations::Create
|
5
|
+
include RedboothRuby::Operations::Update
|
6
|
+
include RedboothRuby::Operations::Show
|
7
|
+
include RedboothRuby::Operations::Delete
|
8
|
+
|
9
|
+
attr_accessor :id,
|
10
|
+
:name,
|
11
|
+
:task_list_id,
|
12
|
+
:comments_count,
|
13
|
+
:assigned_id,
|
14
|
+
:is_private,
|
15
|
+
:project_id,
|
16
|
+
:urgent,
|
17
|
+
:user_id,
|
18
|
+
:position,
|
19
|
+
:last_activity_id,
|
20
|
+
:record_conversion_type,
|
21
|
+
:record_conversion_id,
|
22
|
+
:metadata,
|
23
|
+
:subtasks_count,
|
24
|
+
:resolved_subtasks_count,
|
25
|
+
:watcher_ids,
|
26
|
+
:description,
|
27
|
+
:description_html,
|
28
|
+
:description_updated_by_user_id,
|
29
|
+
:updated_by_id,
|
30
|
+
:deleted,
|
31
|
+
:status,
|
32
|
+
:due_on,
|
33
|
+
:created_at,
|
34
|
+
:updated_at
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RedboothRuby
|
2
|
+
class User < Base
|
3
|
+
include RedboothRuby::Operations::Index
|
4
|
+
include RedboothRuby::Operations::Show
|
5
|
+
|
6
|
+
attr_accessor :id, :email, :first_name, :last_name, :developer, :created_time,
|
7
|
+
:emails, :storage, :confirmed, :user_id
|
8
|
+
|
9
|
+
def id
|
10
|
+
@id || @user_id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'json'
|
4
|
+
require 'redbooth-ruby/version'
|
5
|
+
|
6
|
+
module RedboothRuby
|
7
|
+
DOMAIN_BASE = nil
|
8
|
+
API_BASE_PATH = 'api'
|
9
|
+
API_VERSION = '3'
|
10
|
+
ROOT_PATH = File.dirname(__FILE__)
|
11
|
+
|
12
|
+
autoload :Base, 'redbooth-ruby/base'
|
13
|
+
autoload :Client, 'redbooth-ruby/client'
|
14
|
+
autoload :Session, 'redbooth-ruby/session'
|
15
|
+
autoload :Me, 'redbooth-ruby/me'
|
16
|
+
autoload :User, 'redbooth-ruby/user'
|
17
|
+
autoload :Task, 'redbooth-ruby/task'
|
18
|
+
autoload :Organization, 'redbooth-ruby/organization'
|
19
|
+
autoload :Person, 'redbooth-ruby/person'
|
20
|
+
autoload :Project, 'redbooth-ruby/project'
|
21
|
+
autoload :Conversation, 'redbooth-ruby/conversation'
|
22
|
+
autoload :Membership, 'redbooth-ruby/membership'
|
23
|
+
|
24
|
+
module Operations
|
25
|
+
autoload :Base, 'redbooth-ruby/operations/base'
|
26
|
+
autoload :Index, 'redbooth-ruby/operations/index'
|
27
|
+
autoload :Create, 'redbooth-ruby/operations/create'
|
28
|
+
autoload :Delete, 'redbooth-ruby/operations/delete'
|
29
|
+
autoload :Show, 'redbooth-ruby/operations/show'
|
30
|
+
autoload :Update, 'redbooth-ruby/operations/update'
|
31
|
+
autoload :Meta, 'redbooth-ruby/operations/meta'
|
32
|
+
end
|
33
|
+
|
34
|
+
module Request
|
35
|
+
autoload :Base, 'redbooth-ruby/request/base'
|
36
|
+
autoload :Connection, 'redbooth-ruby/request/connection'
|
37
|
+
autoload :Helpers, 'redbooth-ruby/request/helpers'
|
38
|
+
autoload :Info, 'redbooth-ruby/request/info'
|
39
|
+
autoload :Validator, 'redbooth-ruby/request/validator'
|
40
|
+
autoload :Response, 'redbooth-ruby/request/response'
|
41
|
+
autoload :Collection, 'redbooth-ruby/request/collection'
|
42
|
+
end
|
43
|
+
|
44
|
+
class RedboothError < StandardError; end
|
45
|
+
class AuthenticationError < RedboothError; end
|
46
|
+
class OauhtTokenExpired < AuthenticationError; end
|
47
|
+
class OauhtTokenRevoked < AuthenticationError; end
|
48
|
+
class NotFound < RedboothError; end
|
49
|
+
class APIError < RedboothError; end
|
50
|
+
class ObjectNotFound < APIError; end
|
51
|
+
class BadRequest < APIError; end
|
52
|
+
|
53
|
+
# Signals. Usign errors as control flow
|
54
|
+
#
|
55
|
+
class RedboothSignal < StandardError; end
|
56
|
+
class Processing < RedboothSignal
|
57
|
+
attr_accessor :response
|
58
|
+
|
59
|
+
def initialize(response, message='')
|
60
|
+
@response = response
|
61
|
+
super(message)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# Gives configuration abilities
|
67
|
+
# to setup api_key and api_secret
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# Copy.config do |configuration|
|
71
|
+
# configuration[:api_key] = '_your_api_key'
|
72
|
+
# configuration[:api_secret] = '_your_api_secret'
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# @return [String] The api key
|
76
|
+
def self.config(&block)
|
77
|
+
default_configuration
|
78
|
+
yield(@@configuration)
|
79
|
+
@@configuration
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.configuration
|
83
|
+
default_configuration
|
84
|
+
@@configuration
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.configuration=(value)
|
88
|
+
default_configuration
|
89
|
+
@@configuration = value
|
90
|
+
end
|
91
|
+
|
92
|
+
# Makes a request against the Copy API
|
93
|
+
#
|
94
|
+
# @param [Symbol] http_method The http method to use, must be one of :get, :post, :put and :delete
|
95
|
+
# @param [String] domain The API domain to use
|
96
|
+
# @param [String] api_url The API url to use
|
97
|
+
# @param [Hash] data The data to send, e.g. used when creating new objects.
|
98
|
+
# @return [Array] The parsed JSON response.
|
99
|
+
def self.request(http_method, domain, api_url, data, options = {})
|
100
|
+
info = Request::Info.new(http_method, domain, api_url, data, options)
|
101
|
+
Request::Base.new(info).perform
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.default_configuration
|
105
|
+
return if defined?(@@configuration)
|
106
|
+
@@configuration ||= {}
|
107
|
+
@@configuration[:api_base] ||= 'redbooth.com'
|
108
|
+
@@configuration[:domain_base] ||= nil
|
109
|
+
@@configuration[:api_base_path] ||= 'api'
|
110
|
+
@@configuration[:api_version] ||= '3'
|
111
|
+
@@configuration[:use_ssl] ||= true
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'redbooth-ruby/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'redbooth-ruby'
|
8
|
+
s.version = RedboothRuby::VERSION
|
9
|
+
s.authors = ['Andres Bravo', 'Carlos Saura']
|
10
|
+
s.email = ['support@redbooth.com']
|
11
|
+
s.homepage = 'https://github.com/teambox/redbooth-ruby'
|
12
|
+
s.summary = %q{API wrapper for Redbooth.}
|
13
|
+
s.description = %q{API wrapper for Redbooth.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ['lib']
|
19
|
+
|
20
|
+
s.required_ruby_version = '>= 1.9.3'
|
21
|
+
|
22
|
+
s.add_dependency 'json', '>= 1.8.1'
|
23
|
+
s.add_dependency 'oauth2', '>= 0.9.3'
|
24
|
+
s.add_dependency(%q<multipart-post>, ['>= 1.1.0'])
|
25
|
+
|
26
|
+
s.add_development_dependency 'rspec'
|
27
|
+
s.add_development_dependency 'pry'
|
28
|
+
s.add_development_dependency 'vcr'
|
29
|
+
s.add_development_dependency 'fakeweb'
|
30
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redbooth-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andres Bravo
|
@@ -116,6 +116,41 @@ executables: []
|
|
116
116
|
extensions: []
|
117
117
|
extra_rdoc_files: []
|
118
118
|
files:
|
119
|
+
- .gitignore
|
120
|
+
- .rspec
|
121
|
+
- .travis.yml
|
122
|
+
- Gemfile
|
123
|
+
- LICENSE
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- lib/redbooth-ruby.rb
|
127
|
+
- lib/redbooth-ruby/base.rb
|
128
|
+
- lib/redbooth-ruby/client.rb
|
129
|
+
- lib/redbooth-ruby/conversation.rb
|
130
|
+
- lib/redbooth-ruby/me.rb
|
131
|
+
- lib/redbooth-ruby/membership.rb
|
132
|
+
- lib/redbooth-ruby/operations/base.rb
|
133
|
+
- lib/redbooth-ruby/operations/create.rb
|
134
|
+
- lib/redbooth-ruby/operations/delete.rb
|
135
|
+
- lib/redbooth-ruby/operations/index.rb
|
136
|
+
- lib/redbooth-ruby/operations/meta.rb
|
137
|
+
- lib/redbooth-ruby/operations/show.rb
|
138
|
+
- lib/redbooth-ruby/operations/update.rb
|
139
|
+
- lib/redbooth-ruby/organization.rb
|
140
|
+
- lib/redbooth-ruby/person.rb
|
141
|
+
- lib/redbooth-ruby/project.rb
|
142
|
+
- lib/redbooth-ruby/request/base.rb
|
143
|
+
- lib/redbooth-ruby/request/collection.rb
|
144
|
+
- lib/redbooth-ruby/request/connection.rb
|
145
|
+
- lib/redbooth-ruby/request/helpers.rb
|
146
|
+
- lib/redbooth-ruby/request/info.rb
|
147
|
+
- lib/redbooth-ruby/request/response.rb
|
148
|
+
- lib/redbooth-ruby/request/validator.rb
|
149
|
+
- lib/redbooth-ruby/session.rb
|
150
|
+
- lib/redbooth-ruby/task.rb
|
151
|
+
- lib/redbooth-ruby/user.rb
|
152
|
+
- lib/redbooth-ruby/version.rb
|
153
|
+
- redbooth-ruby.gemspec
|
119
154
|
- spec/cassettes/RedboothRuby_Conversation/_create/.yml
|
120
155
|
- spec/cassettes/RedboothRuby_Conversation/_create/makes_a_new_POST_request_using_the_correct_API_endpoint_to_create_a_specific_conversation.yml
|
121
156
|
- spec/cassettes/RedboothRuby_Conversation/_delete/makes_a_new_DELETE_request_using_the_correct_API_endpoint_to_delete_a_specific_conversation.yml
|
@@ -262,7 +297,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
262
297
|
requirements:
|
263
298
|
- - '>='
|
264
299
|
- !ruby/object:Gem::Version
|
265
|
-
version:
|
300
|
+
version: 1.9.3
|
266
301
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
267
302
|
requirements:
|
268
303
|
- - '>='
|