uploadcare-ruby 3.0.5 → 3.2.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +13 -0
  3. data/CHANGELOG.md +25 -9
  4. data/README.md +401 -39
  5. data/lib/uploadcare/client/conversion/base_conversion_client.rb +59 -0
  6. data/lib/uploadcare/client/conversion/document_conversion_client.rb +41 -0
  7. data/lib/uploadcare/client/conversion/video_conversion_client.rb +46 -0
  8. data/lib/uploadcare/client/file_list_client.rb +4 -4
  9. data/lib/uploadcare/client/group_client.rb +1 -1
  10. data/lib/uploadcare/client/multipart_upload/chunks_client.rb +16 -5
  11. data/lib/uploadcare/client/multipart_upload_client.rb +14 -12
  12. data/lib/uploadcare/client/project_client.rb +3 -1
  13. data/lib/uploadcare/client/rest_client.rb +6 -5
  14. data/lib/uploadcare/client/rest_group_client.rb +2 -2
  15. data/lib/uploadcare/client/upload_client.rb +8 -0
  16. data/lib/uploadcare/client/uploader_client.rb +25 -17
  17. data/lib/uploadcare/client/webhook_client.rb +11 -5
  18. data/lib/uploadcare/concern/error_handler.rb +2 -2
  19. data/lib/uploadcare/entity/conversion/base_converter.rb +36 -0
  20. data/lib/uploadcare/entity/conversion/document_converter.rb +15 -0
  21. data/lib/uploadcare/entity/conversion/video_converter.rb +15 -0
  22. data/lib/uploadcare/entity/decorator/paginator.rb +5 -7
  23. data/lib/uploadcare/entity/file.rb +40 -4
  24. data/lib/uploadcare/entity/file_list.rb +1 -0
  25. data/lib/uploadcare/entity/group.rb +1 -2
  26. data/lib/uploadcare/entity/uploader.rb +11 -3
  27. data/lib/uploadcare/exception/conversion_error.rb +8 -0
  28. data/lib/uploadcare/exception/throttle_error.rb +2 -0
  29. data/lib/uploadcare/param/conversion/document/processing_job_url_builder.rb +39 -0
  30. data/lib/uploadcare/param/conversion/video/processing_job_url_builder.rb +64 -0
  31. data/lib/uploadcare/param/user_agent.rb +1 -1
  32. data/lib/uploadcare/param/webhook_signature_verifier.rb +23 -0
  33. data/lib/uploadcare/ruby/version.rb +1 -1
  34. data/lib/uploadcare.rb +3 -0
  35. data/uploadcare-ruby.gemspec +1 -1
  36. metadata +14 -4
data/README.md CHANGED
@@ -12,12 +12,24 @@
12
12
  [stack-img]: https://img.shields.io/badge/tech-stack-0690fa.svg?style=flat
13
13
  [stack]: https://stackshare.io/uploadcare/stacks/
14
14
 
15
-
16
15
  Uploadcare Ruby integration handles uploads and further operations with files by
17
16
  wrapping Upload and REST APIs.
18
17
 
