cobot_client 4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0a30b5eca1e0c962124b7b58a2b2028b6844a74c
4
- data.tar.gz: d9d307e97fda81cde1e3c857f22e159f9b995d42
2
+ SHA256:
3
+ metadata.gz: 3d961f35435c958c2cf33b88170ce9f5c327f3ee57c332eb534b6b60098a86f1
4
+ data.tar.gz: 33c485cd858e729d508bd331897872f8d24345b75d1e4f192089e7bcfafc2793
5
5
  SHA512:
6
- metadata.gz: 43f4f96b21d31aade0f682f2feb5e65c132663b2de2b3d6449697d9910e55cc789c94169c0305e5afd0a55495813e982799ee9aefea58c74b252572a71ca07d8
7
- data.tar.gz: cc89589edc277e10173a2b1ce8a40e91b058de20afcac50ce6f93e759bb55ba7cb5472052430caf86ea221d6732e926055492b38c83ed4e752a5e139062005d5
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
@@ -16,3 +16,6 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .rvmrc
19
+
20
+ /.gem_rbs_collection/
21
+ /rbs_collection.lock.yaml
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,11 +1,23 @@
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
+
9
+ # 5.0.0
10
+
11
+ Bump oauth2 dependency to ~>2.0.
12
+
1
13
  # 4.0.0
2
14
 
3
- * changed navigation link service to add missing links and return all if there are links already (before it would do nothing if there were any links already)
15
+ - changed navigation link service to add missing links and return all if there are links already (before it would do nothing if there were any links already)
4
16
 
5
17
  # 3.1.0
6
18
 
7
- * adds user_edtiable attribute to navigation links
19
+ - adds user_editable attribute to navigation links
8
20
 
9
21
  # 3.0.0
10
22
 
11
- * bumps rest-client to ~2.0.1, which results in CobotClient::ResourceNotFound to be renamed to CobotClient::NotFound (FrauBienenstich)
23
+ - bumps rest-client to ~2.0.1, which results in CobotClient::ResourceNotFound to be renamed to CobotClient::NotFound (FrauBienenstich)
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/README.md CHANGED
@@ -24,9 +24,11 @@ Or install it yourself as:
24
24
 
25
25
  You can install links to your app into the navigation on Cobot. When users click the link an iframe pointing to the given `iframe_url` will be shown.
26
26
 
27
- client = CobotClient::ApiClient.new <access token>
28
- CobotClient::NavigationLinkService.new(client, 'co-up').install_links [
29
- CobotClient::NavigationLink.new(section: 'admin/manage', label: 'My App', iframe_url: 'http://example.com')]
27
+ ```ruby
28
+ client = CobotClient::ApiClient.new '<access token>'
29
+ CobotClient::NavigationLinkService.new(client, 'co-up').install_links [
30
+ CobotClient::NavigationLink.new(section: 'admin/manage', label: 'My App', iframe_url: 'http://example.com')]
31
+ ```
30
32
 
31
33
  ### Setting up automatic iframe resizing
32
34
 
@@ -48,25 +50,61 @@ When you display layers in the iframe that are positioned relative to the window
48
50
 
49
51
  There is a module `CobotClient::UrlHelper`. After you include it you can call `cobot_url`. Examples:
50
52
 
51
- cobot_url('co-up') # => 'https://co-up.cobot.me/'
52
- cobot_url('co-up', '/api/user') # => 'https://co-up.cobot.me/api/user'
53
- cobot_url('co-up', '/api/user', params: {x: 'y'}) # => 'https://co-up.cobot.me/api/user?x=y'
53
+ ```ruby
54
+ cobot_url('co-up') # => 'https://co-up.cobot.me/'
55
+ cobot_url('co-up', '/api/user') # => 'https://co-up.cobot.me/api/user'
56
+ cobot_url('co-up', '/api/user', params: {x: 'y'}) # => 'https://co-up.cobot.me/api/user?x=y'
57
+ ```
54
58
 
55
59
  ### Calling the API
56
60
 
57
61
  At the moment there are only a few high-level methods. For more details see the specs.
58
62
 
59
- client = CobotClient::ApiClient.new('<access token>')
60
- client.list_resources('<subdomain>')
63
+ ```ruby
64
+ client = CobotClient::ApiClient.new('<access token>')
65
+ client.list_resources('<subdomain>')
66
+ ```
61
67
 
62
68
  For everything else you can use the low-level get/post/put/delete metods:
63
69
 
64
- client.get 'www', '/user'
65
- client.post 'my-subdomain', '/users', {"email": "joe@doe.com"}
70
+ ```ruby
71
+ client.get 'www', '/user'
72
+ client.post 'my-subdomain', '/users', {"email": "joe@doe.com"}
73
+ ```
66
74
 
