uploadcare-ruby 3.0.3 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +13 -0
  3. data/CHANGELOG.md +21 -7
  4. data/README.md +348 -34
  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 +1 -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 +9 -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/ruby/version.rb +1 -1
  33. data/uploadcare-ruby.gemspec +1 -1
  34. metadata +14 -5
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'client/conversion/base_conversion_client'
4
+ require 'param/conversion/document/processing_job_url_builder'
5
+
6
+ module Uploadcare
7
+ module Client
8
+ module Conversion
9
+ # This is client for document conversion
10
+ #
11
+ # @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/documentConvert
12
+ class DocumentConversionClient < BaseConversionClient
13
+ def convert_many(
14
+ arr,
15
+ options = {},
16
+ url_builder_class = Param::Conversion::Document::ProcessingJobUrlBuilder
17
+ )
18
+ send_convert_request(arr, options, url_builder_class)
19
+ end
20
+
21
+ def get_conversion_status(token)
22
+ get(uri: "/convert/document/status/#{token}/")
23
+ end
24
+
25
+ private
26
+
27
+ def convert_uri
28
+ '/convert/document/'
29
+ end
30
+
31
+ def build_paths_body(params)
32
+ {
33
+ uuid: params[:uuid],
34
+ format: params[:format],
35
+ page: params[:page]
36
+ }.compact
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'client/conversion/base_conversion_client'
4
+ require 'param/conversion/video/processing_job_url_builder'
5
+ require 'exception/conversion_error'
6
+
7
+ module Uploadcare
8
+ module Client
9
+ module Conversion
10
+ # This is client for video conversion
11
+ #
12
+ # @see https://uploadcare.com/api-refs/rest-api/v0.6.0/#operation/videoConvert
13
+ class VideoConversionClient < BaseConversionClient
14
+ def convert_many(
15
+ params,
16
+ options = {},
17
+ url_builder_class = Param::Conversion::Video::ProcessingJobUrlBuilder
18
+ )
19
+ video_params = params.is_a?(Hash) ? [params] : params
20
+ send_convert_request(video_params, options, url_builder_class)
21
+ end
22
+
23
+ def get_conversion_status(token)
24
+ get(uri: "/convert/video/status/#{token}/")
25
+ end
26
+
27
+ private
28
+
29
+ def convert_uri
30
+ '/convert/video/'
31
+ end
32
+
33
+ def build_paths_body(params)
34
+ {
35
+ uuid: params[:uuid],
36
+ quality: params[:quality],
37
+ format: params[:format],
38
+ size: params[:size],
39
+ cut: params[:cut],
40
+ thumbs: params[:thumbs]
41
+ }.compact
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -15,8 +15,8 @@ module Uploadcare
15
15
  # limit: (1..1000)
16
16
  # ordering: ["datetime_uploaded"|"-datetime_uploaded"|"size"|"-size"]
17
17
  # from: number of files skipped
18
- def file_list(**options)
19
- query = options.empty? ? '' : '?' + URI.encode_www_form(options)
18
+ def file_list(options = {})
19
+ query = options.empty? ? '' : "?#{URI.encode_www_form(options)}"
20
20
  get(uri: "/files/#{query}")
21
21
  end
22
22
 
@@ -25,7 +25,7 @@ module Uploadcare
25
25
  # uuids: Array
26
26
  def batch_store(uuids)
27
27
  body = uuids.to_json
28
- put(uri: '/files/storage/', body: body)
28
+ put(uri: '/files/storage/', content: body)
29
29
  end
30
30
 
31
31
  alias request_delete delete
@@ -35,7 +35,7 @@ module Uploadcare
35
35
  # uuids: Array
36
36
  def batch_delete(uuids)
37
37
  body = uuids.to_json
38
- request_delete(uri: '/files/storage/', body: body)
38
+ request_delete(uri: '/files/storage/', content: body)
39
39
  end
40
40
 
41
41
  alias store_files batch_store
@@ -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
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'parallel'
4
+ require 'api_struct'
4
5
 
5
6
  module Uploadcare
6
7
  module Client
@@ -15,11 +16,21 @@ module Uploadcare
15
16
  # In multiple threads, split file into chunks and upload those chunks into respective Amazon links
