redbooth-ruby 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ module RedboothRuby
2
+ module Operations
3
+ module Base
4
+ module ClassMethods
5
+ # Options for request
6
+ # overwrite this in the model to set security
7
+ #
8
+ # @return [Hash]
9
+ def options_for_request(attributes)
10
+ fail AuthenticationError unless attributes[:session]
11
+ {
12
+ session: attributes[:session]
13
+ }
14
+ end
15
+
16
+ protected
17
+
18
+ # URl for the member endpoints
19
+ # overwrite this in the model if the api is not well named
20
+ #
21
+ def api_member_url(id = nil, method = nil)
22
+ url = api_resource_name(method)
23
+ url += "/#{id}" if id
24
+ url
25
+ end
26
+
27
+ # URl for the collection endpoints
28
+ # overwrite this in the model if the api is not well named
29
+ #
30
+ def api_collection_url(attrs = {})
31
+ api_resource_name
32
+ end
33
+
34
+ # resource name
35
+ # overwrite this in the model if the api is not well named
36
+ #
37
+ def api_resource_name(method = nil)
38
+ "#{name.split('::').last.downcase}s"
39
+ end
40
+ end
41
+
42
+ def self.included(base)
43
+ base.extend(ClassMethods)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+ module RedboothRuby
2
+ module Operations
3
+ module Create
4
+ module ClassMethods
5
+ # Creates a new object
6
+ #
7
+ # @param [Hash] attributes The attributes of the created object
8
+ def create(attributes)
9
+ session = attributes.delete(:session)
10
+ response = RedboothRuby.request(:post,
11
+ nil,
12
+ api_collection_url(attributes),
13
+ attributes,
14
+ options_for_request(session: session)
15
+ )
16
+ new(response.data)
17
+ end
18
+ end
19
+
20
+ def self.included(base)
21
+ base.extend(ClassMethods)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ module RedboothRuby
2
+ module Operations
3
+ module Delete
4
+ module ClassMethods
5
+ # Deletes the given object
6
+ #
7
+ # @param attributes [Hash] hash of given attributes passed to the delete method
8
+ # @return [Boolean]
9
+ def delete(attributes = {})
10
+ id = attributes.delete(:id)
11
+ response = RedboothRuby.request(:delete,
12
+ nil,
13
+ api_member_url(id, :delete),
14
+ {},
15
+ options_for_request(attributes)
16
+ )
17
+ true
18
+ end
19
+ end
20
+
21
+ def self.included(base)
22
+ base.extend(ClassMethods)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,49 @@
1
+ module RedboothRuby
2
+ module Operations
3
+ module Index
4
+ module ClassMethods
5
+ # Retrieves all available objects from the Copy API
6
+ #
7
+ # @param [Hash] options Options to pass to the API
8
+ # @return [Array] The available objects
9
+ def index(attributes = {})
10
+ session = attributes.delete(:session)
11
+ response = RedboothRuby.request(:get, nil, api_collection_url , attributes, options_for_request(session: session))
12
+ collection_from attributes, response, session
13
+ end
14
+
15
+ private
16
+
17
+ # Creates a collection object from the request and response params
18
+ #
19
+ # @param params [Hash] given request params
20
+ # @param response [RedboothRuby::Request::Response] response object
21
+ # @param session [RedboothRuby::Session] session Object
22
+ # @return [RedboothRuby::Request::Collection]
23
+ def collection_from(params, response, session)
24
+ RedboothRuby::Request::Collection.new(response: response,
25
+ resource: self,
26
+ session: session,
27
+ params: params,
28
+ method: :index)
29
+ end
30
+
31
+ # Returns the collection object build from the received response
32
+ #
33
+ # @param response [Array || Hash] parsed json response
34
+ # @return [RedboothRuby::Collection]
35
+ def results_from(response)
36
+ results = []
37
+ response.data.each do |obj|
38
+ results << self.new(obj)
39
+ end
40
+ results
41
+ end
42
+ end
43
+
44
+ def self.included(base)
45
+ base.extend(ClassMethods)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module RedboothRuby
2
+ module Operations
3
+ module Meta
4
+ # Returns a hash with the object metadata
5
+ #
6
+ # @return [Hash] the object metadata
7
+ def metadata
8
+ response = RedboothRuby.request(:get, nil, 'metadata',
9
+ { target_id: id, target_type: self.class.to_s },
10
+ options_for_request({}))
11
+ response.data
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module RedboothRuby
2
+ module Operations
3
+ module Show
4
+ module ClassMethods
5
+ # Shows a given object
6
+ #
7
+ # @param [Integer] id The id of the object that should be shown
8
+ # @return [Copy::Base] The found object
9
+ def show(attributes={})
10
+ response = RedboothRuby.request(:get,
11
+ nil,
12
+ api_member_url(attributes[:id], :show),
13
+ {},
14
+ options_for_request(attributes)
15
+ )
16
+ new(response.data)
17
+ end
18
+ end
19
+
20
+ def self.included(base)
21
+ base.extend(ClassMethods)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ module RedboothRuby
2
+ module Operations
3
+ module Update
4
+ module ClassMethods
5
+ # Updates a object
6
+ # @param [Integer] id The id of the object that should be updated
7
+ # @param [Hash] attributes The attributes that should be updated
8
+ def update(attributes = {})
9
+ id = attributes.delete(:id)
10
+ session = attributes.delete(:session)
11
+ response = RedboothRuby.request(:put,
12
+ nil,
13
+ api_member_url(id, :updated),
14
+ attributes,
15
+ options_for_request(session: session)
16
+ )
17
+ new(response.data)
18
+ end
19
+ end
20
+
21
+ def self.included(base)
22
+ base.extend(ClassMethods)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ module RedboothRuby
2
+ class Organization < 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
+ :permalink,
12
+ :domain,
13
+ :settings,
14
+ :omit_email_processing,
15
+ :product,
16
+ :product_name,
17
+ :feature_level,
18
+ :subscription_id,
19
+ :seats,
20
+ :remaining_users,
21
+ :available_users,
22
+ :used_users,
23
+ :remaining_projects,
24
+ :available_projects,
25
+ :used_projects,
26
+ :has_logo,
27
+ :square_logo_url,
28
+ :top_logo_url,
29
+ :is_pro,
30
+ :created_at,
31
+ :updated_at
32
+
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ module RedboothRuby
2
+ class Person < 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
+ :user_id,
11
+ :project_id,
12
+ :role,
13
+ :created_at,
14
+ :updated_at
15
+
16
+ # resource name
17
+ # overwrite this in the model if the api is not well named
18
+ #
19
+ def self.api_resource_name(method = nil)
20
+ 'people'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module RedboothRuby
2
+ class Project < 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
+ :permalink,
11
+ :organization_id,
12
+ :archived,
13
+ :name,
14
+ :description,
15
+ :start_date,
16
+ :end_date,
17
+ :tracks_time,
18
+ :public,
19
+ :publish_pages,
20
+ :settings,
21
+ :deleted,
22
+ :created_at,
23
+ :updated_at
24
+
25
+ end
26
+ end
@@ -0,0 +1,41 @@
1
+ module RedboothRuby
2
+ module Request
3
+ class Base
4
+ attr_reader :info
5
+ attr_accessor :response
6
+
7
+ def initialize(info)
8
+ @info = info
9
+ end
10
+
11
+ def perform
12
+ fail RedboothRuby::AuthenticationError unless valid?
13
+ connection.set_request_data
14
+ send_request
15
+
16
+ validator.validated_response_for(response)
17
+ end
18
+
19
+ def valid?
20
+ return false unless info
21
+ return false unless info.session
22
+ return false unless info.session.valid?
23
+ true
24
+ end
25
+
26
+ protected
27
+
28
+ def send_request
29
+ self.response = connection.request
30
+ end
31
+
32
+ def connection
33
+ @connection ||= Connection.new(info)
34
+ end
35
+
36
+ def validator
37
+ @validator ||= Validator.new(info)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,105 @@
1
+ module RedboothRuby
2
+ module Request
3
+ class Collection
4
+ attr_reader :response, :params, :method, :session, :resource
5
+
6
+ def initialize(attributes={})
7
+ @response = attributes[:response]
8
+ @params = attributes[:params]
9
+ @method = attributes[:method]
10
+ @resource = attributes[:resource]
11
+ @session = attributes[:session]
12
+ end
13
+
14
+ # Returns an array of resuce objects built from each one of the response items
15
+ #
16
+ # @return [Array(resource)]
17
+ def all
18
+ results = []
19
+ response.data.each do |obj|
20
+ results << resource.new(obj)
21
+ end
22
+ results
23
+ end
24
+
25
+ # Returns total pages
26
+ #
27
+ # @return [Integer]
28
+ def total_pages
29
+ return unless response.headers['PaginationTotalPages']
30
+ response.headers['PaginationTotalPages'].to_i
31
+ end
32
+
33
+ # Returns elements per page
34
+ #
35
+ # @return [Integer]
36
+ def per_page
37
+ return unless response.headers['PaginationPerPage']
38
+ response.headers['PaginationPerPage'].to_i
39
+ end
40
+
41
+ # Returns elements per page
42
+ #
43
+ # @return [Integer]
44
+ def current_page
45
+ return unless response.headers['PaginationCurrentPage']
46
+ response.headers['PaginationCurrentPage'].to_i
47
+ end
48
+
49
+ # Return total elements
50
+ #
51
+ # @return [Integer]
52
+ def count
53
+ return all.size unless paginated?
54
+ return all.size if total_pages.to_i <= 1
55
+ total_pages * per_page
56
+ end
57
+
58
+ # Performs the request for the next page if exists
59
+ #
60
+ # @return [Redbooth::Request::Collection]
61
+ def next_page
62
+ return nil unless paginated?
63
+ return nil unless (total_pages - current_page) > 0
64
+ request_with(page: current_page + 1)
65
+ end
66
+
67
+ # Performs the request for the next page if exists
68
+ #
69
+ # @return [Redbooth::Request::Collection]
70
+ def prev_page
71
+ return nil unless paginated?
72
+ return nil unless current_page > 1
73
+ request_with(page: current_page - 1)
74
+ end
75
+
76
+ protected
77
+
78
+ # Whenever the response is paginated or not
79
+ def paginated?
80
+ return false unless current_page
81
+ true
82
+ end
83
+
84
+ # Dups the current collection overwriting the given attributes
85
+ #
86
+ # @return [Redbooth::Request::Collection]
87
+ def dup_with(attributes={})
88
+ dup_params = { response: response,
89
+ params: params,
90
+ method: method,
91
+ resource: resource,
92
+ session: session }.merge(attributes)
93
+ self.class.new(dup_params)
94
+ end
95
+
96
+ # Repeats the request merged with the new params given
97
+ #
98
+ # @param new_params [Hash] params to overwrite or add in the new request
99
+ # @return [Redbooth::Request::Collection]
100
+ def request_with(new_params={})
101
+ resource.send(method, params.merge(new_params).merge(session: session))
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,140 @@
1
+ require 'net/http/post/multipart'
2
+
3
+ module RedboothRuby
4
+ module Request
5
+ class Connection
6
+ include Helpers
7
+ attr_reader :access_token, :request_data
8
+
9
+ def initialize(request_info)
10
+ @info = request_info
11
+ @session = @info.session if @info
12
+ @access_token = @info.session.access_token if @session
13
+ end
14
+
15
+ def request
16
+ return unless access_token
17
+ if use_body_file?
18
+ ::File.open(body_file_attrs[:local_path]) do |file|
19
+ req = Net::HTTP::Post::Multipart.new(
20
+ api_url,
21
+ 'file' => UploadIO.new(file,
22
+ 'application/octet-stream',
23
+ body_file_attrs[:name]
24
+ )
25
+ )
26
+ access_token.sign! req
27
+ if RedboothRuby.configuration[:use_ssl]
28
+ http = Net::HTTP.new('redbooth.com' , Net::HTTP.https_default_port)
29
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
30
+ http.use_ssl = RedboothRuby.configuration[:use_ssl]
31
+ end
32
+ http.start do |inner_http|
33
+ inner_http.request(req)
34
+ end
35
+ end
36
+ else
37
+ access_token.send(*request_data)
38
+ end
39
+ end
40
+
41
+ def set_request_data
42
+ @request_data = []
43
+ @request_data << @info.http_method if @info
44
+ @request_data << api_url
45
+ unless use_url_params?
46
+ @request_data << { body: body_hash }
47
+ end
48
+ end
49
+
50
+ protected
51
+
52
+ # Body params hash
53
+ #
54
+ # @return [Hash]
55
+ def body_hash
56
+ return {} unless @info
57
+ @info.data
58
+ end
59
+
60
+ # Json encoded body
61
+ #
62
+ # @return [String]
63
+ def body_json
64
+ return '' unless body_hash
65
+ JSON.generate(body_hash)
66
+ end
67
+
68
+ def body_file_attrs
69
+ body_hash[:file_attrs] || {}
70
+ end
71
+
72
+ # Body params url encoded
73
+ #
74
+ # @return [String]
75
+ def encoded_www_body
76
+ return '' unless body_hash
77
+ URI.encode_www_form(body_hash)
78
+ end
79
+
80
+ def use_body_file?
81
+ return false if use_url_params?
82
+ body_hash.key?(:file)
83
+ end
84
+
85
+ def use_url_params?
86
+ return false unless @info
87
+ case @info.http_method
88
+ when :post, :put
89
+ false
90
+ else
91
+ true
92
+ end
93
+ end
94
+
95
+ # Returns the api url foir this request or default
96
+ def api_url
97
+ url = "#{api_url_method}#{api_url_domain}"
98
+ url += "#{RedboothRuby.configuration[:api_base]}"
99
+ url += "#{api_url_path}"
100
+ url += "#{api_url_version}"
101
+ if @info
102
+ url += @info.url
103
+ if use_url_params? && !body_hash.empty?
104
+ url += '?' + encoded_www_body
105
+ end
106
+ end
107
+ url
108
+ end
109
+
110
+ def api_url_method
111
+ if RedboothRuby.configuration[:use_ssl]
112
+ 'https://'
113
+ else
114
+ 'http://'
115
+ end
116
+ end
117
+
118
+ def api_url_domain
119
+ return '' unless domain
120
+ "#{domain}."
121
+ end
122
+
123
+ def api_url_path
124
+ return '' unless RedboothRuby.configuration[:api_base_path]
125
+ "/#{RedboothRuby.configuration[:api_base_path]}"
126
+ end
127
+
128
+ def api_url_version
129
+ return '' unless RedboothRuby.configuration[:api_version]
130
+ "/#{RedboothRuby.configuration[:api_version]}"
131
+ end
132
+
133
+ # Returns the domain for the current request or the default one
134
+ def domain
135
+ return @info.subdomain if @info
136
+ RedboothRuby.configuration[:domain_base]
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,36 @@
1
+ module RedboothRuby
2
+ module Request
3
+ module Helpers
4
+ def flatten_hash_keys(old_hash, new_hash = {}, keys = nil)
5
+ old_hash.each do |key, value|
6
+ key = key.to_s
7
+ if value.is_a?(Hash)
8
+ all_keys_formatted = keys + "[#{key}]"
9
+ flatten_hash_keys(value, new_hash, all_keys_formatted)
10
+ else
11
+ new_hash[key] = value
12
+ end
13
+ end
14
+ new_hash
15
+ end
16
+
17
+ def normalize_params(params, key = nil)
18
+ params = flatten_hash_keys(params) if params.is_a?(Hash)
19
+ result = {}
20
+ params.each do |name, value|
21
+ case value
22
+ when Hash
23
+ result[name.to_s] = normalize_params(value)
24
+ when Array
25
+ value.each_with_index do |item_value, index|
26
+ result["#{name.to_s}[#{index}]"] = item_value.to_s
27
+ end
28
+ else
29
+ result[name.to_s] = value.to_s
30
+ end
31
+ end
32
+ result
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ module RedboothRuby
2
+ module Request
3
+ class Info
4
+ attr_accessor :http_method, :api_url, :data, :subdomain, :session, :base_path
5
+
6
+ def initialize(http_method, subdomain, api_url, data, options = {})
7
+ @http_method = http_method
8
+ @subdomain = subdomain || DOMAIN_BASE
9
+ @api_url = api_url
10
+ @data = data
11
+ @base_path = RedboothRuby.configuration[:api_base_path]
12
+ @session = options[:session]
13
+ end
14
+
15
+ def url
16
+ url = "/#{api_url}"
17
+ if has_id?
18
+ url += "/#{data[:id]}"
19
+ data.delete(:id)
20
+ end
21
+
22
+ url
23
+ end
24
+
25
+ def path_with_params(path, params)
26
+ unless params.empty?
27
+ encoded_params = URI.encode_www_form(params)
28
+ [path, encoded_params].join("?")
29
+ else
30
+ path
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ def has_id?
37
+ !data[:id].nil?
38
+ end
39
+ end
40
+ end
41
+ end