uploadcare-ruby 2.1.2 → 3.1.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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  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 +33 -0
  7. data/.yardopts +4 -0
  8. data/CHANGELOG.md +29 -47
  9. data/DEVELOPMENT.md +18 -0
  10. data/Gemfile +2 -0
  11. data/LICENSE +1 -1
  12. data/README.md +433 -527
  13. data/Rakefile +5 -5
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/lib/uploadcare/api/api.rb +25 -0
  17. data/lib/uploadcare/client/conversion/base_conversion_client.rb +59 -0
  18. data/lib/uploadcare/client/conversion/document_conversion_client.rb +41 -0
  19. data/lib/uploadcare/client/conversion/video_conversion_client.rb +46 -0
  20. data/lib/uploadcare/client/file_client.rb +44 -0
  21. data/lib/uploadcare/client/file_list_client.rb +46 -0
  22. data/lib/uploadcare/client/group_client.rb +45 -0
  23. data/lib/uploadcare/client/multipart_upload/chunks_client.rb +57 -0
  24. data/lib/uploadcare/client/multipart_upload_client.rb +64 -0
  25. data/lib/uploadcare/client/project_client.rb +18 -0
  26. data/lib/uploadcare/client/rest_client.rb +74 -0
  27. data/lib/uploadcare/client/rest_group_client.rb +23 -0
  28. data/lib/uploadcare/client/upload_client.rb +43 -0
  29. data/lib/uploadcare/client/uploader_client.rb +101 -0
  30. data/lib/uploadcare/client/webhook_client.rb +47 -0
  31. data/lib/uploadcare/concern/error_handler.rb +54 -0
  32. data/lib/uploadcare/concern/throttle_handler.rb +25 -0
  33. data/lib/uploadcare/concern/upload_error_handler.rb +32 -0
  34. data/lib/uploadcare/entity/conversion/base_converter.rb +36 -0
  35. data/lib/uploadcare/entity/conversion/document_converter.rb +15 -0
  36. data/lib/uploadcare/entity/conversion/video_converter.rb +15 -0
  37. data/lib/uploadcare/entity/decorator/paginator.rb +79 -0
  38. data/lib/uploadcare/entity/entity.rb +18 -0
  39. data/lib/uploadcare/entity/file.rb +106 -0
  40. data/lib/uploadcare/entity/file_list.rb +31 -0
  41. data/lib/uploadcare/entity/group.rb +40 -0
  42. data/lib/uploadcare/entity/group_list.rb +24 -0
  43. data/lib/uploadcare/entity/project.rb +13 -0
  44. data/lib/uploadcare/entity/uploader.rb +81 -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/lib/uploadcare.rb +36 -32
  60. data/uploadcare-ruby.gemspec +50 -37
  61. metadata +107 -113
  62. data/.travis.yml +0 -26
  63. data/UPGRADE_NOTES.md +0 -36
  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/upload_params.rb +0 -72
  72. data/lib/uploadcare/api/uploading_api.rb +0 -71
  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/api.rb +0 -26
  76. data/lib/uploadcare/errors/errors.rb +0 -64
  77. data/lib/uploadcare/resources/file.rb +0 -164
  78. data/lib/uploadcare/resources/file_list.rb +0 -14
  79. data/lib/uploadcare/resources/group.rb +0 -115
  80. data/lib/uploadcare/resources/group_list.rb +0 -14
  81. data/lib/uploadcare/resources/project.rb +0 -13
  82. data/lib/uploadcare/resources/resource_list.rb +0 -83
  83. data/lib/uploadcare/rest/auth/auth.rb +0 -31
  84. data/lib/uploadcare/rest/auth/secure.rb +0 -43
  85. data/lib/uploadcare/rest/auth/simple.rb +0 -16
  86. data/lib/uploadcare/rest/connections/api_connection.rb +0 -53
  87. data/lib/uploadcare/rest/connections/upload_connection.rb +0 -22
  88. data/lib/uploadcare/rest/middlewares/auth_middleware.rb +0 -24
  89. data/lib/uploadcare/rest/middlewares/parse_json_middleware.rb +0 -33
  90. data/lib/uploadcare/rest/middlewares/raise_error_middleware.rb +0 -21
  91. data/lib/uploadcare/utils/parser.rb +0 -71
  92. data/lib/uploadcare/utils/user_agent.rb +0 -44
  93. data/lib/uploadcare/version.rb +0 -3
  94. data/spec/api/file_list_api_spec.rb +0 -95
  95. data/spec/api/file_storage_api_spec.rb +0 -88
  96. data/spec/api/group_list_api_spec.rb +0 -59
  97. data/spec/api/raw_api_spec.rb +0 -25
  98. data/spec/api/uploading_api/upload_params_spec.rb +0 -99
  99. data/spec/api/uploading_api_spec.rb +0 -59
  100. data/spec/resources/file_list_spec.rb +0 -25
  101. data/spec/resources/file_spec.rb +0 -223
  102. data/spec/resources/group_list_spec.rb +0 -25
  103. data/spec/resources/group_spec.rb +0 -101
  104. data/spec/resources/operations_spec.rb +0 -59
  105. data/spec/resources/project_spec.rb +0 -21
  106. data/spec/rest/api_connection_spec.rb +0 -68
  107. data/spec/rest/auth/secure_spec.rb +0 -66
  108. data/spec/rest/auth/simple_spec.rb +0 -31
  109. data/spec/rest/errors_spec.rb +0 -75
  110. data/spec/rest/upload_connection_spec.rb +0 -19
  111. data/spec/shared/resource_list.rb +0 -188
  112. data/spec/spec_helper.rb +0 -54
  113. data/spec/uploadcare_spec.rb +0 -43
  114. data/spec/utils/parser_spec.rb +0 -85
  115. data/spec/utils/user_agent_spec.rb +0 -46
  116. data/spec/view.png +0 -0
  117. data/spec/view2.jpg +0 -0
