supersaas-api-client 1.1.0 → 2.0.0
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/.github/workflows/actions.yaml +21 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +296 -0
- data/Gemfile +5 -3
- data/Gemfile.lock +34 -7
- data/README.md +109 -58
- data/Rakefile +8 -6
- data/bin/console +4 -3
- data/examples/appointments.rb +70 -42
- data/examples/forms.rb +20 -22
- data/examples/groups.rb +20 -0
- data/examples/promotions.rb +32 -0
- data/examples/schedules.rb +23 -11
- data/examples/users.rb +31 -23
- data/lib/supersaas-api-client/api/appointments.rb +37 -25
- data/lib/supersaas-api-client/api/base_api.rb +69 -23
- data/lib/supersaas-api-client/api/forms.rb +16 -9
- data/lib/supersaas-api-client/api/groups.rb +12 -0
- data/lib/supersaas-api-client/api/promotions.rb +29 -0
- data/lib/supersaas-api-client/api/schedules.rb +14 -4
- data/lib/supersaas-api-client/api/users.rb +28 -15
- data/lib/supersaas-api-client/client.rb +106 -36
- data/lib/supersaas-api-client/exception.rb +3 -1
- data/lib/supersaas-api-client/models/appointment.rb +9 -12
- data/lib/supersaas-api-client/models/base_model.rb +4 -1
- data/lib/supersaas-api-client/models/field_list.rb +12 -0
- data/lib/supersaas-api-client/models/form.rb +5 -2
- data/lib/supersaas-api-client/models/group.rb +7 -0
- data/lib/supersaas-api-client/models/promotion.rb +7 -0
- data/lib/supersaas-api-client/models/resource.rb +3 -1
- data/lib/supersaas-api-client/models/schedule.rb +3 -1
- data/lib/supersaas-api-client/models/slot.rb +4 -6
- data/lib/supersaas-api-client/models/super_form.rb +7 -0
- data/lib/supersaas-api-client/models/user.rb +5 -8
- data/lib/supersaas-api-client/version.rb +4 -2
- data/lib/supersaas-api-client.rb +3 -1
- data/lib/supersaas.rb +23 -15
- data/supersaas-api-client.gemspec +19 -18
- metadata +52 -38
- data/test/appointments_test.rb +0 -99
- data/test/client_test.rb +0 -46
- data/test/forms_test.rb +0 -22
- data/test/schedules_test.rb +0 -19
- data/test/test_helper.rb +0 -23
- data/test/users_test.rb +0 -68
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'net/http'
|
2
4
|
require 'uri'
|
3
5
|
require 'json'
|
@@ -24,8 +26,8 @@ module Supersaas
|
|
24
26
|
attr_accessor :account_name, :api_key, :host, :dry_run, :verbose
|
25
27
|
attr_reader :last_request
|
26
28
|
|
27
|
-
def initialize(configuration=nil)
|
28
|
-
configuration
|
29
|
+
def initialize(configuration = nil)
|
30
|
+
configuration ||= Configuration.new
|
29
31
|
@account_name = configuration.account_name
|
30
32
|
@api_key = configuration.api_key
|
31
33
|
@host = configuration.host
|
@@ -33,32 +35,70 @@ module Supersaas
|
|
33
35
|
@verbose = configuration.verbose
|
34
36
|
end
|
35
37
|
|
36
|
-
def appointments
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
def appointments
|
39
|
+
@appointments ||= Appointments.new(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
def forms
|
43
|
+
@forms ||= Forms.new(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
def schedules
|
47
|
+
@schedules ||= Schedules.new(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
def users
|
51
|
+
@users ||= Users.new(self)
|
52
|
+
end
|
40
53
|
|
41
|
-
def
|
54
|
+
def promotions
|
55
|
+
@promotions ||= Promotions.new(self)
|
56
|
+
end
|
57
|
+
|
58
|
+
def groups
|
59
|
+
@groups ||= Groups.new(self)
|
60
|
+
end
|
61
|
+
|
62
|
+
def get(path, query = {})
|
42
63
|
request(:get, path, {}, query)
|
43
64
|
end
|
44
65
|
|
45
|
-
def post(path, params={}, query={})
|
66
|
+
def post(path, params = {}, query = {})
|
46
67
|
request(:post, path, params, query)
|
47
68
|
end
|
48
69
|
|
49
|
-
def put(path, params={}, query={})
|
70
|
+
def put(path, params = {}, query = {})
|
50
71
|
request(:put, path, params, query)
|
51
72
|
end
|
52
73
|
|
53
|
-
def delete(path, params={}, query={})
|
74
|
+
def delete(path, params = {}, query = {})
|
54
75
|
request(:delete, path, params, query)
|
55
76
|
end
|
56
77
|
|
57
78
|
private
|
58
79
|
|
59
|
-
|
60
|
-
|
61
|
-
|
80
|
+
# The rate limiter allows a maximum of 4 requests within the specified time window
|
81
|
+
WINDOW_SIZE = 1 # seconds
|
82
|
+
MAX_PER_WINDOW = 4
|
83
|
+
def throttle
|
84
|
+
# A queue to store timestamps of requests made within the rate limiting window
|
85
|
+
@queue ||= Array.new(MAX_PER_WINDOW)
|
86
|
+
# Represents the timestamp of the oldest request within the time window
|
87
|
+
oldest_request = @queue.push(Time.now).shift
|
88
|
+
# This ensures that the client does not make requests faster than the defined rate limit
|
89
|
+
if oldest_request && (d = Time.now - oldest_request) < WINDOW_SIZE
|
90
|
+
sleep WINDOW_SIZE - d
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def request(http_method, path, params = {}, query = {})
|
95
|
+
throttle
|
96
|
+
unless account_name&.size
|
97
|
+
raise Supersaas::Exception, 'Account name not configured. Call `Supersaas::Client.configure`.'
|
98
|
+
end
|
99
|
+
unless api_key&.size
|
100
|
+
raise Supersaas::Exception, 'Account api key not configured. Call `Supersaas::Client.configure`.'
|
101
|
+
end
|
62
102
|
|
63
103
|
uri = URI.parse(host)
|
64
104
|
http = Net::HTTP.new(uri.host, uri.port)
|
@@ -68,7 +108,7 @@ module Supersaas
|
|
68
108
|
query = delete_blank_values query
|
69
109
|
|
70
110
|
path = "/api#{path}.json"
|
71
|
-
path += "?#{URI.encode_www_form(query)}" if query.keys.size
|
111
|
+
path += "?#{URI.encode_www_form(query)}" if query.keys.size.positive?
|
72
112
|
|
73
113
|
case http_method
|
74
114
|
when :get
|
@@ -83,7 +123,8 @@ module Supersaas
|
|
83
123
|
req = Net::HTTP::Delete.new(path)
|
84
124
|
req.body = params.to_json
|
85
125
|
else
|
86
|
-
raise Supersaas::Exception
|
126
|
+
raise Supersaas::Exception,
|
127
|
+
"Invalid HTTP Method: #{http_method}. Only `:get`, `:post`, `:put`, `:delete` supported."
|
87
128
|
end
|
88
129
|
|
89
130
|
req.basic_auth account_name, api_key
|
@@ -93,10 +134,10 @@ module Supersaas
|
|
93
134
|
req['User-Agent'] = self.class.user_agent
|
94
135
|
|
95
136
|
if verbose
|
96
|
-
puts
|
137
|
+
puts '### SuperSaaS Client Request:'
|
97
138
|
puts "#{http_method} #{path}"
|
98
139
|
puts params.to_json
|
99
|
-
puts
|
140
|
+
puts '------------------------------'
|
100
141
|
end
|
101
142
|
|
102
143
|
@last_request = req
|
@@ -106,42 +147,71 @@ module Supersaas
|
|
106
147
|
res = http.request(req)
|
107
148
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
108
149
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
109
|
-
raise Supersaas::Exception
|
150
|
+
raise Supersaas::Exception, "HTTP Request Error (#{uri}#{path}): #{e.message}"
|
110
151
|
end
|
111
152
|
|
112
153
|
if verbose
|
113
|
-
puts
|
154
|
+
puts 'Response:'
|
155
|
+
puts res.inspect
|
114
156
|
puts res.body
|
115
|
-
puts
|
157
|
+
puts '=============================='
|
116
158
|
end
|
117
159
|
|
118
160
|
code = res.code.to_i
|
119
161
|
case code
|
120
162
|
when 200, 201
|
121
|
-
|
122
|
-
|
123
|
-
|
163
|
+
if http_method == :post && res['location'] =~ /www.supersaas.com/
|
164
|
+
res['location']
|
165
|
+
else
|
166
|
+
json_body(res)
|
167
|
+
end
|
168
|
+
else
|
169
|
+
handle_errors(code, res)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def handle_errors(code, res)
|
174
|
+
print_errors(res)
|
175
|
+
case code
|
176
|
+
when 422
|
177
|
+
raise Supersaas::Exception, 'HTTP Request Error: Unprocessable Content'
|
178
|
+
when 400
|
179
|
+
raise Supersaas::Exception, 'HTTP Request Error: Bad Request'
|
124
180
|
when 401
|
125
|
-
raise Supersaas::Exception
|
181
|
+
raise Supersaas::Exception, 'HTTP Request Error: Unauthorised'
|
126
182
|
when 404
|
127
|
-
raise Supersaas::Exception
|
183
|
+
raise Supersaas::Exception, 'HTTP Request Error: Not Found'
|
184
|
+
when 501
|
185
|
+
raise Supersaas::Exception, 'Not yet implemented for service type schedule'
|
186
|
+
when 403
|
187
|
+
raise Supersaas::Exception, 'Unauthorized'
|
188
|
+
when 405
|
189
|
+
raise Supersaas::Exception, 'Not available for capacity type schedule'
|
128
190
|
else
|
129
|
-
{}
|
191
|
+
raise Supersaas::Exception, "HTTP Request Error: #{code}"
|
130
192
|
end
|
131
193
|
end
|
132
194
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
195
|
+
def print_errors(res)
|
196
|
+
json_body = json_body(res)
|
197
|
+
return unless json_body[:errors]
|
198
|
+
|
199
|
+
errors each do |error|
|
200
|
+
puts "Error code: #{error['code']}, #{error['title']}"
|
138
201
|
end
|
139
202
|
end
|
140
203
|
|
204
|
+
def json_body(res)
|
205
|
+
res.body&.size ? JSON.parse(res.body) : {}
|
206
|
+
rescue JSON::ParserError
|
207
|
+
{}
|
208
|
+
end
|
209
|
+
|
141
210
|
def delete_blank_values(hash)
|
142
211
|
return hash unless hash
|
143
|
-
|
144
|
-
|
212
|
+
|
213
|
+
hash.delete_if do |_k, v|
|
214
|
+
v = v.compact if v.is_a?(Hash)
|
145
215
|
v.nil? || v == ''
|
146
216
|
end
|
147
217
|
end
|
@@ -152,12 +222,12 @@ module Supersaas
|
|
152
222
|
attr_accessor :account_name, :host, :api_key, :dry_run, :verbose
|
153
223
|
|
154
224
|
def initialize
|
155
|
-
@account_name = ENV
|
156
|
-
@api_key = ENV
|
225
|
+
@account_name = ENV.fetch('SSS_API_ACCOUNT_NAME', nil)
|
226
|
+
@api_key = ENV.fetch('SSS_API_KEY', nil)
|
157
227
|
@host = DEFAULT_HOST
|
158
228
|
@dry_run = false
|
159
229
|
@verbose = false
|
160
230
|
end
|
161
231
|
end
|
162
232
|
end
|
163
|
-
end
|
233
|
+
end
|
@@ -1,22 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Supersaas
|
2
4
|
class Appointment < BaseModel
|
3
|
-
attr_accessor :address, :country, :created_by, :created_on, :deleted, :description, :email, :field_1, :field_2,
|
5
|
+
attr_accessor :address, :country, :created_by, :created_on, :deleted, :description, :email, :field_1, :field_2,
|
6
|
+
:field_1_r, :field_2_r, :finish, :form_id, :full_name, :id, :mobile, :name, :phone, :price, :res_name,
|
7
|
+
:resource_id, :schedule_id, :schedule_name, :service_id, :service_name, :slot_id, :start, :status,
|
8
|
+
:super_field, :updated_by, :updated_on, :user_id, :waitlisted
|
4
9
|
attr_reader :form, :slot
|
5
10
|
|
6
11
|
def form=(value)
|
7
|
-
|
8
|
-
@form = Supersaas::Form.new(value)
|
9
|
-
else
|
10
|
-
@form = value
|
11
|
-
end
|
12
|
+
@form = value.is_a?(Hash) ? Supersaas::Form.new(value) : value
|
12
13
|
end
|
13
14
|
|
14
15
|
def slot=(value)
|
15
|
-
|
16
|
-
@slot = Supersaas::Slot.new(value)
|
17
|
-
else
|
18
|
-
@slot = value
|
19
|
-
end
|
16
|
+
@slot = value.is_a?(Hash) ? Supersaas::Slot.new(value) : value
|
20
17
|
end
|
21
18
|
end
|
22
|
-
end
|
19
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Supersaas
|
2
4
|
class BaseModel
|
3
5
|
attr_accessor :errors
|
@@ -12,8 +14,9 @@ module Supersaas
|
|
12
14
|
|
13
15
|
def assign_attributes(attributes)
|
14
16
|
attributes.each do |key, value|
|
17
|
+
self.class.module_eval { attr_accessor key }
|
15
18
|
public_send("#{key}=", value) if respond_to?("#{key}=")
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
19
|
-
end
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Supersaas
|
4
|
+
class FieldList < BaseModel
|
5
|
+
attr_accessor :name, :type, :label, :advanced
|
6
|
+
attr_reader :spec
|
7
|
+
|
8
|
+
def spec=(value)
|
9
|
+
@spec = value.is_a?(Array) ? value.map { |attributes| JSON.parse(attributes) } : value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Supersaas
|
2
4
|
class Form < BaseModel
|
3
|
-
attr_accessor :content, :created_on, :deleted, :id, :reservation_process_id, :super_form_id, :uniq, :updated_name,
|
5
|
+
attr_accessor :content, :created_on, :deleted, :id, :reservation_process_id, :super_form_id, :uniq, :updated_name,
|
6
|
+
:updated_on, :user_id
|
4
7
|
end
|
5
|
-
end
|
8
|
+
end
|
@@ -1,14 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Supersaas
|
2
4
|
class Slot < BaseModel
|
3
5
|
attr_accessor :count, :description, :finish, :id, :location, :name, :start, :title
|
4
6
|
attr_reader :bookings
|
5
7
|
|
6
8
|
def bookings=(value)
|
7
|
-
|
8
|
-
@bookings = value.map {|attributes| Supersaas::Appointment.new(attributes) }
|
9
|
-
else
|
10
|
-
@bookings = value
|
11
|
-
end
|
9
|
+
@bookings = value.is_a?(Array) ? value.map { |attributes| Supersaas::Appointment.new(attributes) } : value
|
12
10
|
end
|
13
11
|
end
|
14
|
-
end
|
12
|
+
end
|
@@ -1,16 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Supersaas
|
2
4
|
class User < BaseModel
|
3
|
-
ROLES = [3, 4, -1]
|
5
|
+
ROLES = [3, 4, -1].freeze
|
4
6
|
|
5
|
-
attr_accessor :address, :country, :created_on, :credit, :email, :field_1, :field_2, :fk, :full_name, :id, :mobile, :name, :phone, :role, :super_field
|
6
7
|
attr_reader :form
|
7
8
|
|
8
9
|
def form=(value)
|
9
|
-
|
10
|
-
@form = Supersaas::Form.new(value)
|
11
|
-
else
|
12
|
-
@form = value
|
13
|
-
end
|
10
|
+
@form = value.is_a?(Hash) ? Supersaas::Form.new(value) : value
|
14
11
|
end
|
15
12
|
end
|
16
|
-
end
|
13
|
+
end
|
data/lib/supersaas-api-client.rb
CHANGED
data/lib/supersaas.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'supersaas-api-client/version'
|
4
|
+
require 'supersaas-api-client/exception'
|
5
|
+
require 'supersaas-api-client/models/base_model'
|
6
|
+
require 'supersaas-api-client/models/appointment'
|
7
|
+
require 'supersaas-api-client/models/field_list'
|
8
|
+
require 'supersaas-api-client/models/form'
|
9
|
+
require 'supersaas-api-client/models/super_form'
|
10
|
+
require 'supersaas-api-client/models/group'
|
11
|
+
require 'supersaas-api-client/models/resource'
|
12
|
+
require 'supersaas-api-client/models/schedule'
|
13
|
+
require 'supersaas-api-client/models/promotion'
|
14
|
+
require 'supersaas-api-client/models/slot'
|
15
|
+
require 'supersaas-api-client/models/user'
|
16
|
+
require 'supersaas-api-client/api/base_api'
|
17
|
+
require 'supersaas-api-client/api/appointments'
|
18
|
+
require 'supersaas-api-client/api/forms'
|
19
|
+
require 'supersaas-api-client/api/schedules'
|
20
|
+
require 'supersaas-api-client/api/groups'
|
21
|
+
require 'supersaas-api-client/api/promotions'
|
22
|
+
require 'supersaas-api-client/api/users'
|
23
|
+
require 'supersaas-api-client/client'
|
@@ -1,27 +1,28 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
+
|
5
|
+
require 'supersaas-api-client/version'
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
8
|
+
spec.name = 'supersaas-api-client'
|
7
9
|
spec.version = Supersaas::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
10
|
+
spec.authors = ['Kaarle Kulvik']
|
11
|
+
spec.email = ['kaarle@supersaas.com']
|
10
12
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
13
|
+
spec.summary = 'Manage appointments and users on the SuperSaaS scheduling platform'
|
14
|
+
spec.description = 'Online appointment scheduling for any type of business. Flexible and affordable booking software that can be integrated into any site. Free basic version.'
|
15
|
+
spec.homepage = 'https://www.supersaas.com'
|
16
|
+
spec.license = 'MIT'
|
15
17
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0").reject
|
17
|
-
|
18
|
-
end
|
19
|
-
spec.test_files = Dir['test/**/*']
|
20
|
-
spec.bindir = "bin"
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^test/}) }
|
19
|
+
spec.bindir = 'bin'
|
21
20
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ['lib']
|
23
22
|
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'minitest'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rubocop'
|
27
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
27
28
|
end
|