uploadcare-ruby 3.1.0.pre.rc1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +4 -10
- data/README.md +117 -34
- data/lib/uploadcare/client/conversion/base_conversion_client.rb +15 -10
- data/lib/uploadcare/client/conversion/document_conversion_client.rb +6 -3
- data/lib/uploadcare/client/conversion/video_conversion_client.rb +8 -4
- data/lib/uploadcare/client/group_client.rb +1 -1
- data/lib/uploadcare/client/multipart_upload/chunks_client.rb +15 -6
- data/lib/uploadcare/client/multipart_upload_client.rb +12 -15
- data/lib/uploadcare/client/rest_client.rb +2 -2
- data/lib/uploadcare/client/upload_client.rb +7 -0
- data/lib/uploadcare/client/uploader_client.rb +13 -21
- data/lib/uploadcare/client/webhook_client.rb +1 -1
- data/lib/uploadcare/entity/conversion/base_converter.rb +36 -0
- data/lib/uploadcare/entity/conversion/document_converter.rb +15 -0
- data/lib/uploadcare/entity/conversion/video_converter.rb +15 -0
- data/lib/uploadcare/entity/file.rb +26 -1
- data/lib/uploadcare/entity/uploader.rb +9 -3
- data/lib/uploadcare/ruby/version.rb +1 -1
- data/uploadcare-ruby.gemspec +2 -2
- metadata +9 -9
- data/lib/uploadcare/entity/document_converter.rb +0 -26
- data/lib/uploadcare/entity/video_converter.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08303dd0379957a7780c58d562c2ddbf9ae42e02d8069e19404defb9d7455292'
|
4
|
+
data.tar.gz: d661a6c49bdcb5b5789b3e22dac0a0a439012f0a1bfc5a55b3cdc0c64094ef8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4b2c4f5342f48908731446e7ca2fa5aabef6568d99dede4ca46f3ed3df13993a156f70f84ac6a87d36799b2d589bc465814c7efeefcbfd6a3e459d3e378814f
|
7
|
+
data.tar.gz: 0ffba57715c58eeeabc2d2b44884e67d09a5ee41b916fd10248e46822d5b35d3dd5c24c450ec4961a03b5a6f01903a5867007248bd347b88ac3568d89104c592
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 3.1.0
|
3
|
+
## 3.1.0 2021-09-21
|
4
4
|
|
5
|
-
|
6
|
-
-
|
7
|
-
-
|
8
|
-
- Add new attributes to Uploadcare::File (variations, video_info, source, rekognition_info)
|
9
|
-
|
10
|
-
### Fixed
|
11
|
-
|
12
|
-
- Fix the `uninitialized constant Uploadcare::Client::ApiStruct (NameError)` error
|
5
|
+
- Added documents and videos conversion
|
6
|
+
- Added new attributes to the Entity class (variations, video_info, source, rekognition_info)
|
7
|
+
- Added an opportunity to add custom logic to large files uploading process
|
13
8
|
|
14
9
|
## 3.0.5 2021-04-15
|
15
10
|
|
@@ -23,7 +18,6 @@
|
|
23
18
|
- Added CI
|
24
19
|
|
25
20
|
## 3.0.3-dev 2020-03-13
|
26
|
-
|
27
21
|
- Added better pagination and iterators for GroupList & FileList
|
28
22
|
|
29
23
|
## 3.0.2-dev 2020-03-11
|
data/README.md
CHANGED
@@ -45,7 +45,7 @@ Note that `uploadcare-ruby` **3.x** is not backward compatible with
|
|
45
45
|
Add this line to your application's Gemfile:
|
46
46
|
|
47
47
|
```ruby
|
48
|
-
gem
|
48
|
+
gem "uploadcare-ruby"
|
49
49
|
```
|
50
50
|
|
51
51
|
And then execute:
|
@@ -67,8 +67,8 @@ settings can be seen in [`lib/uploadcare.rb`](lib/uploadcare.rb)
|
|
67
67
|
|
68
68
|
```ruby
|
69
69
|
# your_config_initializer_file.rb
|
70
|
-
Uploadcare.config.public_key =
|
71
|
-
Uploadcare.config.secret_key =
|
70
|
+
Uploadcare.config.public_key = "demopublickey"
|
71
|
+
Uploadcare.config.secret_key = "demoprivatekey"
|
72
72
|
```
|
73
73
|
|
74
74
|
## Usage
|
@@ -116,21 +116,64 @@ Uploadcare supports multiple ways to upload files:
|
|
116
116
|
|
117
117
|
```ruby
|
118
118
|
# Smart upload - detects type of passed object and picks appropriate upload method
|
119
|
-
Uploadcare::Uploader.upload(
|
119
|
+
Uploadcare::Uploader.upload("https://placekitten.com/96/139")
|
120
120
|
```
|
121
121
|
|
122
122
|
There are explicit ways to select upload type:
|
123
123
|
|
124
124
|
```ruby
|
125
|
-
files = [File.open(
|
125
|
+
files = [File.open("1.jpg"), File.open("1.jpg"]
|
126
126
|
Uploadcare::Uploader.upload_files(files)
|
127
127
|
|
128
|
-
Uploadcare::Uploader.upload_from_url(
|
128
|
+
Uploadcare::Uploader.upload_from_url("https://placekitten.com/96/139")
|
129
|
+
```
|
130
|
+
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:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
Uploadcare::Uploader.upload_from_url("https://placekitten.com/96/139", async: true)
|
134
|
+
# => "c6e31082-6bdc-4cb3-bef5-14dd10574d72"
|
135
|
+
```
|
136
|
+
|
137
|
+
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:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
Uploadcare::Uploader.get_upload_from_url_status("1251ee66-3631-4416-a2fb-96ba59f5a515")
|
141
|
+
# => 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"})
|
142
|
+
```
|
143
|
+
|
144
|
+
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.
|
129
145
|
|
146
|
+
```ruby
|
130
147
|
# multipart upload - can be useful for files bigger than 10 mb
|
131
|
-
Uploadcare::Uploader.multipart_upload(File.open(
|
148
|
+
Uploadcare::Uploader.multipart_upload(File.open("big_file.bin"), store: true)
|
132
149
|
```
|
133
150
|
|
151
|
+
For the multipart upload you can pass a block to add some additional logic after each file chunk is uploaded.
|
152
|
+
For example to track file uploading progress you can do something like this:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
file = File.open("big_file.bin")
|
156
|
+
progress = 0
|
157
|
+
Uploadcare::Uploader.multipart_upload(file, store: true) do |options|
|
158
|
+
progress += (100.0 / options[:links_count])
|
159
|
+
puts "PROGRESS = #{progress}"
|
160
|
+
end
|
161
|
+
```
|
162
|
+
Output of the code above looks like:
|
163
|
+
```console
|
164
|
+
PROGRESS = 4.545454545454546
|
165
|
+
PROGRESS = 9.090909090909092
|
166
|
+
PROGRESS = 13.636363636363637
|
167
|
+
...
|
168
|
+
```
|
169
|
+
Options available in a block:
|
170
|
+
- **:chunk_size** - size of each chunk in bytes;
|
171
|
+
- **:object** - file object which is going to be uploaded;
|
172
|
+
- **:offset** - offset from the beginning of a File object in bytes;
|
173
|
+
- **:link_id** - index of a link provided by Uploadcare API. Might be treated as index of a chunk;
|
174
|
+
- **:links** - array of links for uploading file's chunks;
|
175
|
+
- **:links_count** - count of the array of links.
|
176
|
+
|
134
177
|
#### Uploading options
|
135
178
|
|
136
179
|
You can override global [`:autostore`](#initialization) option for each upload request:
|
@@ -144,7 +187,7 @@ You can override global [`:autostore`](#initialization) option for each upload r
|
|
144
187
|
Most methods are also available through `Uploadcare::Api` object:
|
145
188
|
```ruby
|
146
189
|
# Same as Uploadcare::Uploader.upload
|
147
|
-
Uploadcare::Api.upload(
|
190
|
+
Uploadcare::Api.upload("https://placekitten.com/96/139")
|
148
191
|
```
|
149
192
|
|
150
193
|
Entities are representations of objects in Uploadcare cloud.
|
@@ -154,7 +197,7 @@ Entities are representations of objects in Uploadcare cloud.
|
|
154
197
|
File entity contains its metadata.
|
155
198
|
|
156
199
|
```ruby
|
157
|
-
@file = Uploadcare::File.file(
|
200
|
+
@file = Uploadcare::File.file("FILE_ID_IN_YOUR_PROJECT")
|
158
201
|
{"datetime_removed"=>nil,
|
159
202
|
"datetime_stored"=>"2020-01-16T15:03:15.315064Z",
|
160
203
|
"datetime_uploaded"=>"2020-01-16T15:03:14.676902Z",
|
@@ -179,13 +222,53 @@ File entity contains its metadata.
|
|
179
222
|
"https://api.uploadcare.com/files/FILE_ID_IN_YOUR_PROJECT/",
|
180
223
|
"uuid"=>"8f64f313-e6b1-4731-96c0-6751f1e7a50a"}
|
181
224
|
|
182
|
-
@file.
|
225
|
+
@file.copy # copies file, returns a new (copied) file metadata
|
183
226
|
|
184
227
|
@file.store # stores file, returns updated metadata
|
185
228
|
|
186
229
|
@file.delete #deletes file. Returns updated metadata
|
187
230
|
```
|
188
231
|
|
232
|
+
The File object is also can be converted if it is a document or a video file. Imagine, you have a document file:
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
@file = Uploadcare::File.file("FILE_ID_IN_YOUR_PROJECT")
|
236
|
+
```
|
237
|
+
|
238
|
+
To convert it to an another file, just do:
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
@converted_file = @file.convert_document({ format: "png", page: "1" }, store: true)
|
242
|
+
# => {
|
243
|
+
# "uuid"=>"<NEW_FILE_UUID>"}
|
244
|
+
# ...other file info...
|
245
|
+
# }
|
246
|
+
# OR
|
247
|
+
# 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"})
|
248
|
+
```
|
249
|
+
|
250
|
+
Same works for video files:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
@converted_file = @file.convert_video(
|
254
|
+
{
|
255
|
+
format: "ogg",
|
256
|
+
quality: "best",
|
257
|
+
cut: { start_time: "0:0:0.1", length: "end" },
|
258
|
+
size: { resize_mode: "change_ratio", width: "600", height: "400" },
|
259
|
+
thumb: { N: 1, number: 2 }
|
260
|
+
},
|
261
|
+
store: true
|
262
|
+
)
|
263
|
+
# => {
|
264
|
+
# "uuid"=>"<NEW_FILE_UUID>"}
|
265
|
+
# ...other file info...
|
266
|
+
# }
|
267
|
+
# OR
|
268
|
+
# 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\""})
|
269
|
+
```
|
270
|
+
|
271
|
+
More about file conversion [here](#conversion).
|
189
272
|
Metadata of deleted files is stored permanently.
|
190
273
|
|
191
274
|
#### FileList
|
@@ -228,7 +311,7 @@ stored just for your convenience. That is why they are frozen.
|
|
228
311
|
options = {
|
229
312
|
limit: 10,
|
230
313
|
stored: true,
|
231
|
-
ordering:
|
314
|
+
ordering: "-datetime_uploaded",
|
232
315
|
from: "2017-01-01T00:00:00",
|
233
316
|
}
|
234
317
|
@list = @api.file_list(options)
|
@@ -265,8 +348,8 @@ That's a requirement of our API.
|
|
265
348
|
|
266
349
|
```ruby
|
267
350
|
# group can be created from an array of Uploadcare files (UUIDs)
|
268
|
-
@file =
|
269
|
-
@file2 =
|
351
|
+
@file = "134dc30c-093e-4f48-a5b9-966fe9cb1d01"
|
352
|
+
@file2 = "134dc30c-093e-4f48-a5b9-966fe9cb1d02"
|
270
353
|
@files_ary = [@file, @file2]
|
271
354
|
@files = Uploadcare::Uploader.upload @files_ary
|
272
355
|
@group = Uploadcare::Group.create @files
|
@@ -293,9 +376,9 @@ You can use webhooks to provide notifications about your uploads to target urls.
|
|
293
376
|
This gem lets you create and manage webhooks.
|
294
377
|
|
295
378
|
```ruby
|
296
|
-
Uploadcare::Webhook.create(target_url:
|
297
|
-
Uploadcare::Webhook.update(<webhook_id>, target_url:
|
298
|
-
Uploadcare::Webhook.delete(
|
379
|
+
Uploadcare::Webhook.create(target_url: "https://example.com/listen", event: "file.uploaded", is_active: true)
|
380
|
+
Uploadcare::Webhook.update(<webhook_id>, target_url: "https://newexample.com/listen/new", event: "file.uploaded", is_active: true)
|
381
|
+
Uploadcare::Webhook.delete("https://example.com/listen")
|
299
382
|
Uploadcare::Webhook.list
|
300
383
|
```
|
301
384
|
|
@@ -332,13 +415,14 @@ Uploadcare::VideoConverter.convert(
|
|
332
415
|
[
|
333
416
|
{
|
334
417
|
uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
|
335
|
-
size: { resize_mode:
|
336
|
-
quality:
|
337
|
-
format:
|
338
|
-
cut: { start_time:
|
418
|
+
size: { resize_mode: "change_ratio", width: "600", height: "400" },
|
419
|
+
quality: "best",
|
420
|
+
format: "ogg",
|
421
|
+
cut: { start_time: "0:0:0.0", length: "0:0:1.0" },
|
339
422
|
thumbs: { N: 2, number: 1 }
|
340
423
|
}
|
341
|
-
],
|
424
|
+
],
|
425
|
+
store: false
|
342
426
|
)
|
343
427
|
```
|
344
428
|
This method accepts options to set properties of an output file:
|
@@ -392,7 +476,8 @@ To convert multiple videos just add params as a hash for each video to the first
|
|
392
476
|
Uploadcare::VideoConverter.convert(
|
393
477
|
[
|
394
478
|
{ video_one_params }, { video_two_params }, ...
|
395
|
-
],
|
479
|
+
],
|
480
|
+
store: false
|
396
481
|
)
|
397
482
|
```
|
398
483
|
|
@@ -433,7 +518,7 @@ More examples and options can be found [here](https://uploadcare.com/docs/transf
|
|
433
518
|
|
434
519
|
##### Document
|
435
520
|
|
436
|
-
Uploadcare allows converting documents to the following target formats:
|
521
|
+
Uploadcare allows converting documents to the following target formats: doc, docx, xls, xlsx, odt, ods, rtf, txt, pdf, jpg, png. Document Conversion works via our [REST API](https://uploadcare.com/api-refs/rest-api/v0.6.0/).
|
437
522
|
|
438
523
|
After each document file upload you obtain a file identifier in UUID format.
|
439
524
|
Then you can use this file identifier to convert your document to a new format:
|
@@ -443,9 +528,10 @@ Uploadcare::DocumentConverter.convert(
|
|
443
528
|
[
|
444
529
|
{
|
445
530
|
uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
|
446
|
-
format:
|
531
|
+
format: "pdf"
|
447
532
|
}
|
448
|
-
],
|
533
|
+
],
|
534
|
+
store: false
|
449
535
|
)
|
450
536
|
```
|
451
537
|
or create an image of a particular page (if using image format):
|
@@ -454,24 +540,20 @@ Uploadcare::DocumentConverter.convert(
|
|
454
540
|
[
|
455
541
|
{
|
456
542
|
uuid: "a4b9db2f-1591-4f4c-8f68-94018924525d",
|
457
|
-
format:
|
543
|
+
format: "png",
|
458
544
|
page: 1
|
459
545
|
}
|
460
|
-
],
|
546
|
+
],
|
547
|
+
store: false
|
461
548
|
)
|
462
549
|
```
|
463
550
|
|
464
551
|
This method accepts options to set properties of an output file:
|
465
552
|
|
466
553
|
- **uuid** — the file UUID-identifier.
|
467
|
-
- **format** - defines the target format you want a source file converted to. The supported values are: `pdf (default)
|
554
|
+
- **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`.
|
468
555
|
- **page** - a page number of a multi-paged document to either `jpg` or `png`. The method will not work for any other target formats.
|
469
556
|
|
470
|
-
```
|
471
|
-
NOTE: Use an enhanced.jpg output format for PDF documents with inline fonts.
|
472
|
-
When converting multi-page documents to an image format (jpg or png), the output will be a zip archive with one image per page.
|
473
|
-
```
|
474
|
-
|
475
557
|
```ruby
|
476
558
|
# Response
|
477
559
|
{
|
@@ -498,7 +580,8 @@ To convert multiple documents just add params as a hash for each document to the
|
|
498
580
|
Uploadcare::DocumentConverter.convert(
|
499
581
|
[
|
500
582
|
{ doc_one_params }, { doc_two_params }, ...
|
501
|
-
],
|
583
|
+
],
|
584
|
+
store: false
|
502
585
|
)
|
503
586
|
```
|
504
587
|
|
@@ -10,42 +10,47 @@ module Uploadcare
|
|
10
10
|
#
|
11
11
|
# @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#tag/Conversion
|
12
12
|
class BaseConversionClient < RestClient
|
13
|
+
API_VERSION_HEADER_VALUE = 'application/vnd.uploadcare-v0.5+json'
|
14
|
+
|
13
15
|
def headers
|
14
16
|
{
|
15
|
-
'Content-
|
16
|
-
'Accept':
|
17
|
+
'Content-Type': 'application/json',
|
18
|
+
'Accept': API_VERSION_HEADER_VALUE,
|
17
19
|
'User-Agent': Uploadcare::Param::UserAgent.call
|
18
20
|
}
|
19
21
|
end
|
20
22
|
|
21
23
|
private
|
22
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
|
+
|
23
30
|
def success(response)
|
24
31
|
body = response.body.to_s
|
25
|
-
|
26
|
-
|
27
|
-
Dry::Monads::Success(result)
|
32
|
+
extract_result(body)
|
28
33
|
end
|
29
34
|
|
30
35
|
def extract_result(response_body)
|
31
|
-
return
|
36
|
+
return if response_body.empty?
|
32
37
|
|
33
38
|
parsed_body = JSON.parse(response_body, symbolize_names: true)
|
34
39
|
errors = parsed_body[:error] || parsed_body[:problems]
|
35
|
-
|
40
|
+
return Dry::Monads::Failure(errors) unless errors.nil? || errors.empty?
|
36
41
|
|
37
|
-
parsed_body
|
42
|
+
Dry::Monads::Success(parsed_body)
|
38
43
|
end
|
39
44
|
|
40
45
|
# Prepares body for convert_many method
|
41
46
|
def build_body_for_many(arr, options, url_builder_class)
|
42
47
|
{
|
43
|
-
|
48
|
+
paths: arr.map do |params|
|
44
49
|
url_builder_class.call(
|
45
50
|
**build_paths_body(params)
|
46
51
|
)
|
47
52
|
end,
|
48
|
-
|
53
|
+
store: options[:store]
|
49
54
|
}.compact.to_json
|
50
55
|
end
|
51
56
|
end
|
@@ -13,10 +13,9 @@ module Uploadcare
|
|
13
13
|
def convert_many(
|
14
14
|
arr,
|
15
15
|
options = {},
|
16
|
-
url_builder_class =
|
16
|
+
url_builder_class = Param::Conversion::Document::ProcessingJobUrlBuilder
|
17
17
|
)
|
18
|
-
|
19
|
-
post(uri: '/convert/document/', content: body)
|
18
|
+
send_convert_request(arr, options, url_builder_class)
|
20
19
|
end
|
21
20
|
|
22
21
|
def get_conversion_status(token)
|
@@ -25,6 +24,10 @@ module Uploadcare
|
|
25
24
|
|
26
25
|
private
|
27
26
|
|
27
|
+
def convert_uri
|
28
|
+
'/convert/document/'
|
29
|
+
end
|
30
|
+
|
28
31
|
def build_paths_body(params)
|
29
32
|
{
|
30
33
|
uuid: params[:uuid],
|
@@ -12,12 +12,12 @@ module Uploadcare
|
|
12
12
|
# @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/videoConvert
|
13
13
|
class VideoConversionClient < BaseConversionClient
|
14
14
|
def convert_many(
|
15
|
-
|
15
|
+
params,
|
16
16
|
options = {},
|
17
|
-
url_builder_class =
|
17
|
+
url_builder_class = Param::Conversion::Video::ProcessingJobUrlBuilder
|
18
18
|
)
|
19
|
-
|
20
|
-
|
19
|
+
video_params = params.is_a?(Hash) ? [params] : params
|
20
|
+
send_convert_request(video_params, options, url_builder_class)
|
21
21
|
end
|
22
22
|
|
23
23
|
def get_conversion_status(token)
|
@@ -26,6 +26,10 @@ module Uploadcare
|
|
26
26
|
|
27
27
|
private
|
28
28
|
|
29
|
+
def convert_uri
|
30
|
+
'/convert/video/'
|
31
|
+
end
|
32
|
+
|
29
33
|
def build_paths_body(params)
|
30
34
|
{
|
31
35
|
uuid: params[:uuid],
|
@@ -14,7 +14,7 @@ module Uploadcare
|
|
14
14
|
body_hash = group_body_hash(file_list, **options)
|
15
15
|
body = HTTP::FormData::Multipart.new(body_hash)
|
16
16
|
post(path: 'group/',
|
17
|
-
headers: { 'Content-
|
17
|
+
headers: { 'Content-Type': body.content_type },
|
18
18
|
body: body)
|
19
19
|
end
|
20
20
|
|
@@ -16,12 +16,21 @@ module Uploadcare
|
|
16
16
|
# In multiple threads, split file into chunks and upload those chunks into respective Amazon links
|
17
17
|
# @param object [File]
|
18
18
|
# @param links [Array] of strings; by default list of Amazon storage urls
|
19
|
-
def upload_chunks(object, links)
|
19
|
+
def self.upload_chunks(object, links)
|
20
20
|
Parallel.each(0...links.count, in_threads: Uploadcare.config.upload_threads) do |link_id|
|
21
|
-
client = self.class.new
|
22
21
|
offset = link_id * CHUNK_SIZE
|
23
22
|
chunk = IO.read(object, CHUNK_SIZE, offset)
|
24
|
-
|
23
|
+
new.upload_chunk(chunk, links[link_id])
|
24
|
+
next unless block_given?
|
25
|
+
|
26
|
+
yield(
|
27
|
+
chunk_size: CHUNK_SIZE,
|
28
|
+
object: object,
|
29
|
+
offset: offset,
|
30
|
+
link_id: link_id,
|
31
|
+
links: links,
|
32
|
+
links_count: links.count
|
33
|
+
)
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
@@ -33,12 +42,12 @@ module Uploadcare
|
|
33
42
|
{}
|
34
43
|
end
|
35
44
|
|
36
|
-
private
|
37
|
-
|
38
45
|
def upload_chunk(chunk, link)
|
39
|
-
put(path: link, body: chunk, headers: { 'Content-
|
46
|
+
put(path: link, body: chunk, headers: { 'Content-Type': 'application/octet-stream' })
|
40
47
|
end
|
41
48
|
|
49
|
+
private
|
50
|
+
|
42
51
|
def default_params
|
43
52
|
{}
|
44
53
|
end
|
@@ -13,23 +13,23 @@ module Uploadcare
|
|
13
13
|
|
14
14
|
# Upload a big file by splitting it into parts and sending those parts into assigned buckets
|
15
15
|
# object should be File
|
16
|
-
def upload(object, store: false)
|
16
|
+
def upload(object, store: false, &block)
|
17
17
|
response = upload_start(object, store: store)
|
18
18
|
return response unless response.success[:parts] && response.success[:uuid]
|
19
19
|
|
20
20
|
links = response.success[:parts]
|
21
21
|
uuid = response.success[:uuid]
|
22
|
-
ChunksClient.
|
22
|
+
ChunksClient.upload_chunks(object, links, &block)
|
23
23
|
upload_complete(uuid)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Asks Uploadcare server to create a number of storage bin for uploads
|
27
27
|
def upload_start(object, store: false)
|
28
28
|
body = HTTP::FormData::Multipart.new(
|
29
|
-
Param::Upload::UploadParamsGenerator.call(store).merge(
|
29
|
+
Param::Upload::UploadParamsGenerator.call(store).merge(form_data_for(object))
|
30
30
|
)
|
31
31
|
post(path: 'multipart/start/',
|
32
|
-
headers: { 'Content-
|
32
|
+
headers: { 'Content-Type': body.content_type },
|
33
33
|
body: body)
|
34
34
|
end
|
35
35
|
|
@@ -37,24 +37,21 @@ module Uploadcare
|
|
37
37
|
def upload_complete(uuid)
|
38
38
|
body = HTTP::FormData::Multipart.new(
|
39
39
|
{
|
40
|
-
|
41
|
-
|
40
|
+
UPLOADCARE_PUB_KEY: Uploadcare.config.public_key,
|
41
|
+
uuid: uuid
|
42
42
|
}
|
43
43
|
)
|
44
|
-
post(path: 'multipart/complete/', body: body, headers: { 'Content-
|
44
|
+
post(path: 'multipart/complete/', body: body, headers: { 'Content-Type': body.content_type })
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
-
def
|
50
|
-
|
51
|
-
mime_type = file.content_type if file.respond_to?(:content_type)
|
52
|
-
options = { filename: filename, content_type: mime_type }.compact
|
53
|
-
file = HTTP::FormData::File.new(file, options)
|
49
|
+
def form_data_for(file)
|
50
|
+
form_data_file = super(file)
|
54
51
|
{
|
55
|
-
filename:
|
56
|
-
size:
|
57
|
-
content_type:
|
52
|
+
filename: form_data_file.filename,
|
53
|
+
size: form_data_file.size,
|
54
|
+
content_type: form_data_file.content_type
|
58
55
|
}
|
59
56
|
end
|
60
57
|
|
@@ -25,7 +25,7 @@ module Uploadcare
|
|
25
25
|
# Handle throttling as well
|
26
26
|
def request(uri:, method: 'GET', **options)
|
27
27
|
request_headers = Param::AuthenticationHeader.call(method: method.upcase, uri: uri,
|
28
|
-
content_type: headers[:'Content-
|
28
|
+
content_type: headers[:'Content-Type'], **options)
|
29
29
|
handle_throttling do
|
30
30
|
send("api_struct_#{method.downcase}", path: remove_trailing_slash(uri),
|
31
31
|
headers: request_headers, body: options[:content])
|
@@ -54,7 +54,7 @@ module Uploadcare
|
|
54
54
|
|
55
55
|
def headers
|
56
56
|
{
|
57
|
-
'Content-
|
57
|
+
'Content-Type': 'application/json',
|
58
58
|
'Accept': 'application/vnd.uploadcare-v0.5+json',
|
59
59
|
'User-Agent': Uploadcare::Param::UserAgent.call
|
60
60
|
}
|
@@ -28,6 +28,13 @@ module Uploadcare
|
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
+
def form_data_for(file)
|
32
|
+
filename = file.original_filename if file.respond_to?(:original_filename)
|
33
|
+
mime_type = file.content_type if file.respond_to?(:content_type)
|
34
|
+
options = { filename: filename, content_type: mime_type }.compact
|
35
|
+
HTTP::FormData::File.new(file, options)
|
36
|
+
end
|
37
|
+
|
31
38
|
def default_params
|
32
39
|
{}
|
33
40
|
end
|
@@ -15,7 +15,7 @@ module Uploadcare
|
|
15
15
|
def upload_many(arr, **options)
|
16
16
|
body = upload_many_body(arr, **options)
|
17
17
|
post(path: 'base/',
|
18
|
-
headers: { 'Content-
|
18
|
+
headers: { 'Content-Type': body.content_type },
|
19
19
|
body: body)
|
20
20
|
end
|
21
21
|
|
@@ -35,7 +35,7 @@ module Uploadcare
|
|
35
35
|
# - async - returns upload token instead of upload data
|
36
36
|
def upload_from_url(url, **options)
|
37
37
|
body = upload_from_url_body(url, **options)
|
38
|
-
token_response = post(path: 'from_url/', headers: { 'Content-
|
38
|
+
token_response = post(path: 'from_url/', headers: { 'Content-Type': body.content_type }, body: body)
|
39
39
|
return token_response if options[:async]
|
40
40
|
|
41
41
|
uploaded_response = poll_upload_response(token_response.success[:token])
|
@@ -44,6 +44,14 @@ module Uploadcare
|
|
44
44
|
Dry::Monads::Success(files: [uploaded_response.success])
|
45
45
|
end
|
46
46
|
|
47
|
+
# Check upload status
|
48
|
+
#
|
49
|
+
# @see https://uploadcare.com/api-refs/upload-api/#operation/fromURLUploadStatus
|
50
|
+
def get_upload_from_url_status(token)
|
51
|
+
query_params = { token: token }
|
52
|
+
get(path: 'from_url/status/', params: query_params)
|
53
|
+
end
|
54
|
+
|
47
55
|
private
|
48
56
|
|
49
57
|
alias api_struct_post post
|
@@ -55,41 +63,25 @@ module Uploadcare
|
|
55
63
|
with_retries(max_tries: Uploadcare.config.max_request_tries,
|
56
64
|
base_sleep_seconds: Uploadcare.config.base_request_sleep,
|
57
65
|
max_sleep_seconds: Uploadcare.config.max_request_sleep) do
|
58
|
-
response =
|
66
|
+
response = get_upload_from_url_status(token)
|
59
67
|
raise RequestError if %w[progress waiting unknown].include?(response.success[:status])
|
60
68
|
|
61
69
|
response
|
62
70
|
end
|
63
71
|
end
|
64
72
|
|
65
|
-
# Check upload status
|
66
|
-
#
|
67
|
-
# @see https://uploadcare.com/api-refs/upload-api/#operation/fromURLUploadStatus
|
68
|
-
def get_status_response(token)
|
69
|
-
query_params = { token: token }
|
70
|
-
get(path: 'from_url/status/', params: query_params)
|
71
|
-
end
|
72
|
-
|
73
73
|
# Prepares body for upload_many method
|
74
74
|
def upload_many_body(arr, **options)
|
75
75
|
files_formdata = arr.map do |file|
|
76
76
|
[HTTP::FormData::File.new(file).filename,
|
77
77
|
form_data_for(file)]
|
78
78
|
end.to_h
|
79
|
-
p Param::Upload::UploadParamsGenerator.call(options[:store]).merge(files_formdata)
|
80
79
|
HTTP::FormData::Multipart.new(
|
81
80
|
Param::Upload::UploadParamsGenerator.call(options[:store]).merge(files_formdata)
|
82
81
|
)
|
83
82
|
end
|
84
83
|
|
85
|
-
|
86
|
-
filename = file.original_filename if file.respond_to?(:original_filename)
|
87
|
-
mime_type = file.content_type if file.respond_to?(:content_type)
|
88
|
-
options = { filename: filename, content_type: mime_type }.compact
|
89
|
-
HTTP::FormData::File.new(file, options)
|
90
|
-
end
|
91
|
-
|
92
|
-
STORE_VALUES = {
|
84
|
+
STORE_VALUES_MAP = {
|
93
85
|
true => '1',
|
94
86
|
false => '0'
|
95
87
|
}.freeze
|
@@ -100,7 +92,7 @@ module Uploadcare
|
|
100
92
|
options.merge(
|
101
93
|
'pub_key' => Uploadcare.config.public_key,
|
102
94
|
'source_url' => url,
|
103
|
-
'store' =>
|
95
|
+
'store' => STORE_VALUES_MAP[options[:store]]
|
104
96
|
)
|
105
97
|
)
|
106
98
|
end
|
@@ -13,7 +13,7 @@ module Uploadcare
|
|
13
13
|
body = {
|
14
14
|
'target_url': options[:target_url],
|
15
15
|
'event': options[:event] || 'file.uploaded',
|
16
|
-
'is_active': options[:is_active]
|
16
|
+
'is_active': options[:is_active].nil? ? true : options[:is_active]
|
17
17
|
}.to_json
|
18
18
|
post(uri: '/webhooks/', content: body)
|
19
19
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Uploadcare
|
4
|
+
module Entity
|
5
|
+
module Conversion
|
6
|
+
# This serializer lets a user convert uploaded documents
|
7
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/documentConvert
|
8
|
+
class BaseConverter < Entity
|
9
|
+
class << self
|
10
|
+
# Converts files
|
11
|
+
#
|
12
|
+
# @param doc_params [Array] of hashes with params or [Hash]
|
13
|
+
# @option options [Boolean] :store (false) whether to store file on servers.
|
14
|
+
def convert(params, options = {})
|
15
|
+
files_params = params.is_a?(Hash) ? [params] : params
|
16
|
+
conversion_client.new.convert_many(files_params, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a status of a conversion job
|
20
|
+
#
|
21
|
+
# @param token [Integer, String] token obtained from a server in convert method
|
22
|
+
def status(token)
|
23
|
+
conversion_client.new.get_conversion_status(token)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def conversion_client
|
29
|
+
clients[:base]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
include Conversion
|
36
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_converter'
|
4
|
+
|
5
|
+
module Uploadcare
|
6
|
+
module Entity
|
7
|
+
module Conversion
|
8
|
+
# This serializer lets a user convert uploaded documents
|
9
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/documentConvert
|
10
|
+
class DocumentConverter < BaseConverter
|
11
|
+
client_service Client::Conversion::DocumentConversionClient
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_converter'
|
4
|
+
|
5
|
+
module Uploadcare
|
6
|
+
module Entity
|
7
|
+
module Conversion
|
8
|
+
# This serializer lets a user convert uploaded videos, and usually returns an array of results
|
9
|
+
# @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/videoConvert
|
10
|
+
class VideoConverter < BaseConverter
|
11
|
+
client_service Client::Conversion::VideoConversionClient
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -13,7 +13,7 @@ module Uploadcare
|
|
13
13
|
:source, :rekognition_info
|
14
14
|
|
15
15
|
# gets file's uuid - even if it's only initialized with url
|
16
|
-
# @
|
16
|
+
# @returns [String]
|
17
17
|
def uuid
|
18
18
|
return @entity.uuid if @entity.uuid
|
19
19
|
|
@@ -26,6 +26,20 @@ module Uploadcare
|
|
26
26
|
initialize(File.info(uuid).entity)
|
27
27
|
end
|
28
28
|
|
29
|
+
# The method to convert a document file to another file
|
30
|
+
# gets (conversion) params [Hash], options (store: Boolean) [Hash], converter [Class]
|
31
|
+
# @returns [File]
|
32
|
+
def convert_document(params = {}, options = {}, converter = Conversion::DocumentConverter)
|
33
|
+
convert_file(params, converter, options)
|
34
|
+
end
|
35
|
+
|
36
|
+
# The method to convert a video file to another file
|
37
|
+
# gets (conversion) params [Hash], options (store: Boolean) [Hash], converter [Class]
|
38
|
+
# @returns [File]
|
39
|
+
def convert_video(params = {}, options = {}, converter = Conversion::VideoConverter)
|
40
|
+
convert_file(params, converter, options)
|
41
|
+
end
|
42
|
+
|
29
43
|
# 'copy' method is used to copy original files or their modified versions to default storage.
|
30
44
|
#
|
31
45
|
# Source files MAY either be stored or just uploaded and MUST NOT be deleted.
|
@@ -76,6 +90,17 @@ module Uploadcare
|
|
76
90
|
def remote_copy(target, **args)
|
77
91
|
File.copy(uuid, target: target, **args)
|
78
92
|
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def convert_file(params, converter, options = {})
|
97
|
+
raise Uploadcare::Exception::ConversionError, 'The first argument must be a Hash' unless params.is_a?(Hash)
|
98
|
+
|
99
|
+
params_with_symbolized_keys = params.map { |k, v| [k.to_sym, v] }.to_h
|
100
|
+
params_with_symbolized_keys[:uuid] = uuid
|
101
|
+
result = converter.convert(params_with_symbolized_keys, options)
|
102
|
+
result.success? ? File.info(result.value![:result].first[:uuid]) : result
|
103
|
+
end
|
79
104
|
end
|
80
105
|
end
|
81
106
|
end
|
@@ -18,7 +18,7 @@ module Uploadcare
|
|
18
18
|
# @option options [Boolean] :store (false) whether to store file on servers.
|
19
19
|
def self.upload(object, **options)
|
20
20
|
if big_file?(object)
|
21
|
-
|
21
|
+
multipart_upload(object, **options)
|
22
22
|
elsif file?(object)
|
23
23
|
upload_file(object, **options)
|
24
24
|
elsif object.is_a?(Array)
|
@@ -43,8 +43,8 @@ module Uploadcare
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# upload file of size above 10mb (involves multipart upload)
|
46
|
-
def self.
|
47
|
-
response = MultipartUploaderClient.new.upload(file)
|
46
|
+
def self.multipart_upload(file, **options, &block)
|
47
|
+
response = MultipartUploaderClient.new.upload(file, **options, &block)
|
48
48
|
Uploadcare::Entity::File.new(response.success)
|
49
49
|
end
|
50
50
|
|
@@ -57,6 +57,12 @@ module Uploadcare
|
|
57
57
|
response.success[:files].map { |file_data| Uploadcare::Entity::File.new(file_data) }
|
58
58
|
end
|
59
59
|
|
60
|
+
# gets a status of upload from url
|
61
|
+
# @param url [String]
|
62
|
+
def self.get_upload_from_url_status(token)
|
63
|
+
UploaderClient.new.get_upload_from_url_status(token)
|
64
|
+
end
|
65
|
+
|
60
66
|
class << self
|
61
67
|
private
|
62
68
|
|
data/uploadcare-ruby.gemspec
CHANGED
@@ -7,8 +7,8 @@ require 'uploadcare/ruby/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'uploadcare-ruby'
|
9
9
|
spec.version = Uploadcare::VERSION
|
10
|
-
spec.authors = ['Stepan Redka
|
11
|
-
spec.email = ['stepan.redka@railsmuffin.com'
|
10
|
+
spec.authors = ['Stepan Redka']
|
11
|
+
spec.email = ['stepan.redka@railsmuffin.com']
|
12
12
|
|
13
13
|
spec.summary = 'Ruby wrapper for uploadcare API'
|
14
14
|
spec.description = spec.summary
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uploadcare-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Stepan Redka
|
7
|
+
- Stepan Redka
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: api_struct
|
@@ -153,7 +153,6 @@ dependencies:
|
|
153
153
|
description: Ruby wrapper for uploadcare API
|
154
154
|
email:
|
155
155
|
- stepan.redka@railsmuffin.com
|
156
|
-
- dmitrij.ivanchenko@gmail.com
|
157
156
|
executables: []
|
158
157
|
extensions: []
|
159
158
|
extra_rdoc_files: []
|
@@ -191,8 +190,10 @@ files:
|
|
191
190
|
- lib/uploadcare/concern/error_handler.rb
|
192
191
|
- lib/uploadcare/concern/throttle_handler.rb
|
193
192
|
- lib/uploadcare/concern/upload_error_handler.rb
|
193
|
+
- lib/uploadcare/entity/conversion/base_converter.rb
|
194
|
+
- lib/uploadcare/entity/conversion/document_converter.rb
|
195
|
+
- lib/uploadcare/entity/conversion/video_converter.rb
|
194
196
|
- lib/uploadcare/entity/decorator/paginator.rb
|
195
|
-
- lib/uploadcare/entity/document_converter.rb
|
196
197
|
- lib/uploadcare/entity/entity.rb
|
197
198
|
- lib/uploadcare/entity/file.rb
|
198
199
|
- lib/uploadcare/entity/file_list.rb
|
@@ -200,7 +201,6 @@ files:
|
|
200
201
|
- lib/uploadcare/entity/group_list.rb
|
201
202
|
- lib/uploadcare/entity/project.rb
|
202
203
|
- lib/uploadcare/entity/uploader.rb
|
203
|
-
- lib/uploadcare/entity/video_converter.rb
|
204
204
|
- lib/uploadcare/entity/webhook.rb
|
205
205
|
- lib/uploadcare/exception/conversion_error.rb
|
206
206
|
- lib/uploadcare/exception/request_error.rb
|
@@ -237,11 +237,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
237
237
|
version: '0'
|
238
238
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
239
239
|
requirements:
|
240
|
-
- - "
|
240
|
+
- - ">="
|
241
241
|
- !ruby/object:Gem::Version
|
242
|
-
version:
|
242
|
+
version: '0'
|
243
243
|
requirements: []
|
244
|
-
rubygems_version: 3.
|
244
|
+
rubygems_version: 3.0.1
|
245
245
|
signing_key:
|
246
246
|
specification_version: 4
|
247
247
|
summary: Ruby wrapper for uploadcare API
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Uploadcare
|
4
|
-
module Entity
|
5
|
-
# This serializer lets a user convert uploaded documents
|
6
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/documentConvert
|
7
|
-
class DocumentConverter < Entity
|
8
|
-
client_service Conversion::DocumentConversionClient
|
9
|
-
# Converts documents
|
10
|
-
#
|
11
|
-
# @param doc_params [Array] of hashes with params or [Hash]
|
12
|
-
# @option options [Boolean] :store (false) whether to store file on servers.
|
13
|
-
def self.convert(doc_params, **options)
|
14
|
-
params = doc_params.is_a?(Hash) ? [doc_params] : doc_params
|
15
|
-
Conversion::DocumentConversionClient.new.convert_many(params, **options)
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns a status of document conversion job
|
19
|
-
#
|
20
|
-
# @param token [Integer, String] token obtained from a server in convert method
|
21
|
-
def self.status(token)
|
22
|
-
Conversion::DocumentConversionClient.new.get_conversion_status(token)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Uploadcare
|
4
|
-
module Entity
|
5
|
-
# This serializer lets a user convert uploaded videos, and usually returns an array of results
|
6
|
-
# @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/videoConvert
|
7
|
-
class VideoConverter < Entity
|
8
|
-
client_service Conversion::VideoConversionClient
|
9
|
-
# Converts video files
|
10
|
-
#
|
11
|
-
# @param doc_params [Array] of hashes with params or [Hash]
|
12
|
-
# @option options [Boolean] :store (false) whether to store file on servers.
|
13
|
-
def self.convert(video_params, **options)
|
14
|
-
params = video_params.is_a?(Hash) ? [video_params] : video_params
|
15
|
-
Conversion::VideoConversionClient.new.convert_many(params, **options)
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns a status of video conversion job
|
19
|
-
#
|
20
|
-
# @param token [Integer, String] token obtained from a server in convert method
|
21
|
-
def self.status(token)
|
22
|
-
Conversion::VideoConversionClient.new.get_conversion_status(token)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|