cloudinary 1.27.0 → 2.3.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.
@@ -6,29 +6,29 @@ class Cloudinary::Migrator
6
6
  attr_reader :db
7
7
  attr_reader :work, :results, :mutex
8
8
  attr_reader :extra_options
9
-
10
-
9
+
10
+
11
11
  @@init = false
12
12
  def self.init
13
13
  return if @@init
14
14
  @@init = true
15
15
 
16
- begin
16
+ begin
17
17
  require 'sqlite3'
18
18
  rescue LoadError
19
- raise "Please add sqlite3 to your Gemfile"
19
+ raise "Please add sqlite3 to your Gemfile"
20
20
  end
21
21
  require 'tempfile'
22
22
  end
23
-
23
+
24
24
  def json_decode(str)
25
25
  Cloudinary::Utils.json_decode(str)
26
26
  end
27
-
27
+
28
28
  def initialize(options={})
29
29
  self.class.init
30
-
31
- options[:db_file] = "tmp/migration#{$$}.db" if options[:private_database] && !options[:db_file]
30
+
31
+ options[:db_file] = "tmp/migration#{$$}.db" if options[:private_database] && !options[:db_file]
32
32
  @dbfile = options[:db_file] || "tmp/migration.db"
33
33
  FileUtils.mkdir_p(File.dirname(@dbfile))
34
34
  @db = SQLite3::Database.new @dbfile, :results_as_hash=>true
@@ -37,7 +37,6 @@ class Cloudinary::Migrator
37
37
  @debug = options[:debug] || false
38
38
  @ignore_duplicates = options[:ignore_duplicates]
39
39
  @threads = [options[:threads] || 10, 100].min
40
- @threads = 1 if RUBY_VERSION < "1.9"
41
40
  @extra_options = {:api_key=>options[:api_key], :api_secret=>options[:api_secret]}
42
41
  @delete_after_done = options[:delete_after_done] || options[:private_database]
43
42
  @max_processing = @threads * 10
@@ -77,7 +76,7 @@ class Cloudinary::Migrator
77
76
  @db.execute("delete from queue")
78
77
  end
79
78
  end
80
-
79
+
81
80
  def register_retrieve(&block)
82
81
  @retrieve = block
83
82
  end
@@ -85,26 +84,26 @@ class Cloudinary::Migrator
85
84
  def register_complete(&block)
86
85
  @complete = block
87
86
  end
88
-
89
- def process(options={})
87
+
88
+ def process(options={})
90
89
  raise CloudinaryException, "url not given and no retrieve callback given" if options[:url].nil? && self.retrieve.nil?
91
90
  raise CloudinaryException, "id not given and retrieve or complete callback given" if options[:id].nil? && (!self.retrieve.nil? || !self.complete.nil?)
92
91
 
93
92
  debug("Process: #{options.inspect}")
94
93
  start
95
- process_results
94
+ process_results
96
95
  wait_for_queue
97
96
  options = options.dup
98
97
  id = options.delete(:id)
99
98
  url = options.delete(:url)
100
99
  public_id = options.delete(:public_id)
101
100
  row = {
102
- "internal_id"=>id,
103
- "url"=>url,
104
- "public_id"=>public_id,
101
+ "internal_id"=>id,
102
+ "url"=>url,
103
+ "public_id"=>public_id,
105
104
  "metadata"=>options.to_json,
106
- "status"=>"processing"
107
- }
105
+ "status"=>"processing"
106
+ }
108
107
  begin
109
108
  insert_row(row)
110
109
  add_to_work_queue(row)
@@ -112,7 +111,7 @@ class Cloudinary::Migrator
112
111
  raise if !@ignore_duplicates
113
112
  end
114
113
  end
115
-
114
+
116
115
  def done
117
116
  start
118
117
  process_all_pending
@@ -122,37 +121,37 @@ class Cloudinary::Migrator
122
121
  @db.close
123
122
  File.delete(@dbfile) if @delete_after_done
124
123
  end
125
-
124
+
126
125
  def max_given_id