16
17
  # @param object [File]
17
18
  # @param links [Array] of strings; by default list of Amazon storage urls
18
- def upload_chunks(object, links)
19
+ def self.upload_chunks(object, links)
19
20
  Parallel.each(0...links.count, in_threads: Uploadcare.config.upload_threads) do |link_id|
20
21
  offset = link_id * CHUNK_SIZE
21
22
  chunk = IO.read(object, CHUNK_SIZE, offset)
22
- 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
+ )
23
34
  end
24
35
  end
25
36
 
@@ -31,12 +42,12 @@ module Uploadcare
31
42
  {}
32
43
  end
33
44
 
34
- private
35
-
36
45
  def upload_chunk(chunk, link)
37
- put(path: link, body: chunk, headers: { 'Content-type': 'application/octet-stream' })
46
+ put(path: link, body: chunk, headers: { 'Content-Type': 'application/octet-stream' })
38
47
  end
39
48
 
49
+ private
50
+
40
51
  def default_params
41
52
  {}
42
53
  end
@@ -13,43 +13,45 @@ 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
 
36
36
  # When every chunk is uploaded, ask Uploadcare server to finish the upload
37
37
  def upload_complete(uuid)
38
38
  body = HTTP::FormData::Multipart.new(
39
- 'UPLOADCARE_PUB_KEY': Uploadcare.config.public_key,
40
- 'uuid': uuid
39
+ {
40
+ UPLOADCARE_PUB_KEY: Uploadcare.config.public_key,
41
+ uuid: uuid
42
+ }
41
43
  )
42
- 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 })
43
45
  end
44
46
 
45
47
  private
46
48
 
47
- def multiupload_metadata(file)
48
- file = HTTP::FormData::File.new(file)
49
+ def form_data_for(file)
50
+ form_data_file = super(file)
49
51
  {
50
- filename: file.filename,
51
- size: file.size,
52
- 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
53
55
  }
54
56
  end
55
57
 
@@ -6,7 +6,7 @@ module Uploadcare
6
6
  # @see https://uploadcare.com/docs/api_reference/rest/handling_projects/
7
7
  class ProjectClient < RestClient
8
8
  # get information about current project
9
- # current project is determined by public and private key combination
9
+ # current project is determined by public and secret key combination
10
10
  # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#tag/Project
11
11
  def show
12
12
  get(uri: '/project/')
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'rest_client'
4
+ require 'api_struct'
4
5
  require 'uploadcare/concern/error_handler'
5
6
  require 'uploadcare/concern/throttle_handler'
6
7
  require 'param/authentication_header'
@@ -22,11 +23,11 @@ module Uploadcare
22
23
  # Send request with authentication header
23
24
  #
24
25
  # Handle throttling as well
25
- def request(method: 'GET', uri:, **options)
26
+ def request(uri:, method: 'GET', **options)
26
27
  request_headers = Param::AuthenticationHeader.call(method: method.upcase, uri: uri,
27
- content_type: headers[:'Content-type'], **options)
28
+ content_type: headers[:'Content-Type'], **options)
28
29
  handle_throttling do
29
- send('api_struct_' + method.downcase, path: remove_trailing_slash(uri),
30
+ send("api_struct_#{method.downcase}", path: remove_trailing_slash(uri),
30
31
  headers: request_headers, body: options[:content])
31
32
  end
32
33
  end
@@ -53,7 +54,7 @@ module Uploadcare
53
54
 
54
55
  def headers
55
56
  {
56
- 'Content-type': 'application/json',
57
+ 'Content-Type': 'application/json',
57
58
  'Accept': 'application/vnd.uploadcare-v0.5+json',
58
59
  'User-Agent': Uploadcare::Param::UserAgent.call
59
60
  }
@@ -62,7 +63,7 @@ module Uploadcare
62
63
  private
63
64
 
64
65
  def remove_trailing_slash(str)
65
- str.gsub(%r{^\/}, '')
66
+ str.gsub(%r{^/}, '')
66
67
  end
67
68
 
68
69
  def default_params
@@ -14,8 +14,8 @@ module Uploadcare
14
14
 
15
15
  # return paginated list of groups
16
16
  # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/groupsList
17
- def list(**options)
18
- query = options.empty? ? '' : '?' + URI.encode_www_form(options)
17
+ def list(options = {})
18
+ query = options.empty? ? '' : "?#{URI.encode_www_form(options)}"
19
19
  get(uri: "/groups/#{query}")
20
20
  end
21
21
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'api_struct'
3
4
  require 'param/user_agent'
4
5
  require 'uploadcare/concern/error_handler'
5
6
  require 'uploadcare/concern/throttle_handler'
@@ -27,6 +28,13 @@ module Uploadcare
27
28
 
28
29
  private
29
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
+
30
38
  def default_params
31
39
  {}
32
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,38 +63,38 @@ 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
- HTTP::FormData::File.new(file)]
78
- end .to_h
77
+ form_data_for(file)]
78
+ end.to_h
79
79
  HTTP::FormData::Multipart.new(
80
80
  Param::Upload::UploadParamsGenerator.call(options[:store]).merge(files_formdata)
81
81
  )
