cloudinary 1.29.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.travis.yml +0 -1
 - data/CHANGELOG.md +33 -0
 - data/README.md +5 -3
 - data/cloudinary.gemspec +21 -51
 - data/lib/active_storage/service/cloudinary_service.rb +4 -2
 - data/lib/cloudinary/account_api.rb +21 -8
 - data/lib/cloudinary/analytics.rb +157 -0
 - data/lib/cloudinary/api.rb +24 -4
 - data/lib/cloudinary/auth_token.rb +1 -5
 - data/lib/cloudinary/base_api.rb +36 -31
 - data/lib/cloudinary/carrier_wave/storage.rb +2 -1
 - data/lib/cloudinary/carrier_wave.rb +0 -5
 - data/lib/cloudinary/helper.rb +2 -10
 - data/lib/cloudinary/migrator.rb +70 -71
 - data/lib/cloudinary/uploader.rb +70 -90
 - data/lib/cloudinary/utils.rb +31 -54
 - data/lib/cloudinary/version.rb +1 -1
 - data/lib/cloudinary.rb +3 -9
 - data/lib/tasks/cloudinary/fetch_assets.rake +9 -3
 - data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +3 -3
 - metadata +164 -38
 - data/lib/cloudinary/ostruct2.rb +0 -284
 
    
        data/lib/cloudinary/migrator.rb
    CHANGED
    
    | 
         @@ -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 =  
     | 
| 
      
 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
         
     | 
    
        data/lib/cloudinary/uploader.rb
    CHANGED
    
    | 
         @@ -1,83 +1,53 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Copyright Cloudinary
         
     | 
| 
       2 
     | 
    
         
            -
            require ' 
     | 
| 
      
 2 
     | 
    
         
            +
            require 'faraday'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'json'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'cloudinary/cache'
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            class Cloudinary::Uploader
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
               
     | 
| 
       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 
     | 
| 
       22 
     | 
    
         
            -
                  : 
     | 
| 
       23 
     | 
    
         
            -
                  : 
     | 
| 
       24 
     | 
    
         
            -
                  : 
     | 
| 
       25 
     | 
    
         
            -
                  : 
     | 
| 
       26 
     | 
    
         
            -
                  : 
     | 
| 
       27 
     | 
    
         
            -
                  : 
     | 
| 
       28 
     | 
    
         
            -
                  : 
     | 
| 
       29 
     | 
    
         
            -
                  : 
     | 
| 
       30 
     | 
    
         
            -
                  : 
     | 
| 
       31 
     | 
    
         
            -
                  : 
     | 
| 
       32 
     | 
    
         
            -
                  : 
     | 
| 
       33 
     | 
    
         
            -
                  : 
     | 
| 
       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 
     | 
    
         
            -
                  :on_success                           => options[:on_success],
         
     | 
| 
       44 
     | 
    
         
            -
                  :face_coordinates                     => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
         
     | 
| 
       45 
     | 
    
         
            -
                  :faces                                => Cloudinary::Utils.as_safe_bool(options[:faces]),
         
     | 
| 
       46 
     | 
    
         
            -
                  :folder                               => options[:folder],
         
     | 
| 
       47 
     | 
    
         
            -
                  :format                               => options[:format],
         
     | 
| 
       48 
     | 
    
         
            -
                  :filename_override                    => options[:filename_override],
         
     | 
| 
       49 
     | 
    
         
            -
                  :headers                              => build_custom_headers(options[:headers]),
         
     | 
| 
       50 
     | 
    
         
            -
                  :image_metadata                       => Cloudinary::Utils.as_safe_bool(options[:image_metadata]),
         
     | 
| 
       51 
     | 
    
         
            -
                  :media_metadata                       => Cloudinary::Utils.as_safe_bool(options[:media_metadata]),
         
     | 
| 
       52 
     | 
    
         
            -
                  :invalidate                           => Cloudinary::Utils.as_safe_bool(options[:invalidate]),
         
     | 
| 
       53 
     | 
    
         
            -
                  :moderation                           => options[:moderation],
         
     | 
| 
       54 
     | 
    
         
            -
                  :notification_url                     => options[:notification_url],
         
     | 
| 
       55 
     | 
    
         
            -
                  :ocr                                  => options[:ocr],
         
     | 
| 
       56 
     | 
    
         
            -
                  :overwrite                            => Cloudinary::Utils.as_safe_bool(options[:overwrite]),
         
     | 
| 
       57 
     | 
    
         
            -
                  :phash                                => Cloudinary::Utils.as_safe_bool(options[:phash]),
         
     | 
| 
       58 
     | 
    
         
            -
                  :proxy                                => options[:proxy],
         
     | 
| 
       59 
     | 
    
         
            -
                  :public_id                            => options[:public_id],
         
     | 
| 
       60 
     | 
    
         
            -
                  :public_id_prefix                     => options[:public_id_prefix],
         
     | 
| 
       61 
     | 
    
         
            -
                  :quality_analysis                     => Cloudinary::Utils.as_safe_bool(options[:quality_analysis]),
         
     | 