127
126
  db.get_first_value("select max(internal_id) from queue").to_i
128
127
  end
129
-
128
+
130
129
  def close_if_needed(file)
131
130
  if file.nil?
132
131
  # Do nothing.
133
- elsif file.respond_to?(:close!)
134
- file.close!
132
+ elsif file.respond_to?(:close!)
133
+ file.close!
135
134
  elsif file.respond_to?(:close)
136
135
  file.close
137
136
  end
138
137
  rescue
139
138
  # Ignore errors in closing files
140
- end
139
+ end
141
140
 
142
- def temporary_file(data, filename)
143
- file = RUBY_VERSION == "1.8.7" ? Tempfile.new('cloudinary') : Tempfile.new('cloudinary', :encoding => 'ascii-8bit')
141
+ def temporary_file(data, filename)
142
+ file = Tempfile.new('cloudinary', :encoding => 'ascii-8bit')
144
143
  file.unlink
145
144
  file.write(data)
146
145
  file.rewind
147
- # Tempfile return path == nil after unlink, which break rest-client
146
+ # Tempfile return path == nil after unlink, which break rest-client
148
147
  class << file
149
148
  attr_accessor :original_filename
150
149
  def content_type
151
- "application/octet-stream"
150
+ "application/octet-stream"
152
151
  end
153
152
  end
154
153
  file.original_filename = filename
155
- file
154
+ file
156
155
  end
157
156
 
158
157
  private
@@ -160,21 +159,21 @@ class Cloudinary::Migrator
160
159
  def update_all(values)