67
75
  You can also pass a URL instead of subdomain/path:
68
76
 
69
- client.get 'https://www/cobot.me/user'
77
+ ```ruby
78
+ client.get 'https://www/cobot.me/user'
79
+ ```
80
+
81
+ ### Error handling
82
+
83
+ In case of Cobot returning a 4xx or 5xx status code, the `ApiClient` throws an exception that is a subclass of `CobotClient::Exception`.
84
+
85
+ The most common exceptions encountered are `CobotClient::NotFound` (404), `CobotClient::Forbidden` (403), `CobotClient::UnprocesseableEntity` (422) and `CobotClient::TooManyRequests` (429).
86
+
87
+ To access the error message contained in the response, rescue the exception and `http_body` on it:
88
+
89
+ ```ruby
90
+ begin
91
+ client = CobotClient::ApiClient.new('<access token>')
92
+ client.get('www', '/user')
93
+ rescue CobotClient::Exception => e
94
+ puts JSON.parse(e.http_body)
95
+ end
96
+ ```
97
+
98
+ To access response headers, for example the `Retry-After` header of a rate-limited request:
99
+
100
+ ```ruby
101
+ begin
102
+ client = CobotClient::ApiClient.new('<access token>')
103
+ client.get('www', '/user')
104
+ rescue CobotClient::TooManyRequests => e
105
+ puts e.response.headers[:retry_after].to_i
106
+ end
107
+ ```
70
108
 
71
109
  ## Contributing
72
110
 
data/Rakefile CHANGED
@@ -1,7 +1,11 @@
1
1
  #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
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: :spec
11
+ task default: %i[spec rubocop]
data/cobot_client.gemspec CHANGED
@@ -1,25 +1,26 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/cobot_client/version', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('lib/cobot_client/version', __dir__)
3
4
 
4
5
  Gem::Specification.new do |gem|
5
- gem.authors = ["Alexander Lang"]
6
- gem.email = ["alex@cobot.me"]
7
- gem.description = %q{Client for the Cobot API plus helpers}
8
- gem.summary = %q{Client for the Cobot API plus helpers}
9
- gem.homepage = "http://github.com/cobot/cobot_client"
6
+ gem.authors = ['Alexander Lang']
7
+ gem.email = ['alex@cobot.me']
8
+ gem.description = 'Client for the Cobot API plus helpers'
9
+ gem.summary = 'Client for the Cobot API plus helpers'
10
+ gem.homepage = 'http://github.com/cobot/cobot_client'
10
11
  gem.license = 'MIT'
11
12
 
12
- gem.files = `git ls-files`.split($\)
13
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
- gem.name = "cobot_client"
16
- gem.require_paths = ["lib"]
13
+ gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
15
+ gem.name = 'cobot_client'
16
+ gem.require_paths = ['lib']
17
17
  gem.version = CobotClient::VERSION
18
18
 
19
- gem.add_dependency 'virtus', '~>1.0'
20
- gem.add_dependency 'oauth2', '~>1.0'
21
- gem.add_dependency 'rest-client', '~>2.0.1'
19
+ gem.required_ruby_version = ['>=3.3', '<5']
20
+
21
+ gem.add_dependency 'activemodel', '>=5.2'
22
22
  gem.add_dependency 'json', '~>2.0'
23
- gem.add_development_dependency 'rspec', '~>3.0'
24
- gem.add_development_dependency 'rake', '~>10.0'
23
+ gem.add_dependency 'oauth2', '~>2.0'
24
+
25
+ gem.metadata['rubygems_mfa_required'] = 'true'
25
26
  end
@@ -1,5 +1,4 @@
1
- require 'rest_client'
2
- require 'json'
1
+ # frozen_string_literal: true
3
2
 
4
3
  module CobotClient
5
4
  class ApiClient
@@ -8,127 +7,69 @@ module CobotClient
8
7
  class << self
9
8
  attr_accessor :user_agent, :retry_time
10
9
  end
10
+
11
11
  self.retry_time = 1
12
12
 
13
13
  def initialize(access_token)
14
14
  @access_token = access_token
15
15
  end
16
16
 
17
- def get_resources(subdomain)
18
- get subdomain, '/resources'
19
- end
20
-
21
- def create_booking(subdomain, resource_id, attributes)
22
- post subdomain, "/resources/#{resource_id}/bookings", attributes
23
- end
24
-
25
- def update_booking(subdomain, id, attributes)
26
- put subdomain, "/bookings/#{id}", attributes
27
- end
28
-
29
- def delete_booking(subdomain, id)
30
- delete subdomain, "/bookings/#{id}"
31
- end
32
-
33
17
  # args: either a full URL or subdomain, path, plus a body as hash
