uploadcare-ruby 4.4.2 → 5.0.0.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 +4 -4
- data/.env.example +7 -0
- data/.github/workflows/gem-push.yml +1 -1
- data/.github/workflows/ruby.yml +10 -13
- data/.gitignore +9 -0
- data/.rubocop.yml +95 -8
- data/CHANGELOG.md +78 -0
- data/Gemfile +23 -6
- data/MIGRATING_V5.md +290 -0
- data/README.md +422 -671
- data/Rakefile +5 -1
- data/api_examples/README.md +77 -0
- data/api_examples/rest_api/delete_files_storage.rb +3 -5
- data/api_examples/rest_api/delete_files_uuid_metadata_key.rb +3 -4
- data/api_examples/rest_api/delete_files_uuid_storage.rb +3 -4
- data/api_examples/rest_api/delete_groups_uuid.rb +3 -4
- data/api_examples/rest_api/delete_webhooks_unsubscribe.rb +3 -4
- data/api_examples/rest_api/get_addons_aws_rekognition_detect_labels_execute_status.rb +3 -6
- data/api_examples/rest_api/get_addons_aws_rekognition_detect_moderation_labels_execute_status.rb +3 -6
- data/api_examples/rest_api/get_addons_remove_bg_execute_status.rb +3 -6
- data/api_examples/rest_api/get_addons_uc_clamav_virus_scan_execute_status.rb +3 -6
- data/api_examples/rest_api/get_convert_document_status_token.rb +3 -5
- data/api_examples/rest_api/get_convert_document_uuid.rb +3 -5
- data/api_examples/rest_api/get_convert_video_status_token.rb +3 -5
- data/api_examples/rest_api/get_files.rb +3 -5
- data/api_examples/rest_api/get_files_uuid.rb +3 -5
- data/api_examples/rest_api/get_files_uuid_metadata.rb +3 -5
- data/api_examples/rest_api/get_files_uuid_metadata_key.rb +3 -5
- data/api_examples/rest_api/get_groups.rb +3 -5
- data/api_examples/rest_api/get_groups_uuid.rb +3 -5
- data/api_examples/rest_api/get_project.rb +3 -5
- data/api_examples/rest_api/get_webhooks.rb +3 -5
- data/api_examples/rest_api/post_addons_aws_rekognition_detect_labels_execute.rb +3 -5
- data/api_examples/rest_api/post_addons_aws_rekognition_detect_moderation_labels_execute.rb +3 -5
- data/api_examples/rest_api/post_addons_remove_bg_execute.rb +3 -5
- data/api_examples/rest_api/post_addons_uc_clamav_virus_scan_execute.rb +3 -5
- data/api_examples/rest_api/post_convert_document.rb +3 -6
- data/api_examples/rest_api/post_convert_video.rb +3 -10
- data/api_examples/rest_api/post_files_local_copy.rb +3 -6
- data/api_examples/rest_api/post_files_remote_copy.rb +3 -7
- data/api_examples/rest_api/post_webhooks.rb +3 -9
- data/api_examples/rest_api/put_files_storage.rb +3 -8
- data/api_examples/rest_api/put_files_uuid_metadata_key.rb +3 -7
- data/api_examples/rest_api/put_files_uuid_storage.rb +3 -5
- data/api_examples/rest_api/put_webhooks_id.rb +3 -11
- data/api_examples/support/example_helper.rb +250 -0
- data/api_examples/support/run_rest_example.rb +161 -0
- data/api_examples/support/run_upload_example.rb +88 -0
- data/api_examples/upload_api/get_from_url_status.rb +3 -5
- data/api_examples/upload_api/get_group_info.rb +3 -6
- data/api_examples/upload_api/get_info.rb +3 -6
- data/api_examples/upload_api/post_base.rb +3 -5
- data/api_examples/upload_api/post_from_url.rb +3 -5
- data/api_examples/upload_api/post_group.rb +3 -8
- data/api_examples/upload_api/post_multipart_complete.rb +3 -7
- data/api_examples/upload_api/post_multipart_start.rb +3 -7
- data/api_examples/upload_api/put_multipart_part.rb +4 -0
- data/bin/console +1 -1
- data/docs/release-notes-5.0.0.rc1.md +34 -0
- data/examples/README.md +39 -0
- data/examples/batch_upload.rb +54 -0
- data/examples/group_creation.rb +88 -0
- data/examples/large_file_upload.rb +88 -0
- data/examples/simple_upload.rb +39 -0
- data/examples/upload_with_progress.rb +84 -0
- data/examples/url_upload.rb +56 -0
- data/lib/uploadcare/api/rest/addons.rb +107 -0
- data/lib/uploadcare/api/rest/document_conversions.rb +65 -0
- data/lib/uploadcare/api/rest/file_metadata.rb +71 -0
- data/lib/uploadcare/api/rest/files.rb +112 -0
- data/lib/uploadcare/api/rest/groups.rb +49 -0
- data/lib/uploadcare/api/rest/project.rb +23 -0
- data/lib/uploadcare/api/rest/video_conversions.rb +52 -0
- data/lib/uploadcare/api/rest/webhooks.rb +74 -0
- data/lib/uploadcare/api/rest.rb +254 -0
- data/lib/uploadcare/api/upload/files.rb +313 -0
- data/lib/uploadcare/api/upload/groups.rb +72 -0
- data/lib/uploadcare/api/upload.rb +272 -0
- data/lib/uploadcare/client/addons_accessor.rb +85 -0
- data/lib/uploadcare/client/api.rb +33 -0
- data/lib/uploadcare/client/conversions_accessor.rb +33 -0
- data/lib/uploadcare/client/document_conversions_accessor.rb +41 -0
- data/lib/uploadcare/client/file_metadata_accessor.rb +46 -0
- data/lib/uploadcare/client/files_accessor.rb +82 -0
- data/lib/uploadcare/client/groups_accessor.rb +35 -0
- data/lib/uploadcare/client/project_accessor.rb +17 -0
- data/lib/uploadcare/client/video_conversions_accessor.rb +33 -0
- data/lib/uploadcare/client/webhooks_accessor.rb +42 -0
- data/lib/uploadcare/client.rb +127 -0
- data/lib/uploadcare/cname_generator.rb +68 -0
- data/lib/uploadcare/collections/batch_result.rb +35 -0
- data/lib/uploadcare/collections/paginated.rb +165 -0
- data/lib/uploadcare/configuration.rb +81 -0
- data/lib/uploadcare/exception/auth_error.rb +2 -6
- data/lib/uploadcare/exception/configuration_error.rb +4 -0
- data/lib/uploadcare/exception/conversion_error.rb +2 -6
- data/lib/uploadcare/exception/invalid_request_error.rb +4 -0
- data/lib/uploadcare/exception/multipart_upload_error.rb +4 -0
- data/lib/uploadcare/exception/not_found_error.rb +4 -0
- data/lib/uploadcare/exception/request_error.rb +2 -6
- data/lib/uploadcare/exception/retry_error.rb +2 -6
- data/lib/uploadcare/exception/throttle_error.rb +7 -11
- data/lib/uploadcare/exception/unknown_status_error.rb +4 -0
- data/lib/uploadcare/exception/upload_error.rb +4 -0
- data/lib/uploadcare/exception/upload_timeout_error.rb +4 -0
- data/lib/uploadcare/internal/authenticator.rb +101 -0
- data/lib/uploadcare/internal/error_handler.rb +102 -0
- data/lib/uploadcare/internal/signature_generator.rb +31 -0
- data/lib/uploadcare/internal/throttle_handler.rb +36 -0
- data/lib/uploadcare/internal/upload_io.rb +110 -0
- data/lib/uploadcare/internal/upload_params_generator.rb +86 -0
- data/lib/uploadcare/internal/user_agent.rb +22 -0
- data/lib/uploadcare/operations/multipart_upload.rb +213 -0
- data/lib/uploadcare/operations/upload_router.rb +162 -0
- data/lib/uploadcare/resources/addon_execution.rb +97 -0
- data/lib/uploadcare/resources/base_resource.rb +61 -0
- data/lib/uploadcare/resources/document_conversion.rb +81 -0
- data/lib/uploadcare/resources/file.rb +366 -0
- data/lib/uploadcare/resources/file_metadata.rb +135 -0
- data/lib/uploadcare/resources/group.rb +142 -0
- data/lib/uploadcare/resources/project.rb +26 -0
- data/lib/uploadcare/resources/video_conversion.rb +59 -0
- data/lib/uploadcare/resources/webhook.rb +85 -0
- data/lib/uploadcare/result.rb +85 -0
- data/lib/uploadcare/signed_url_generators/akamai_generator.rb +60 -56
- data/lib/uploadcare/signed_url_generators/base_generator.rb +15 -15
- data/lib/uploadcare/version.rb +7 -0
- data/lib/uploadcare/webhook_signature_verifier.rb +60 -0
- data/lib/uploadcare.rb +84 -50
- data/mise.toml +2 -0
- data/uploadcare-ruby.gemspec +8 -7
- metadata +102 -74
- data/api_examples/upload_api/put_presigned_url_x.rb +0 -8
- data/lib/uploadcare/api/api.rb +0 -25
- data/lib/uploadcare/client/addons_client.rb +0 -69
- data/lib/uploadcare/client/conversion/base_conversion_client.rb +0 -59
- data/lib/uploadcare/client/conversion/document_conversion_client.rb +0 -45
- data/lib/uploadcare/client/conversion/video_conversion_client.rb +0 -46
- data/lib/uploadcare/client/file_client.rb +0 -48
- data/lib/uploadcare/client/file_list_client.rb +0 -46
- data/lib/uploadcare/client/file_metadata_client.rb +0 -36
- data/lib/uploadcare/client/group_client.rb +0 -45
- data/lib/uploadcare/client/multipart_upload/chunks_client.rb +0 -58
- data/lib/uploadcare/client/multipart_upload_client.rb +0 -64
- data/lib/uploadcare/client/project_client.rb +0 -20
- data/lib/uploadcare/client/rest_client.rb +0 -77
- data/lib/uploadcare/client/rest_group_client.rb +0 -43
- data/lib/uploadcare/client/upload_client.rb +0 -46
- data/lib/uploadcare/client/uploader_client.rb +0 -128
- data/lib/uploadcare/client/webhook_client.rb +0 -49
- data/lib/uploadcare/concern/error_handler.rb +0 -54
- data/lib/uploadcare/concern/throttle_handler.rb +0 -25
- data/lib/uploadcare/concern/upload_error_handler.rb +0 -32
- data/lib/uploadcare/entity/addons.rb +0 -14
- data/lib/uploadcare/entity/conversion/base_converter.rb +0 -43
- data/lib/uploadcare/entity/conversion/document_converter.rb +0 -15
- data/lib/uploadcare/entity/conversion/video_converter.rb +0 -15
- data/lib/uploadcare/entity/decorator/paginator.rb +0 -79
- data/lib/uploadcare/entity/entity.rb +0 -18
- data/lib/uploadcare/entity/file.rb +0 -103
- data/lib/uploadcare/entity/file_list.rb +0 -32
- data/lib/uploadcare/entity/file_metadata.rb +0 -30
- data/lib/uploadcare/entity/group.rb +0 -49
- data/lib/uploadcare/entity/group_list.rb +0 -24
- data/lib/uploadcare/entity/project.rb +0 -13
- data/lib/uploadcare/entity/uploader.rb +0 -93
- data/lib/uploadcare/entity/webhook.rb +0 -14
- data/lib/uploadcare/param/authentication_header.rb +0 -37
- data/lib/uploadcare/param/conversion/document/processing_job_url_builder.rb +0 -39
- data/lib/uploadcare/param/conversion/video/processing_job_url_builder.rb +0 -64
- data/lib/uploadcare/param/param.rb +0 -10
- data/lib/uploadcare/param/secure_auth_header.rb +0 -51
- data/lib/uploadcare/param/simple_auth_header.rb +0 -14
- data/lib/uploadcare/param/upload/signature_generator.rb +0 -24
- data/lib/uploadcare/param/upload/upload_params_generator.rb +0 -41
- data/lib/uploadcare/param/user_agent.rb +0 -21
- data/lib/uploadcare/param/webhook_signature_verifier.rb +0 -23
- data/lib/uploadcare/ruby/version.rb +0 -5
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'client/conversion/base_conversion_client'
|
|
4
|
-
require 'param/conversion/video/processing_job_url_builder'
|
|
5
|
-
require 'exception/conversion_error'
|
|
6
|
-
|
|
7
|
-
module Uploadcare
|
|
8
|
-
module Client
|
|
9
|
-
module Conversion
|
|
10
|
-
# This is client for video conversion
|
|
11
|
-
#
|
|
12
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/videoConvert
|
|
13
|
-
class VideoConversionClient < BaseConversionClient
|
|
14
|
-
def convert_many(
|
|
15
|
-
params,
|
|
16
|
-
options = {},
|
|
17
|
-
url_builder_class = Param::Conversion::Video::ProcessingJobUrlBuilder
|
|
18
|
-
)
|
|
19
|
-
video_params = params.is_a?(Hash) ? [params] : params
|
|
20
|
-
send_convert_request(video_params, options, url_builder_class)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def get_conversion_status(token)
|
|
24
|
-
get(uri: "/convert/video/status/#{token}/")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
def convert_uri
|
|
30
|
-
'/convert/video/'
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def build_paths_body(params)
|
|
34
|
-
{
|
|
35
|
-
uuid: params[:uuid],
|
|
36
|
-
quality: params[:quality],
|
|
37
|
-
format: params[:format],
|
|
38
|
-
size: params[:size],
|
|
39
|
-
cut: params[:cut],
|
|
40
|
-
thumbs: params[:thumbs]
|
|
41
|
-
}.compact
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'rest_client'
|
|
4
|
-
|
|
5
|
-
module Uploadcare
|
|
6
|
-
module Client
|
|
7
|
-
# API client for handling single files
|
|
8
|
-
# @see https://uploadcare.com/docs/api_reference/rest/accessing_files/
|
|
9
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File
|
|
10
|
-
class FileClient < RestClient
|
|
11
|
-
# Gets list of files without pagination fields
|
|
12
|
-
def index
|
|
13
|
-
response = get(uri: '/files/')
|
|
14
|
-
response.fmap { |i| i[:results] }
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Acquire file info
|
|
18
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/fileInfo
|
|
19
|
-
def info(uuid, params = {})
|
|
20
|
-
get(uri: "/files/#{uuid}/", params: params)
|
|
21
|
-
end
|
|
22
|
-
alias file info
|
|
23
|
-
|
|
24
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/createLocalCopy
|
|
25
|
-
def local_copy(options = {})
|
|
26
|
-
body = options.compact.to_json
|
|
27
|
-
post(uri: '/files/local_copy/', content: body)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File/operation/createRemoteCopy
|
|
31
|
-
def remote_copy(options = {})
|
|
32
|
-
body = options.compact.to_json
|
|
33
|
-
post(uri: '/files/remote_copy/', content: body)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/deleteFileStorage
|
|
37
|
-
def delete(uuid)
|
|
38
|
-
request(method: 'DELETE', uri: "/files/#{uuid}/storage/")
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Store a single file, preventing it from being deleted in 2 weeks
|
|
42
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/storeFile
|
|
43
|
-
def store(uuid)
|
|
44
|
-
put(uri: "/files/#{uuid}/storage/")
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'rest_client'
|
|
4
|
-
|
|
5
|
-
module Uploadcare
|
|
6
|
-
module Client
|
|
7
|
-
# API client for handling file lists
|
|
8
|
-
class FileListClient < RestClient
|
|
9
|
-
# Returns a pagination json of files stored in project
|
|
10
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/filesList
|
|
11
|
-
#
|
|
12
|
-
# valid options:
|
|
13
|
-
# removed: [true|false]
|
|
14
|
-
# stored: [true|false]
|
|
15
|
-
# limit: (1..1000)
|
|
16
|
-
# ordering: ["datetime_uploaded"|"-datetime_uploaded"]
|
|
17
|
-
# from: number of files skipped
|
|
18
|
-
def file_list(options = {})
|
|
19
|
-
query = options.empty? ? '' : "?#{URI.encode_www_form(options)}"
|
|
20
|
-
get(uri: "/files/#{query}")
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Make a set of files "stored". This will prevent them from being deleted automatically
|
|
24
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/filesStoring
|
|
25
|
-
# uuids: Array
|
|
26
|
-
def batch_store(uuids)
|
|
27
|
-
body = uuids.to_json
|
|
28
|
-
put(uri: '/files/storage/', content: body)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
alias request_delete delete
|
|
32
|
-
|
|
33
|
-
# Delete several files by list of uids
|
|
34
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/filesDelete
|
|
35
|
-
# uuids: Array
|
|
36
|
-
def batch_delete(uuids)
|
|
37
|
-
body = uuids.to_json
|
|
38
|
-
request_delete(uri: '/files/storage/', content: body)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
alias store_files batch_store
|
|
42
|
-
alias delete_files batch_delete
|
|
43
|
-
alias list file_list
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'rest_client'
|
|
4
|
-
|
|
5
|
-
module Uploadcare
|
|
6
|
-
module Client
|
|
7
|
-
# API client for handling single metadata_files
|
|
8
|
-
# @see https://uploadcare.com/docs/file-metadata/
|
|
9
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/File-metadata
|
|
10
|
-
class FileMetadataClient < RestClient
|
|
11
|
-
# Get file's metadata keys and values
|
|
12
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/fileMetadata
|
|
13
|
-
def index(uuid)
|
|
14
|
-
get(uri: "/files/#{uuid}/metadata/")
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Get the value of a single metadata key.
|
|
18
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/fileMetadataKey
|
|
19
|
-
def show(uuid, key)
|
|
20
|
-
get(uri: "/files/#{uuid}/metadata/#{key}/")
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Update the value of a single metadata key. If the key does not exist, it will be created.
|
|
24
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/updateFileMetadataKey
|
|
25
|
-
def update(uuid, key, value)
|
|
26
|
-
put(uri: "/files/#{uuid}/metadata/#{key}/", content: value.to_json)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Delete a file's metadata key.
|
|
30
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/deleteFileMetadataKey
|
|
31
|
-
def delete(uuid, key)
|
|
32
|
-
request(method: 'DELETE', uri: "/files/#{uuid}/metadata/#{key}/")
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'upload_client'
|
|
4
|
-
|
|
5
|
-
module Uploadcare
|
|
6
|
-
module Client
|
|
7
|
-
# Groups serve a purpose of better organizing files in your Uploadcare projects.
|
|
8
|
-
# You can create one from a set of files by using their UUIDs.
|
|
9
|
-
# @see https://uploadcare.com/docs/api_reference/upload/groups/
|
|
10
|
-
class GroupClient < UploadClient
|
|
11
|
-
# Create files group from a set of files by using their UUIDs.
|
|
12
|
-
# @see https://uploadcare.com/api-refs/upload-api/#operation/createFilesGroup
|
|
13
|
-
def create(file_list, options = {})
|
|
14
|
-
body_hash = group_body_hash(file_list, options)
|
|
15
|
-
body = HTTP::FormData::Multipart.new(body_hash)
|
|
16
|
-
post(path: 'group/',
|
|
17
|
-
headers: { 'Content-Type': body.content_type },
|
|
18
|
-
body: body)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Get group info
|
|
22
|
-
# @see https://uploadcare.com/api-refs/upload-api/#operation/filesGroupInfo
|
|
23
|
-
def info(group_id)
|
|
24
|
-
get(path: 'group/info/', params: { pub_key: Uploadcare.config.public_key, group_id: group_id })
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
def file_params(file_ids)
|
|
30
|
-
ids = (0...file_ids.size).map { |i| "files[#{i}]" }
|
|
31
|
-
ids.zip(file_ids).to_h
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def group_body_hash(file_list, options = {})
|
|
35
|
-
{ pub_key: Uploadcare.config.public_key }.merge(file_params(parse_file_list(file_list))).merge(options)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# API accepts only list of ids, but some users may want to upload list of files
|
|
39
|
-
# @return [Array] of [String]
|
|
40
|
-
def parse_file_list(file_list)
|
|
41
|
-
file_list.map { |file| file.methods.include?(:uuid) ? file.uuid : file }
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'parallel'
|
|
4
|
-
require 'dry/monads'
|
|
5
|
-
require 'api_struct'
|
|
6
|
-
|
|
7
|
-
module Uploadcare
|
|
8
|
-
module Client
|
|
9
|
-
module MultipartUpload
|
|
10
|
-
# This class splits file into chunks of set chunk_size
|
|
11
|
-
# and uploads them into cloud storage.
|
|
12
|
-
# Used for multipart uploads
|
|
13
|
-
# @see https://uploadcare.com/api-refs/upload-api/#tag/Upload/paths/https:~1~1uploadcare.s3-accelerate.amazonaws.com~1%3C%3Cpresigned-url%3E/put
|
|
14
|
-
class ChunksClient < ApiStruct::Client
|
|
15
|
-
CHUNK_SIZE = 5_242_880
|
|
16
|
-
|
|
17
|
-
# In multiple threads, split file into chunks and upload those chunks into respective Amazon links
|
|
18
|
-
# @param object [File]
|
|
19
|
-
# @param links [Array] of strings; by default list of Amazon storage urls
|
|
20
|
-
def self.upload_chunks(object, links)
|
|
21
|
-
Parallel.each(0...links.count, in_threads: Uploadcare.config.upload_threads) do |link_id|
|
|
22
|
-
offset = link_id * CHUNK_SIZE
|
|
23
|
-
chunk = File.read(object, CHUNK_SIZE, offset)
|
|
24
|
-
new.upload_chunk(chunk, links[link_id])
|
|
25
|
-
next unless block_given?
|
|
26
|
-
|
|
27
|
-
yield(
|
|
28
|
-
chunk_size: CHUNK_SIZE,
|
|
29
|
-
object: object,
|
|
30
|
-
offset: offset,
|
|
31
|
-
link_id: link_id,
|
|
32
|
-
links: links,
|
|
33
|
-
links_count: links.count
|
|
34
|
-
)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def api_root
|
|
39
|
-
''
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def headers
|
|
43
|
-
{}
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def upload_chunk(chunk, link)
|
|
47
|
-
put(path: link, body: chunk, headers: { 'Content-Type': 'application/octet-stream' })
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
private
|
|
51
|
-
|
|
52
|
-
def default_params
|
|
53
|
-
{}
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
@@ -1,64 +0,0 @@
|
|
|
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, options = {}, &block)
|
|
17
|
-
response = upload_start(object, options)
|
|
18
|
-
return response unless response.success[:parts] && response.success[:uuid]
|
|
19
|
-
|
|
20
|
-
links = response.success[:parts]
|
|
21
|
-
uuid = response.success[:uuid]
|
|
22
|
-
ChunksClient.upload_chunks(object, links, &block)
|
|
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, options = {})
|
|
28
|
-
body = HTTP::FormData::Multipart.new(
|
|
29
|
-
Param::Upload::UploadParamsGenerator.call(options).merge(form_data_for(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 form_data_for(file)
|
|
50
|
-
form_data_file = super
|
|
51
|
-
{
|
|
52
|
-
filename: form_data_file.filename,
|
|
53
|
-
size: form_data_file.size,
|
|
54
|
-
content_type: form_data_file.content_type
|
|
55
|
-
}
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
alias api_struct_post post
|
|
59
|
-
def post(**args)
|
|
60
|
-
handle_throttling { api_struct_post(**args) }
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'rest_client'
|
|
4
|
-
|
|
5
|
-
module Uploadcare
|
|
6
|
-
module Client
|
|
7
|
-
# API client for getting project info
|
|
8
|
-
# @see https://uploadcare.com/docs/api_reference/rest/handling_projects/
|
|
9
|
-
class ProjectClient < RestClient
|
|
10
|
-
# get information about current project
|
|
11
|
-
# current project is determined by public and secret key combination
|
|
12
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Project
|
|
13
|
-
def show
|
|
14
|
-
get(uri: '/project/')
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
alias project show
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'dry/monads'
|
|
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}",
|
|
31
|
-
path: remove_trailing_slash(uri),
|
|
32
|
-
headers: request_headers,
|
|
33
|
-
body: options[:content],
|
|
34
|
-
params: options[:params])
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def get(options = {})
|
|
39
|
-
request(method: 'GET', **options)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def post(options = {})
|
|
43
|
-
request(method: 'POST', **options)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def put(options = {})
|
|
47
|
-
request(method: 'PUT', **options)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def delete(options = {})
|
|
51
|
-
request(method: 'DELETE', **options)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def api_root
|
|
55
|
-
Uploadcare.config.rest_api_root
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def headers
|
|
59
|
-
{
|
|
60
|
-
'Content-Type': 'application/json',
|
|
61
|
-
Accept: 'application/vnd.uploadcare-v0.7+json',
|
|
62
|
-
'User-Agent': Uploadcare::Param::UserAgent.call
|
|
63
|
-
}
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
private
|
|
67
|
-
|
|
68
|
-
def remove_trailing_slash(str)
|
|
69
|
-
str.gsub(%r{^/}, '')
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def default_params
|
|
73
|
-
{}
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
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.7.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.7.0/#operation/storeFile
|
|
11
|
-
def store(uuid)
|
|
12
|
-
files = info(uuid).success[:files].compact
|
|
13
|
-
client = ::Uploadcare::Client::FileClient.new
|
|
14
|
-
files.each_slice(Uploadcare.config.file_chunk_size) do |file_chunk|
|
|
15
|
-
file_chunk.each do |file|
|
|
16
|
-
client.store(file[:uuid])
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
Dry::Monads::Result::Success.call(nil)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Get a file group by its ID.
|
|
24
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/groupInfo
|
|
25
|
-
def info(uuid)
|
|
26
|
-
get(uri: "/groups/#{uuid}/")
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# return paginated list of groups
|
|
30
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/groupsList
|
|
31
|
-
def list(options = {})
|
|
32
|
-
query = options.empty? ? '' : "?#{URI.encode_www_form(options)}"
|
|
33
|
-
get(uri: "/groups/#{query}")
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Delete a file group by its ID.
|
|
37
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/deleteGroup
|
|
38
|
-
def delete(uuid)
|
|
39
|
-
request(method: 'DELETE', uri: "/groups/#{uuid}/")
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'dry/monads'
|
|
4
|
-
require 'api_struct'
|
|
5
|
-
require 'param/user_agent'
|
|
6
|
-
require 'uploadcare/concern/error_handler'
|
|
7
|
-
require 'uploadcare/concern/throttle_handler'
|
|
8
|
-
require 'mimemagic'
|
|
9
|
-
|
|
10
|
-
module Uploadcare
|
|
11
|
-
module Client
|
|
12
|
-
# @abstract
|
|
13
|
-
#
|
|
14
|
-
# Headers and helper methods for clients working with upload API
|
|
15
|
-
# @see https://uploadcare.com/docs/api_reference/upload/
|
|
16
|
-
class UploadClient < ApiStruct::Client
|
|
17
|
-
include Concerns::ErrorHandler
|
|
18
|
-
include Concerns::ThrottleHandler
|
|
19
|
-
include Exception
|
|
20
|
-
|
|
21
|
-
def api_root
|
|
22
|
-
Uploadcare.config.upload_api_root
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def headers
|
|
26
|
-
{
|
|
27
|
-
'User-Agent': Uploadcare::Param::UserAgent.call
|
|
28
|
-
}
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private
|
|
32
|
-
|
|
33
|
-
def form_data_for(file)
|
|
34
|
-
filename = file.original_filename if file.respond_to?(:original_filename)
|
|
35
|
-
mime_type = MimeMagic.by_magic(file)&.type
|
|
36
|
-
mime_type = file.content_type if mime_type.nil? && file.respond_to?(:content_type)
|
|
37
|
-
options = { filename: filename, content_type: mime_type }.compact
|
|
38
|
-
HTTP::FormData::File.new(file, options)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def default_params
|
|
42
|
-
{}
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'upload_client'
|
|
4
|
-
require 'retries'
|
|
5
|
-
require 'param/upload/upload_params_generator'
|
|
6
|
-
require 'param/upload/signature_generator'
|
|
7
|
-
|
|
8
|
-
module Uploadcare
|
|
9
|
-
module Client
|
|
10
|
-
# This is client for general uploads
|
|
11
|
-
#
|
|
12
|
-
# @see https://uploadcare.com/api-refs/upload-api/#tag/Upload
|
|
13
|
-
class UploaderClient < UploadClient
|
|
14
|
-
# @see https://uploadcare.com/api-refs/upload-api/#operation/baseUpload
|
|
15
|
-
|
|
16
|
-
def upload_many(arr, options = {})
|
|
17
|
-
body = upload_many_body(arr, options)
|
|
18
|
-
post(path: 'base/',
|
|
19
|
-
headers: { 'Content-Type': body.content_type },
|
|
20
|
-
body: body)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# syntactic sugar for upload_many
|
|
24
|
-
# There is actual upload method for one file, but it is redundant
|
|
25
|
-
|
|
26
|
-
def upload(file, options = {})
|
|
27
|
-
upload_many([file], options)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Upload files from url
|
|
31
|
-
# @see https://uploadcare.com/api-refs/upload-api/#operation/fromURLUpload
|
|
32
|
-
# options:
|
|
33
|
-
# - check_URL_duplicates
|
|
34
|
-
# - filename
|
|
35
|
-
# - save_URL_duplicates
|
|
36
|
-
# - async - returns upload token instead of upload data
|
|
37
|
-
# - metadata - file metadata, hash
|
|
38
|
-
def upload_from_url(url, options = {})
|
|
39
|
-
body = upload_from_url_body(url, options)
|
|
40
|
-
token_response = post(path: 'from_url/', headers: { 'Content-Type': body.content_type }, body: body)
|
|
41
|
-
return token_response if options[:async]
|
|
42
|
-
|
|
43
|
-
uploaded_response = poll_upload_response(token_response.success[:token])
|
|
44
|
-
return uploaded_response if uploaded_response.success[:status] == 'error'
|
|
45
|
-
|
|
46
|
-
Dry::Monads::Result::Success.call(files: [uploaded_response.success])
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Check upload status
|
|
50
|
-
#
|
|
51
|
-
# @see https://uploadcare.com/api-refs/upload-api/#operation/fromURLUploadStatus
|
|
52
|
-
def get_upload_from_url_status(token)
|
|
53
|
-
query_params = { token: token }
|
|
54
|
-
get(path: 'from_url/status/', params: query_params)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Get information about an uploaded file
|
|
58
|
-
# Secret key not needed
|
|
59
|
-
#
|
|
60
|
-
# https://uploadcare.com/api-refs/upload-api/#tag/Upload/operation/fileUploadInfo
|
|
61
|
-
def file_info(uuid)
|
|
62
|
-
query_params = {
|
|
63
|
-
file_id: uuid,
|
|
64
|
-
pub_key: Uploadcare.config.public_key
|
|
65
|
-
}
|
|
66
|
-
get(path: 'info/', params: query_params)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
alias api_struct_post post
|
|
72
|
-
def post(args = {})
|
|
73
|
-
handle_throttling { api_struct_post(**args) }
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def poll_upload_response(token)
|
|
77
|
-
with_retries(max_tries: Uploadcare.config.max_request_tries,
|
|
78
|
-
base_sleep_seconds: Uploadcare.config.base_request_sleep,
|
|
79
|
-
max_sleep_seconds: Uploadcare.config.max_request_sleep,
|
|
80
|
-
rescue: RetryError) do
|
|
81
|
-
response = get_upload_from_url_status(token)
|
|
82
|
-
handle_polling_response(response)
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def handle_polling_response(response)
|
|
87
|
-
case response.success[:status]
|
|
88
|
-
when 'error'
|
|
89
|
-
raise RequestError, response.success[:error]
|
|
90
|
-
when 'progress', 'waiting', 'unknown'
|
|
91
|
-
raise RetryError, response.success[:error] || 'Upload is taking longer than expected. Try increasing the max_request_tries config if you know your file uploads will take more time.' # rubocop:disable Layout/LineLength
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
response
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Prepares body for upload_many method
|
|
98
|
-
def upload_many_body(arr, options = {})
|
|
99
|
-
files_formdata = arr.to_h do |file|
|
|
100
|
-
[HTTP::FormData::File.new(file).filename,
|
|
101
|
-
form_data_for(file)]
|
|
102
|
-
end
|
|
103
|
-
HTTP::FormData::Multipart.new(
|
|
104
|
-
Param::Upload::UploadParamsGenerator.call(options).merge(files_formdata)
|
|
105
|
-
)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# Prepare upload_from_url initial request body
|
|
109
|
-
def upload_from_url_body(url, options = {})
|
|
110
|
-
opts = {
|
|
111
|
-
'pub_key' => Uploadcare.config.public_key,
|
|
112
|
-
'source_url' => url,
|
|
113
|
-
'store' => store_value(options[:store])
|
|
114
|
-
}
|
|
115
|
-
opts.merge!(Param::Upload::SignatureGenerator.call) if Uploadcare.config.sign_uploads
|
|
116
|
-
HTTP::FormData::Multipart.new(options.merge(opts))
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def store_value(store)
|
|
120
|
-
case store
|
|
121
|
-
when true, '1', 1 then '1'
|
|
122
|
-
when false, '0', 0 then '0'
|
|
123
|
-
else 'auto'
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|