Skip to content

Commit 3e1d35f

Browse files
committed
Fix remaining review follow-ups
1 parent 83fbc3d commit 3e1d35f

File tree

14 files changed

+134
-18
lines changed

14 files changed

+134
-18
lines changed

.snyk

Lines changed: 0 additions & 4 deletions
This file was deleted.

api_examples/support/example_helper.rb

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def with_multipart_session
121121
yield file, response
122122
ensure
123123
file&.close
124+
safe_delete_file(response['completed_uuid']) if response.is_a?(Hash) && response['completed_uuid']
124125
end
125126

126127
def upload_multipart_part(file:, session:, index:)
@@ -132,11 +133,15 @@ def upload_multipart_part(file:, session:, index:)
132133
data.bytesize
133134
end
134135

135-
def finish_multipart_upload(file:, session:)
136+
def finish_multipart_upload(file:, session:, skip_indices: [])
136137
session.fetch('parts').each_index do |index|
138+
next if skip_indices.include?(index)
139+
137140
upload_multipart_part(file: file, session: session, index: index)
138141
end
139-
unwrap(client.api.upload.files.multipart_complete(uuid: session.fetch('uuid')))
142+
result = unwrap(client.api.upload.files.multipart_complete(uuid: session.fetch('uuid')))
143+
session['completed_uuid'] = result['uuid']
144+
result
140145
end
141146

142147
def uploaded_uuid_from_base_response(response)
@@ -171,9 +176,16 @@ def safe_delete_file(file)
171176
end
172177

173178
def safe_delete_group(group)
174-
return unless group&.id
175-
176-
client.api.rest.groups.delete(uuid: group.id)
179+
group_id = if group.respond_to?(:id)
180+
group.id
181+
elsif group.is_a?(Hash)
182+
group['id'] || group[:id]
183+
else
184+
group
185+
end
186+
return if group_id.to_s.empty?
187+
188+
client.api.rest.groups.delete(uuid: group_id)
177189
rescue StandardError
178190
nil
179191
end

api_examples/support/run_rest_example.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ def call
3030
end
3131
when 'post_files_local_copy.rb'
3232
ApiExamples::ExampleHelper.with_uploaded_file do |file|
33-
client.files.copy_to_local(source: file.uuid, options: { store: true })
33+
copied = client.files.copy_to_local(source: file.uuid, options: { store: true })
34+
copied
35+
ensure
36+
ApiExamples::ExampleHelper.safe_delete_file(copied)
3437
end
3538
when 'post_files_remote_copy.rb'
3639
target = ENV.fetch('UPLOADCARE_REMOTE_STORAGE', nil)

