uploadcare-ruby 4.4.3 → 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.
Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +7 -0
  3. data/.github/workflows/gem-push.yml +1 -1
  4. data/.github/workflows/ruby.yml +10 -13
  5. data/.gitignore +9 -0
  6. data/.rubocop.yml +95 -8
  7. data/CHANGELOG.md +71 -1
  8. data/Gemfile +23 -6
  9. data/MIGRATING_V5.md +290 -0
  10. data/README.md +422 -671
  11. data/Rakefile +5 -1
  12. data/api_examples/README.md +77 -0
  13. data/api_examples/rest_api/delete_files_storage.rb +3 -5
  14. data/api_examples/rest_api/delete_files_uuid_metadata_key.rb +3 -4
  15. data/api_examples/rest_api/delete_files_uuid_storage.rb +3 -4
  16. data/api_examples/rest_api/delete_groups_uuid.rb +3 -4
  17. data/api_examples/rest_api/delete_webhooks_unsubscribe.rb +3 -4
  18. data/api_examples/rest_api/get_addons_aws_rekognition_detect_labels_execute_status.rb +3 -6
  19. data/api_examples/rest_api/get_addons_aws_rekognition_detect_moderation_labels_execute_status.rb +3 -6
  20. data/api_examples/rest_api/get_addons_remove_bg_execute_status.rb +3 -6
  21. data/api_examples/rest_api/get_addons_uc_clamav_virus_scan_execute_status.rb +3 -6
  22. data/api_examples/rest_api/get_convert_document_status_token.rb +3 -5
  23. data/api_examples/rest_api/get_convert_document_uuid.rb +3 -5
  24. data/api_examples/rest_api/get_convert_video_status_token.rb +3 -5
  25. data/api_examples/rest_api/get_files.rb +3 -5
  26. data/api_examples/rest_api/get_files_uuid.rb +3 -5
  27. data/api_examples/rest_api/get_files_uuid_metadata.rb +3 -5
  28. data/api_examples/rest_api/get_files_uuid_metadata_key.rb +3 -5
  29. data/api_examples/rest_api/get_groups.rb +3 -5
  30. data/api_examples/rest_api/get_groups_uuid.rb +3 -5
  31. data/api_examples/rest_api/get_project.rb +3 -5
  32. data/api_examples/rest_api/get_webhooks.rb +3 -5
  33. data/api_examples/rest_api/post_addons_aws_rekognition_detect_labels_execute.rb +3 -5
  34. data/api_examples/rest_api/post_addons_aws_rekognition_detect_moderation_labels_execute.rb +3 -5
  35. data/api_examples/rest_api/post_addons_remove_bg_execute.rb +3 -5
  36. data/api_examples/rest_api/post_addons_uc_clamav_virus_scan_execute.rb +3 -5
  37. data/api_examples/rest_api/post_convert_document.rb +3 -8
  38. data/api_examples/rest_api/post_convert_video.rb +3 -10
  39. data/api_examples/rest_api/post_files_local_copy.rb +3 -6
  40. data/api_examples/rest_api/post_files_remote_copy.rb +3 -7
  41. data/api_examples/rest_api/post_webhooks.rb +3 -9
  42. data/api_examples/rest_api/put_files_storage.rb +3 -8
  43. data/api_examples/rest_api/put_files_uuid_metadata_key.rb +3 -7
  44. data/api_examples/rest_api/put_files_uuid_storage.rb +3 -5
  45. data/api_examples/rest_api/put_webhooks_id.rb +3 -11
  46. data/api_examples/support/example_helper.rb +250 -0
  47. data/api_examples/support/run_rest_example.rb +161 -0
  48. data/api_examples/support/run_upload_example.rb +88 -0
  49. data/api_examples/upload_api/get_from_url_status.rb +3 -5
  50. data/api_examples/upload_api/get_group_info.rb +3 -6
  51. data/api_examples/upload_api/get_info.rb +3 -6
  52. data/api_examples/upload_api/post_base.rb +3 -5
  53. data/api_examples/upload_api/post_from_url.rb +3 -5
  54. data/api_examples/upload_api/post_group.rb +3 -8
  55. data/api_examples/upload_api/post_multipart_complete.rb +3 -7
  56. data/api_examples/upload_api/post_multipart_start.rb +3 -7
  57. data/api_examples/upload_api/put_multipart_part.rb +4 -0
  58. data/bin/console +1 -1
  59. data/docs/release-notes-5.0.0.rc1.md +34 -0
  60. data/examples/README.md +39 -0
  61. data/examples/batch_upload.rb +54 -0
  62. data/examples/group_creation.rb +88 -0
  63. data/examples/large_file_upload.rb +88 -0
  64. data/examples/simple_upload.rb +39 -0
  65. data/examples/upload_with_progress.rb +84 -0
  66. data/examples/url_upload.rb +56 -0
  67. data/lib/uploadcare/api/rest/addons.rb +107 -0
  68. data/lib/uploadcare/api/rest/document_conversions.rb +65 -0
  69. data/lib/uploadcare/api/rest/file_metadata.rb +71 -0
  70. data/lib/uploadcare/api/rest/files.rb +112 -0
  71. data/lib/uploadcare/api/rest/groups.rb +49 -0
  72. data/lib/uploadcare/api/rest/project.rb +23 -0
  73. data/lib/uploadcare/api/rest/video_conversions.rb +52 -0
  74. data/lib/uploadcare/api/rest/webhooks.rb +74 -0
  75. data/lib/uploadcare/api/rest.rb +254 -0
  76. data/lib/uploadcare/api/upload/files.rb +313 -0
  77. data/lib/uploadcare/api/upload/groups.rb +72 -0
  78. data/lib/uploadcare/api/upload.rb +272 -0
  79. data/lib/uploadcare/client/addons_accessor.rb +85 -0
  80. data/lib/uploadcare/client/api.rb +33 -0
  81. data/lib/uploadcare/client/conversions_accessor.rb +33 -0
  82. data/lib/uploadcare/client/document_conversions_accessor.rb +41 -0
  83. data/lib/uploadcare/client/file_metadata_accessor.rb +46 -0
  84. data/lib/uploadcare/client/files_accessor.rb +82 -0
  85. data/lib/uploadcare/client/groups_accessor.rb +35 -0
  86. data/lib/uploadcare/client/project_accessor.rb +17 -0
  87. data/lib/uploadcare/client/video_conversions_accessor.rb +33 -0
  88. data/lib/uploadcare/client/webhooks_accessor.rb +42 -0
  89. data/lib/uploadcare/client.rb +127 -0
  90. data/lib/uploadcare/cname_generator.rb +68 -0
  91. data/lib/uploadcare/collections/batch_result.rb +35 -0
  92. data/lib/uploadcare/collections/paginated.rb +165 -0
  93. data/lib/uploadcare/configuration.rb +81 -0
  94. data/lib/uploadcare/exception/auth_error.rb +2 -6
  95. data/lib/uploadcare/exception/configuration_error.rb +4 -0
  96. data/lib/uploadcare/exception/conversion_error.rb +2 -6
  97. data/lib/uploadcare/exception/invalid_request_error.rb +4 -0
  98. data/lib/uploadcare/exception/multipart_upload_error.rb +4 -0
  99. data/lib/uploadcare/exception/not_found_error.rb +4 -0
  100. data/lib/uploadcare/exception/request_error.rb +2 -6
  101. data/lib/uploadcare/exception/retry_error.rb +2 -6
  102. data/lib/uploadcare/exception/throttle_error.rb +7 -11
  103. data/lib/uploadcare/exception/unknown_status_error.rb +4 -0
  104. data/lib/uploadcare/exception/upload_error.rb +4 -0
  105. data/lib/uploadcare/exception/upload_timeout_error.rb +4 -0
  106. data/lib/uploadcare/internal/authenticator.rb +101 -0
  107. data/lib/uploadcare/internal/error_handler.rb +102 -0
  108. data/lib/uploadcare/internal/signature_generator.rb +31 -0
  109. data/lib/uploadcare/internal/throttle_handler.rb +36 -0
  110. data/lib/uploadcare/internal/upload_io.rb +110 -0
  111. data/lib/uploadcare/internal/upload_params_generator.rb +86 -0
  112. data/lib/uploadcare/internal/user_agent.rb +22 -0
  113. data/lib/uploadcare/operations/multipart_upload.rb +213 -0
  114. data/lib/uploadcare/operations/upload_router.rb +162 -0
  115. data/lib/uploadcare/resources/addon_execution.rb +97 -0
  116. data/lib/uploadcare/resources/base_resource.rb +61 -0
  117. data/lib/uploadcare/resources/document_conversion.rb +81 -0
  118. data/lib/uploadcare/resources/file.rb +366 -0
  119. data/lib/uploadcare/resources/file_metadata.rb +135 -0
  120. data/lib/uploadcare/resources/group.rb +142 -0
  121. data/lib/uploadcare/resources/project.rb +26 -0
  122. data/lib/uploadcare/resources/video_conversion.rb +59 -0
  123. data/lib/uploadcare/resources/webhook.rb +85 -0
  124. data/lib/uploadcare/result.rb +85 -0
  125. data/lib/uploadcare/signed_url_generators/akamai_generator.rb +50 -51
  126. data/lib/uploadcare/signed_url_generators/base_generator.rb +15 -15
  127. data/lib/uploadcare/version.rb +7 -0
  128. data/lib/uploadcare/webhook_signature_verifier.rb +60 -0
  129. data/lib/uploadcare.rb +84 -50
  130. data/mise.toml +2 -0
  131. data/uploadcare-ruby.gemspec +8 -7
  132. metadata +102 -74
  133. data/api_examples/upload_api/put_presigned_url_x.rb +0 -8
  134. data/lib/uploadcare/api/api.rb +0 -25
  135. data/lib/uploadcare/client/addons_client.rb +0 -69
  136. data/lib/uploadcare/client/conversion/base_conversion_client.rb +0 -60
  137. data/lib/uploadcare/client/conversion/document_conversion_client.rb +0 -45
  138. data/lib/uploadcare/client/conversion/video_conversion_client.rb +0 -46
  139. data/lib/uploadcare/client/file_client.rb +0 -48
  140. data/lib/uploadcare/client/file_list_client.rb +0 -46
  141. data/lib/uploadcare/client/file_metadata_client.rb +0 -36
  142. data/lib/uploadcare/client/group_client.rb +0 -45
  143. data/lib/uploadcare/client/multipart_upload/chunks_client.rb +0 -58
  144. data/lib/uploadcare/client/multipart_upload_client.rb +0 -64
  145. data/lib/uploadcare/client/project_client.rb +0 -20
  146. data/lib/uploadcare/client/rest_client.rb +0 -77
  147. data/lib/uploadcare/client/rest_group_client.rb +0 -43
  148. data/lib/uploadcare/client/upload_client.rb +0 -46
  149. data/lib/uploadcare/client/uploader_client.rb +0 -128
  150. data/lib/uploadcare/client/webhook_client.rb +0 -49
  151. data/lib/uploadcare/concern/error_handler.rb +0 -54
  152. data/lib/uploadcare/concern/throttle_handler.rb +0 -25
  153. data/lib/uploadcare/concern/upload_error_handler.rb +0 -32
  154. data/lib/uploadcare/entity/addons.rb +0 -14
  155. data/lib/uploadcare/entity/conversion/base_converter.rb +0 -43
  156. data/lib/uploadcare/entity/conversion/document_converter.rb +0 -15
  157. data/lib/uploadcare/entity/conversion/video_converter.rb +0 -15
  158. data/lib/uploadcare/entity/decorator/paginator.rb +0 -79
  159. data/lib/uploadcare/entity/entity.rb +0 -18
  160. data/lib/uploadcare/entity/file.rb +0 -103
  161. data/lib/uploadcare/entity/file_list.rb +0 -32
  162. data/lib/uploadcare/entity/file_metadata.rb +0 -30
  163. data/lib/uploadcare/entity/group.rb +0 -49
  164. data/lib/uploadcare/entity/group_list.rb +0 -24
  165. data/lib/uploadcare/entity/project.rb +0 -13
  166. data/lib/uploadcare/entity/uploader.rb +0 -93
  167. data/lib/uploadcare/entity/webhook.rb +0 -14
  168. data/lib/uploadcare/param/authentication_header.rb +0 -37
  169. data/lib/uploadcare/param/conversion/document/processing_job_url_builder.rb +0 -39
  170. data/lib/uploadcare/param/conversion/video/processing_job_url_builder.rb +0 -64
  171. data/lib/uploadcare/param/param.rb +0 -10
  172. data/lib/uploadcare/param/secure_auth_header.rb +0 -51
  173. data/lib/uploadcare/param/simple_auth_header.rb +0 -14
  174. data/lib/uploadcare/param/upload/signature_generator.rb +0 -24
  175. data/lib/uploadcare/param/upload/upload_params_generator.rb +0 -41
  176. data/lib/uploadcare/param/user_agent.rb +0 -21
  177. data/lib/uploadcare/param/webhook_signature_verifier.rb +0 -23
  178. data/lib/uploadcare/ruby/version.rb +0 -5
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ # High-level add-on execution helpers scoped to a client instance.
4
+ class Uploadcare::Client::AddonsAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param uuid [String]
13
+ # @param request_options [Hash]
14
+ # @return [Uploadcare::Resources::AddonExecution]
15
+ def aws_rekognition_detect_labels(uuid:, request_options: {})
16
+ Uploadcare::Resources::AddonExecution.aws_rekognition_detect_labels(
17
+ uuid: uuid, client: client, request_options: request_options
18
+ )
19
+ end
20
+
21
+ # @param request_id [String]
22
+ # @param request_options [Hash]
23
+ # @return [Uploadcare::Resources::AddonExecution]
24
+ def aws_rekognition_detect_labels_status(request_id:, request_options: {})
25
+ Uploadcare::Resources::AddonExecution.aws_rekognition_detect_labels_status(
26
+ request_id: request_id, client: client, request_options: request_options
27
+ )
28
+ end
29
+
30
+ # @param uuid [String]
31
+ # @param request_options [Hash]
32
+ # @return [Uploadcare::Resources::AddonExecution]
33
+ def aws_rekognition_detect_moderation_labels(uuid:, request_options: {})
34
+ Uploadcare::Resources::AddonExecution.aws_rekognition_detect_moderation_labels(
35
+ uuid: uuid, client: client, request_options: request_options
36
+ )
37
+ end
38
+
39
+ # @param request_id [String]
40
+ # @param request_options [Hash]
41
+ # @return [Uploadcare::Resources::AddonExecution]
42
+ def aws_rekognition_detect_moderation_labels_status(request_id:, request_options: {})
43
+ Uploadcare::Resources::AddonExecution.aws_rekognition_detect_moderation_labels_status(
44
+ request_id: request_id, client: client, request_options: request_options
45
+ )
46
+ end
47
+
48
+ # @param uuid [String]
49
+ # @param params [Hash]
50
+ # @param request_options [Hash]
51
+ # @return [Uploadcare::Resources::AddonExecution]
52
+ def uc_clamav_virus_scan(uuid:, params: {}, request_options: {})
53
+ Uploadcare::Resources::AddonExecution.uc_clamav_virus_scan(
54
+ uuid: uuid, params: params, client: client, request_options: request_options
55
+ )
56
+ end
57
+
58
+ # @param request_id [String]
59
+ # @param request_options [Hash]
60
+ # @return [Uploadcare::Resources::AddonExecution]
61
+ def uc_clamav_virus_scan_status(request_id:, request_options: {})
62
+ Uploadcare::Resources::AddonExecution.uc_clamav_virus_scan_status(
63
+ request_id: request_id, client: client, request_options: request_options
64
+ )
65
+ end
66
+
67
+ # @param uuid [String]
68
+ # @param params [Hash]
69
+ # @param request_options [Hash]
70
+ # @return [Uploadcare::Resources::AddonExecution]
71
+ def remove_bg(uuid:, params: {}, request_options: {})
72
+ Uploadcare::Resources::AddonExecution.remove_bg(
73
+ uuid: uuid, params: params, client: client, request_options: request_options
74
+ )
75
+ end
76
+
77
+ # @param request_id [String]
78
+ # @param request_options [Hash]
79
+ # @return [Uploadcare::Resources::AddonExecution]
80
+ def remove_bg_status(request_id:, request_options: {})
81
+ Uploadcare::Resources::AddonExecution.remove_bg_status(
82
+ request_id: request_id, client: client, request_options: request_options
83
+ )
84
+ end
85
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Access to the endpoint-parity REST and Upload API clients for one configuration.
4
+ class Uploadcare::Client::Api
5
+ attr_reader :config
6
+
7
+ # @param config [Uploadcare::Configuration]
8
+ def initialize(config:)
9
+ @config = config
10
+ @memo_mutex = Mutex.new
11
+ end
12
+
13
+ # @return [Uploadcare::Api::Rest]
14
+ def rest
15
+ memoized(:@rest) { Uploadcare::Api::Rest.new(config: config) }
16
+ end
17
+
18
+ # @return [Uploadcare::Api::Upload]
19
+ def upload
20
+ memoized(:@upload) { Uploadcare::Api::Upload.new(config: config) }
21
+ end
22
+
23
+ private
24
+
25
+ def memoized(ivar)
26
+ cached = instance_variable_get(ivar)
27
+ return cached if cached
28
+
29
+ @memo_mutex.synchronize do
30
+ instance_variable_get(ivar) || instance_variable_set(ivar, yield)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Entry point for document and video conversion helpers on a client.
4
+ class Uploadcare::Client::ConversionsAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ @memo_mutex = Mutex.new
11
+ end
12
+
13
+ # @return [Uploadcare::Client::DocumentConversionsAccessor]
14
+ def documents
15
+ memoized(:@documents) { Uploadcare::Client::DocumentConversionsAccessor.new(client: client) }
16
+ end
17
+
18
+ # @return [Uploadcare::Client::VideoConversionsAccessor]
19
+ def videos
20
+ memoized(:@videos) { Uploadcare::Client::VideoConversionsAccessor.new(client: client) }
21
+ end
22
+
23
+ private
24
+
25
+ def memoized(ivar)
26
+ cached = instance_variable_get(ivar)
27
+ return cached if cached
28
+
29
+ @memo_mutex.synchronize do
30
+ instance_variable_get(ivar) || instance_variable_set(ivar, yield)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # High-level document conversion helpers scoped to a client instance.
4
+ class Uploadcare::Client::DocumentConversionsAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param uuid [String]
13
+ # @param format [String, Symbol]
14
+ # @param options [Hash]
15
+ # @param request_options [Hash]
16
+ # @return [Hash]
17
+ def convert(uuid:, format:, options: {}, request_options: {})
18
+ Uploadcare::Resources::DocumentConversion.convert_document(
19
+ params: { uuid: uuid, format: format }, options: options, client: client,
20
+ request_options: request_options
21
+ )
22
+ end
23
+
24
+ # @param token [String]
25
+ # @param request_options [Hash]
26
+ # @return [Uploadcare::Resources::DocumentConversion]
27
+ def status(token:, request_options: {})
28
+ Uploadcare::Resources::DocumentConversion.status(
29
+ token: token, client: client, request_options: request_options
30
+ )
31
+ end
32
+
33
+ # @param uuid [String]
34
+ # @param request_options [Hash]
35
+ # @return [Uploadcare::Resources::DocumentConversion]
36
+ def info(uuid:, request_options: {})
37
+ Uploadcare::Resources::DocumentConversion.info_for(
38
+ uuid: uuid, client: client, request_options: request_options
39
+ )
40
+ end
41
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # File metadata operations scoped to a client instance.
4
+ class Uploadcare::Client::FileMetadataAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param uuid [String]
13
+ # @param request_options [Hash]
14
+ # @return [Uploadcare::Resources::FileMetadata]
15
+ def index(uuid:, request_options: {})
16
+ Uploadcare::Resources::FileMetadata.index(uuid: uuid, client: client, request_options: request_options)
17
+ end
18
+
19
+ # @param uuid [String]
20
+ # @param key [String]
21
+ # @param request_options [Hash]
22
+ # @return [String, nil]
23
+ def show(uuid:, key:, request_options: {})
24
+ Uploadcare::Resources::FileMetadata.show(uuid: uuid, key: key, client: client,
25
+ request_options: request_options)
26
+ end
27
+
28
+ # @param uuid [String]
29
+ # @param key [String]
30
+ # @param value [String]
31
+ # @param request_options [Hash]
32
+ # @return [Uploadcare::Resources::FileMetadata]
33
+ def update(uuid:, key:, value:, request_options: {})
34
+ Uploadcare::Resources::FileMetadata.update(uuid: uuid, key: key, value: value, client: client,
35
+ request_options: request_options)
36
+ end
37
+
38
+ # @param uuid [String]
39
+ # @param key [String]
40
+ # @param request_options [Hash]
41
+ # @return [nil]
42
+ def delete(uuid:, key:, request_options: {})
43
+ Uploadcare::Resources::FileMetadata.delete(uuid: uuid, key: key, client: client,
44
+ request_options: request_options)
45
+ end
46
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ # High-level file operations scoped to a client instance.
4
+ class Uploadcare::Client::FilesAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param uuid [String]
13
+ # @param params [Hash]
14
+ # @param request_options [Hash]
15
+ # @return [Uploadcare::Resources::File]
16
+ def find(uuid:, params: {}, request_options: {})
17
+ Uploadcare::Resources::File.find(
18
+ uuid: uuid, params: params, client: client, request_options: request_options
19
+ )
20
+ end
21
+
22
+ # @param request_options [Hash]
23
+ # @param options [Hash]
24
+ # @return [Uploadcare::Collections::Paginated]
25
+ def list(request_options: {}, **options)
26
+ Uploadcare::Resources::File.list(
27
+ options: options, client: client, request_options: request_options
28
+ )
29
+ end
30
+
31
+ # @param source [IO, Array<IO>, String]
32
+ # @param request_options [Hash]
33
+ # @param options [Hash]
34
+ # @yield [Hash]
35
+ # @return [Uploadcare::Resources::File, Array<Uploadcare::Resources::File>, Hash]
36
+ def upload(source, request_options: {}, **options, &block)
37
+ client.uploads.upload(source, request_options: request_options, **options, &block)
38
+ end
39
+
40
+ # @param url [String]
41
+ # @param request_options [Hash]
42
+ # @param options [Hash]
43
+ # @return [Uploadcare::Resources::File, Hash]
44
+ def upload_from_url(url, request_options: {}, **options)
45
+ client.uploads.upload_from_url(url: url, request_options: request_options, **options)
46
+ end
47
+
48
+ # @param uuids [Array<String>]
49
+ # @param request_options [Hash]
50
+ # @return [Uploadcare::BatchResult]
51
+ def batch_store(uuids:, request_options: {})
52
+ Uploadcare::Resources::File.batch_store(uuids: uuids, client: client, request_options: request_options)
53
+ end
54
+
55
+ # @param uuids [Array<String>]
56
+ # @param request_options [Hash]
57
+ # @return [Uploadcare::BatchResult]
58
+ def batch_delete(uuids:, request_options: {})
59
+ Uploadcare::Resources::File.batch_delete(uuids: uuids, client: client, request_options: request_options)
60
+ end
61
+
62
+ # @param source [String]
63
+ # @param options [Hash]
64
+ # @param request_options [Hash]
65
+ # @return [Uploadcare::Resources::File]
66
+ def copy_to_local(source:, options: {}, request_options: {})
67
+ Uploadcare::Resources::File.local_copy(
68
+ source: source, options: options, client: client, request_options: request_options
69
+ )
70
+ end
71
+
72
+ # @param source [String]
73
+ # @param target [String]
74
+ # @param options [Hash]
75
+ # @param request_options [Hash]
76
+ # @return [Hash]
77
+ def copy_to_remote(source:, target:, options: {}, request_options: {})
78
+ Uploadcare::Resources::File.remote_copy(
79
+ source: source, target: target, options: options, client: client, request_options: request_options
80
+ )
81
+ end
82
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # High-level group operations scoped to a client instance.
4
+ class Uploadcare::Client::GroupsAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param uuids [Array<String>]
13
+ # @param request_options [Hash]
14
+ # @param options [Hash]
15
+ # @return [Uploadcare::Resources::Group]
16
+ def create(uuids:, request_options: {}, **options)
17
+ Uploadcare::Resources::Group.create(
18
+ uuids: uuids, client: client, request_options: request_options, **options
19
+ )
20
+ end
21
+
22
+ # @param group_id [String]
23
+ # @param request_options [Hash]
24
+ # @return [Uploadcare::Resources::Group]
25
+ def find(group_id:, request_options: {})
26
+ Uploadcare::Resources::Group.find(group_id: group_id, client: client, request_options: request_options)
27
+ end
28
+
29
+ # @param request_options [Hash]
30
+ # @param params [Hash]
31
+ # @return [Uploadcare::Collections::Paginated]
32
+ def list(request_options: {}, **params)
33
+ Uploadcare::Resources::Group.list(params: params, client: client, request_options: request_options)
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Project endpoint wrapper scoped to a client instance.
4
+ class Uploadcare::Client::ProjectAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param request_options [Hash]
13
+ # @return [Uploadcare::Resources::Project]
14
+ def current(request_options: {})
15
+ Uploadcare::Resources::Project.current(client: client, request_options: request_options)
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # High-level video conversion helpers scoped to a client instance.
4
+ class Uploadcare::Client::VideoConversionsAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param uuid [String]
13
+ # @param format [String, Symbol]
14
+ # @param quality [String, Symbol]
15
+ # @param options [Hash]
16
+ # @param request_options [Hash]
17
+ # @return [Uploadcare::Resources::VideoConversion]
18
+ def convert(uuid:, format:, quality:, options: {}, request_options: {})
19
+ Uploadcare::Resources::VideoConversion.convert(
20
+ params: { uuid: uuid, format: format, quality: quality }, options: options, client: client,
21
+ request_options: request_options
22
+ )
23
+ end
24
+
25
+ # @param token [String]
26
+ # @param request_options [Hash]
27
+ # @return [Uploadcare::Resources::VideoConversion]
28
+ def status(token:, request_options: {})
29
+ Uploadcare::Resources::VideoConversion.status(
30
+ token: token, client: client, request_options: request_options
31
+ )
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # High-level webhook operations scoped to a client instance.
4
+ class Uploadcare::Client::WebhooksAccessor
5
+ attr_reader :client
6
+
7
+ # @param client [Uploadcare::Client]
8
+ def initialize(client:)
9
+ @client = client
10
+ end
11
+
12
+ # @param request_options [Hash]
13
+ # @return [Array<Uploadcare::Resources::Webhook>]
14
+ def list(request_options: {})
15
+ Uploadcare::Resources::Webhook.list(client: client, request_options: request_options)
16
+ end
17
+
18
+ # @param target_url [String]
19
+ # @param request_options [Hash]
20
+ # @param options [Hash]
21
+ # @return [Uploadcare::Resources::Webhook]
22
+ def create(target_url:, request_options: {}, **options)
23
+ Uploadcare::Resources::Webhook.create(
24
+ target_url: target_url, client: client, request_options: request_options, **options
25
+ )
26
+ end
27
+
28
+ # @param id [String]
29
+ # @param request_options [Hash]
30
+ # @param options [Hash]
31
+ # @return [Uploadcare::Resources::Webhook]
32
+ def update(id:, request_options: {}, **options)
33
+ Uploadcare::Resources::Webhook.update(id: id, client: client, request_options: request_options, **options)
34
+ end
35
+
36
+ # @param target_url [String]
37
+ # @param request_options [Hash]
38
+ # @return [nil]
39
+ def delete(target_url:, request_options: {})
40
+ Uploadcare::Resources::Webhook.delete(target_url: target_url, client: client, request_options: request_options)
41
+ end
42
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Primary entry point for interacting with the Uploadcare API.
4
+ #
5
+ # Each Client instance owns its own configuration and provides domain-scoped
6
+ # accessors for all API operations. Multiple clients can coexist for
7
+ # multi-account support.
8
+ #
9
+ # @example Basic usage
10
+ # client = Uploadcare::Client.new(public_key: "pk", secret_key: "sk")
11
+ # file = client.files.upload(File.open("photo.jpg"), store: true)
12
+ # file = client.files.find(uuid: "file-uuid")
13
+ # files = client.files.list(limit: 100)
14
+ #
15
+ # @example Multi-account
16
+ # account_a = Uploadcare::Client.new(public_key: "a", secret_key: "x")
17
+ # account_b = Uploadcare::Client.new(public_key: "b", secret_key: "y")
18
+ #
19
+ # @example Raw API access
20
+ # client.api.rest.files.list(params: { limit: 10 })
21
+ # client.api.upload.files.direct(file: file_obj)
22
+ class Uploadcare::Client
23
+ attr_reader :config
24
+
25
+ # Build a client bound to a specific configuration.
26
+ #
27
+ # @param config [Uploadcare::Configuration, nil] Base configuration to clone
28
+ # @param options [Hash] Per-client configuration overrides
29
+ def initialize(config: nil, **options)
30
+ base_config = config || Uploadcare.configuration
31
+ @config = base_config.with(**options)
32
+ @memo_mutex = Mutex.new
33
+ end
34
+
35
+ # Build a new client derived from this client.
36
+ #
37
+ # @param options [Hash] Configuration overrides
38
+ # @return [Uploadcare::Client]
39
+ def with(**options)
40
+ self.class.new(config: config, **options)
41
+ end
42
+
43
+ # Access the raw endpoint-parity API.
44
+ #
45
+ # @return [Uploadcare::Client::Api]
46
+ def api
47
+ memoized(:@api) { Api.new(config: config) }
48
+ end
49
+
50
+ # Access file operations and upload helpers.
51
+ #
52
+ # @return [Uploadcare::Client::FilesAccessor]
53
+ def files
54
+ memoized(:@files) { FilesAccessor.new(client: self) }
55
+ end
56
+
57
+ # Access group operations.
58
+ #
59
+ # @return [Uploadcare::Client::GroupsAccessor]
60
+ def groups
61
+ memoized(:@groups) { GroupsAccessor.new(client: self) }
62
+ end
63
+
64
+ # Access upload routing helpers.
65
+ #
66
+ # @return [Uploadcare::Operations::UploadRouter]
67
+ def uploads
68
+ memoized(:@uploads) { Uploadcare::Operations::UploadRouter.new(client: self) }
69
+ end
70
+
71
+ # Access project operations.
72
+ #
73
+ # @return [Uploadcare::Client::ProjectAccessor]
74
+ def project
75
+ memoized(:@project) { ProjectAccessor.new(client: self) }
76
+ end
77
+
78
+ # Access webhook operations.
79
+ #
80
+ # @return [Uploadcare::Client::WebhooksAccessor]
81
+ def webhooks
82
+ memoized(:@webhooks) { WebhooksAccessor.new(client: self) }
83
+ end
84
+
85
+ # Access add-on execution helpers.
86
+ #
87
+ # @return [Uploadcare::Client::AddonsAccessor]
88
+ def addons
89
+ memoized(:@addons) { AddonsAccessor.new(client: self) }
90
+ end
91
+
92
+ # Access file metadata operations.
93
+ #
94
+ # @return [Uploadcare::Client::FileMetadataAccessor]
95
+ def file_metadata
96
+ memoized(:@file_metadata) { FileMetadataAccessor.new(client: self) }
97
+ end
98
+
99
+ # Access conversion helpers.
100
+ #
101
+ # @return [Uploadcare::Client::ConversionsAccessor]
102
+ def conversions
103
+ memoized(:@conversions) { ConversionsAccessor.new(client: self) }
104
+ end
105
+
106
+ # Upload a source through the convenience upload router.
107
+ #
108
+ # @param source [IO, Array<IO>, String] File object, file array, or URL
109
+ # @param request_options [Hash] Per-request HTTP options
110
+ # @param options [Hash] Upload options
111
+ # @yield [Hash] Multipart progress callback
112
+ # @return [Uploadcare::Resources::File, Array<Uploadcare::Resources::File>, Hash]
113
+ def upload(source, request_options: {}, **options, &block)
114
+ uploads.upload(source, request_options: request_options, **options, &block)
115
+ end
116
+
117
+ private
118
+
119
+ def memoized(ivar)
120
+ cached = instance_variable_get(ivar)
121
+ return cached if cached
122
+
123
+ @memo_mutex.synchronize do
124
+ instance_variable_get(ivar) || instance_variable_set(ivar, yield)
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # lib/uploadcare/client/cname_generator.rb
4
+ require 'digest'
5
+ require 'monitor'
6
+ require 'uri'
7
+
8
+ # CNAME generator for Uploadcare CDN.
9
+ # @see https://uploadcare.com/docs/delivery/cdn
10
+ class Uploadcare::CnameGenerator
11
+ # CNAME prefix length.
12
+ CNAME_PREFIX_LEN = 10
13
+
14
+ class << self
15
+ # Build CDN base URL with a generated CNAME prefix.
16
+ #
17
+ # @param config [Uploadcare::Configuration]
18
+ # @return [String]
19
+ def cdn_base_postfix(config: Uploadcare.configuration)
20
+ key = [config.cdn_base_postfix, config.public_key]
21
+ cached = @cdn_base_postfix_cache&.[](key)
22
+ return cached if cached
23
+
24
+ cache_mutex.synchronize do
25
+ @cdn_base_postfix_cache ||= {}
26
+ @cdn_base_postfix_cache[key] ||= begin
27
+ uri = URI.parse(config.cdn_base_postfix)
28
+ uri.host = "#{generate_cname(public_key: config.public_key)}.#{uri.host}"
29
+ uri.to_s
30
+ rescue URI::InvalidURIError => e
31
+ raise Uploadcare::Exception::ConfigurationError, "Invalid cdn_base_postfix URL: #{e.message}"
32
+ end
33
+ end
34
+ end
35
+
36
+ # Generate a CNAME prefix for the current public key.
37
+ #
38
+ # @param public_key [String]
39
+ # @return [String]
40
+ def generate_cname(public_key: Uploadcare.configuration.public_key)
41
+ custom_cname(public_key)
42
+ end
43
+
44
+ private
45
+
46
+ # Generate CNAME prefix
47
+ def custom_cname(public_key = Uploadcare.configuration.public_key)
48
+ raise Uploadcare::Exception::ConfigurationError, "Invalid public_key: #{public_key}" if public_key.nil?
49
+
50
+ cached = @custom_cname_cache&.[](public_key)
51
+ return cached if cached
52
+
53
+ cache_mutex.synchronize do
54
+ @custom_cname_cache ||= {}
55
+ @custom_cname_cache[public_key] ||= begin
56
+ sha256_hex = Digest::SHA256.hexdigest(public_key)
57
+ sha256_hex = sha256_hex.to_i(16)
58
+ sha256_base36 = sha256_hex.to_s(36)
59
+ sha256_base36[0, CNAME_PREFIX_LEN]
60
+ end
61
+ end
62
+ end
63
+
64
+ def cache_mutex
65
+ @cache_mutex ||= Monitor.new
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Result object for batch file operations (store/delete).
4
+ #
5
+ # Wraps the response from batch operations and provides access to:
6
+ # - Successfully processed files
7
+ # - Files that encountered problems
8
+ # - Overall operation status
9
+ #
10
+ # @example
11
+ # result = client.files.batch_store(uuids: ["uuid1", "uuid2"])
12
+ # result.result.each { |file| puts file.uuid }
13
+ # result.problems.each { |uuid, error| puts "#{uuid}: #{error}" }
14
+ class Uploadcare::Collections::BatchResult
15
+ # @return [Integer, nil] HTTP status code of the operation
16
+ attr_reader :status
17
+
18
+ # @return [Array<Uploadcare::Resources::File>] Successfully processed File objects
19
+ attr_reader :result
20
+
21
+ # @return [Hash] Hash mapping UUIDs to error messages
22
+ attr_reader :problems
23
+
24
+ # Initialize a new BatchResult.
25
+ #
26
+ # @param status [Integer, nil] HTTP status code
27
+ # @param result [Array<Hash>] Array of file data hashes from the API
28
+ # @param problems [Hash] Hash of UUIDs to error messages
29
+ # @param client [Uploadcare::Client] Client for creating File objects
30
+ def initialize(status:, result:, problems:, client:)
31
+ @status = status
32
+ @result = result ? result.map { |file_data| Uploadcare::Resources::File.new(file_data, client) } : []
33
+ @problems = problems || {}
34
+ end
35
+ end