82
82
  end
83
83
 
84
+ STORE_VALUES_MAP = {
85
+ true => '1',
86
+ false => '0'
87
+ }.freeze
88
+
84
89
  # Prepare upload_from_url initial request body
85
90
  def upload_from_url_body(url, **options)
86
- HTTP::FormData::Multipart.new({
87
- 'pub_key': Uploadcare.config.public_key,
88
- 'source_url': url
89
- }.merge(**options))
91
+ HTTP::FormData::Multipart.new(
92
+ options.merge(
93
+ 'pub_key' => Uploadcare.config.public_key,
94
+ 'source_url' => url,
95
+ 'store' => STORE_VALUES_MAP[options[:store]]
96
+ )
97
+ )
90
98
  end
91
99
  end
92
100
  end
@@ -9,8 +9,12 @@ module Uploadcare
9
9
  class WebhookClient < RestClient
10
10
  # Create webhook
11
11
  # @see https://uploadcare.com/docs/api_reference/rest/webhooks/#subscribe
12
- def create(target_url, event: 'file.uploaded', is_active: true)
13
- body = { 'target_url': target_url, 'event': event, 'is_active': is_active }.to_json
12
+ def create(options = {})
13
+ body = {
14
+ 'target_url': options[:target_url],
15
+ 'event': options[:event] || 'file.uploaded',
16
+ 'is_active': options[:is_active].nil? ? true : options[:is_active]
17
+ }.to_json
14
18
  post(uri: '/webhooks/', content: body)
15
19
  end
16
20
 
@@ -22,14 +26,14 @@ module Uploadcare
22
26
 
23
27
  # Permanently deletes subscription
24
28
  # @see https://uploadcare.com/docs/api_reference/rest/webhooks/#unsubscribe
25
- def delete(name)
26
- body = { 'name': name }.to_json
29
+ def delete(target_url)
30
+ body = { 'target_url': target_url }.to_json
27
31
  post(uri: '/webhooks/unsubscribe/', content: body)
28
32
  end
29
33
 
30
34
  # Updates webhook
31
35
  # @see https://uploadcare.com/docs/api_reference/rest/webhooks/#subscribe-update
32
- def update(id, **options)
36
+ def update(id, options = {})
33
37
  body = options.to_json
34
38
  post(uri: "/webhooks/#{id}/", content: body)
35
39
  end
@@ -14,9 +14,9 @@ module Uploadcare
14
14
  def failure(response)
15
15
  catch_upload_errors(response)
16
16
  parsed_response = JSON.parse(response.body.to_s)
17
- raise RequestError, parsed_response['detail']
17
+ raise RequestError, parsed_response['detail'] || parsed_response.map { |k, v| "#{k}: #{v}" }.join('; ')
18
18
  rescue JSON::ParserError
19
- raise RequestError, response.status
19
+ raise RequestError, response.body.to_s
20
20
  end
21
21
 
22
22
  # Extension of ApiStruct's wrap method
@@ -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
@@ -26,7 +26,7 @@ module Uploadcare
26
26
  return unless url
27
27
 
28
28
  query = URI.decode_www_form(URI(url).query).to_h
