uploadcare-ruby 2.1.1 → 3.1.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/gem-push.yml +20 -0
  3. data/.github/workflows/ruby.yml +52 -0
  4. data/.gitignore +13 -6
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +32 -0
  7. data/.yardopts +4 -0
  8. data/CHANGELOG.md +33 -34
  9. data/DEVELOPMENT.md +18 -0
  10. data/Gemfile +2 -0
  11. data/LICENSE +1 -1
  12. data/README.md +369 -546
  13. data/Rakefile +5 -5
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/lib/uploadcare.rb +36 -26
  17. data/lib/uploadcare/api/api.rb +25 -0
  18. data/lib/uploadcare/client/conversion/base_conversion_client.rb +54 -0
  19. data/lib/uploadcare/client/conversion/document_conversion_client.rb +38 -0
  20. data/lib/uploadcare/client/conversion/video_conversion_client.rb +42 -0
  21. data/lib/uploadcare/client/file_client.rb +44 -0
  22. data/lib/uploadcare/client/file_list_client.rb +46 -0
  23. data/lib/uploadcare/client/group_client.rb +45 -0
  24. data/lib/uploadcare/client/multipart_upload/chunks_client.rb +48 -0
  25. data/lib/uploadcare/client/multipart_upload_client.rb +67 -0
  26. data/lib/uploadcare/client/project_client.rb +18 -0
  27. data/lib/uploadcare/client/rest_client.rb +74 -0
  28. data/lib/uploadcare/client/rest_group_client.rb +23 -0
  29. data/lib/uploadcare/client/upload_client.rb +36 -0
  30. data/lib/uploadcare/client/uploader_client.rb +109 -0
  31. data/lib/uploadcare/client/webhook_client.rb +47 -0
  32. data/lib/uploadcare/concern/error_handler.rb +54 -0
  33. data/lib/uploadcare/concern/throttle_handler.rb +25 -0
  34. data/lib/uploadcare/concern/upload_error_handler.rb +32 -0
  35. data/lib/uploadcare/entity/decorator/paginator.rb +79 -0
  36. data/lib/uploadcare/entity/document_converter.rb +26 -0
  37. data/lib/uploadcare/entity/entity.rb +18 -0
  38. data/lib/uploadcare/entity/file.rb +81 -0
  39. data/lib/uploadcare/entity/file_list.rb +31 -0
  40. data/lib/uploadcare/entity/group.rb +40 -0
  41. data/lib/uploadcare/entity/group_list.rb +24 -0
  42. data/lib/uploadcare/entity/project.rb +13 -0
  43. data/lib/uploadcare/entity/uploader.rb +75 -0
  44. data/lib/uploadcare/entity/video_converter.rb +26 -0
  45. data/lib/uploadcare/entity/webhook.rb +14 -0
  46. data/lib/uploadcare/exception/conversion_error.rb +8 -0
  47. data/lib/uploadcare/exception/request_error.rb +9 -0
  48. data/lib/uploadcare/exception/throttle_error.rb +16 -0
  49. data/lib/uploadcare/param/authentication_header.rb +25 -0
  50. data/lib/uploadcare/param/conversion/document/processing_job_url_builder.rb +39 -0
  51. data/lib/uploadcare/param/conversion/video/processing_job_url_builder.rb +64 -0
  52. data/lib/uploadcare/param/param.rb +10 -0
  53. data/lib/uploadcare/param/secure_auth_header.rb +37 -0
  54. data/lib/uploadcare/param/simple_auth_header.rb +14 -0
  55. data/lib/uploadcare/param/upload/signature_generator.rb +24 -0
  56. data/lib/uploadcare/param/upload/upload_params_generator.rb +23 -0
  57. data/lib/uploadcare/param/user_agent.rb +21 -0
  58. data/lib/uploadcare/ruby/version.rb +5 -0
  59. data/uploadcare-ruby.gemspec +50 -37
  60. metadata +109 -115
  61. data/.travis.yml +0 -26
  62. data/UPGRADE_NOTES.md +0 -36
  63. data/lib/uploadcare/api.rb +0 -26
  64. data/lib/uploadcare/api/file_api.rb +0 -7
  65. data/lib/uploadcare/api/file_list_api.rb +0 -19
  66. data/lib/uploadcare/api/file_storage_api.rb +0 -34
  67. data/lib/uploadcare/api/group_api.rb +0 -38
  68. data/lib/uploadcare/api/group_list_api.rb +0 -17
  69. data/lib/uploadcare/api/project_api.rb +0 -9
  70. data/lib/uploadcare/api/raw_api.rb +0 -38
  71. data/lib/uploadcare/api/uploading_api.rb +0 -71
  72. data/lib/uploadcare/api/uploading_api/upload_params.rb +0 -72
  73. data/lib/uploadcare/api/validators/file_list_options_validator.rb +0 -73
  74. data/lib/uploadcare/api/validators/group_list_options_validator.rb +0 -49
  75. data/lib/uploadcare/errors/errors.rb +0 -64
  76. data/lib/uploadcare/resources/file.rb +0 -164
  77. data/lib/uploadcare/resources/file_list.rb +0 -14
  78. data/lib/uploadcare/resources/group.rb +0 -115
  79. data/lib/uploadcare/resources/group_list.rb +0 -14
  80. data/lib/uploadcare/resources/project.rb +0 -13
  81. data/lib/uploadcare/resources/resource_list.rb +0 -83
  82. data/lib/uploadcare/rest/auth/auth.rb +0 -31
  83. data/lib/uploadcare/rest/auth/secure.rb +0 -43
  84. data/lib/uploadcare/rest/auth/simple.rb +0 -16
  85. data/lib/uploadcare/rest/connections/api_connection.rb +0 -53
  86. data/lib/uploadcare/rest/connections/upload_connection.rb +0 -22
  87. data/lib/uploadcare/rest/middlewares/auth_middleware.rb +0 -24
  88. data/lib/uploadcare/rest/middlewares/parse_json_middleware.rb +0 -33
  89. data/lib/uploadcare/rest/middlewares/raise_error_middleware.rb +0 -21
  90. data/lib/uploadcare/utils/parser.rb +0 -71
  91. data/lib/uploadcare/utils/user_agent.rb +0 -44
  92. data/lib/uploadcare/version.rb +0 -3
  93. data/spec/api/file_list_api_spec.rb +0 -95
  94. data/spec/api/file_storage_api_spec.rb +0 -88
  95. data/spec/api/group_list_api_spec.rb +0 -59
  96. data/spec/api/raw_api_spec.rb +0 -25
  97. data/spec/api/uploading_api/upload_params_spec.rb +0 -99
  98. data/spec/api/uploading_api_spec.rb +0 -59
  99. data/spec/resources/file_list_spec.rb +0 -25
  100. data/spec/resources/file_spec.rb +0 -223
  101. data/spec/resources/group_list_spec.rb +0 -25
  102. data/spec/resources/group_spec.rb +0 -101
  103. data/spec/resources/operations_spec.rb +0 -59
  104. data/spec/resources/project_spec.rb +0 -21
  105. data/spec/rest/api_connection_spec.rb +0 -68
  106. data/spec/rest/auth/secure_spec.rb +0 -66
  107. data/spec/rest/auth/simple_spec.rb +0 -31
  108. data/spec/rest/errors_spec.rb +0 -75
  109. data/spec/rest/upload_connection_spec.rb +0 -19
  110. data/spec/shared/resource_list.rb +0 -188
  111. data/spec/spec_helper.rb +0 -54
  112. data/spec/uploadcare_spec.rb +0 -16
  113. data/spec/utils/parser_spec.rb +0 -85
  114. data/spec/utils/user_agent_spec.rb +0 -46
  115. data/spec/view.png +0 -0
  116. data/spec/view2.jpg +0 -0
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env rake
1
+ # frozen_string_literal: true
2
+
2
3
  require 'bundler/gem_tasks'