api_examples/support/run_upload_example.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ def call
2727
end
2828
when 'post_group.rb'
2929
ApiExamples::ExampleHelper.with_uploaded_files do |files|
30-
ApiExamples::ExampleHelper.unwrap(client.api.upload.groups.create(files: files.map(&:uuid)))
30+
group = ApiExamples::ExampleHelper.unwrap(client.api.upload.groups.create(files: files.map(&:uuid)))
31+
group
32+
ensure
33+
ApiExamples::ExampleHelper.safe_delete_group(group)
3134
end
3235
when 'get_group_info.rb'
3336
ApiExamples::ExampleHelper.with_uploaded_group do |group, _files|
@@ -45,7 +48,11 @@ def call
4548
when 'put_multipart_part.rb'
4649
ApiExamples::ExampleHelper.with_multipart_session do |file, session|
4750
uploaded = ApiExamples::ExampleHelper.upload_multipart_part(file: file, session: session, index: 0)
48-
completed = ApiExamples::ExampleHelper.finish_multipart_upload(file: file, session: session)
51+
completed = ApiExamples::ExampleHelper.finish_multipart_upload(
52+
file: file,
53+
session: session,
54+
skip_indices: [0]
55+
)
4956
{
5057
'uuid' => session.fetch('uuid'),
5158
'uploaded_bytes' => uploaded,

lib/uploadcare.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class << self
1717
# @yieldparam config [Uploadcare::Configuration] The configuration object
1818
def configure
1919
yield configuration if block_given?
20+
ensure
2021
@client = nil
2122
end
2223

lib/uploadcare/api/upload/files.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ def build_from_url_params(source_url, options)
203203
store = store_value(options[:store])
204204
params['store'] = store unless store.nil?
205205

206-
params['check_URL_duplicates'] = options[:check_URL_duplicates].to_s if options[:check_URL_duplicates]
207-
params['save_URL_duplicates'] = options[:save_URL_duplicates].to_s if options[:save_URL_duplicates]
206+
params['check_URL_duplicates'] = options[:check_URL_duplicates].to_s if options.key?(:check_URL_duplicates)
207+
params['save_URL_duplicates'] = options[:save_URL_duplicates].to_s if options.key?(:save_URL_duplicates)
208208

209209
metadata_params = generate_metadata_params(options[:metadata])
210210
params.merge!(metadata_params) if metadata_params.any?

lib/uploadcare/internal/error_handler.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require 'json'
4+
require 'time'
45

56
# Handles API errors and converts them to appropriate exceptions.
67
#
@@ -85,7 +86,16 @@ def catch_upload_errors(response)
8586
def raise_throttle_error(response, message)
8687
headers = response.is_a?(Hash) ? response[:headers] : nil
8788
retry_after = headers && (headers['retry-after'] || headers['Retry-After'])
88-
timeout = retry_after.to_f
89+
timeout =
90+
if retry_after.to_s.match?(/\A\d+(\.\d+)?\z/)
91+
retry_after.to_f
92+
else
93+
begin
94+
[Time.httpdate(retry_after.to_s) - Time.now, 0].max
95+
rescue ArgumentError
96+
0
97+
end
98+
end
8999
timeout = 10.0 if timeout <= 0
90100
raise Uploadcare::Exception::ThrottleError.new(message, timeout: timeout)
91101
end

lib/uploadcare/operations/multipart_upload.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def upload(file:, request_options: {}, **options, &block)
4242
file_size = prepared_file.size
4343
filename = prepared_file.original_filename
4444
content_type = MIME::Types.type_for(prepared_file.path).first&.content_type || 'application/octet-stream'
45+
part_size, threads = normalize_upload_options(options)
4546

4647
start_response = Uploadcare::Result.unwrap(
4748
upload_client.files.multipart_start(
@@ -56,9 +57,6 @@ def upload(file:, request_options: {}, **options, &block)
5657
uuid = start_response['uuid']
5758
presigned_urls = start_response['parts']
5859

59-
part_size = options.fetch(:part_size, config.multipart_chunk_size)
60-
threads = options.fetch(:threads, 1)
61-
6260
if threads > 1
6361
upload_parts_parallel(prepared_file, presigned_urls, part_size, threads, &block)
6462
else
@@ -77,6 +75,16 @@ def upload(file:, request_options: {}, **options, &block)
7775

7876
private
7977

78+
def normalize_upload_options(options)
79+
part_size = Integer(options.fetch(:part_size, config.multipart_chunk_size || CHUNK_SIZE))
80+
threads = Integer(options.fetch(:threads, 1))
81+
82+
raise ArgumentError, 'part_size must be > 0' if part_size <= 0
83+
raise ArgumentError, 'threads must be >= 1' if threads < 1
84+
85+
[part_size, threads]
86+
end
87+
8088
def upload_parts_sequential(file, presigned_urls, part_size, &block)
8189
total_size = file.respond_to?(:size) ? file.size : ::File.size(file.path)
8290
uploaded = 0

lib/uploadcare/resources/file.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ def uuid
307307
def cdn_url
308308
return @url if uploadcare_cdn_url?(@url)
309309
return @original_file_url if uploadcare_cdn_url?(@original_file_url)
310+
return nil unless uuid
310311

311312
"#{config.cdn_base}#{uuid}/"
312313
end

spec/uploadcare/api/upload/files_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,30 @@
136136

137137
expect(stub).to have_been_requested
138138
end
139+
140+
it 'preserves explicit false duplicate flags in the request params' do
141+
stub = stub_request(:post, 'https://upload.uploadcare.com/from_url/')
142+
.with(
143+
body: hash_including(
144+
'check_URL_duplicates' => 'false',
145+
'save_URL_duplicates' => 'false'
146+
)
147+
)
148+
.to_return(
149+
status: 200,
150+
body: { token: 'upload-token' }.to_json,
151+
headers: { 'Content-Type' => 'application/json' }
152+
)
153+
154+
files.from_url(
155+
source_url: source_url,
156+
async: true,
157+
check_URL_duplicates: false,
158+
save_URL_duplicates: false
159+
)
160+
161+
expect(stub).to have_been_requested
162+
end
139163
end
140164

141165
describe '#from_url_status' do

0 commit comments

Comments
 (0)