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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b37d6357bdceca37eb0175201e52847b253c701771e3bed959e7e945e4b384b7
4
- data.tar.gz: c70b33bed6660c649df6e93a5bb7e8b3cb5a4c79884a7c146086f0658da690a3
3
+ metadata.gz: '08303dd0379957a7780c58d562c2ddbf9ae42e02d8069e19404defb9d7455292'
4
+ data.tar.gz: d661a6c49bdcb5b5789b3e22dac0a0a439012f0a1bfc5a55b3cdc0c64094ef8b
5
5
  SHA512:
6
- metadata.gz: 47b8ead48824c45759a89a62e170374afe3cc0e8a39690ba4851c04785ee52096769a4415fea2e7ecffb62a864a5fae5f6fb1e95bf450442141973b0412990e7
7
- data.tar.gz: a7aa262e0982825592487187f99018f5276582dffbfa3ef412abc06a3c9d723906d64d2443c79c20eb0dce137ae1cec4384c40b54e692170915289c8191032b0
6
+ metadata.gz: b4b2c4f5342f48908731446e7ca2fa5aabef6568d99dede4ca46f3ed3df13993a156f70f84ac6a87d36799b2d589bc465814c7efeefcbfd6a3e459d3e378814f
7
+ data.tar.gz: 0ffba57715c58eeeabc2d2b44884e67d09a5ee41b916fd10248e46822d5b35d3dd5c24c450ec4961a03b5a6f01903a5867007248bd347b88ac3568d89104c592
data/.rubocop.yml CHANGED
@@ -11,6 +11,7 @@ Style/HashTransformKeys:
11
11
  Exclude:
12
12
  - 'lib/uploadcare/entity/decorator/paginator.rb'
13
13
  - 'lib/uploadcare/client/conversion/video_conversion_client.rb'
14
+ - 'lib/uploadcare/entity/file.rb'
14
15
 
15
16
  Gemspec/RequiredRubyVersion:
16
17
  Exclude:
data/CHANGELOG.md CHANGED
@@ -1,15 +1,10 @@
1
1
  # Changelog
2
2
 
3
- ## 3.1.0-rc1 2021-08-11
3
+ ## 3.1.0 2021-09-21
4
4
 
5
- ### Added
6
- - Add video conversion
7
- - Add document conversion
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 'uploadcare-ruby'
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 = 'demopublickey'
71
- Uploadcare.config.secret_key = 'demoprivatekey'
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('https://placekitten.com/96/139')
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('1.jpg'), File.open('1.jpg']
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('https://placekitten.com/96/139')
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('big_file.bin'))
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('https://placekitten.com/96/139')
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('FILE_ID_IN_YOUR_PROJECT')
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.store # copies file, returns a new (copied) file metadata
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: '-datetime_uploaded',
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 = '134dc30c-093e-4f48-a5b9-966fe9cb1d01'
269
- @file2 = '134dc30c-093e-4f48-a5b9-966fe9cb1d02'
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: 'https://example.com/listen', event: 'file.uploaded', is_active: true)
297
- Uploadcare::Webhook.update(<webhook_id>, target_url: 'https://newexample.com/listen/new', event: 'file.uploaded', is_active: true)
298
- Uploadcare::Webhook.delete('https://example.com/listen')
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: 'change_ratio', width: '600', height: '400' },
336
- quality: 'best',
337
- format: 'ogg',
338
- cut: { start_time: '0:0:0.0', length: '0:0:1.0' },
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
- ], store: false
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
- ], store: false
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: DOC, DOCX, XLS, XLSX, ODT, ODS, RTF, TXT, PDF, JPG, ENHANCED JPG, PNG. Document Conversion works via our [REST API](https://uploadcare.com/api-refs/rest-api/v0.6.0/).
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: 'pdf'
531
+ format: "pdf"
447
532
  }
448
- ], store: false
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: 'png',
543
+ format: "png",
458
544
  page: 1
459
545
  }
460
- ], store: false
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)`, `doc`, `docx`, `xls`, `xlsx`, `odt`, `ods`, `rtf`, `txt`, `jpg`, `enhanced.jpg`, `png`. In case the format operation was not found, your input document will be converted to `pdf`.
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
- ], store: false
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-type': 'application/json',
16
- 'Accept': 'application/vnd.uploadcare-v0.6+json',
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
- result = extract_result(body)
26
-
27
- Dry::Monads::Success(result)
32
+ extract_result(body)
28
33
  end
29
34
 
30
35
  def extract_result(response_body)
31
- return nil if response_body.nil? || response_body.empty?
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
- raise ConversionError, errors unless errors.nil? || errors.empty?
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
- "paths": arr.map do |params|
48
+ paths: arr.map do |params|
44
49
  url_builder_class.call(
45
50
  **build_paths_body(params)
46
51
  )
47
52
  end,
48
- "store": options[:store]
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 = Uploadcare::Param::Conversion::Document::ProcessingJobUrlBuilder
16
+ url_builder_class = Param::Conversion::Document::ProcessingJobUrlBuilder
17
17
  )
18
- body = build_body_for_many(arr, options, url_builder_class)
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
- arr,
15
+ params,
16
16
  options = {},
17
- url_builder_class = Uploadcare::Param::Conversion::Video::ProcessingJobUrlBuilder
17
+ url_builder_class = Param::Conversion::Video::ProcessingJobUrlBuilder
18
18
  )
19
- body = build_body_for_many(arr, options, url_builder_class)
20
- post(uri: '/convert/video/', content: body)
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-type': body.content_type },
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
- client.send(:upload_chunk, chunk, links[link_id])
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-type': 'application/octet-stream' })
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.new.upload_chunks(object, links)
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(multiupload_metadata(object))
29
+ Param::Upload::UploadParamsGenerator.call(store).merge(form_data_for(object))
30
30
  )
31
31
  post(path: 'multipart/start/',
32
- headers: { 'Content-type': body.content_type },
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
- 'UPLOADCARE_PUB_KEY': Uploadcare.config.public_key,
41
- 'uuid': uuid
40
+ UPLOADCARE_PUB_KEY: Uploadcare.config.public_key,
41
+ uuid: uuid
42
42
  }
43
43
  )
44
- post(path: 'multipart/complete/', body: body, headers: { 'Content-type': body.content_type })
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 multiupload_metadata(file)
50
- filename = file.original_filename if file.respond_to?(:original_filename)
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: file.filename,
56
- size: file.size,
57
- content_type: file.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-type'], **options)
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-type': 'application/json',
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-type': body.content_type },
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-type': body.content_type }, body: body)
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 = get_status_response(token)
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
- def form_data_for(file)
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' => STORE_VALUES[options[: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] || true
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
- # @return [String]
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
- upload_big_file(object, **options)
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.upload_big_file(file, **_options)
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uploadcare
4
- VERSION = '3.1.0-rc1'
4
+ VERSION = '3.1.0'
5
5
  end
@@ -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, Dmitrij Ivanchenko']
11
- spec.email = ['stepan.redka@railsmuffin.com', 'dmitrij.ivanchenko@gmail.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.pre.rc1
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Stepan Redka, Dmitrij Ivanchenko
7
+ - Stepan Redka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-11 00:00:00.000000000 Z
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: 1.3.1
242
+ version: '0'
243
243
  requirements: []
244
- rubygems_version: 3.2.22
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