3
4
  require 'rspec/core/rake_task'
4
- require 'coveralls/rake/task'
5
5
 
6
- task :default => :spec
7
- RSpec::Core::RakeTask.new
8
- Coveralls::RakeTask.new
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'uploadcare/ruby'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/uploadcare.rb CHANGED
@@ -1,32 +1,42 @@
1
- require 'faraday'
2
- require 'json'
3
- require 'ostruct'
1
+ # frozen_string_literal: true
4
2
 
5
- require_relative 'uploadcare/api'
6
- require_relative 'uploadcare/version'
3
+ # Gem version
4
+ require 'ruby/version'
7
5
 
8
- module Uploadcare
9
- DEFAULT_SETTINGS = {
10
- public_key: 'demopublickey',
11
- private_key: 'demoprivatekey',
12
- upload_url_base: 'https://upload.uploadcare.com',
13
- api_url_base: 'https://api.uploadcare.com',
14
- static_url_base: 'https://ucarecdn.com',
15
- api_version: '0.5',
16
- cache_files: true,
17
- autostore: :auto,
18
- auth_scheme: :secure,
19
- }
6
+ # Exceptions
7
+ require 'exception/throttle_error'
8
+ require 'exception/request_error'
20
9
 
21
- warn '[DEPRECATION] `Uploadcare::USER_AGENT` constant is deprecated and will be removed in version 3.0'
22
- USER_AGENT = "uploadcare-ruby/#{Gem.ruby_version}/#{Uploadcare::VERSION}"
10
+ # Entities
11
+ require 'entity/entity'
12
+ require 'entity/file'
13
+ require 'entity/file_list'
14
+ require 'entity/group'
15
+ require 'entity/group_list'
16
+ require 'entity/project'
17
+ require 'entity/uploader'
18
+ require 'entity/webhook'
23
19
 