29
- query = Hash[query.map { |k, v| [k.to_sym, v] }]
29
+ query = query.map { |k, v| [k.to_sym, v] }.to_h
30
30
  self.class.list(**query)
31
31
  end
32
32
 
@@ -36,7 +36,7 @@ module Uploadcare
36
36
  return unless url
37
37
 
38
38
  query = URI.decode_www_form(URI(url).query).to_h
39
- query = Hash[query.map { |k, v| [k.to_sym, v] }]
39
+ query = query.map { |k, v| [k.to_sym, v] }.to_h
40
40
  self.class.list(**query)
41
41
  end
42
42
 
@@ -44,7 +44,7 @@ module Uploadcare
44
44
  #
45
45
  # It's possible to avoid loading objects on previous pages by offsetting them first
46
46
  def load
47
- return if @entity[:next].nil? || @entity[:results].length == @entity[:total]
47
+ return self if @entity[:next].nil? || @entity[:results].length == @entity[:total]
48
48
 
49
49
  np = self
50
50
  until np.next.nil?
@@ -59,12 +59,10 @@ module Uploadcare
59
59
  # iterate through pages, starting with current one
60
60
  #
61
61
  # @yield [Block]
62
- def each
62
+ def each(&block)
63
63
  current_page = self
64
64
  while current_page
65
- current_page.results.each do |obj|
66
- yield obj
67
- end
65
+ current_page.results.each(&block)
68
66
  current_page = current_page.next_page
69
67
  end
70
68
  end
@@ -9,16 +9,16 @@ module Uploadcare
9
9
  client_service FileClient
10
10
 
11
11
  attr_entity :datetime_removed, :datetime_stored, :datetime_uploaded, :image_info, :is_image, :is_ready,
12
- :mime_type, :original_file_url, :original_filename, :size, :url, :uuid
12
+ :mime_type, :original_file_url, :original_filename, :size, :url, :uuid, :variations, :video_info,
13
+ :source, :rekognition_info
13
14
 
14
15
  # gets file's uuid - even if it's only initialized with url
15
- # @return [String]
16
+ # @returns [String]
16
17
  def uuid
17
18
  return @entity.uuid if @entity.uuid
18
19
 
19
20
  uuid = @entity.url.gsub('https://ucarecdn.com/', '')
20
- uuid = uuid.gsub(%r{\/.*}, '')
21
- uuid
21
+ uuid.gsub(%r{/.*}, '')
22
22
  end
23
23
 
24
24
  # loads file metadata, if it's initialized with url or uuid
@@ -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,28 @@ module Uploadcare
76
90
  def remote_copy(target, **args)
77
91
  File.copy(uuid, target: target, **args)
78
92
  end
93
+
94
+ # Store a single file, preventing it from being deleted in 2 weeks
95
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/storeFile
96
+ def store
97
+ File.store(uuid)
98
+ end
99
+
100
+ # @see https://uploadcare.com/api-refs/rest-api/v0.5.0/#operation/deleteFile
101
+ def delete
102
+ File.delete(uuid)
103
+ end
104
+
105
+ private
106
+
107
+ def convert_file(params, converter, options = {})
108
+ raise Uploadcare::Exception::ConversionError, 'The first argument must be a Hash' unless params.is_a?(Hash)
109
+
110
+ params_with_symbolized_keys = params.map { |k, v| [k.to_sym, v] }.to_h
111
+ params_with_symbolized_keys[:uuid] = uuid
112
+ result = converter.convert(params_with_symbolized_keys, options)
113
+ result.success? ? File.info(result.value![:result].first[:uuid]) : result
114
+ end
79
115
  end
80
116
  end
81
117
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'uploadcare/entity/file'
4
4
  require 'uploadcare/entity/decorator/paginator'
5
+ require 'api_struct'
5
6
 
6
7
  module Uploadcare
7
8
  module Entity
@@ -28,8 +28,7 @@ module Uploadcare
28
28
  return @entity.id if @entity.id
29
29
 
30
30
  id = @entity.cdn_url.gsub('https://ucarecdn.com/', '')
31
- id = id.gsub(%r{\/.*}, '')
32
- id
31
+ id.gsub(%r{/.*}, '')
33
32
  end
34
33
 
35
34
  # loads group metadata, if it's initialized with url or id