19
18
  * [Installation](#installation)
20
19
  * [Usage](#usage)
20
+ * [Uploading files](#uploading-files)
21
+ * [Uploading and storing a single file](#uploading-and-storing-a-single-file)
22
+ * [Multiple ways to upload files](#multiple-ways-to-upload-files)
23
+ * [Uploading options](#uploading-options)
24
+ * [File management](#file-management)
25
+ * [File](#file)
26
+ * [FileList](#filelist)
27
+ * [Pagination](#pagination)
28
+ * [Group](#group)
29
+ * [GroupList](#grouplist)
30
+ * [Webhook](#webhook)
31
+ * [Project](#project)
32
+ * [Conversion](#conversion)
21
33
  * [Useful links](#useful-links)
22
34
 
23
35
  ## Requirements
@@ -25,7 +37,7 @@ wrapping Upload and REST APIs.
25
37
 
26
38
  ## Compatibility
27
39
 
28
- Note that `uploadcare-ruby` **3.x** is not backward compativble with
40
+ Note that `uploadcare-ruby` **3.x** is not backward compatible with
29
41
  **[2.x](https://github.com/uploadcare/uploadcare-ruby/tree/v2.x)**.
30
42
 
31
43
  ## Installation
@@ -33,14 +45,14 @@ Note that `uploadcare-ruby` **3.x** is not backward compativble with
33
45
  Add this line to your application's Gemfile:
34
46
 
35
47
  ```ruby
36
- gem 'uploadcare-ruby'
48
+ gem "uploadcare-ruby"
37
49
  ```
38
50
 
39
51
  And then execute:
40
52
 
41
53
  $ bundle
42
54
 
43
- If already not, create your project in [Uploadcare dashboard](https://uploadcare.com/dashboard/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) and copy
55
+ If already not, create your project in [Uploadcare dashboard](https://app.uploadcare.com/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) and copy
44
56
  its API keys from there.
45
57
 
46
58
  Set your Uploadcare keys in config file or through environment variables:
@@ -55,17 +67,21 @@ settings can be seen in [`lib/uploadcare.rb`](lib/uploadcare.rb)
55
67
 
56
68
  ```ruby
57
69
  # your_config_initializer_file.rb
58
- Uploadcare.config.public_key = 'demopublickey'
59
- Uploadcare.config.secret_key = 'demoprivatekey'
70
+ Uploadcare.config.public_key = "demopublickey"
71
+ Uploadcare.config.secret_key = "demoprivatekey"
60
72
  ```
61
73
 
62
74
  ## Usage
63
75
 
64
76
  This section contains practical usage examples. Please note, everything that
65
77
  follows gets way more clear once you've looked through our
66
- [docs](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
78
+ [docs](https://uploadcare.com/docs/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby)
79
+ and [Upload](https://uploadcare.com/api-refs/upload-api/) and [REST](https://uploadcare.com/api-refs/rest-api/) API refs.
80
+
81
+ You can also find an example project [here](https://github.com/uploadcare/uploadcare-rails-example).
67
82
 
68
- ### Uploading and storing a single file
83
+ ### Uploading files
84
+ #### Uploading and storing a single file
69
85
 
70
86
  Using Uploadcare is simple, and here are the basics of handling files.
71
87
 
@@ -78,7 +94,7 @@ Using Uploadcare is simple, and here are the basics of handling files.
78
94
  # => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
79
95
 
80
96
  # URL for the file, can be used with your website or app right away
81
- @uc_file.cdn_url
97
+ @uc_file.url
82
98
  # => "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/"
83
99
  ```
84
100
 
@@ -97,28 +113,71 @@ within a 24-hour period.
97
113
  # => #<Uploadcare::Api::File ...
98
114
  ```
99
115
 
100
- ### Uploads
116
+ #### Multiple ways to upload files
101
117
 
102
118
  Uploadcare supports multiple ways to upload files:
103
119
 
104
120
  ```ruby
105
121
  # Smart upload - detects type of passed object and picks appropriate upload method
106
- Uploadcare::Uploader.upload('https://placekitten.com/96/139')
122
+ Uploadcare::Uploader.upload("https://placekitten.com/96/139")
107
123
  ```
108
124
 
109
125
  There are explicit ways to select upload type:
110
126
 
111
127
  ```ruby
112
- files = [File.open('1.jpg'), File.open('1.jpg']
128
+ files = [File.open("1.jpg"), File.open("1.jpg"]
113
129
  Uploadcare::Uploader.upload_files(files)
114
130
 
115
- Uploadcare::Uploader.upload_from_url('https://placekitten.com/96/139')
131
+ Uploadcare::Uploader.upload_from_url("https://placekitten.com/96/139")
132
+ ```
133
+ It is possible to track progress of the upload-from-URL process. To do that, you should specify the `async` option and get a token:
134
+
135
+ ```ruby
136
+ Uploadcare::Uploader.upload_from_url("https://placekitten.com/96/139", async: true)
137
+ # => "c6e31082-6bdc-4cb3-bef5-14dd10574d72"
138
+ ```
139
+
140
+ After the request for uploading-from-URL is sent, you can check the progress of the upload by sending the `get_upload_from_url_status` request:
116
141
 
142
+ ```ruby
143
+ Uploadcare::Uploader.get_upload_from_url_status("1251ee66-3631-4416-a2fb-96ba59f5a515")
144
+ # => Success({:size=>28511, :total=>28511, :done=>28511, :uuid=>"b829753b-6b64-4989-a167-ef15e4f3d190", :file_id=>"b859753b-zb64-4989-a167-ef15e4f3a190", :original_filename=>"video.ogg", :is_image=>false, :is_stored=>false, :image_info=>nil, :video_info=>nil, :is_ready=>true, :filename=>"video.ogg", :mime_type=>"audio/ogg", :status=>"success"})
145
+ ```
146
+
147
+ In case of the `async` option is disabled, uploadcare-ruby tries to request the upload status several times (depending on the `max_request_tries` config param) and then returns uploaded file attributes.
148
+
149
+ ```ruby
117
150
  # multipart upload - can be useful for files bigger than 10 mb
118
- Uploadcare::Uploader.multipart_upload(File.open('big_file.bin'))
151
+ Uploadcare::Uploader.multipart_upload(File.open("big_file.bin"), store: true)
152
+ ```
153
+
154
+ For the multipart upload you can pass a block to add some additional logic after each file chunk is uploaded.
155
+ For example to track file uploading progress you can do something like this:
156
+
157
+ ```ruby
158
+ file = File.open("big_file.bin")
159
+ progress = 0
160
+ Uploadcare::Uploader.multipart_upload(file, store: true) do |options|
161
+ progress += (100.0 / options[:links_count])
162
+ puts "PROGRESS = #{progress}"
163
+ end
164
+ ```
165
+ Output of the code above looks like:
166
+ ```console
167
+ PROGRESS = 4.545454545454546
168
+ PROGRESS = 9.090909090909092
169
+ PROGRESS = 13.636363636363637
170
+ ...
119
171
  ```
172
+ Options available in a block:
173
+ - **:chunk_size** - size of each chunk in bytes;
174
+ - **:object** - file object which is going to be uploaded;
175
+ - **:offset** - offset from the beginning of a File object in bytes;
176
+ - **:link_id** - index of a link provided by Uploadcare API. Might be treated as index of a chunk;
177
+ - **:links** - array of links for uploading file's chunks;
178
+ - **:links_count** - count of the array of links.
120
179
 
121
- ### Upload options
180
+ #### Uploading options
122
181
 
123
182
  You can override global [`:autostore`](#initialization) option for each upload request:
124
183
 
@@ -127,14 +186,7 @@ You can override global [`:autostore`](#initialization) option for each upload r
127
186
  @api.upload_from_url(url, store: :auto)
128
187
  ```
129
188
 
130
- ### Api
131
- Most methods are also available through `Uploadcare::Api` object:
132
- ```ruby
133
- # Same as Uploadcare::Uploader.upload
134
- Uploadcare::Api.upload('https://placekitten.com/96/139')
135
- ```
136
-
137
- ### Entity object
189
+ ### File management
138
190
 
139
191
  Entities are representations of objects in Uploadcare cloud.
140
192
 
@@ -143,7 +195,7 @@ Entities are representations of objects in Uploadcare cloud.
143
195
  File entity contains its metadata.
144
196
 
145
197
  ```ruby
146
- @file = Uploadcare::File.file('FILE_ID_IN_YOUR_PROJECT')
198
+ @file = Uploadcare::File.file("FILE_ID_IN_YOUR_PROJECT")
147
199
  {"datetime_removed"=>nil,
148
200
  "datetime_stored"=>"2020-01-16T15:03:15.315064Z",
149
201
  "datetime_uploaded"=>"2020-01-16T15:03:14.676902Z",
@@ -168,22 +220,64 @@ File entity contains its metadata.
168
220
  "https://api.uploadcare.com/files/FILE_ID_IN_YOUR_PROJECT/",
169
221
  "uuid"=>"8f64f313-e6b1-4731-96c0-6751f1e7a50a"}
170
222
 
223
+ @file.copy # copies file, returns a new (copied) file metadata
224
+
171
225
  @file.store # stores file, returns updated metadata
172
226
 
173
227
  @file.delete #deletes file. Returns updated metadata
174
228
  ```
175
229
 
230
+ The File object is also can be converted if it is a document or a video file. Imagine, you have a document file:
231
+
232
+ ```ruby
233
+ @file = Uploadcare::File.file("FILE_ID_IN_YOUR_PROJECT")
234
+ ```
235
+
236
+ To convert it to an another file, just do:
237
+
238
+ ```ruby
239
+ @converted_file = @file.convert_document({ format: "png", page: "1" }, store: true)
240
+ # => {
241
+ # "uuid"=>"<NEW_FILE_UUID>"}
242
+ # ...other file info...
243
+ # }
244
+ # OR
245
+ # Failure({:"<FILE_UUID>/document/-/format/png/-/page/1/"=>"the target_format is not a supported 'to' format for this source file. <you_source_file_extension> -> png"})
246
+ ```
247
+
248
+ Same works for video files:
249
+
250
+ ```ruby
251
+ @converted_file = @file.convert_video(
252
+ {
253
+ format: "ogg",
254
+ quality: "best",
255
+ cut: { start_time: "0:0:0.1", length: "end" },
256
+ size: { resize_mode: "change_ratio", width: "600", height: "400" },
257
+ thumb: { N: 1, number: 2 }
258
+ },
259
+ store: true
260
+ )
261
+ # => {
262
+ # "uuid"=>"<NEW_FILE_UUID>"}
263
+ # ...other file info...
264
+ # }
265
+ # OR
266
+ # Failure({:"<FILE_UUID>/video/-/size/600x400/preserve_ratio/-/quality/best/-/format/ogg/-/cut/0:0:0.1/end/-/thumbs~1/2/"=>"CDN Path error: Failed to parse remainder \"/preserve_ratio\" of \"size/600x400/preserve_ratio\""})
267
+ ```
268
+
269
+ More about file conversion [here](#conversion).
176
270
  Metadata of deleted files is stored permanently.
177
271
 
178
272
  #### FileList
179
273
 
180
- `Uploadcare::Entity::FileList` represents the whole collection of files (or it's
274
+ `Uploadcare::FileList` represents the whole collection of files (or it's
181
275
  subset) and provides a way to iterate through it, making pagination transparent.
182
- FileList objects can be created using `Uploadcare::Entity.file_list` method.
276
+ FileList objects can be created using `Uploadcare::FileList.file_list` method.
183
277
 
184
278
  ```ruby
185
- @list = Uploadcare::Entity.file_list
186
- # Returns instance of Uploadcare::Api::FileList
279
+ @list = Uploadcare::FileList.file_list
280
+ # Returns instance of Uploadcare::Entity::FileList
187
281
  <Hashie::Mash
188
282
  next=nil
189
283
  per_page=100
@@ -198,14 +292,14 @@ FileList objects can be created using `Uploadcare::Entity.file_list` method.
198
292
  @all_files = @list.load
199
293
  ```
200
294
 
201
- This method accepts some options to controll which files should be fetched and
295
+ This method accepts some options to control which files should be fetched and
202
296
  how they should be fetched:
203
297
 
204
298
  - **:limit** — Controls page size. Accepts values from 1 to 1000, defaults to 100.
205
299
  - **:stored** — Can be either `true` or `false`. When true, file list will contain only stored files. When false — only not stored.
206
300
  - **:removed** — Can be either `true` or `false`. When true, file list will contain only removed files. When false — all except removed. Defaults to false.
207
- - **:ordering** — Controls the order of returned files. Available values: `datetime_updated`, `-datetime_updated`, `size`, `-size`. Defaults to `datetime_uploaded`. More info can be found [here](https://uploadcare.com/documentation/rest/#file-files/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
208
- - **:from** — Specifies the starting point for a collection. Resulting collection will contain files from the given value and to the end in a direction set by an **ordering** option. When files are ordered by `datetime_updated` in any direction, accepts either a `DateTime` object or an ISO 8601 string. When files are ordered by size, accepts non-negative integers (size in bytes). More info can be found [here](https://uploadcare.com/documentation/rest/#file-files/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby).
301
+ - **:ordering** — Controls the order of returned files. Available values: `datetime_updated`, `-datetime_updated`, `size`, `-size`. Defaults to `datetime_uploaded`. More info can be found [here](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/filesList).
302
+ - **:from** — Specifies the starting point for a collection. Resulting collection will contain files from the given value and to the end in a direction set by an **ordering** option. When files are ordered by `datetime_updated` in any direction, accepts either a `DateTime` object or an ISO 8601 string. When files are ordered by size, accepts non-negative integers (size in bytes). More info can be found [here](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/filesList).
209
303
 
210
304
  Options used to create a file list can be accessed through `#options` method.
211
305
  Note that, once set, they don't affect file fetching process anymore and are
@@ -215,7 +309,7 @@ stored just for your convenience. That is why they are frozen.
215
309
  options = {
216
310
  limit: 10,
217
311
  stored: true,
218
- ordering: '-datetime_uploaded',
312
+ ordering: "-datetime_uploaded",
219
313
  from: "2017-01-01T00:00:00",
220
314
  }
221
315
  @list = @api.file_list(options)
@@ -226,15 +320,15 @@ To simply get all associated objects:
226
320
  @list.all # => returns Array of Files
227
321
  ```
228
322
 
229
- ##### Pagination
323
+ #### Pagination
230
324
 
231
325
  Initially, `FileList` is a paginated collection. It can be navigated using following methods:
232
326
  ```ruby
233
- @file_list = Uploadcare::Entity::FileList.file_list
327
+ @file_list = Uploadcare::FileList.file_list
234
328
  # Let's assume there are 250 files in cloud. By default, UC loads 100 files. To get next 100 files, do:
235
329
  @next_page = @file_list.next_page
236
330
  # To get previous page:
237
- @previous_page = @next_page.previous_page
331
+ @previous_page = @file_list.previous_page
238
332
  ```
239
333
 
240
334
  Alternatively, it's possible to iterate through full list of groups or files with `each`:
@@ -251,10 +345,14 @@ assigned UUID. Note, group UUIDs include a `~#{files_count}` part at the end.
251
345
  That's a requirement of our API.
252
346
 
253
347
  ```ruby
254
- # group can be created from an array of Uploadcare files
348
+ # group can be created from an array of Uploadcare files (UUIDs)
349
+ @file = "134dc30c-093e-4f48-a5b9-966fe9cb1d01"
350
+ @file2 = "134dc30c-093e-4f48-a5b9-966fe9cb1d02"
255
351
  @files_ary = [@file, @file2]
256
- @files = Uploadcare::Uploader.upload @files_ary
257
352
  @group = Uploadcare::Group.create @files
353
+
354
+ # group can be stored by group ID. It means that all files of a group will be stored on Uploadcare servers permanently
355
+ Uploadcare::Group.store(group.id)
258
356
  ```
259
357
 
260
358
  #### GroupList
@@ -274,15 +372,67 @@ https://uploadcare.com/docs/api_reference/rest/webhooks/
274
372
  You can use webhooks to provide notifications about your uploads to target urls.
275
373
  This gem lets you create and manage webhooks.
276
374
 
375
+ Each webhook payload can be signed with a secret (the `signing_secret` option) to ensure that the request comes from the expected sender.
376
+ More info about secure webhooks [here](https://uploadcare.com/docs/security/secure-webhooks/).
377
+
277
378
  ```ruby
278
- Uploadcare::Webhook.create('example.com/listen', event: 'file.uploaded')
379
+ Uploadcare::Webhook.create(target_url: "https://example.com/listen", event: "file.uploaded", is_active: true, signing_secret: "some-secret")
380
+ Uploadcare::Webhook.update(<webhook_id>, target_url: "https://newexample.com/listen/new", event: "file.uploaded", is_active: true, signing_secret: "some-secret")
381
+ Uploadcare::Webhook.delete("https://example.com/listen")
382
+ Uploadcare::Webhook.list
383
+ ```
384
+
385
+ ##### Webhook signature verification
386
+
387
+ The gem has a helper class to verify a webhook signature from headers —
388
+ `Uploadcare::Param::WebhookSignatureVerifier`. This class accepts three
389
+ important options:
390
+
391
+ - **:webhook_body** — this option represents parameters received in the webhook
392
+ request in the JSON format.
393
+ **NOTE**: if you're using Rails, you should exclude options `controller`,
394
+ `action` and `post` from the `webhook_body`.
395
+ - **:signing_secret** — the secret that was set while creating/updating a
396
+ webhook. This option can be specified as an ENV var with the name
397
+ `UC_SIGNING_SECRET` — then no need to send it to the verifier class.
398
+ - **:x_uc_signature_header** — the content of the `X-Uc-Signature` HTTP header
399
+ in the webhook request.
400
+
401
+ Using the `Uploadcare::Param::WebhookSignatureVerifier` class example:
402
+
403
+ ```ruby
404
+ webhook_body = '{...}'
405
+
406
+ signing_secret = "12345X"
407
+ x_uc_signature_header = "v1=9b31c7dd83fdbf4a2e12b19d7f2b9d87d547672a325b9492457292db4f513c70"
408
+
409
+ Uploadcare::Param::WebhookSignatureVerifier.valid?(signing_secret: signing_secret, x_uc_signature_header: x_uc_signature_header, webhook_body: webhook_body)
410
+ ```
411
+
412
+ You can write your verifier. Example code:
413
+
414
+ ```ruby
415
+ webhook_body_json = '{...}'
416
+
417
+ signing_secret = ENV['UC_SIGNING_SECRET']
418
+ x_uc_signature_header = "v1=f4d859ed2fe47b9a4fcc81693d34e58ad12366a841e58a7072c1530483689cc0"
419
+
420
+ digest = OpenSSL::Digest.new('sha256')
421
+
422
+ calculated_signature = "v1=#{OpenSSL::HMAC.hexdigest(digest, signing_secret.force_encoding("utf-8"), webhook_body_json.force_encoding("utf-8"))}"
423
+
424
+ if calculated_signature == x_uc_signature_header
425
+ puts "WebHook signature matches!"
426
+ else
427
+ puts "WebHook signature mismatch!"
428
+ end
279
429
  ```
280
430
 
281
431
  #### Project
282
432
 
283
433
  `Project` provides basic info about the connected Uploadcare project. That
284
434
  object is also an Hashie::Mash, so every methods out of
285
- [these](https://uploadcare.com/documentation/rest/#project/?utm_source=github&utm_medium=referral&utm_campaign=uploadcare-ruby) will work.
435
+ [these](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/projectInfo) will work.
286
436
 
287
437
  ```ruby
288
438
  @project = Uploadcare::Project.project
@@ -297,6 +447,218 @@ object is also an Hashie::Mash, so every methods out of
297
447
  # [{"email": collaborator@gmail.com, "name": "Collaborator"}, {"email": collaborator@gmail.com, "name": "Collaborator"}]
298
448
  ```
299
449
 
450
+ #### Conversion
451
+
452
+ ##### Video
453
+
454
+ After each video file upload you obtain a file identifier in UUID format.
455
+ Then you can use this file identifier to convert your video in multiple ways:
456
+
457
+ ```ruby
458
+ Uploadcare::VideoConverter.convert(
459
+ [
460
+ {
461
+ uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
462
+ size: { resize_mode: "change_ratio", width: "600", height: "400" },
463
+ quality: "best",
464
+ format: "ogg",
465
+ cut: { start_time: "0:0:0.0", length: "0:0:1.0" },
466
+ thumbs: { N: 2, number: 1 }
467
+ }
468
+ ],
469
+ store: false
470
+ )
471
+ ```
472
+ This method accepts options to set properties of an output file:
473
+
474
+ - **uuid** — the file UUID-identifier.
475
+ - **size**:
476
+ - **resize_mode** - size operation to apply to a video file. Can be `preserve_ratio (default)`, `change_ratio`, `scale_crop` or `add_padding`.
477
+ - **width** - width for a converted video.
478
+ - **height** - height for a converted video.
479
+
480
+ ```
481
+ NOTE: you can choose to provide a single dimension (width OR height).
482
+ The value you specify for any of the dimensions should be a non-zero integer divisible by 4
483
+ ```
484
+
485
+ - **quality** - sets the level of video quality that affects file sizes and hence loading times and volumes of generated traffic. Can be `normal (default)`, `better`, `best`, `lighter`, `lightest`.
486
+ - **format** - format for a converted video. Can be `mp4 (default)`, `webm`, `ogg`.
487
+ - **cut**:
488
+ - **start_time** - defines the starting point of a fragment to cut based on your input file timeline.
489
+ - **length** - defines the duration of that fragment.
490
+ - **thumbs**:
491
+ - **N** - quantity of thumbnails for your video - non-zero integer ranging from 1 to 50; defaults to 1.
492
+ - **number** - zero-based index of a particular thumbnail in a created set, ranging from 1 to (N - 1).
493
+ - **store** - a flag indicating if Uploadcare should store your transformed outputs.
494
+
495
+ ```ruby
496
+ # Response
497
+ {
498
+ :result => [
499
+ {
500
+ :original_source=>"dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/video/-/size/600x400/change_ratio/-/quality/best/-/format/ogg/-/cut/0:0:0.0/0:0:1.0/-/thumbs~2/1/",
501
+ :token=>911933811,
502
+ :uuid=>"6f9b88bd-625c-4d60-bfde-145fa3813d95",
503
+ :thumbnails_group_uuid=>"cf34c5a1-8fcc-4db2-9ec5-62c389e84468~2"
504
+ }
505
+ ],
506
+ :problems=>{}
507
+ }
508
+ ```
509
+ Params in the response:
510
+ - **result** - info related to your transformed output(-s):
511
+ - **original_source** - built path for a particular video with all the conversion operations and parameters.
512
+ - **token** - a processing job token that can be used to get a [job status](https://uploadcare.com/docs/transformations/video-encoding/#status) (see below).
513
+ - **uuid** - UUID of your processed video file.
514
+ - **thumbnails_group_uuid** - holds :uuid-thumb-group, a UUID of a [file group](https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/groupsList) with thumbnails for an output video, based on the thumbs [operation](https://uploadcare.com/docs/transformations/video-encoding/#operation-thumbs) parameters.
515
+ - **problems** - problems related to your processing job, if any.
516
+
517
+ To convert multiple videos just add params as a hash for each video to the first argument of the `Uploadcare::VideoConverter#convert` method:
518
+
519
+ ```ruby
520
+ Uploadcare::VideoConverter.convert(
521
+ [
522
+ { video_one_params }, { video_two_params }, ...
523
+ ],
524
+ store: false
525
+ )
526
+ ```
527
+
528
+
529
+ To check a status of a video processing job you can simply use appropriate method of `Uploadcare::VideoConverter`:
530
+
531
+ ```ruby
532
+ token = 911933811
533
+ Uploadcare::VideoConverter.status(token)
534
+ ```
535
+ `token` here is a processing job token, obtained in a response of a convert video request.
536
+
537
+ ```ruby
538
+ # Response
539
+ {
540
+ :status => "finished",
541
+ :error => nil,
542
+ :result => {
543
+ :uuid => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
544
+ :thumbnails_group_uuid => "0f181f24-7551-42e5-bebc-14b15d9d3838~2"
545
+ }
546
+ }
547
+ ```
548
+
549
+ Params in the response:
550
+ - **status** - processing job status, can have one of the following values:
551
+ - *pending* — video file is being prepared for conversion.
552
+ - *processing* — video file processing is in progress.
553
+ - *finished* — the processing is finished.
554
+ - *failed* — we failed to process the video, see error for details.
555
+ - *canceled* — video processing was canceled.
556
+ - **error** - holds a processing error if we failed to handle your video.
557
+ - **result** - repeats the contents of your processing output.
558
+ - **thumbnails_group_uuid** - holds :uuid-thumb-group, a UUID of a file group with thumbnails for an output video, based on the thumbs operation parameters.
559
+ - **uuid** - a UUID of your processed video file.
560
+
561
+ More examples and options can be found [here](https://uploadcare.com/docs/transformations/video-encoding/#video-encoding).
562
+
563
+ ##### Document
564
+
565
+ After each document file upload you obtain a file identifier in UUID format.
566
+ Then you can use this file identifier to convert your document to a new format:
567
+
568
+ ```ruby
569
+ Uploadcare::DocumentConverter.convert(
570
+ [
571
+ {
572
+ uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
573
+ format: "pdf"
574
+ }
575
+ ],
576
+ store: false
577
+ )
578
+ ```
579
+ or create an image of a particular page (if using image format):
580
+ ```ruby
581
+ Uploadcare::DocumentConverter.convert(
582
+ [
583
+ {
584
+ uuid: "a4b9db2f-1591-4f4c-8f68-94018924525d",
585
+ format: "png",
586
+ page: 1
587
+ }
588
+ ],
589
+ store: false
590
+ )
591
+ ```
592
+
593
+ This method accepts options to set properties of an output file:
594
+
595
+ - **uuid** — the file UUID-identifier.
596
+ - **format** - defines the target format you want a source file converted to. The supported values are: `pdf` (default), `doc`, `docx`, `xls`, `xlsx`, `odt`, `ods`, `rtf`, `txt`, `jpg`, `png`. In case the format operation was not found, your input document will be converted to `pdf`.
597
+ - **page** - a page number of a multi-paged document to either `jpg` or `png`. The method will not work for any other target formats.
598
+
599
+ ```ruby
600
+ # Response
601
+ {
602
+ :result => [
603
+ {
604
+ :original_source=>"a4b9db2f-1591-4f4c-8f68-94018924525d/document/-/format/png/-/page/1/",
605
+ :token=>21120220
606
+ :uuid=>"88fe5ada-90f1-422a-a233-3a0f3a7cf23c"
607
+ }
608
+ ],
609
+ :problems=>{}
610
+ }
611
+ ```
612
+ Params in the response:
613
+ - **result** - info related to your transformed output(-s):
614
+ - **original_source** - source file identifier including a target format, if present.
615
+ - **token** - a processing job token that can be used to get a [job status](https://uploadcare.com/docs/transformations/document-conversion/#status) (see below).
616
+ - **uuid** - UUID of your processed document file.
617
+ - **problems** - problems related to your processing job, if any.
618
+
619
+ To convert multiple documents just add params as a hash for each document to the first argument of the `Uploadcare::DocumentConverter#convert` method:
620
+
621
+ ```ruby
622
+ Uploadcare::DocumentConverter.convert(
623
+ [
624
+ { doc_one_params }, { doc_two_params }, ...
625
+ ],
626
+ store: false
627
+ )
628
+ ```
629
+
630
+ To check a status of a document processing job you can simply use appropriate method of `Uploadcare::DocumentConverter`:
631
+
632
+ ```ruby
633
+ token = 21120220
634
+ Uploadcare::DocumentConverter.status(token)
635
+ ```
636
+ `token` here is a processing job token, obtained in a response of a convert document request.
637
+
638
+ ```ruby
639
+ # Response
640
+ {
641
+ :status => "finished",
642
+ :error => nil,
643
+ :result => {
644
+ :uuid => "a4b9db2f-1591-4f4c-8f68-94018924525d"
645
+ }
646
+ }
647
+ ```
648
+
649
+ Params in the response:
650
+ - **status** - processing job status, can have one of the following values:
651
+ - *pending* — document file is being prepared for conversion.
652
+ - *processing* — document file processing is in progress.
653
+ - *finished* — the processing is finished.
654
+ - *failed* — we failed to process the document, see error for details.
655
+ - *canceled* — document processing was canceled.
656
+ - **error** - holds a processing error if we failed to handle your document.
657
+ - **result** - repeats the contents of your processing output.
658
+ - **uuid** - a UUID of your processed document file.
659
+
660
+ More examples and options can be found [here](https://uploadcare.com/docs/transformations/document-conversion/#document-conversion)
661
+
300
662
  ## Useful links
301
663
 
302
664
  * [Development](https://github.com/uploadcare/uploadcare-ruby/blob/main/DEVELOPMENT.md)
@@ -0,0 +1,59 @@
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
+ API_VERSION_HEADER_VALUE = 'application/vnd.uploadcare-v0.5+json'
14
+
15
+ def headers
16
+ {
17
+ 'Content-Type': 'application/json',
18
+ 'Accept': API_VERSION_HEADER_VALUE,
19
+ 'User-Agent': Uploadcare::Param::UserAgent.call
20
+ }
21
+ end
22
+
23
+ private
24
+
25
+ def send_convert_request(arr, options, url_builder_class)
26
+ body = build_body_for_many(arr, options, url_builder_class)
27
+ post(uri: convert_uri, content: body)
28
+ end
29
+
30
+ def success(response)
31
+ body = response.body.to_s
32
+ extract_result(body)
33
+ end
34
+
35
+ def extract_result(response_body)
36
+ return if response_body.empty?
37
+
38
+ parsed_body = JSON.parse(response_body, symbolize_names: true)
39
+ errors = parsed_body[:error] || parsed_body[:problems]
40
+ return Dry::Monads::Failure(errors) unless errors.nil? || errors.empty?
41
+
42
+ Dry::Monads::Success(parsed_body)
43
+ end
44
+
45
+ # Prepares body for convert_many method
46
+ def build_body_for_many(arr, options, url_builder_class)
47
+ {
48
+ paths: arr.map do |params|
49
+ url_builder_class.call(
50
+ **build_paths_body(params)
51
+ )
52
+ end,
53
+ store: options[:store]
54
+ }.compact.to_json
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end