| 
       62 
     | 
    
         
            -
                  :quality_override                     => options[:quality_override],
         
     | 
| 
       63 
     | 
    
         
            -
                  :raw_convert                          => options[:raw_convert],
         
     | 
| 
       64 
     | 
    
         
            -
                  :responsive_breakpoints               => Cloudinary::Utils.generate_responsive_breakpoints_string(options[:responsive_breakpoints]),
         
     | 
| 
       65 
     | 
    
         
            -
                  :return_delete_token                  => Cloudinary::Utils.as_safe_bool(options[:return_delete_token]),
         
     | 
| 
       66 
     | 
    
         
            -
                  :similarity_search                    => options[:similarity_search],
         
     | 
| 
       67 
     | 
    
         
            -
                  :visual_search                        => Cloudinary::Utils.as_safe_bool(options[:visual_search]),
         
     | 
| 
       68 
     | 
    
         
            -
                  :tags                                 => options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
         
     | 
| 
       69 
     | 
    
         
            -
                  :timestamp                            => (options[:timestamp] || Time.now.to_i),
         
     | 
| 
       70 
     | 
    
         
            -
                  :transformation                       => Cloudinary::Utils.generate_transformation_string(options.clone),
         
     | 
| 
       71 
     | 
    
         
            -
                  :type                                 => options[:type],
         
     | 
| 
       72 
     | 
    
         
            -
                  :unique_filename                      => Cloudinary::Utils.as_safe_bool(options[:unique_filename]),
         
     | 
| 
       73 
     | 
    
         
            -
                  :upload_preset                        => options[:upload_preset],
         
     | 
| 
       74 
     | 
    
         
            -
                  :use_filename                         => Cloudinary::Utils.as_safe_bool(options[:use_filename]),
         
     | 
| 
       75 
     | 
    
         
            -
                  :use_filename_as_display_name         => Cloudinary::Utils.as_safe_bool(options[:use_filename_as_display_name]),
         
     | 
| 
       76 
     | 
    
         
            -
                  :use_asset_folder_as_public_id_prefix => Cloudinary::Utils.as_safe_bool(options[:use_asset_folder_as_public_id_prefix]),
         
     | 
| 
       77 
     | 
    
         
            -
                  :unique_display_name                  => Cloudinary::Utils.as_safe_bool(options[:unique_display_name]),
         
     | 
| 
       78 
     | 
    
         
            -
                  :accessibility_analysis               => Cloudinary::Utils.as_safe_bool(options[:accessibility_analysis]),
         
     | 
| 
       79 
     | 
    
         
            -
                  :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])
         
     | 
| 
       80 
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 
     | 
    
         
            +
             
     | 
| 
       81 
51 
     | 
    
         
             
                params
         
     | 
| 
       82 
52 
     | 
    
         
             
              end
         
     | 
| 
       83 
53 
     | 
    
         | 
| 
         @@ -394,29 +364,39 @@ class Cloudinary::Uploader 
     | 
|
| 
       394 
364 
     | 
    
         
             
                  params[:signature]  = Cloudinary::Utils.api_sign_request(params.reject { |k, v| non_signable.include?(k) }, api_secret, signature_algorithm)
         
     | 
| 
       395 
365 
     | 
    
         
             
                  params[:api_key]    = api_key
         
     | 
| 
       396 
366 
     | 
    
         
             
                end
         
     | 
| 
       397 
     | 
    
         
            -
             
     | 
| 
       398 
     | 
    
         
            -
                 
     | 
| 
       399 
     | 
    
         
            -
             
     | 
| 
       400 
     | 
    
         
            -
                 
     | 
| 
       401 
     | 
    
         
            -
             
     | 
| 
       402 
     | 
    
         
            -
                 
     | 
| 
       403 
     | 
    
         
            -
             
     | 
| 
       404 
     | 
    
         
            -
             
     | 
| 
       405 
     | 
    
         
            -
                   
     | 
| 
       406 
     | 
    
         
            -
                   
     | 
| 
       407 
     | 
    
         
            -
             
     | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
     | 
    
         
            -
             
     | 
| 
       410 
     | 
    
         
            -
             
     | 
| 
       411 
     | 
    
         
            -
                   
     | 
| 
       412 
     | 
    
         
            -
                  if  
     | 
| 
       413 
     | 
    
         
            -
             
     | 
| 
       414 
     | 
    
         
            -
             
     | 
| 
       415 
     | 
    
         
            -
             
     | 
| 
       416 
     | 
    
         
            -
             
     | 
| 
       417 
     | 
    
         
            -
             
     | 
| 
      
 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"]
         
     | 
| 
       418 
397 
     | 
    
         
             
                  end
         
     | 
| 
       419 
398 
     | 
    
         
             
                end
         
     | 
| 
      
 399 
     | 
    
         
            +
             
     | 
| 
       420 
400 
     | 
    
         
             
                if use_cache && !result.nil?
         
     | 
| 
       421 
401 
     | 
    
         
             
                  cache_results(result)
         
     | 
| 
       422 
402 
     | 
    
         
             
                end
         
     |