@@ -0,0 +1,101 @@
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
+ # Check upload status
48
+ #
49
+ # @see https://uploadcare.com/api-refs/upload-api/#operation/fromURLUploadStatus
50
+ def get_upload_from_url_status(token)
51
+ query_params = { token: token }
52
+ get(path: 'from_url/status/', params: query_params)
53
+ end
54
+
55
+ private
56
+
57
+ alias api_struct_post post
58
+ def post(**args)
59
+ handle_throttling { api_struct_post(**args) }
60
+ end
61
+
62
+ def poll_upload_response(token)
63
+ with_retries(max_tries: Uploadcare.config.max_request_tries,
64
+ base_sleep_seconds: Uploadcare.config.base_request_sleep,
65
+ max_sleep_seconds: Uploadcare.config.max_request_sleep) do
66
+ response = get_upload_from_url_status(token)
67
+ raise RequestError if %w[progress waiting unknown].include?(response.success[:status])
68
+
69
+ response
70
+ end
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
+ HTTP::FormData::Multipart.new(
80
+ Param::Upload::UploadParamsGenerator.call(options[:store]).merge(files_formdata)
81
+ )
82
+ end
83
+
84
+ STORE_VALUES_MAP = {
85
+ true => '1',
86
+ false => '0'
87
+ }.freeze
88
+
89
+ # Prepare upload_from_url initial request body
90
+ def upload_from_url_body(url, **options)
91
+ HTTP::FormData::Multipart.new(
92
+ options.merge(
93
+ 'pub_key' => Uploadcare.config.public_key,
94
+ 'source_url' => url,
95
+ 'store' => STORE_VALUES_MAP[options[:store]]
96
+ )
97
+ )
98
+ end
99
+ end
100
+ end
101
+ 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].nil? ? true : options[:is_active]
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
@@ -0,0 +1,32 @@
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 UploadErrorHandler
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_throttling_error(response)
16
+ parsed_response = JSON.parse(response.body.to_s)
17
+ raise RequestError, parsed_response['detail']
18
+ rescue JSON::ParserError
19
+ raise RequestError, response.status
20
+ end
21
+
22
+ private
23
+
24
+ def catch_throttling_error(response)
25
+ return unless response.code == 429
26
+
27
+ retry_after = response.headers['Retry-After'].to_i + 1 || 11
28
+ raise ThrottleError.new(retry_after), "Response throttled, retry #{retry_after} seconds later"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uploadcare
4
+ module Entity
5
+ module Conversion
6
+ # This serializer lets a user convert uploaded documents
7
+ # @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/documentConvert
8
+ class BaseConverter < Entity
9
+ class << self
10
+ # Converts files
11
+ #
12
+ # @param doc_params [Array] of hashes with params or [Hash]
13
+ # @option options [Boolean] :store (false) whether to store file on servers.
14
+ def convert(params, options = {})
15
+ files_params = params.is_a?(Hash) ? [params] : params
16
+ conversion_client.new.convert_many(files_params, options)
17
+ end
18
+
19
+ # Returns a status of a conversion job
20
+ #
21
+ # @param token [Integer, String] token obtained from a server in convert method
22
+ def status(token)
23
+ conversion_client.new.get_conversion_status(token)
24
+ end
25
+
26
+ private
27
+
28
+ def conversion_client
29
+ clients[:base]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ include Conversion
36
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_converter'
4
+
5
+ module Uploadcare
6
+ module Entity
7
+ module Conversion
8
+ # This serializer lets a user convert uploaded documents
9
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/documentConvert
10
+ class DocumentConverter < BaseConverter
11
+ client_service Client::Conversion::DocumentConversionClient
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_converter'
4
+
5
+ module Uploadcare
6
+ module Entity
7
+ module Conversion
8
+ # This serializer lets a user convert uploaded videos, and usually returns an array of results
9
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/videoConvert
10
+ class VideoConverter < BaseConverter
11
+ client_service Client::Conversion::VideoConversionClient
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uploadcare
4
+ module Entity
5
+ # @abstract
6
+ module Decorator
7
+ # provides pagination methods for things in Uploadcare that paginate,
8
+ # namely [FileList] and [Group]
9
+ #
10
+ # Requirements:
11
+ # - Should be Entity with Client
12
+ # - Associated Client should have `list` method that returns objects with pagination
13
+ # - Response should have :next, :previous, :total, :per_page params and :results fields
14
+ module Paginator
15
+ @entity ||= Hashie::Mash.new
16
+
17
+ # meta data of a pagination object
18
+ def meta
19
+ Hashie::Mash.new(next: @entity[:next], previous: @entity[:previous],
20
+ total: @entity[:total], per_page: @entity[:per_page])
21
+ end
22
+
23
+ # Returns new instance of current object on next page
24
+ def next_page
25
+ url = @entity[:next]
26
+ return unless url
27
+
28
+ query = URI.decode_www_form(URI(url).query).to_h
29
+ query = query.map { |k, v| [k.to_sym, v] }.to_h
30
+ self.class.list(**query)
31
+ end
32
+
33
+ # Returns new instance of current object on previous page
34
+ def previous_page
35
+ url = @entity[:previous]
36
+ return unless url
37
+
38
+ query = URI.decode_www_form(URI(url).query).to_h
39
+ query = query.map { |k, v| [k.to_sym, v] }.to_h
40
+ self.class.list(**query)
41
+ end
42
+
43
+ # Attempts to load the entire list after offset into results of current object
44
+ #
45
+ # It's possible to avoid loading objects on previous pages by offsetting them first
46
+ def load
47
+ return if @entity[:next].nil? || @entity[:results].length == @entity[:total]
48
+
49
+ np = self
50
+ until np.next.nil?
51
+ np = np.next_page
52
+ @entity[:results].concat(np.results.map(&:to_h))
53
+ end
54
+ @entity[:next] = nil
55
+ @entity[:per_page] = @entity[:total]
56
+ self
57
+ end
58
+
59
+ # iterate through pages, starting with current one
60
+ #
61
+ # @yield [Block]
62
+ def each(&block)
63
+ current_page = self
64
+ while current_page
65
+ current_page.results.each(&block)
66
+ current_page = current_page.next_page
67
+ end
68
+ end
69
+
70
+ # Load and return all objects in list
71
+ #
72
+ # @return [Array]
73
+ def all
74
+ load[:results]
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem.find_files('client/**/*.rb').each { |path| require path }
4
+
5
+ module Uploadcare
6
+ # Entities represent objects existing in Uploadcare cloud
7
+ #
8
+ # Typically, Entities inherit class methods from {Client} instance methods
9
+ # @see Client
10
+ module Entity
11
+ # @abstract
12
+ class Entity < ApiStruct::Entity
13
+ include Client
14
+ end
15
+ end
16
+
17
+ include Entity
18
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uploadcare
4
+ module Entity
5
+ # This serializer returns a single file
6
+ #
7
+ # @see https://uploadcare.com/docs/api_reference/rest/handling_projects/
8
+ class File < Entity
9
+ client_service FileClient
10
+
11
+ attr_entity :datetime_removed, :datetime_stored, :datetime_uploaded, :image_info, :is_image, :is_ready,
12
+ :mime_type, :original_file_url, :original_filename, :size, :url, :uuid, :variations, :video_info,
13
+ :source, :rekognition_info
14
+
15
+ # gets file's uuid - even if it's only initialized with url
16
+ # @returns [String]
17
+ def uuid
18
+ return @entity.uuid if @entity.uuid
19
+
20
+ uuid = @entity.url.gsub('https://ucarecdn.com/', '')
21
+ uuid.gsub(%r{/.*}, '')
22
+ end
23
+
24
+ # loads file metadata, if it's initialized with url or uuid
25
+ def load
26
+ initialize(File.info(uuid).entity)
27
+ end
28
+
29
+ # The method to convert a document file to another file
30
+ # gets (conversion) params [Hash], options (store: Boolean) [Hash], converter [Class]
31
+ # @returns [File]
32
+ def convert_document(params = {}, options = {}, converter = Conversion::DocumentConverter)
33
+ convert_file(params, converter, options)
34
+ end
35
+
36
+ # The method to convert a video file to another file
37
+ # gets (conversion) params [Hash], options (store: Boolean) [Hash], converter [Class]
38
+ # @returns [File]
39
+ def convert_video(params = {}, options = {}, converter = Conversion::VideoConverter)
40
+ convert_file(params, converter, options)
41
+ end
42
+
43
+ # 'copy' method is used to copy original files or their modified versions to default storage.
44
+ #
45
+ # Source files MAY either be stored or just uploaded and MUST NOT be deleted.
46
+ #
47
+ # @param [String] source uuid or uploadcare link to file.
48
+ # @param [Hash] args
49
+ # @option args [Boolean] :store Whether to store the file
50
+ # @option args [Boolean] :strip_operations Copies file without transformations (if source has them)
51
+ # @option args [String] :target points to a target custom storage.
52
+ # @option args [Boolean] :make_public make files on custom storage available via public links.
53
+ # @option args [String] :pattern define file naming pattern for the custom storage scenario.
54
+ #
55
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/copyFile
56
+ def self.copy(source, **args)
57
+ response = FileClient.new.copy(source: source, **args).success[:result]
58
+ File.new(response)
59
+ end
60
+
61
+ # Copies file to current project
62
+ #
63
+ # source can be UID or full CDN link
64
+ #
65
+ # @see .copy
66
+ def self.local_copy(source, **args)
67
+ File.copy(source, **args)
68
+ end
69
+
70
+ # copy file to different project
71
+ #
72
+ # source can be UID or full CDN link
73
+ #
74
+ # @see .copy
75
+ def self.remote_copy(source, target, **args)
76
+ File.copy(source: source, target: target, **args)
77
+ end
78
+
79
+ # Instance version of #{copy}. Copies current file.
80
+ def copy(**args)
81
+ File.copy(uuid, **args)
82
+ end
83
+
84
+ # Instance version of {internal_copy}
85
+ def local_copy(**args)
86
+ File.local_copy(uuid, **args)
87
+ end
88
+
89
+ # Instance version of {external_copy}
90
+ def remote_copy(target, **args)
91
+ File.copy(uuid, target: target, **args)
92
+ end
93
+
94
+ private
95
+
96
+ def convert_file(params, converter, options = {})
97
+ raise Uploadcare::Exception::ConversionError, 'The first argument must be a Hash' unless params.is_a?(Hash)
98
+
99
+ params_with_symbolized_keys = params.map { |k, v| [k.to_sym, v] }.to_h
100
+ params_with_symbolized_keys[:uuid] = uuid
101
+ result = converter.convert(params_with_symbolized_keys, options)
102
+ result.success? ? File.info(result.value![:result].first[:uuid]) : result
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uploadcare/entity/file'
4
+ require 'uploadcare/entity/decorator/paginator'
5
+ require 'api_struct'
6
+
7
+ module Uploadcare
8
+ module Entity
9
+ # This serializer returns lists of files
10
+ #
11
+ # This is a paginated list, so all pagination methods apply
12
+ # @see Uploadcare::Entity::Decorator::Paginator
13
+ class FileList < ApiStruct::Entity
14
+ include Uploadcare::Entity::Decorator::Paginator
15
+ client_service Client::FileListClient
16
+
17
+ attr_entity :next, :previous, :total, :per_page
18
+
19
+ has_entities :results, as: Uploadcare::Entity::File
20
+ has_entities :result, as: Uploadcare::Entity::File
21
+
22
+ # alias for result/results, depending on which API this FileList was initialized from
23
+ # @return [Array] of [Uploadcare::Entity::File]
24
+ def files
25
+ results
26
+ rescue ApiStruct::EntityError
27
+ result
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uploadcare/entity/file'
4
+
5
+ module Uploadcare
6
+ module Entity
7
+ # Groups serve a purpose of better organizing files in your Uploadcare projects.
8
+ #
9
+ # You can create one from a set of files by using their UUIDs.
10
+ #
11
+ # @see https://uploadcare.com/docs/api_reference/upload/groups/
12
+ class Group < Entity
13
+ client_service RestGroupClient, prefix: 'rest', only: :store
14
+ client_service GroupClient
15
+
16
+ attr_entity :id, :datetime_created, :datetime_stored, :files_count, :cdn_url, :url
17
+ has_entities :files, as: Uploadcare::Entity::File
18
+
19
+ # Remove these lines and bump api_struct version when this PR is accepted:
20
+ # @see https://github.com/rubygarage/api_struct/pull/15
21
+ def self.store(uuid)
22
+ rest_store(uuid)
23
+ end
24
+
25
+ # gets groups's id - even if it's only initialized with cdn_url
26
+ # @return [String]
27
+ def id
28
+ return @entity.id if @entity.id
29
+
30
+ id = @entity.cdn_url.gsub('https://ucarecdn.com/', '')
31
+ id.gsub(%r{/.*}, '')
32
+ end
33
+
34
+ # loads group metadata, if it's initialized with url or id
35
+ def load
36
+ initialize(Group.info(id).entity)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uploadcare/entity/group'
4
+ require 'uploadcare/entity/decorator/paginator'
5
+
6
+ module Uploadcare
7
+ module Entity
8
+ # List of groups
9
+ #
10
+ # @see https://uploadcare.com/docs/api_reference/upload/groups/
11
+ #
12
+ # This is a paginated list, so all pagination methods apply
13
+ # @see Uploadcare::Entity::Decorator::Paginator
14
+ class GroupList < Entity
15
+ include Uploadcare::Entity::Decorator::Paginator
16
+ client_service RestGroupClient, only: :list
17
+
18
+ attr_entity :next, :previous, :total, :per_page, :results
19
+ has_entities :results, as: Group
20
+
21
+ alias groups results
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uploadcare
4
+ module Entity
5
+ # This serializer returns info about a project and its data
6
+ # @see https://uploadcare.com/docs/api_reference/rest/handling_projects/
7
+ class Project < Entity
8
+ client_service ProjectClient
9
+
10
+ attr_entity :collaborators, :pub_key, :name, :autostore_enabled
11
+ end
12
+ end
13
+ end