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.
@@ -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