24
- def self.default_settings
25
- DEFAULT_SETTINGS
26
- end
20
+ # General api
21
+ require 'api/api'
27
22
 
28
- def self.user_agent(options={})
29
- warn '[DEPRECATION] `Uploadcare::user_agent` method is deprecated and will be removed in version 3.0'
30
- UserAgent.new.call(options)
31
- end
23
+ # Ruby wrapper for Uploadcare API
24
+ #
25
+ # @see https://uploadcare.com/docs/api_reference
26
+ module Uploadcare
27
+ extend Dry::Configurable
28
+ setting :public_key, ENV.fetch('UPLOADCARE_PUBLIC_KEY')
29
+ setting :secret_key, ENV.fetch('UPLOADCARE_SECRET_KEY')
30
+ setting :auth_type, 'Uploadcare'
31
+ setting :multipart_size_threshold, 100 * 1024 * 1024
32
+ setting :rest_api_root, 'https://api.uploadcare.com'
33
+ setting :upload_api_root, 'https://upload.uploadcare.com'
34
+ setting :max_request_tries, 100
35
+ setting :base_request_sleep, 1 # seconds
36
+ setting :max_request_sleep, 60.0 # seconds
37
+ setting :sign_uploads, false
38
+ setting :upload_signature_lifetime, 30 * 60 # seconds
39
+ setting :max_throttle_attempts, 5
40
+ setting :upload_threads, 2 # used for multiupload only ATM
41
+ setting :framework_data, ''
32
42
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem.find_files('client/**/*.rb').each { |path| require path }
4
+ Gem.find_files('entity/**/*.rb').each { |path| require path }
5
+
6
+ module Uploadcare
7
+ # End-user interface
8
+ #
9
+ # It delegates methods to other classes:
10
+ # * To class methods of Entity objects
11
+ # * To instance methods of Client objects
12
+ # @see Uploadcare::Entity
13
+ # @see Uploadcare::Client
14
+ class Api
15
+ extend Forwardable
16
+ include Entity
17
+
18
+ def_delegator File, :file
19
+ def_delegators FileList, :file_list, :store_files, :delete_files
20
+ def_delegators Group, :group
21
+ def_delegators Project, :project
22
+ def_delegators Uploader, :upload, :upload_files, :upload_url
23
+ def_delegators Webhook, :create_webhook, :list_webhooks, :delete_webhook, :update_webhook
24
+ end
25
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../rest_client'
4
+ require 'exception/conversion_error'
5
+
6
+ module Uploadcare
7
+ module Client
8
+ module Conversion
9
+ # This is a base client for conversion operations
10
+ #
11
+ # @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#tag/Conversion
12
+ class BaseConversionClient < RestClient
13
+ def headers
14
+ {
15
+ 'Content-type': 'application/json',
16
+ 'Accept': 'application/vnd.uploadcare-v0.6+json',
17
+ 'User-Agent': Uploadcare::Param::UserAgent.call
18
+ }
19
+ end
20
+
21
+ private
22
+
23
+ def success(response)
24
+ body = response.body.to_s
25
+ result = extract_result(body)
26
+
27
+ Dry::Monads::Success(result)
28
+ end
29
+
30
+ def extract_result(response_body)
31
+ return nil if response_body.nil? || response_body.empty?
32
+
33
+ parsed_body = JSON.parse(response_body, symbolize_names: true)
34
+ errors = parsed_body[:error] || parsed_body[:problems]
35
+ raise ConversionError, errors unless errors.nil? || errors.empty?
36
+
37
+ parsed_body
38
+ end
39
+
40
+ # Prepares body for convert_many method
41
+ def build_body_for_many(arr, options, url_builder_class)
42
+ {
43
+ "paths": arr.map do |params|
44
+ url_builder_class.call(
45
+ **build_paths_body(params)
46
+ )
47
+ end,
48
+ "store": options[:store]
49
+ }.compact.to_json
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'client/conversion/base_conversion_client'
4
+ require 'param/conversion/document/processing_job_url_builder'
5
+
6
+ module Uploadcare
7
+ module Client
8
+ module Conversion
9
+ # This is client for document conversion
10
+ #
11
+ # @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/documentConvert
12
+ class DocumentConversionClient < BaseConversionClient
13
+ def convert_many(
14
+ arr,
15
+ options = {},
16
+ url_builder_class = Uploadcare::Param::Conversion::Document::ProcessingJobUrlBuilder
17
+ )
18
+ body = build_body_for_many(arr, options, url_builder_class)
19
+ post(uri: '/convert/document/', content: body)
20
+ end
21
+
22
+ def get_conversion_status(token)
23
+ get(uri: "/convert/document/status/#{token}/")
24
+ end
25
+
26
+ private
27
+
28
+ def build_paths_body(params)
29
+ {
30
+ uuid: params[:uuid],
31
+ format: params[:format],
32
+ page: params[:page]
33
+ }.compact
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,42 @@
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.6.0/#operation/videoConvert
13
+ class VideoConversionClient < BaseConversionClient
14
+ def convert_many(
15
+ arr,
16
+ options = {},
17
+ url_builder_class = Uploadcare::Param::Conversion::Video::ProcessingJobUrlBuilder
18
+ )
19
+ body = build_body_for_many(arr, options, url_builder_class)
20
+ post(uri: '/convert/video/', content: body)
21
+ end
22
+
23
+ def get_conversion_status(token)
24
+ get(uri: "/convert/video/status/#{token}/")
25
+ end
26
+
27
+ private
28
+
29
+ def build_paths_body(params)
30
+ {
31
+ uuid: params[:uuid],
32
+ quality: params[:quality],
33
+ format: params[:format],
34
+ size: params[:size],
35
+ cut: params[:cut],
36
+ thumbs: params[:thumbs]
37
+ }.compact
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,44 @@
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.5.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.5.0/#operation/fileInfo
19
+ def info(uuid)
20
+ get(uri: "/files/#{uuid}/")
21
+ end
22
+ alias file info
23
+
24
+ # 'copy' method is used to copy original files or their modified versions to default storage.
25
+ # Source files MAY either be stored or just uploaded and MUST NOT be deleted.
26
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/copyFile
27
+ def copy(**options)
28
+ body = options.compact.to_json
29
+ post(uri: '/files/', content: body)
30
+ end
31
+
32
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/deleteFile
33
+ def delete(uuid)
34
+ request(method: 'DELETE', uri: "/files/#{uuid}/")
35
+ end
36
+
37
+ # Store a single file, preventing it from being deleted in 2 weeks
38
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/storeFile
39
+ def store(uuid)
40
+ put(uri: "/files/#{uuid}/storage/")
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,46 @@
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.5.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"|"size"|"-size"]
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.5.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.5.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
@@ -0,0 +1,45 @@
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
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parallel'
4
+ require 'api_struct'
5
+
6
+ module Uploadcare
7
+ module Client
8
+ module MultipartUpload
9
+ # This class splits file into chunks of set chunk_size
10
+ # and uploads them into cloud storage.
11
+ # Used for multipart uploads
12
+ # @see https://uploadcare.com/api-refs/upload-api/#tag/Upload/paths/https:~1~1uploadcare.s3-accelerate.amazonaws.com~1%3C%3Cpresigned-url%3E/put
13
+ class ChunksClient < ApiStruct::Client
14
+ CHUNK_SIZE = 5_242_880
15
+
16
+ # In multiple threads, split file into chunks and upload those chunks into respective Amazon links
17
+ # @param object [File]
18
+ # @param links [Array] of strings; by default list of Amazon storage urls
19
+ def upload_chunks(object, links)
20
+ Parallel.each(0...links.count, in_threads: Uploadcare.config.upload_threads) do |link_id|
21
+ client = self.class.new
22
+ offset = link_id * CHUNK_SIZE
23
+ chunk = IO.read(object, CHUNK_SIZE, offset)
24
+ client.send(:upload_chunk, chunk, links[link_id])
25
+ end
26
+ end
27
+
28
+ def api_root
29
+ ''
30
+ end
31
+
32
+ def headers
33
+ {}
34
+ end
35
+
36
+ private
37
+
38
+ def upload_chunk(chunk, link)
39
+ put(path: link, body: chunk, headers: { 'Content-type': 'application/octet-stream' })
40
+ end
41
+
42
+ def default_params
43
+ {}
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end