cobot_client 5.0.0 → 6.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/ruby.yml +23 -0
- data/.github/workflows/test.yml +26 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +31 -0
- data/CHANGELOG.md +9 -1
- data/Gemfile +10 -0
- data/Rakefile +6 -2
- data/cobot_client.gemspec +6 -6
- data/lib/cobot_client/api_client.rb +30 -77
- data/lib/cobot_client/engine.rb +2 -0
- data/lib/cobot_client/errors.rb +47 -0
- data/lib/cobot_client/navigation_link.rb +11 -8
- data/lib/cobot_client/navigation_link_service.rb +11 -6
- data/lib/cobot_client/request.rb +89 -0
- data/lib/cobot_client/response.rb +45 -0
- data/lib/cobot_client/url_helper.rb +23 -20
- data/lib/cobot_client/version.rb +3 -1
- data/lib/cobot_client.rb +11 -1
- data/rbs_collection.yaml +20 -0
- data/sig/cobot_client/api_client.rbs +51 -0
- data/sig/cobot_client/errors.rbs +23 -0
- data/sig/cobot_client/navigation_link.rbs +11 -0
- data/sig/cobot_client/navigation_link_service.rbs +17 -0
- data/sig/cobot_client/request.rbs +39 -0
- data/sig/cobot_client/response.rbs +23 -0
- data/sig/cobot_client/url_helper.rbs +25 -0
- data/sig/cobot_client/version.rbs +3 -0
- data/sig/manifests.yaml +4 -0
- data/spec/cobot_client/api_client_spec.rb +186 -111
- data/spec/cobot_client/navigation_link_service_spec.rb +48 -23
- data/spec/cobot_client/url_helper_spec.rb +8 -6
- data/spec/spec_helper.rb +10 -0
- metadata +33 -64
- data/.travis.yml +0 -4
- data/lib/cobot_client/exceptions.rb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3d961f35435c958c2cf33b88170ce9f5c327f3ee57c332eb534b6b60098a86f1
|
|
4
|
+
data.tar.gz: 33c485cd858e729d508bd331897872f8d24345b75d1e4f192089e7bcfafc2793
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 101809ca57f22278713eeedd3f3f3f32c21552b2ed6e15189cb866f1d37d2d104c493acda5348e90dd187d3906e89c1290e35ec549f219caabd86d0adf2a9a5b
|
|
7
|
+
data.tar.gz: 27a001426e07ab13b48724219ae62b58e72a706b9547f4863b97f282c72568dff88657fbd0e380d3c2863e477524291cd8d851cb809c04428166e82199b526bd
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Push gem
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
jobs:
|
|
8
|
+
release:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: write
|
|
12
|
+
id-token: write
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v5
|
|
15
|
+
with:
|
|
16
|
+
persist-credentials: false
|
|
17
|
+
- name: Set up Ruby
|
|
18
|
+
uses: ruby/setup-ruby@v1
|
|
19
|
+
with:
|
|
20
|
+
bundler-cache: true
|
|
21
|
+
ruby-version: ruby
|
|
22
|
+
- name: Release gem
|
|
23
|
+
uses: rubygems/release-gem@v1
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Ruby CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
pull_request:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
ruby: ["4.0", "3.4", "3.3"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v5
|
|
18
|
+
- name: Set up Ruby
|
|
19
|
+
uses: ruby/setup-ruby@v1
|
|
20
|
+
with:
|
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
|
22
|
+
bundler-cache: true
|
|
23
|
+
- name: Install RBS type declaration collection
|
|
24
|
+
run: bundle exec rbs collection install
|
|
25
|
+
- name: Run tests
|
|
26
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-rake
|
|
3
|
+
- rubocop-rspec
|
|
4
|
+
|
|
5
|
+
AllCops:
|
|
6
|
+
NewCops: enable
|
|
7
|
+
TargetRubyVersion: 3.3
|
|
8
|
+
|
|
9
|
+
Layout/SpaceInsideHashLiteralBraces:
|
|
10
|
+
EnforcedStyle: no_space
|
|
11
|
+
|
|
12
|
+
RSpec/AnyInstance:
|
|
13
|
+
Enabled: false
|
|
14
|
+
|
|
15
|
+
RSpec/ExampleLength:
|
|
16
|
+
Enabled: false
|
|
17
|
+
|
|
18
|
+
RSpec/MessageSpies:
|
|
19
|
+
Enabled: false
|
|
20
|
+
|
|
21
|
+
RSpec/MultipleExpectations:
|
|
22
|
+
Enabled: false
|
|
23
|
+
|
|
24
|
+
RSpec/StubbedMock:
|
|
25
|
+
Enabled: false
|
|
26
|
+
|
|
27
|
+
RSpec/VerifiedDoubles:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
Style/Documentation:
|
|
31
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# 6.0.0
|
|
2
|
+
|
|
3
|
+
- Drop support for EOL Rubies (< 3.3)
|
|
4
|
+
- Add support for Ruby v4
|
|
5
|
+
- Add RBS type declarations
|
|
6
|
+
- Replace discontinued `Virtus` with `ActiveModel::Attributes`
|
|
7
|
+
- Replace abandoned `rest-client` with `net/http`
|
|
8
|
+
|
|
1
9
|
# 5.0.0
|
|
2
10
|
|
|
3
11
|
Bump oauth2 dependency to ~>2.0.
|
|
@@ -8,7 +16,7 @@ Bump oauth2 dependency to ~>2.0.
|
|
|
8
16
|
|
|
9
17
|
# 3.1.0
|
|
10
18
|
|
|
11
|
-
- adds
|
|
19
|
+
- adds user_editable attribute to navigation links
|
|
12
20
|
|
|
13
21
|
# 3.0.0
|
|
14
22
|
|
data/Gemfile
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
source 'https://rubygems.org'
|
|
2
4
|
|
|
3
5
|
# Specify your gem's dependencies in cobot_client.gemspec
|
|
4
6
|
gemspec
|
|
7
|
+
|
|
8
|
+
gem 'rake', '~> 13.4'
|
|
9
|
+
gem 'rbs'
|
|
10
|
+
gem 'rspec', '~> 3.0'
|
|
11
|
+
gem 'rubocop'
|
|
12
|
+
gem 'rubocop-rake'
|
|
13
|
+
gem 'rubocop-rspec'
|
|
14
|
+
gem 'webmock', require: false
|
data/Rakefile
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
|
-
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/gem_tasks'
|
|
3
5
|
require 'rspec/core/rake_task'
|
|
6
|
+
require 'rubocop/rake_task'
|
|
4
7
|
|
|
5
8
|
RSpec::Core::RakeTask.new(:spec)
|
|
9
|
+
RuboCop::RakeTask.new(:rubocop)
|
|
6
10
|
|
|
7
|
-
task default:
|
|
11
|
+
task default: %i[spec rubocop]
|
data/cobot_client.gemspec
CHANGED
|
@@ -12,15 +12,15 @@ Gem::Specification.new do |gem|
|
|
|
12
12
|
|
|
13
13
|
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
|
14
14
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
15
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
16
15
|
gem.name = 'cobot_client'
|
|
17
16
|
gem.require_paths = ['lib']
|
|
18
17
|
gem.version = CobotClient::VERSION
|
|
19
18
|
|
|
20
|
-
gem.
|
|
21
|
-
|
|
22
|
-
gem.add_dependency '
|
|
19
|
+
gem.required_ruby_version = ['>=3.3', '<5']
|
|
20
|
+
|
|
21
|
+
gem.add_dependency 'activemodel', '>=5.2'
|
|
23
22
|
gem.add_dependency 'json', '~>2.0'
|
|
24
|
-
gem.
|
|
25
|
-
|
|
23
|
+
gem.add_dependency 'oauth2', '~>2.0'
|
|
24
|
+
|
|
25
|
+
gem.metadata['rubygems_mfa_required'] = 'true'
|
|
26
26
|
end
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'rest_client'
|
|
4
|
-
require 'json'
|
|
5
|
-
|
|
6
3
|
module CobotClient
|
|
7
4
|
class ApiClient
|
|
8
5
|
include UrlHelper
|
|
@@ -10,6 +7,7 @@ module CobotClient
|
|
|
10
7
|
class << self
|
|
11
8
|
attr_accessor :user_agent, :retry_time
|
|
12
9
|
end
|
|
10
|
+
|
|
13
11
|
self.retry_time = 1
|
|
14
12
|
|
|
15
13
|
def initialize(access_token)
|
|
@@ -17,106 +15,61 @@ module CobotClient
|
|
|
17
15
|
end
|
|
18
16
|
|
|
19
17
|
# args: either a full URL or subdomain, path, plus a body as hash
|
|
20
|
-
def post(*
|
|
21
|
-
request
|
|
18
|
+
def post(*)
|
|
19
|
+
request(:post, *).parsed_body
|
|
22
20
|
end
|
|
23
21
|
|
|
24
22
|
# args: either a full URL or subdomain, path, plus a body as hash
|
|
25
|
-
def put(*
|
|
26
|
-
request
|
|
23
|
+
def put(*)
|
|
24
|
+
request(:put, *).parsed_body
|
|
27
25
|
end
|
|
28
26
|
|
|
29
|
-
def patch(*
|
|
30
|
-
request
|
|
27
|
+
def patch(*)
|
|
28
|
+
request(:patch, *).parsed_body
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
# args: either a full URL or subdomain, path, plus an optional params hash
|
|
34
|
-
def get(*
|
|
35
|
-
|
|
36
|
-
JSON.parse(
|
|
37
|
-
rewrap_errors do
|
|
38
|
-
RestClient.get(
|
|
39
|
-
build_url(url || subdomain, path, params),
|
|
40
|
-
headers
|
|
41
|
-
).body
|
|
42
|
-
end, symbolize_names: true
|
|
43
|
-
)
|
|
32
|
+
def get(*)
|
|
33
|
+
request(:get, *).parsed_body
|
|
44
34
|
end
|
|
45
35
|
|
|
46
36
|
# args: either a full URL or subdomain, path
|
|
47
|
-
def delete(*
|
|
48
|
-
|
|
49
|
-
rewrap_errors do
|
|
50
|
-
RestClient.delete(build_url(url || subdomain, path), headers)
|
|
51
|
-
end
|
|
37
|
+
def delete(*)
|
|
38
|
+
request(:delete, *)
|
|
52
39
|
end
|
|
53
40
|
|
|
54
41
|
private
|
|
55
42
|
|
|
56
|
-
def request(method, *
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
headers.merge(content_type_header))
|
|
63
|
-
JSON.parse response.body, symbolize_names: true unless response.code == 204
|
|
43
|
+
def request(method, *)
|
|
44
|
+
request = Request.new(method, *)
|
|
45
|
+
request.headers = headers
|
|
46
|
+
|
|
47
|
+
retry_errors do
|
|
48
|
+
request.submit
|
|
64
49
|
end
|
|
65
50
|
end
|
|
66
51
|
|
|
67
|
-
def rewrap_errors
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
def rewrap_errors
|
|
53
|
+
yield.tap do |response|
|
|
54
|
+
raise response.to_error if response.client_error? || response.server_error?
|
|
55
|
+
end
|
|
56
|
+
rescue Net::ProtocolError, SocketError, Timeout::Error => e
|
|
57
|
+
raise ConnectionError, "#{e.class}: #{e.message}"
|
|
71
58
|
end
|
|
72
59
|
|
|
73
|
-
def retry_errors
|
|
60
|
+
def retry_errors(&)
|
|
74
61
|
retries = 0
|
|
75
62
|
begin
|
|
76
|
-
|
|
77
|
-
rescue
|
|
78
|
-
|
|
79
|
-
sleep self.class.retry_time
|
|
80
|
-
retries += 1
|
|
81
|
-
retry
|
|
82
|
-
else
|
|
83
|
-
raise e
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def parse_args(*args)
|
|
89
|
-
params = if args.size == 3 || (args.size == 2 && args[0].match(%r{https?://}))
|
|
90
|
-
args.pop
|
|
91
|
-
else
|
|
92
|
-
{}
|
|
93
|
-
end
|
|
94
|
-
if args.size == 1
|
|
95
|
-
url = args[0]
|
|
96
|
-
path = nil
|
|
97
|
-
subdomain = nil
|
|
98
|
-
else
|
|
99
|
-
subdomain = args[0]
|
|
100
|
-
path = args[1]
|
|
101
|
-
url = nil
|
|
102
|
-
end
|
|
103
|
-
[url, subdomain, path, params]
|
|
104
|
-
end
|
|
63
|
+
rewrap_errors(&)
|
|
64
|
+
rescue ConnectionError, BadGateway, InternalServerError => e
|
|
65
|
+
raise e unless retries < 3
|
|
105
66
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
else
|
|
110
|
-
uri = URI.parse(subdomain_or_url)
|
|
111
|
-
uri.query = URI.encode_www_form(params) if params&.any?
|
|
112
|
-
uri.to_s
|
|
67
|
+
sleep self.class.retry_time
|
|
68
|
+
retries += 1
|
|
69
|
+
retry
|
|
113
70
|
end
|
|
114
71
|
end
|
|
115
72
|
|
|
116
|
-
def content_type_header
|
|
117
|
-
{ 'Content-Type' => 'application/json' }
|
|
118
|
-
end
|
|
119
|
-
|
|
120
73
|
def headers
|
|
121
74
|
{
|
|
122
75
|
'Authorization' => "Bearer #{@access_token}",
|
data/lib/cobot_client/engine.rb
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CobotClient
|
|
4
|
+
class Error < StandardError; end
|
|
5
|
+
|
|
6
|
+
class ConnectionError < Error; end
|
|
7
|
+
|
|
8
|
+
class ResponseError < Error
|
|
9
|
+
HTTP_CODE = nil
|
|
10
|
+
|
|
11
|
+
attr_reader :response
|
|
12
|
+
|
|
13
|
+
def self.build(msg = nil, response:)
|
|
14
|
+
RESPONSE_CODE_TO_ERROR_CLASS
|
|
15
|
+
.fetch(response.code, self)
|
|
16
|
+
.new(msg, response: response)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize(msg = nil, response: nil)
|
|
20
|
+
@response = response
|
|
21
|
+
|
|
22
|
+
super(
|
|
23
|
+
[
|
|
24
|
+
"HTTP #{http_code}",
|
|
25
|
+
msg
|
|
26
|
+
].compact.join(' - ')
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def http_body
|
|
31
|
+
@response&.body
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def http_code
|
|
35
|
+
@response&.code || self.class.const_get(:HTTP_CODE)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
RESPONSE_CODE_TO_ERROR_CLASS = ::Net::HTTPResponse::CODE_TO_OBJ.to_h do |code, net_http_class|
|
|
40
|
+
class_name = net_http_class.name.delete_prefix('Net::HTTP')
|
|
41
|
+
|
|
42
|
+
class_object = Class.new(ResponseError)
|
|
43
|
+
class_object.const_get(:HTTP_CODE, code)
|
|
44
|
+
|
|
45
|
+
[code.to_i, const_set(class_name, class_object)]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
module CobotClient
|
|
4
|
+
class NavigationLink
|
|
5
|
+
include ActiveModel::Model
|
|
6
|
+
include ActiveModel::Attributes
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
attribute :section, :string
|
|
9
|
+
attribute :label, :string
|
|
10
|
+
attribute :iframe_url, :string
|
|
11
|
+
attribute :user_url, :string
|
|
12
|
+
attribute :user_editable, :boolean, default: true
|
|
13
|
+
end
|
|
11
14
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'oauth2'
|
|
2
4
|
|
|
3
5
|
module CobotClient
|
|
@@ -5,9 +7,9 @@ module CobotClient
|
|
|
5
7
|
class NavigationLinkService
|
|
6
8
|
# api_client - an CobotClient::ApiClient
|
|
7
9
|
# access_token - an access token string (owner must be admin of the space to be used)
|
|
8
|
-
def initialize(api_client,
|
|
10
|
+
def initialize(api_client, space_subdomain)
|
|
9
11
|
@api_client = api_client
|
|
10
|
-
@subdomain =
|
|
12
|
+
@subdomain = space_subdomain
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
# Checks if links are already installed and if not installs them.
|
|
@@ -16,7 +18,7 @@ module CobotClient
|
|
|
16
18
|
#
|
|
17
19
|
# Returns the links as `[CobotClient::NavigationLink]`
|
|
18
20
|
def install_links(new_links)
|
|
19
|
-
existing_links =
|
|
21
|
+
existing_links = fetch_links
|
|
20
22
|
missing_links = new_links.reject do |new_link|
|
|
21
23
|
existing_links.find do |existing_link|
|
|
22
24
|
existing_link.section == new_link.section && existing_link.iframe_url == new_link.iframe_url
|
|
@@ -30,18 +32,21 @@ module CobotClient
|
|
|
30
32
|
|
|
31
33
|
private
|
|
32
34
|
|
|
33
|
-
def
|
|
35
|
+
def fetch_links
|
|
34
36
|
@api_client.get(@subdomain, '/navigation_links').map do |attributes|
|
|
35
37
|
NavigationLink.new attributes
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
def create_link(link)
|
|
40
|
-
response = @api_client.post(
|
|
42
|
+
response = @api_client.post(
|
|
43
|
+
@subdomain,
|
|
44
|
+
'/navigation_links',
|
|
41
45
|
section: link.section,
|
|
42
46
|
label: link.label,
|
|
43
47
|
iframe_url: link.iframe_url,
|
|
44
|
-
user_editable: link.user_editable
|
|
48
|
+
user_editable: link.user_editable
|
|
49
|
+
)
|
|
45
50
|
|
|
46
51
|
NavigationLink.new response
|
|
47
52
|
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CobotClient
|
|
4
|
+
class Request
|
|
5
|
+
include UrlHelper
|
|
6
|
+
|
|
7
|
+
CONTENT_TYPE_HEADER = {'Content-Type' => 'application/json'}.freeze
|
|
8
|
+
VERBS = %i[get post put patch delete].freeze
|
|
9
|
+
|
|
10
|
+
attr_reader :body, :headers, :uri, :verb
|
|
11
|
+
|
|
12
|
+
def initialize(verb, *)
|
|
13
|
+
raise ArgumentError, "Unsupported verb: #{verb.inspect}" unless VERBS.include?(verb)
|
|
14
|
+
|
|
15
|
+
@verb = verb
|
|
16
|
+
@headers = CONTENT_TYPE_HEADER
|
|
17
|
+
|
|
18
|
+
url, subdomain, path, params = parse_args(*)
|
|
19
|
+
@uri, @body = case @verb
|
|
20
|
+
when :get, :delete
|
|
21
|
+
[build_uri(url || subdomain, path, **params), nil]
|
|
22
|
+
else
|
|
23
|
+
[build_uri(url || subdomain, path), params.to_json]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def headers=(headers)
|
|
28
|
+
raise ArgumentError, "Expected Hash, got: #{headers.inspect}" unless headers.is_a?(Hash)
|
|
29
|
+
|
|
30
|
+
@headers = headers.merge(CONTENT_TYPE_HEADER)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def submit
|
|
34
|
+
Response.new(
|
|
35
|
+
http.request(net_http_request)
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def build_uri(subdomain_or_url, path, **params)
|
|
42
|
+
if path
|
|
43
|
+
cobot_uri(subdomain_or_url, "/api#{path}", params: params)
|
|
44
|
+
else
|
|
45
|
+
uri = URI.parse(subdomain_or_url)
|
|
46
|
+
uri.query = URI.encode_www_form(params) unless params.empty?
|
|
47
|
+
uri
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def http
|
|
52
|
+
@http ||= Net::HTTP.new(uri.host, uri.port).tap do |http|
|
|
53
|
+
http.use_ssl = (uri.scheme == 'https')
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Do not memoize this because `headers` can change
|
|
58
|
+
def net_http_request
|
|
59
|
+
request_class.new(uri).tap do |request|
|
|
60
|
+
request.body = body if body
|
|
61
|
+
request.initialize_http_header(headers)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def request_class
|
|
66
|
+
case @verb
|
|
67
|
+
when :get then Net::HTTP::Get
|
|
68
|
+
when :post then Net::HTTP::Post
|
|
69
|
+
when :put then Net::HTTP::Put
|
|
70
|
+
when :patch then Net::HTTP::Patch
|
|
71
|
+
when :delete then Net::HTTP::Delete
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def parse_args(*args)
|
|
76
|
+
params = if args.size == 3 || (args.size == 2 && args[0].match(%r{https?://}))
|
|
77
|
+
args.pop
|
|
78
|
+
else
|
|
79
|
+
{}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
if args.size == 1
|
|
83
|
+
[args[0], nil, nil, params]
|
|
84
|
+
else
|
|
85
|
+
[nil, args[0], args[1], params]
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CobotClient
|
|
4
|
+
class Response
|
|
5
|
+
def initialize(net_http_response)
|
|
6
|
+
@net_http_response = net_http_response
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def body
|
|
10
|
+
@net_http_response.body
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def headers
|
|
14
|
+
@net_http_response.to_hash
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def code
|
|
18
|
+
Integer(@net_http_response.code)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def parsed_body
|
|
22
|
+
return if !success? || code == 204
|
|
23
|
+
|
|
24
|
+
JSON.parse(@net_http_response.body, symbolize_names: true)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def client_error?
|
|
28
|
+
(400..499).cover?(code)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def server_error?
|
|
32
|
+
(500..599).cover?(code)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def success?
|
|
36
|
+
(200..299).cover?(code)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_error
|
|
40
|
+
return if success?
|
|
41
|
+
|
|
42
|
+
ResponseError.build(@net_http_response.message, response: self)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -1,28 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
module CobotClient
|
|
4
|
-
|
|
3
|
+
module CobotClient
|
|
4
|
+
module UrlHelper
|
|
5
|
+
DEFAULT_SITE = 'https://www.cobot.me'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
# set this to override the site for accessing the cobot api
|
|
8
|
+
def self.site
|
|
9
|
+
@site || DEFAULT_SITE
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
def self.site=(site)
|
|
13
|
+
@site = site
|
|
14
|
+
end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
# generates a uri to access the cobot api
|
|
17
|
+
# see the spec for usage examples
|
|
18
|
+
def cobot_uri(subdomain = 'www', path = '/', params: {}, **)
|
|
19
|
+
uri = URI.parse(CobotClient::UrlHelper.site)
|
|
20
|
+
uri.host = uri.host.split('.').tap { |parts| parts[0] = subdomain }.join('.')
|
|
21
|
+
uri.path = path
|
|
22
|
+
uri.query = URI.encode_www_form(params) unless params.empty?
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
url.path = path
|
|
24
|
-
url.query = URI.encode_www_form(options[:params]) if options[:params] && options[:params].any?
|
|
24
|
+
uri
|
|
25
|
+
end
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
def cobot_url(subdomain = 'www', path = '/', params: {}, **)
|
|
28
|
+
cobot_uri(subdomain, path, params: params, **).to_s
|
|
29
|
+
end
|
|
27
30
|
end
|
|
28
31
|
end
|
data/lib/cobot_client/version.rb
CHANGED
data/lib/cobot_client.rb
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'uri'
|
|
6
|
+
|
|
7
|
+
require 'active_model'
|
|
8
|
+
|
|
1
9
|
require 'cobot_client/version'
|
|
2
10
|
require 'cobot_client/engine' if defined?(Rails)
|
|
3
|
-
require 'cobot_client/
|
|
11
|
+
require 'cobot_client/errors'
|
|
4
12
|
|
|
5
13
|
module CobotClient
|
|
6
14
|
autoload :ApiClient, 'cobot_client/api_client'
|
|
7
15
|
autoload :NavigationLink, 'cobot_client/navigation_link'
|
|
8
16
|
autoload :NavigationLinkService, 'cobot_client/navigation_link_service'
|
|
17
|
+
autoload :Response, 'cobot_client/response'
|
|
18
|
+
autoload :Request, 'cobot_client/request'
|
|
9
19
|
autoload :UrlHelper, 'cobot_client/url_helper'
|
|
10
20
|
end
|