uploadcare-ruby 3.0.5 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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