34
- def post(*args)
35
- request :post, *args
18
+ def post(*)
19
+ request(:post, *).parsed_body
36
20
  end
37
21
 
38
22
  # args: either a full URL or subdomain, path, plus a body as hash
39
- def put(*args)
40
- request :put, *args
23
+ def put(*)
24
+ request(:put, *).parsed_body
41
25
  end
42
26
 
43
- def patch(*args)
44
- request :patch, *args
27
+ def patch(*)
28
+ request(:patch, *).parsed_body
45
29
  end
46
30
 
47
31
  # args: either a full URL or subdomain, path, plus an optional params hash
48
- def get(*args)
49
- url, subdomain, path, params = parse_args(*args)
50
- JSON.parse(
51
- rewrap_errors do
52
- RestClient.get(
53
- build_url(url || subdomain, path, params),
54
- headers).body
55
- end, symbolize_names: true)
32
+ def get(*)
33
+ request(:get, *).parsed_body
56
34
  end
57
35
 
58
36
  # args: either a full URL or subdomain, path
59
- def delete(*args)
60
- url, subdomain, path, _ = parse_args(*args)
61
- rewrap_errors do
62
- RestClient.delete(build_url(url || subdomain, path), headers)
63
- end
37
+ def delete(*)
38
+ request(:delete, *)
64
39
  end
65
40
 
66
41
  private
67
42
 
68
- def request(method, *args)
69
- url, subdomain, path, body = parse_args(*args)
70
- rewrap_errors do
71
- response = RestClient.public_send(method,
72
- build_url(url || subdomain, path),
73
- body.to_json,
74
- headers.merge(content_type_header))
75
- 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
76
49
  end
77
50
  end
78
51
 
79
- def rewrap_errors(&block)
80
- retry_errors(&block)
81
- rescue RestClient::Exception => e
82
- fail CobotClient::Exceptions::EXCEPTIONS_MAP[e.class].new(e.response)
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}"
83
58
  end
84
59
 
85
- def retry_errors
60
+ def retry_errors(&)
86
61
  retries = 0
87
62
  begin
88
- yield
89
- rescue RestClient::BadGateway, SocketError, RestClient::RequestTimeout, CobotClient::InternalServerError => e
90
- if retries < 3
91
- sleep self.class.retry_time
92
- retries += 1
93
- retry
94
- else
95
- raise e
96
- end
97
- end
98
- end
99
-
100
- def parse_args(*args)
101
- if args.size == 3 || (args.size == 2 && args[0].match(%r{https?://}))
102
- params = args.pop
103
- else
104
- params = {}
105
- end
106
- if args.size == 1
107
- url = args[0]
108
- path = nil
109
- subdomain = nil
110
- else
111
- subdomain = args[0]
112
- path = args[1]
113
- url = nil
114
- end
115
- [url, subdomain, path, params]
116
- end
63
+ rewrap_errors(&)
64
+ rescue ConnectionError, BadGateway, InternalServerError => e
65
+ raise e unless retries < 3
117
66
 
118
- def build_url(subdomain_or_url, path, params = {})
119
- if path
120
- cobot_url(subdomain_or_url, "/api#{path}", params: params)
121
- else
122
- uri = URI.parse(subdomain_or_url)
123
- uri.query = URI.encode_www_form(params) if params && params.any?
124
- uri.to_s
67
+ sleep self.class.retry_time
68
+ retries += 1
69
+ retry
125
70
  end
126
71
  end
127
72
 
128
- def content_type_header
129
- {'Content-Type' => 'application/json'}
130
- end
131
-
132
73
  def headers
133
74
  {
134
75
  'Authorization' => "Bearer #{@access_token}",
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CobotClient
2
4
  class Engine < Rails::Engine
3
5
  isolate_namespace CobotClient
@@ -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
- require 'virtus'
1
+ # frozen_string_literal: true
2
2
 
3
- class CobotClient::NavigationLink
4
- include Virtus.model
3
+ module CobotClient
4
+ class NavigationLink
5
+ include ActiveModel::Model
6
+ include ActiveModel::Attributes
5
7
 
6
- attribute :section, String
7
- attribute :label, String
8
- attribute :iframe_url, String
9
- attribute :user_url, String
10
- attribute :user_editable, Boolean, default: true
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, space_sudomain)
10
+ def initialize(api_client, space_subdomain)
9
11
  @api_client = api_client
10
- @subdomain = space_sudomain
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 = get_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 get_links
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(@subdomain, '/navigation_links',
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