161
160
  @db.execute("update queue set #{values.keys.map{|key| "#{key}=?"}.join(",")}", *values.values)
162
161
  end
163
-
164
- def update_row(row, values)
162
+
163
+ def update_row(row, values)
165
164
  values.merge!("updated_at"=>Time.now.to_i)
166
165
  query = ["update queue set #{values.keys.map{|key| "#{key}=?"}.join(",")} where id=?"] + values.values + [row["id"]]
167
166
  @db.execute(*query)
168
167
  values.each{|key, value| row[key.to_s] = value}
169
- row
168
+ row
170
169
  end
171
-
170
+
172
171
  def insert_row(values)
173
172
  values.merge!("updated_at"=>Time.now.to_i)
174
173
  @db.execute("insert into queue (#{values.keys.join(",")}) values (#{values.keys.map{"?"}.join(",")})", *values.values)
175
174
  values["id"] = @db.last_insert_row_id
176
175
  end
177
-
176
+
178
177
  def refill_queue(last_id)
179
178
  @db.execute("select * from queue where status in ('error', 'processing') and id > ? limit ?", last_id, 10000) do
180
179
  |row|
@@ -183,25 +182,25 @@ class Cloudinary::Migrator
183
182
  add_to_work_queue(row)
184
183
  end
185
184
  last_id
186
- end
185
+ end
187
186
 
188
187
  def process_results
189
188
  while self.results.length > 0
190
189
  row = self.results.pop
191
- result = json_decode(row["result"])
190
+ result = json_decode(row["result"])
192
191
  debug("Done ID=#{row['internal_id']}, result=#{result.inspect}")
193
- complete.call(row["internal_id"], result) if complete
194
- if result["error"]
192
+ complete.call(row["internal_id"], result) if complete
193
+ if result["error"]
195
194
  status = case result["error"]["http_code"]
196
195
  when 400, 404 then "fatal" # Problematic request. Not a server problem.
197
196
  else "error"
198
197
  end
199
198
  else
200
199
  status = "completed"
201
- end
200
+ end
202
201
  updates = {:status=>status, :result=>row["result"]}
203
202
  updates["public_id"] = result["public_id"] if result["public_id"] && !row["public_id"]
204
- begin
203
+ begin
205
204
  update_row(row, updates)
206
205
  rescue SQLite3::ConstraintException
207
206
  updates = {:status=>"error", :result=>{:error=>{:message=>"public_id already exists"}}.to_json}
@@ -219,16 +218,16 @@ class Cloudinary::Migrator
219
218
  raise if retry_count > tries
220
219
  sleep rand * 3
221
220
  retry
222
- end
221
+ end
223
222
  end
224
-
223
+
225
224
  def start
226
225
  return if @started
227
226
  @started = true
228
227
  @terminate = false
229
-
228
+
230
229
  self.work.clear
231
-
230
+
232
231
  main = self
233
232
  Thread.abort_on_exception = true
234
233
  1.upto(@threads) do
@@ -251,8 +250,8 @@ class Cloudinary::Migrator
251
250
  elsif defined?(::CarrierWave) && defined?(Cloudinary::CarrierWave) && data.is_a?(Cloudinary::CarrierWave)
252
251
  cw = true
253
252
  begin
254
- data.model.save!
255
- rescue Cloudinary::CarrierWave::UploadError
253
+ data.model.save!
254
+ rescue Cloudinary::CarrierWave::UploadError
256
255
  # upload errors will be handled by the result values.
257
256
  end
258
257
  result = data.metadata
@@ -264,22 +263,22 @@ class Cloudinary::Migrator
264
263
  elsif data.match(/^https?:/)
265
264
  url = data
266
265
  else
267
- file = main.temporary_file(data, row["public_id"] || "cloudinaryfile")
266
+ file = main.temporary_file(data, row["public_id"] || "cloudinaryfile")
268
267
  end
269
268
  end
270
-
269
+
271
270
  if url || file
272
271
  options = main.extra_options.merge(:public_id=>row["public_id"])
273
272
  json_decode(row["metadata"]).each do
274
273
  |key, value|
275
274
  options[key.to_sym] = value
276
275
  end
277
-
276
+
278
277
  result = Cloudinary::Uploader.upload(url || file, options.merge(:return_error=>true)) || ({:error=>{:message=>"Received nil from uploader!"}})
279
278
  elsif cw
280
279
  result ||= {"status" => "saved"}
281
280
  else
282
- result = {"error" => {"message" => "Empty data and url", "http_code"=>404}}
281
+ result = {"error" => {"message" => "Empty data and url", "http_code"=>404}}
283
282
  end
284
283
  main.results << {"id"=>row["id"], "internal_id"=>row["internal_id"], "result"=>result.to_json}
285
284
  rescue => e
@@ -289,14 +288,14 @@ class Cloudinary::Migrator
289
288
  ensure
290
289
  main.mutex.synchronize{main.in_process -= 1}
291
290
  main.close_if_needed(file)
292
- end
291
+ end
293
292
  end
294
293
  end
295
- end
296
-
294
+ end
295
+
297
296
  retry_previous_queue # Retry all work from previous iteration before we start processing this one.
298
297
  end
299
-
298
+
300
299
  def debug(message)
301
300
  if @debug
302
301
  mutex.synchronize{
@@ -310,60 +309,60 @@ class Cloudinary::Migrator
310
309
  begin
311
310
  prev_last_id, last_id = last_id, refill_queue(last_id)
312
311
  end while last_id > prev_last_id
313
- process_results
312
+ process_results
314
313
  end
315
-
314
+
316
315
  def process_all_pending
317
316
  # Waiting for work to finish. While we are at it, process results.
318
- while self.in_process > 0
317
+ while self.in_process > 0
319
318
  process_results
320
319
  sleep 0.1
321
320
  end
322
321
  # Make sure we processed all the results
323
322
  process_results
324
323
  end
325
-
324
+
326
325
  def add_to_work_queue(row)
327
326
  self.work << row
328
327
  mutex.synchronize{self.in_process += 1}
329
328
  end
330
-
329
+
331
330
  def wait_for_queue
332
331
  # Waiting f
333
332
  while self.work.length > @max_processing
334
- process_results
333
+ process_results
335
334
  sleep 0.1
336
- end
335
+ end
337
336
  end
338
337
 
339
- def self.sample
338
+ def self.sample
340
339
  migrator = Cloudinary::Migrator.new(
341
- :retrieve=>proc{|id| Post.find(id).data},
340
+ :retrieve=>proc{|id| Post.find(id).data},
342
341
  :complete=>proc{|id, result| a}
343
342
  )
344
-
343
+
345
344
  Post.find_each(:conditions=>["id > ?", migrator.max_given_id], :select=>"id") do
346
345
  |post|
347
346
  migrator.process(:id=>post.id, :public_id=>"post_#{post.id}")
348
347
  end
349
348
  migrator.done
350
- end
351
-
352
- def self.test
349
+ end
350
+
351
+ def self.test
353
352
  posts = {}
354
- done = {}
353
+ done = {}
355
354
  migrator = Cloudinary::Migrator.new(
356
- :retrieve=>proc{|id| posts[id]},
355
+ :retrieve=>proc{|id| posts[id]},
357
356
  :complete=>proc{|id, result| $stderr.print "done #{id} #{result}\n"; done[id] = result}
358
357
  )
359
358
  start = migrator.max_given_id + 1
360
359
  (start..1000).each{|i| posts[i] = "hello#{i}"}
361
-
360
+
362
361
  posts.each do
363
362
  |id, data|
364
363
  migrator.process(:id=>id, :public_id=>"post_#{id}")
365
364
  end
366
365
  migrator.done
367
366
  pp [done.length, start]
368
- end
367
+ end
369
368
  end
@@ -3,7 +3,9 @@ class Cloudinary::Railtie < Rails::Railtie
3
3
  Dir[File.join(File.dirname(__FILE__),'../tasks/**/*.rake')].each { |f| load f }
4
4
  end
5
5
  config.after_initialize do |app|
6
- ActionView::Base.send :include, CloudinaryHelper
6
+ ActiveSupport.on_load(:action_view) do
7
+ ActionView::Base.send :include, CloudinaryHelper
8
+ end
7
9
  end
8
10
 
9
11
  ActiveSupport.on_load(:action_controller_base) do
@@ -4,7 +4,8 @@ class Cloudinary::Search
4
4
  SORT_BY = :sort_by
5
5
  AGGREGATE = :aggregate
6
6
  WITH_FIELD = :with_field
7
- KEYS_WITH_UNIQUE_VALUES = [SORT_BY, AGGREGATE, WITH_FIELD].freeze
7
+ FIELDS = :fields
8
+ KEYS_WITH_UNIQUE_VALUES = [SORT_BY, AGGREGATE, WITH_FIELD, FIELDS].freeze
8
9
 
9
10
  TTL = 300 # Used for search URLs
10
11
 
@@ -12,7 +13,8 @@ class Cloudinary::Search
12
13
  @query_hash = {
13
14
  SORT_BY => {},
14
15
  AGGREGATE => {},
15
- WITH_FIELD => {}
16
+ WITH_FIELD => {},
17
+ FIELDS => {},
16
18
  }
17
19
 
18
20
  @endpoint = self.class::ENDPOINT
@@ -59,7 +61,7 @@ class Cloudinary::Search
59
61
  #
60
62
  # @param [String] value Supported values: resource_type, type, pixels (only the image assets in the response are
61
63
  # aggregated), duration (only the video assets in the response are aggregated), format, and
62
- # bytes. For aggregation fields without discrete values, the results are divided into
64
+ # bytes. For aggregation fields without discrete values, the results are divided into
63
65
  # categories.
64
66
  # @return [Cloudinary::Search]
65
67
  def aggregate(value)
@@ -77,6 +79,19 @@ class Cloudinary::Search
77
79
  self
78
80
  end
79
81
 
82
+
83
+ # The list of the asset attributes to include for each asset in the response.
84
+ #
85
+ # @param [Array] value The array of attributes' names.
86
+ #
87
+ # @return [Cloudinary::Search]
88
+ def fields(value)
89
+ Cloudinary::Utils.build_array(value).each do |field|
90
+ @query_hash[FIELDS][field] = field
91
+ end
92
+ self
93
+ end
94
+
80
95
  # Sets the time to live of the search URL.
81
96
  #
82
97
  # @param [Object] ttl The time to live in seconds.
@@ -1,82 +1,53 @@
1
1
  # Copyright Cloudinary
2
- require 'rest_client'
2
+ require 'faraday'
3
3
  require 'json'
4
4
  require 'cloudinary/cache'
5
5
 
6
6
  class Cloudinary::Uploader
7
-
8
- REMOTE_URL_REGEX = Cloudinary::Utils::REMOTE_URL_REGEX
9
- # @deprecated use {Cloudinary::Utils.build_eager} instead
10
- def self.build_eager(eager)
11
- Cloudinary::Utils.build_eager(eager)
12
- end
13
-
14
- # @private
15
- def self.build_upload_params(options)
7
+ @adapter = nil
8
+ def self.build_upload_params(options, as_bool = false)
16
9
  #symbolize keys
17
10
  options = options.clone
18
11
  options.keys.each { |key| options[key.to_sym] = options.delete(key) if key.is_a?(String) }
19
12
 
20
13
  params = {
21
- :access_control => Cloudinary::Utils.json_array_param(options[:access_control]),
22
- :access_mode => options[:access_mode],
23
- :allowed_formats => Cloudinary::Utils.build_array(options[:allowed_formats]).join(","),
24
- :asset_folder => options[:asset_folder],
25
- :async => Cloudinary::Utils.as_safe_bool(options[:async]),
26
- :auto_tagging => options[:auto_tagging] && options[:auto_tagging].to_f,
27
- :background_removal => options[:background_removal],
28
- :backup => Cloudinary::Utils.as_safe_bool(options[:backup]),
29
- :callback => options[:callback],
30
- :categorization => options[:categorization],
31
- :cinemagraph_analysis => Cloudinary::Utils.as_safe_bool(options[:cinemagraph_analysis]),
32
- :colors => Cloudinary::Utils.as_safe_bool(options[:colors]),
33
- :context => Cloudinary::Utils.encode_context(options[:context]),
34
- :custom_coordinates => Cloudinary::Utils.encode_double_array(options[:custom_coordinates]),
35
- :detection => options[:detection],
36
- :discard_original_filename => Cloudinary::Utils.as_safe_bool(options[:discard_original_filename]),
37
- :display_name => options[:display_name],
38
- :eager => Cloudinary::Utils.build_eager(options[:eager]),
39
- :eager_async => Cloudinary::Utils.as_safe_bool(options[:eager_async]),
40
- :eager_notification_url => options[:eager_notification_url],
41
- :exif => Cloudinary::Utils.as_safe_bool(options[:exif]),
42
- :eval => options[:eval],
43
- :face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
44
- :faces => Cloudinary::Utils.as_safe_bool(options[:faces]),
45
- :folder => options[:folder],
46
- :format => options[:format],
47
- :filename_override => options[:filename_override],
48
- :headers => build_custom_headers(options[:headers]),
49
- :image_metadata => Cloudinary::Utils.as_safe_bool(options[:image_metadata]),
50
- :media_metadata => Cloudinary::Utils.as_safe_bool(options[:media_metadata]),
51
- :invalidate => Cloudinary::Utils.as_safe_bool(options[:invalidate]),
52
- :moderation => options[:moderation],
53
- :notification_url => options[:notification_url],
54
- :ocr => options[:ocr],
55
- :overwrite => Cloudinary::Utils.as_safe_bool(options[:overwrite]),
56
- :phash => Cloudinary::Utils.as_safe_bool(options[:phash]),
57
- :proxy => options[:proxy],
58
- :public_id => options[:public_id],
59
- :public_id_prefix => options[:public_id_prefix],
60
- :quality_analysis => Cloudinary::Utils.as_safe_bool(options[:quality_analysis]),
61
- :quality_override => options[:quality_override],
62
- :raw_convert => options[:raw_convert],
63
- :responsive_breakpoints => Cloudinary::Utils.generate_responsive_breakpoints_string(options[:responsive_breakpoints]),
64
- :return_delete_token => Cloudinary::Utils.as_safe_bool(options[:return_delete_token]),
65
- :similarity_search => options[:similarity_search],
66
- :visual_search => Cloudinary::Utils.as_safe_bool(options[:visual_search]),
67
- :tags => options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
68
- :timestamp => (options[:timestamp] || Time.now.to_i),
69
- :transformation => Cloudinary::Utils.generate_transformation_string(options.clone),
70
- :type => options[:type],
71
- :unique_filename => Cloudinary::Utils.as_safe_bool(options[:unique_filename]),
72
- :upload_preset => options[:upload_preset],
73
- :use_filename => Cloudinary::Utils.as_safe_bool(options[:use_filename]),
74
- :use_filename_as_display_name => Cloudinary::Utils.as_safe_bool(options[:use_filename_as_display_name]),
75
- :use_asset_folder_as_public_id_prefix => Cloudinary::Utils.as_safe_bool(options[:use_asset_folder_as_public_id_prefix]),
76
- :unique_display_name => Cloudinary::Utils.as_safe_bool(options[:unique_display_name]),
77
- :accessibility_analysis => Cloudinary::Utils.as_safe_bool(options[:accessibility_analysis]),
78
- :metadata => Cloudinary::Utils.encode_context(options[:metadata])
14
+ :access_control => Cloudinary::Utils.json_array_param(options[:access_control]),
15
+ :allowed_formats => Cloudinary::Utils.build_array(options[:allowed_formats]).join(","),
16
+ :auto_tagging => options[:auto_tagging] && options[:auto_tagging].to_f,
17
+ :context => Cloudinary::Utils.encode_context(options[:context]),
18
+ :custom_coordinates => Cloudinary::Utils.encode_double_array(options[:custom_coordinates]),
19
+ :eager => Cloudinary::Utils.build_eager(options[:eager]),
20
+ :face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
21
+ :headers => build_custom_headers(options[:headers]),
22
+ :responsive_breakpoints => Cloudinary::Utils.generate_responsive_breakpoints_string(options[:responsive_breakpoints]),
23
+ :tags => options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
24
+ :timestamp => (options[:timestamp] || Time.now.to_i),
25
+ :transformation => Cloudinary::Utils.generate_transformation_string(options.clone),
26
+ :metadata => Cloudinary::Utils.encode_context(options[:metadata])
79
27
  }
28
+
29
+ bool_params = [
30
+ :async, :backup, :cinemagraph_analysis, :colors, :discard_original_filename, :eager_async, :exif, :faces,
31
+ :image_metadata, :media_metadata, :invalidate, :overwrite, :phash, :quality_analysis, :return_delete_token,
32
+ :visual_search, :unique_filename, :use_filename, :use_filename_as_display_name,
33
+ :use_asset_folder_as_public_id_prefix, :unique_display_name, :accessibility_analysis
34
+ ]
35
+
36
+ string_params = [
37
+ :access_mode, :asset_folder, :background_removal, :callback, :categorization, :detection, :display_name,
38
+ :eager_notification_url, :eval, :on_success, :folder, :format, :filename_override, :moderation, :notification_url,
39
+ :ocr, :proxy, :public_id, :public_id_prefix, :quality_override, :raw_convert, :similarity_search, :type,
40
+ :upload_preset
41
+ ]
42
+
43
+ bool_params.each do |b|
44
+ params[b] = as_bool ? Cloudinary::Utils.as_bool(options[b]): Cloudinary::Utils.as_safe_bool(options[b])
45
+ end
46
+
47
+ string_params.each do |s|
48
+ params[s] = options[s]
49
+ end
50
+
80
51
  params
81
52
  end
82
53
 
@@ -87,16 +58,7 @@ class Cloudinary::Uploader
87
58
  def self.upload(file, options={})
88
59
  call_api("upload", options) do
89
60
  params = build_upload_params(options)
90
- if file.is_a?(Pathname)
91
- params[:file] = File.open(file, "rb")
92
- elsif file.is_a?(StringIO)
93
- file.rewind
94
- params[:file] = Cloudinary::Blob.new(file.read, options)
95
- elsif file.respond_to?(:read) || Cloudinary::Utils.is_remote?(file)
96
- params[:file] = file
97
- else
98
- params[:file] = File.open(file, "rb")
99
- end
61
+ params[:file] = Cloudinary::Utils.handle_file_param(file, options)
100
62
  [params, [:file]]
101
63
  end
102
64
  end
@@ -153,11 +115,7 @@ class Cloudinary::Uploader
153
115
  options[:resource_type] ||= :raw
154
116
  call_api("upload", options) do
155
117
  params = build_upload_params(options)
156
- if file.is_a?(Pathname) || !file.respond_to?(:read)
157
- params[:file] = File.open(file, "rb")
158
- else
159
- params[:file] = file
160
- end
118
+ params[:file] = Cloudinary::Utils.handle_file_param(file, options)
161
119
  [params, [:file]]
162
120
  end
163
121
  end
@@ -406,29 +364,39 @@ class Cloudinary::Uploader
406
364
  params[:signature] = Cloudinary::Utils.api_sign_request(params.reject { |k, v| non_signable.include?(k) }, api_secret, signature_algorithm)
407
365
  params[:api_key] = api_key
408
366
  end
409
- proxy = options[:api_proxy] || Cloudinary.config.api_proxy
410
- timeout = options.fetch(:timeout) { Cloudinary.config.to_h.fetch(:timeout, 60) }
411
-
412
- result = nil
413
-
414
- api_url = Cloudinary::Utils.cloudinary_api_url(action, options)
415
- RestClient::Request.execute(:method => :post, :url => api_url, :payload => params.reject { |k, v| v.nil? || v=="" }, :timeout => timeout, :headers => headers, :proxy => proxy) do
416
- |response, request, tmpresult|
417
- raise CloudinaryException, "Server returned unexpected status code - #{response.code} - #{response.body}" unless [200, 400, 401, 403, 404, 500].include?(response.code)
418
- begin
419
- result = Cloudinary::Utils.json_decode(response.body)
420
- rescue => e
421
- # Error is parsing json
422
- raise CloudinaryException, "Error parsing server response (#{response.code}) - #{response.body}. Got - #{e}"
423
- end
424
- if result["error"]
425
- if return_error
426
- result["error"]["http_code"] = response.code
427
- else
428
- raise CloudinaryException, result["error"]["message"]
429
- end
367
+
368
+ api_url = Cloudinary::Utils.cloudinary_api_url(action, options)
369
+ api_proxy = options[:api_proxy] || Cloudinary.config.api_proxy
370
+ timeout = options.fetch(:timeout) { Cloudinary.config.to_h.fetch(:timeout, 60) }
371
+
372
+ conn = Faraday.new(url: api_url) do |faraday|
373
+ faraday.proxy = api_proxy if api_proxy
374
+ faraday.request :multipart, **options
375
+ faraday.request :url_encoded
376
+ faraday.adapter @adapter || Faraday.default_adapter
377
+ end
378
+
379
+ response = conn.send(:post) do |req|
380
+ req.headers = headers
381
+ req.body = params.reject { |_, v| v.nil? || v=="" }
382
+ req.options.timeout = timeout if timeout
383
+ end
384
+
385
+ raise CloudinaryException, "Server returned unexpected status code - #{response.status} - #{response.body}" unless [200, 400, 401, 403, 404, 500].include?(response.status)
386
+ begin
387
+ result = Cloudinary::Utils.json_decode(response.body)
388
+ rescue => e
389
+ # Error is parsing json
390
+ raise CloudinaryException, "Error parsing server response (#{response.status}) - #{response.body}. Got - #{e}"
391
+ end
392
+ if result["error"]
393
+ if return_error
394
+ result["error"]["http_code"] = response.status
395
+ else
396
+ raise CloudinaryException, result["error"]["message"]
430
397
  end
431
398
  end
399
+
432
400
  if use_cache && !result.nil?
433
401
  cache_results(result)
434
402
  end