uploadcare-ruby 2.1.1 → 3.1.0.pre.rc1
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 +5 -5
- data/.github/workflows/gem-push.yml +20 -0
- data/.github/workflows/ruby.yml +52 -0
- data/.gitignore +13 -6
- data/.rspec +2 -0
- data/.rubocop.yml +32 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +33 -34
- data/DEVELOPMENT.md +18 -0
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +369 -546
- data/Rakefile +5 -5
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/uploadcare.rb +36 -26
- data/lib/uploadcare/api/api.rb +25 -0
- data/lib/uploadcare/client/conversion/base_conversion_client.rb +54 -0
- data/lib/uploadcare/client/conversion/document_conversion_client.rb +38 -0
- data/lib/uploadcare/client/conversion/video_conversion_client.rb +42 -0
- data/lib/uploadcare/client/file_client.rb +44 -0
- data/lib/uploadcare/client/file_list_client.rb +46 -0
- data/lib/uploadcare/client/group_client.rb +45 -0
- data/lib/uploadcare/client/multipart_upload/chunks_client.rb +48 -0
- data/lib/uploadcare/client/multipart_upload_client.rb +67 -0
- data/lib/uploadcare/client/project_client.rb +18 -0
- data/lib/uploadcare/client/rest_client.rb +74 -0
- data/lib/uploadcare/client/rest_group_client.rb +23 -0
- data/lib/uploadcare/client/upload_client.rb +36 -0
- data/lib/uploadcare/client/uploader_client.rb +109 -0
- data/lib/uploadcare/client/webhook_client.rb +47 -0
- data/lib/uploadcare/concern/error_handler.rb +54 -0
- data/lib/uploadcare/concern/throttle_handler.rb +25 -0
- data/lib/uploadcare/concern/upload_error_handler.rb +32 -0
- data/lib/uploadcare/entity/decorator/paginator.rb +79 -0
- data/lib/uploadcare/entity/document_converter.rb +26 -0
- data/lib/uploadcare/entity/entity.rb +18 -0
- data/lib/uploadcare/entity/file.rb +81 -0
- data/lib/uploadcare/entity/file_list.rb +31 -0
- data/lib/uploadcare/entity/group.rb +40 -0
- data/lib/uploadcare/entity/group_list.rb +24 -0
- data/lib/uploadcare/entity/project.rb +13 -0
- data/lib/uploadcare/entity/uploader.rb +75 -0
- data/lib/uploadcare/entity/video_converter.rb +26 -0
- data/lib/uploadcare/entity/webhook.rb +14 -0
- data/lib/uploadcare/exception/conversion_error.rb +8 -0
- data/lib/uploadcare/exception/request_error.rb +9 -0
- data/lib/uploadcare/exception/throttle_error.rb +16 -0
- data/lib/uploadcare/param/authentication_header.rb +25 -0
- data/lib/uploadcare/param/conversion/document/processing_job_url_builder.rb +39 -0
- data/lib/uploadcare/param/conversion/video/processing_job_url_builder.rb +64 -0
- data/lib/uploadcare/param/param.rb +10 -0
- data/lib/uploadcare/param/secure_auth_header.rb +37 -0
- data/lib/uploadcare/param/simple_auth_header.rb +14 -0
- data/lib/uploadcare/param/upload/signature_generator.rb +24 -0
- data/lib/uploadcare/param/upload/upload_params_generator.rb +23 -0
- data/lib/uploadcare/param/user_agent.rb +21 -0
- data/lib/uploadcare/ruby/version.rb +5 -0
- data/uploadcare-ruby.gemspec +50 -37
- metadata +109 -115
- data/.travis.yml +0 -26
- data/UPGRADE_NOTES.md +0 -36
- data/lib/uploadcare/api.rb +0 -26
- data/lib/uploadcare/api/file_api.rb +0 -7
- data/lib/uploadcare/api/file_list_api.rb +0 -19
- data/lib/uploadcare/api/file_storage_api.rb +0 -34
- data/lib/uploadcare/api/group_api.rb +0 -38
- data/lib/uploadcare/api/group_list_api.rb +0 -17
- data/lib/uploadcare/api/project_api.rb +0 -9
- data/lib/uploadcare/api/raw_api.rb +0 -38
- data/lib/uploadcare/api/uploading_api.rb +0 -71
- data/lib/uploadcare/api/uploading_api/upload_params.rb +0 -72
- data/lib/uploadcare/api/validators/file_list_options_validator.rb +0 -73
- data/lib/uploadcare/api/validators/group_list_options_validator.rb +0 -49
- data/lib/uploadcare/errors/errors.rb +0 -64
- data/lib/uploadcare/resources/file.rb +0 -164
- data/lib/uploadcare/resources/file_list.rb +0 -14
- data/lib/uploadcare/resources/group.rb +0 -115
- data/lib/uploadcare/resources/group_list.rb +0 -14
- data/lib/uploadcare/resources/project.rb +0 -13
- data/lib/uploadcare/resources/resource_list.rb +0 -83
- data/lib/uploadcare/rest/auth/auth.rb +0 -31
- data/lib/uploadcare/rest/auth/secure.rb +0 -43
- data/lib/uploadcare/rest/auth/simple.rb +0 -16
- data/lib/uploadcare/rest/connections/api_connection.rb +0 -53
- data/lib/uploadcare/rest/connections/upload_connection.rb +0 -22
- data/lib/uploadcare/rest/middlewares/auth_middleware.rb +0 -24
- data/lib/uploadcare/rest/middlewares/parse_json_middleware.rb +0 -33
- data/lib/uploadcare/rest/middlewares/raise_error_middleware.rb +0 -21
- data/lib/uploadcare/utils/parser.rb +0 -71
- data/lib/uploadcare/utils/user_agent.rb +0 -44
- data/lib/uploadcare/version.rb +0 -3
- data/spec/api/file_list_api_spec.rb +0 -95
- data/spec/api/file_storage_api_spec.rb +0 -88
- data/spec/api/group_list_api_spec.rb +0 -59
- data/spec/api/raw_api_spec.rb +0 -25
- data/spec/api/uploading_api/upload_params_spec.rb +0 -99
- data/spec/api/uploading_api_spec.rb +0 -59
- data/spec/resources/file_list_spec.rb +0 -25
- data/spec/resources/file_spec.rb +0 -223
- data/spec/resources/group_list_spec.rb +0 -25
- data/spec/resources/group_spec.rb +0 -101
- data/spec/resources/operations_spec.rb +0 -59
- data/spec/resources/project_spec.rb +0 -21
- data/spec/rest/api_connection_spec.rb +0 -68
- data/spec/rest/auth/secure_spec.rb +0 -66
- data/spec/rest/auth/simple_spec.rb +0 -31
- data/spec/rest/errors_spec.rb +0 -75
- data/spec/rest/upload_connection_spec.rb +0 -19
- data/spec/shared/resource_list.rb +0 -188
- data/spec/spec_helper.rb +0 -54
- data/spec/uploadcare_spec.rb +0 -16
- data/spec/utils/parser_spec.rb +0 -85
- data/spec/utils/user_agent_spec.rb +0 -46
- data/spec/view.png +0 -0
- data/spec/view2.jpg +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'client/multipart_upload/chunks_client'
|
|
4
|
+
require_relative 'upload_client'
|
|
5
|
+
|
|
6
|
+
module Uploadcare
|
|
7
|
+
module Client
|
|
8
|
+
# Client for multipart uploads
|
|
9
|
+
#
|
|
10
|
+
# @see https://uploadcare.com/api-refs/upload-api/#tag/Upload
|
|
11
|
+
class MultipartUploaderClient < UploadClient
|
|
12
|
+
include MultipartUpload
|
|
13
|
+
|
|
14
|
+
# Upload a big file by splitting it into parts and sending those parts into assigned buckets
|
|
15
|
+
# object should be File
|
|
16
|
+
def upload(object, store: false)
|
|
17
|
+
response = upload_start(object, store: store)
|
|
18
|
+
return response unless response.success[:parts] && response.success[:uuid]
|
|
19
|
+
|
|
20
|
+
links = response.success[:parts]
|
|
21
|
+
uuid = response.success[:uuid]
|
|
22
|
+
ChunksClient.new.upload_chunks(object, links)
|
|
23
|
+
upload_complete(uuid)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Asks Uploadcare server to create a number of storage bin for uploads
|
|
27
|
+
def upload_start(object, store: false)
|
|
28
|
+
body = HTTP::FormData::Multipart.new(
|
|
29
|
+
Param::Upload::UploadParamsGenerator.call(store).merge(multiupload_metadata(object))
|
|
30
|
+
)
|
|
31
|
+
post(path: 'multipart/start/',
|
|
32
|
+
headers: { 'Content-type': body.content_type },
|
|
33
|
+
body: body)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# When every chunk is uploaded, ask Uploadcare server to finish the upload
|
|
37
|
+
def upload_complete(uuid)
|
|
38
|
+
body = HTTP::FormData::Multipart.new(
|
|
39
|
+
{
|
|
40
|
+
'UPLOADCARE_PUB_KEY': Uploadcare.config.public_key,
|
|
41
|
+
'uuid': uuid
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
post(path: 'multipart/complete/', body: body, headers: { 'Content-type': body.content_type })
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def multiupload_metadata(file)
|
|
50
|
+
filename = file.original_filename if file.respond_to?(:original_filename)
|
|
51
|
+
mime_type = file.content_type if file.respond_to?(:content_type)
|
|
52
|
+
options = { filename: filename, content_type: mime_type }.compact
|
|
53
|
+
file = HTTP::FormData::File.new(file, options)
|
|
54
|
+
{
|
|
55
|
+
filename: file.filename,
|
|
56
|
+
size: file.size,
|
|
57
|
+
content_type: file.content_type
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
alias api_struct_post post
|
|
62
|
+
def post(**args)
|
|
63
|
+
handle_throttling { api_struct_post(**args) }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uploadcare
|
|
4
|
+
module Client
|
|
5
|
+
# API client for getting project info
|
|
6
|
+
# @see https://uploadcare.com/docs/api_reference/rest/handling_projects/
|
|
7
|
+
class ProjectClient < RestClient
|
|
8
|
+
# get information about current project
|
|
9
|
+
# current project is determined by public and private key combination
|
|
10
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#tag/Project
|
|
11
|
+
def show
|
|
12
|
+
get(uri: '/project/')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
alias project show
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'rest_client'
|
|
4
|
+
require 'api_struct'
|
|
5
|
+
require 'uploadcare/concern/error_handler'
|
|
6
|
+
require 'uploadcare/concern/throttle_handler'
|
|
7
|
+
require 'param/authentication_header'
|
|
8
|
+
|
|
9
|
+
module Uploadcare
|
|
10
|
+
module Client
|
|
11
|
+
# @abstract
|
|
12
|
+
# General client for signed REST requests
|
|
13
|
+
class RestClient < ApiStruct::Client
|
|
14
|
+
include Uploadcare::Concerns::ErrorHandler
|
|
15
|
+
include Uploadcare::Concerns::ThrottleHandler
|
|
16
|
+
include Exception
|
|
17
|
+
|
|
18
|
+
alias api_struct_delete delete
|
|
19
|
+
alias api_struct_get get
|
|
20
|
+
alias api_struct_post post
|
|
21
|
+
alias api_struct_put put
|
|
22
|
+
|
|
23
|
+
# Send request with authentication header
|
|
24
|
+
#
|
|
25
|
+
# Handle throttling as well
|
|
26
|
+
def request(uri:, method: 'GET', **options)
|
|
27
|
+
request_headers = Param::AuthenticationHeader.call(method: method.upcase, uri: uri,
|
|
28
|
+
content_type: headers[:'Content-type'], **options)
|
|
29
|
+
handle_throttling do
|
|
30
|
+
send("api_struct_#{method.downcase}", path: remove_trailing_slash(uri),
|
|
31
|
+
headers: request_headers, body: options[:content])
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def get(**options)
|
|
36
|
+
request(method: 'GET', **options)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def post(**options)
|
|
40
|
+
request(method: 'POST', **options)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def put(**options)
|
|
44
|
+
request(method: 'PUT', **options)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def delete(**options)
|
|
48
|
+
request(method: 'DELETE', **options)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def api_root
|
|
52
|
+
Uploadcare.config.rest_api_root
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def headers
|
|
56
|
+
{
|
|
57
|
+
'Content-type': 'application/json',
|
|
58
|
+
'Accept': 'application/vnd.uploadcare-v0.5+json',
|
|
59
|
+
'User-Agent': Uploadcare::Param::UserAgent.call
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def remove_trailing_slash(str)
|
|
66
|
+
str.gsub(%r{^/}, '')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def default_params
|
|
70
|
+
{}
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'rest_client'
|
|
4
|
+
|
|
5
|
+
module Uploadcare
|
|
6
|
+
module Client
|
|
7
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#tag/Group/paths/~1groups~1%3Cuuid%3E~1storage~1/put
|
|
8
|
+
class RestGroupClient < RestClient
|
|
9
|
+
# store all files in a group
|
|
10
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#tag/Group/paths/~1groups~1%3Cuuid%3E~1storage~1/put
|
|
11
|
+
def store(uuid)
|
|
12
|
+
put(uri: "/groups/#{uuid}/storage/")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# return paginated list of groups
|
|
16
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/groupsList
|
|
17
|
+
def list(options = {})
|
|
18
|
+
query = options.empty? ? '' : "?#{URI.encode_www_form(options)}"
|
|
19
|
+
get(uri: "/groups/#{query}")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'api_struct'
|
|
4
|
+
require 'param/user_agent'
|
|
5
|
+
require 'uploadcare/concern/error_handler'
|
|
6
|
+
require 'uploadcare/concern/throttle_handler'
|
|
7
|
+
|
|
8
|
+
module Uploadcare
|
|
9
|
+
module Client
|
|
10
|
+
# @abstract
|
|
11
|
+
#
|
|
12
|
+
# Headers and helper methods for clients working with upload API
|
|
13
|
+
# @see https://uploadcare.com/docs/api_reference/upload/
|
|
14
|
+
class UploadClient < ApiStruct::Client
|
|
15
|
+
include Concerns::ErrorHandler
|
|
16
|
+
include Concerns::ThrottleHandler
|
|
17
|
+
include Exception
|
|
18
|
+
|
|
19
|
+
def api_root
|
|
20
|
+
Uploadcare.config.upload_api_root
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def headers
|
|
24
|
+
{
|
|
25
|
+
'User-Agent': Uploadcare::Param::UserAgent.call
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def default_params
|
|
32
|
+
{}
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'upload_client'
|
|
4
|
+
require 'retries'
|
|
5
|
+
require 'param/upload/upload_params_generator'
|
|
6
|
+
|
|
7
|
+
module Uploadcare
|
|
8
|
+
module Client
|
|
9
|
+
# This is client for general uploads
|
|
10
|
+
#
|
|
11
|
+
# @see https://uploadcare.com/api-refs/upload-api/#tag/Upload
|
|
12
|
+
class UploaderClient < UploadClient
|
|
13
|
+
# @see https://uploadcare.com/api-refs/upload-api/#operation/baseUpload
|
|
14
|
+
|
|
15
|
+
def upload_many(arr, **options)
|
|
16
|
+
body = upload_many_body(arr, **options)
|
|
17
|
+
post(path: 'base/',
|
|
18
|
+
headers: { 'Content-type': body.content_type },
|
|
19
|
+
body: body)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# syntactic sugar for upload_many
|
|
23
|
+
# There is actual upload method for one file, but it is redundant
|
|
24
|
+
|
|
25
|
+
def upload(file, **options)
|
|
26
|
+
upload_many([file], **options)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Upload files from url
|
|
30
|
+
# @see https://uploadcare.com/api-refs/upload-api/#operation/fromURLUpload
|
|
31
|
+
# options:
|
|
32
|
+
# - check_URL_duplicates
|
|
33
|
+
# - filename
|
|
34
|
+
# - save_URL_duplicates
|
|
35
|
+
# - async - returns upload token instead of upload data
|
|
36
|
+
def upload_from_url(url, **options)
|
|
37
|
+
body = upload_from_url_body(url, **options)
|
|
38
|
+
token_response = post(path: 'from_url/', headers: { 'Content-type': body.content_type }, body: body)
|
|
39
|
+
return token_response if options[:async]
|
|
40
|
+
|
|
41
|
+
uploaded_response = poll_upload_response(token_response.success[:token])
|
|
42
|
+
return uploaded_response if uploaded_response.success[:status] == 'error'
|
|
43
|
+
|
|
44
|
+
Dry::Monads::Success(files: [uploaded_response.success])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
alias api_struct_post post
|
|
50
|
+
def post(**args)
|
|
51
|
+
handle_throttling { api_struct_post(**args) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def poll_upload_response(token)
|
|
55
|
+
with_retries(max_tries: Uploadcare.config.max_request_tries,
|
|
56
|
+
base_sleep_seconds: Uploadcare.config.base_request_sleep,
|
|
57
|
+
max_sleep_seconds: Uploadcare.config.max_request_sleep) do
|
|
58
|
+
response = get_status_response(token)
|
|
59
|
+
raise RequestError if %w[progress waiting unknown].include?(response.success[:status])
|
|
60
|
+
|
|
61
|
+
response
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Check upload status
|
|
66
|
+
#
|
|
67
|
+
# @see https://uploadcare.com/api-refs/upload-api/#operation/fromURLUploadStatus
|
|
68
|
+
def get_status_response(token)
|
|
69
|
+
query_params = { token: token }
|
|
70
|
+
get(path: 'from_url/status/', params: query_params)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Prepares body for upload_many method
|
|
74
|
+
def upload_many_body(arr, **options)
|
|
75
|
+
files_formdata = arr.map do |file|
|
|
76
|
+
[HTTP::FormData::File.new(file).filename,
|
|
77
|
+
form_data_for(file)]
|
|
78
|
+
end.to_h
|
|
79
|
+
p Param::Upload::UploadParamsGenerator.call(options[:store]).merge(files_formdata)
|
|
80
|
+
HTTP::FormData::Multipart.new(
|
|
81
|
+
Param::Upload::UploadParamsGenerator.call(options[:store]).merge(files_formdata)
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def form_data_for(file)
|
|
86
|
+
filename = file.original_filename if file.respond_to?(:original_filename)
|
|
87
|
+
mime_type = file.content_type if file.respond_to?(:content_type)
|
|
88
|
+
options = { filename: filename, content_type: mime_type }.compact
|
|
89
|
+
HTTP::FormData::File.new(file, options)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
STORE_VALUES = {
|
|
93
|
+
true => '1',
|
|
94
|
+
false => '0'
|
|
95
|
+
}.freeze
|
|
96
|
+
|
|
97
|
+
# Prepare upload_from_url initial request body
|
|
98
|
+
def upload_from_url_body(url, **options)
|
|
99
|
+
HTTP::FormData::Multipart.new(
|
|
100
|
+
options.merge(
|
|
101
|
+
'pub_key' => Uploadcare.config.public_key,
|
|
102
|
+
'source_url' => url,
|
|
103
|
+
'store' => STORE_VALUES[options[:store]]
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'rest_client'
|
|
4
|
+
|
|
5
|
+
module Uploadcare
|
|
6
|
+
module Client
|
|
7
|
+
# client for webhook management
|
|
8
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#tag/Webhook
|
|
9
|
+
class WebhookClient < RestClient
|
|
10
|
+
# Create webhook
|
|
11
|
+
# @see https://uploadcare.com/docs/api_reference/rest/webhooks/#subscribe
|
|
12
|
+
def create(options = {})
|
|
13
|
+
body = {
|
|
14
|
+
'target_url': options[:target_url],
|
|
15
|
+
'event': options[:event] || 'file.uploaded',
|
|
16
|
+
'is_active': options[:is_active] || true
|
|
17
|
+
}.to_json
|
|
18
|
+
post(uri: '/webhooks/', content: body)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Returns array (not paginated list) of webhooks
|
|
22
|
+
# @see https://uploadcare.com/docs/api_reference/rest/webhooks/#get-list
|
|
23
|
+
def list
|
|
24
|
+
get(uri: '/webhooks/')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Permanently deletes subscription
|
|
28
|
+
# @see https://uploadcare.com/docs/api_reference/rest/webhooks/#unsubscribe
|
|
29
|
+
def delete(target_url)
|
|
30
|
+
body = { 'target_url': target_url }.to_json
|
|
31
|
+
post(uri: '/webhooks/unsubscribe/', content: body)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Updates webhook
|
|
35
|
+
# @see https://uploadcare.com/docs/api_reference/rest/webhooks/#subscribe-update
|
|
36
|
+
def update(id, options = {})
|
|
37
|
+
body = options.to_json
|
|
38
|
+
post(uri: "/webhooks/#{id}/", content: body)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
alias create_webhook create
|
|
42
|
+
alias list_webhooks list
|
|
43
|
+
alias delete_webhook delete
|
|
44
|
+
alias update_webhook update
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uploadcare
|
|
4
|
+
module Concerns
|
|
5
|
+
# Wrapper for responses
|
|
6
|
+
# raises errors instead of returning monads
|
|
7
|
+
module ErrorHandler
|
|
8
|
+
include Exception
|
|
9
|
+
|
|
10
|
+
# Extension of ApiStruct's failure method
|
|
11
|
+
#
|
|
12
|
+
# Raises errors instead of returning falsey objects
|
|
13
|
+
# @see https://github.com/rubygarage/api_struct/blob/master/lib/api_struct/client.rb#L55
|
|
14
|
+
def failure(response)
|
|
15
|
+
catch_upload_errors(response)
|
|
16
|
+
parsed_response = JSON.parse(response.body.to_s)
|
|
17
|
+
raise RequestError, parsed_response['detail'] || parsed_response.map { |k, v| "#{k}: #{v}" }.join('; ')
|
|
18
|
+
rescue JSON::ParserError
|
|
19
|
+
raise RequestError, response.body.to_s
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Extension of ApiStruct's wrap method
|
|
23
|
+
#
|
|
24
|
+
# Catches throttling errors and Upload API errors
|
|
25
|
+
#
|
|
26
|
+
# @see https://github.com/rubygarage/api_struct/blob/master/lib/api_struct/client.rb#L45
|
|
27
|
+
def wrap(response)
|
|
28
|
+
raise_throttling_error(response) if response.status == 429
|
|
29
|
+
return failure(response) if response.status >= 300
|
|
30
|
+
|
|
31
|
+
catch_upload_errors(response)
|
|
32
|
+
success(response)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# Raise ThrottleError. Also, tells in error when server will be ready for next request
|
|
38
|
+
def raise_throttling_error(response)
|
|
39
|
+
retry_after = response.headers['Retry-After'].to_i + 1 || 11
|
|
40
|
+
raise ThrottleError.new(retry_after), "Response throttled, retry #{retry_after} seconds later"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Upload API returns its errors with code 200, and stores its actual code and details within response message
|
|
44
|
+
# This methods detects that and raises apropriate error
|
|
45
|
+
def catch_upload_errors(response)
|
|
46
|
+
return unless response.code == 200
|
|
47
|
+
|
|
48
|
+
parsed_response = JSON.parse(response.body.to_s)
|
|
49
|
+
error = parsed_response['error'] if parsed_response.is_a?(Hash)
|
|
50
|
+
raise RequestError, error if error
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uploadcare
|
|
4
|
+
module Concerns
|
|
5
|
+
# This module lets clients send request multiple times if request is throttled
|
|
6
|
+
module ThrottleHandler
|
|
7
|
+
# call given block. If ThrottleError is returned, it will wait and attempt again 4 more times
|
|
8
|
+
# @yield executable block (HTTP request that may be throttled)
|
|
9
|
+
def handle_throttling
|
|
10
|
+
(Uploadcare.config.max_throttle_attempts - 1).times do
|
|
11
|
+
# rubocop:disable Style/RedundantBegin
|
|
12
|
+
begin
|
|
13
|
+
return yield
|
|
14
|
+
rescue(Exception::ThrottleError) => e
|
|
15
|
+
wait_time = e.timeout
|
|
16
|
+
sleep(wait_time)
|
|
17
|
+
next
|
|
18
|
+
end
|
|
19
|
+
# rubocop:enable Style/RedundantBegin
|
|
20
|
+
end
|
|
21
|
+
yield
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|