cloudinary 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +342 -142
- data/README.md +24 -7
- data/Rakefile +45 -19
- data/lib/cloudinary/carrier_wave/storage.rb +4 -1
- data/lib/cloudinary/helper.rb +2 -2
- data/lib/cloudinary/utils.rb +146 -30
- data/lib/cloudinary/version.rb +1 -1
- data/spec/spec_helper.rb +65 -6
- data/spec/utils_methods_spec.rb +3 -3
- data/spec/utils_spec.rb +437 -152
- data/spec/video_tag_spec.rb +1 -1
- data/spec/video_url_spec.rb +63 -22
- data/vendor/assets/html/cloudinary_cors.html +3 -7
- data/vendor/assets/javascripts/cloudinary/canvas-to-blob.min.js +1 -1
- data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +3482 -1001
- data/vendor/assets/javascripts/cloudinary/jquery.fileupload-image.js +9 -3
- data/vendor/assets/javascripts/cloudinary/jquery.fileupload-process.js +5 -2
- data/vendor/assets/javascripts/cloudinary/jquery.fileupload-validate.js +6 -3
- data/vendor/assets/javascripts/cloudinary/jquery.fileupload.js +32 -15
- data/vendor/assets/javascripts/cloudinary/jquery.iframe-transport.js +5 -2
- data/vendor/assets/javascripts/cloudinary/jquery.ui.widget.js +29 -15
- data/vendor/assets/javascripts/cloudinary/load-image.all.min.js +1 -0
- data/vendor/assets/javascripts/cloudinary/processing.js +1 -1
- metadata +4 -4
- data/vendor/assets/javascripts/cloudinary/load-image.min.js +0 -1
data/README.md
CHANGED
@@ -22,23 +22,23 @@ To install the Cloudinary Ruby GEM, run:
|
|
22
22
|
|
23
23
|
If you use Rails 3.x or higher, edit your `Gemfile`, add the following line and run `bundle install`
|
24
24
|
|
25
|
-
|
25
|
+
gem 'cloudinary'
|
26
26
|
|
27
27
|
Or in Rails 2.x, edit your `environment.rb` and add:
|
28
28
|
|
29
|
-
|
29
|
+
config.gem 'cloudinary'
|
30
30
|
|
31
31
|
If you would like to use our optional integration module of image uploads with ActiveRecord using `CarrierWave`, install CarrierWave GEM:
|
32
32
|
|
33
33
|
Rails 3.x: edit your `Gemfile` and run `bundle install`:
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
gem 'carrierwave'
|
36
|
+
gem 'cloudinary'
|
37
37
|
|
38
38
|
Rails 2.x environment.rb:
|
39
39
|
|
40
|
-
|
41
|
-
|
40
|
+
config.gem 'carrierwave', :version => '~> 0.4.10'
|
41
|
+
config.gem 'cloudinary'
|
42
42
|
|
43
43
|
|
44
44
|
*Note: The CarrierWave GEM should be loaded before the Cloudinary GEM.*
|
@@ -92,6 +92,18 @@ It contains settings for each of your deployment environments. You can always ov
|
|
92
92
|
|
93
93
|
You can [download your customized cloudinary.yml](https://cloudinary.com/console/cloudinary.yml) configuration file using our Management Console.
|
94
94
|
|
95
|
+
Passing the parameters manually looks like this:
|
96
|
+
|
97
|
+
``` ruby
|
98
|
+
auth = {
|
99
|
+
cloud_name: "somename",
|
100
|
+
api_key: "1234567890",
|
101
|
+
api_secret: "FooBarBaz123"
|
102
|
+
}
|
103
|
+
|
104
|
+
Cloudinary::Uploader.upload("my_picture.jpg", auth)
|
105
|
+
```
|
106
|
+
|
95
107
|
|
96
108
|
### Embedding and transforming images
|
97
109
|
|
@@ -163,12 +175,15 @@ Cloudinary's Ruby GEM includes an optional plugin for [CarrierWave](https://gith
|
|
163
175
|
|
164
176
|
We also published an interesting blog post about [Ruby on Rails image uploads with CarrierWave and Cloudinary](http://cloudinary.com/blog/ruby_on_rails_image_uploads_with_carrierwave_and_cloudinary).
|
165
177
|
|
178
|
+
## Neo4j integration
|
179
|
+
|
180
|
+
Starting from version 1.1.1 Cloudinary's Ruby GEM supports the use of carrierwave with Neo4j.
|
181
|
+
|
166
182
|
### Samples
|
167
183
|
|
168
184
|
You can find our simple and ready-to-use samples projects, along with documentation in the [samples folder](https://github.com/cloudinary/cloudinary_gem/tree/master/samples).
|
169
185
|
Please consult with the [README file](https://github.com/cloudinary/cloudinary_gem/blob/master/samples/README.md), for usage and explanations.
|
170
186
|
|
171
|
-
|
172
187
|
## Additional resources ##########################################################
|
173
188
|
|
174
189
|
Additional resources are available at:
|
@@ -193,3 +208,5 @@ Stay tuned for updates, tips and tutorials: [Blog](http://cloudinary.com/blog),
|
|
193
208
|
## License #######################################################################
|
194
209
|
|
195
210
|
Released under the MIT license.
|
211
|
+
|
212
|
+
|
data/Rakefile
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
require 'bundler'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'rest_client'
|
5
|
+
require 'json'
|
6
|
+
require 'rubygems/package'
|
2
7
|
|
3
8
|
require 'rspec/core/rake_task'
|
4
9
|
RSpec::Core::RakeTask.new(:spec)
|
@@ -6,24 +11,45 @@ task :default => :spec
|
|
6
11
|
|
7
12
|
Bundler::GemHelper.install_tasks
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
14
|
+
namespace :cloudinary do
|
15
|
+
desc "Fetch the latest JavaScript library files and create the JavaScript index files"
|
16
|
+
task :fetch_assets do
|
17
|
+
index_files = %w[jquery.ui.widget.js jquery.iframe-transport.js jquery.fileupload.js jquery.cloudinary.js]
|
18
|
+
processing_files = %w[canvas-to-blob.min.js load-image.all.min.js jquery.fileupload-process.js jquery.fileupload-image.js jquery.fileupload-validate.js]
|
19
|
+
files = index_files + processing_files
|
20
|
+
|
21
|
+
release = JSON(RestClient.get("https://api.github.com/repos/cloudinary/cloudinary_js/releases/latest"))
|
22
|
+
|
23
|
+
FileUtils.rm_rf 'vendor/assets'
|
24
|
+
html_folder = 'vendor/assets/html'
|
25
|
+
FileUtils.mkdir_p html_folder
|
26
|
+
js_folder = 'vendor/assets/javascripts/cloudinary'
|
27
|
+
FileUtils.mkdir_p js_folder
|
28
|
+
|
29
|
+
puts "Fetching cloudinary_js version #{release["tag_name"]}\n\n"
|
30
|
+
sio = StringIO.new(RestClient.get(release["tarball_url"]).body)
|
31
|
+
file =Zlib::GzipReader.new(sio)
|
32
|
+
tar = Gem::Package::TarReader.new(file)
|
33
|
+
tar.each_entry do |entry|
|
34
|
+
name = File.basename(entry.full_name)
|
35
|
+
if files.include? name
|
36
|
+
js_full_name = File.join(js_folder, name)
|
37
|
+
puts "Adding #{js_full_name}"
|
38
|
+
File.write js_full_name, entry.read
|
39
|
+
elsif name == 'cloudinary_cors.html'
|
40
|
+
html_full_name = File.join(html_folder, name)
|
41
|
+
puts "Adding #{html_full_name}"
|
42
|
+
File.write html_full_name, entry.read
|
43
|
+
end
|
44
|
+
end
|
45
|
+
puts "Creating 'index.js' and 'processing.js' files"
|
46
|
+
File.open("vendor/assets/javascripts/cloudinary/index.js", "w") do |f|
|
47
|
+
index_files.each { |name| f.puts "//= require ./#{name}" }
|
48
|
+
end
|
49
|
+
File.open("vendor/assets/javascripts/cloudinary/processing.js", "w") do |f|
|
50
|
+
processing_files.each { |name| f.puts "//= require ./#{name}" }
|
51
|
+
end
|
26
52
|
end
|
27
|
-
end
|
28
53
|
|
29
|
-
|
54
|
+
end
|
55
|
+
task :build => "cloudinary:fetch_assets"
|
@@ -68,9 +68,10 @@ class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
|
|
68
68
|
column = uploader.model.send(:_mounter, uploader.mounted_as).send(:serialization_column)
|
69
69
|
if defined?(ActiveRecord::Base) && uploader.model.is_a?(ActiveRecord::Base)
|
70
70
|
primary_key = model_class.primary_key.to_sym
|
71
|
-
if
|
71
|
+
if defined?(::ActiveRecord::VERSION::MAJOR) && ::ActiveRecord::VERSION::MAJOR > 2
|
72
72
|
model_class.where(primary_key=>uploader.model.send(primary_key)).update_all(column=>name)
|
73
73
|
else
|
74
|
+
# Removed since active record version 3.0.0
|
74
75
|
model_class.update_all({column=>name}, {primary_key=>uploader.model.send(primary_key)})
|
75
76
|
end
|
76
77
|
uploader.model.send :write_attribute, column, name
|
@@ -83,6 +84,8 @@ class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
|
|
83
84
|
else
|
84
85
|
uploader.model.set(column, name)
|
85
86
|
end
|
87
|
+
elsif defined?(Neo4j::VERSION) && Neo4j::VERSION.split(".").first.to_i >= 5
|
88
|
+
uploader.model.set(column, name)
|
86
89
|
elsif defined?(Sequel::Model) && uploader.model.is_a?(Sequel::Model)
|
87
90
|
# Sequel support
|
88
91
|
uploader.model.this.update(column => name)
|
data/lib/cloudinary/helper.rb
CHANGED
@@ -250,7 +250,7 @@ module CloudinaryHelper
|
|
250
250
|
if !method_defined?(:image_tag)
|
251
251
|
include ActionView::Helpers::AssetTagHelper
|
252
252
|
end
|
253
|
-
if defined?(Rails::
|
253
|
+
if defined?(::Rails::VERSION::MAJOR) && ::Rails::VERSION::MAJOR > 2 && Cloudinary.config.enhance_image_tag
|
254
254
|
alias_method_chain :image_tag, :cloudinary # defines image_tag_without_cloudinary
|
255
255
|
alias_method_chain :image_path, :cloudinary # defines image_path_without_cloudinary
|
256
256
|
else
|
@@ -316,7 +316,7 @@ if defined? ActionView::Helpers::AssetUrlHelper
|
|
316
316
|
end
|
317
317
|
end
|
318
318
|
|
319
|
-
if defined?(Rails::
|
319
|
+
if defined?(::Rails::VERSION::MAJOR) && ::Rails::VERSION::MAJOR == 2
|
320
320
|
ActionView::Base.send :include, ActionView::Helpers::AssetTagHelper
|
321
321
|
ActionView::Base.send :include, CloudinaryHelper
|
322
322
|
end
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -14,11 +14,9 @@ class Cloudinary::Utils
|
|
14
14
|
if options.is_a?(Array)
|
15
15
|
return options.map{|base_transformation| generate_transformation_string(base_transformation.clone)}.join("/")
|
16
16
|
end
|
17
|
-
|
18
|
-
options
|
19
|
-
|
20
|
-
end
|
21
|
-
|
17
|
+
|
18
|
+
symbolize_keys!(options)
|
19
|
+
|
22
20
|
responsive_width = config_option_consume(options, :responsive_width)
|
23
21
|
size = options.delete(:size)
|
24
22
|
options[:width], options[:height] = size.split("x") if size
|
@@ -70,6 +68,9 @@ class Cloudinary::Utils
|
|
70
68
|
options[:start_offset], options[:end_offset] = split_range options.delete(:offset)
|
71
69
|
end
|
72
70
|
|
71
|
+
overlay = process_layer(options.delete(:overlay))
|
72
|
+
underlay = process_layer(options.delete(:underlay))
|
73
|
+
|
73
74
|
params = {
|
74
75
|
:a => angle,
|
75
76
|
:b => background,
|
@@ -80,7 +81,9 @@ class Cloudinary::Utils
|
|
80
81
|
:e => effect,
|
81
82
|
:fl => flags,
|
82
83
|
:h => height,
|
84
|
+
:l => overlay,
|
83
85
|
:t => named_transformation,
|
86
|
+
:u => underlay,
|
84
87
|
:w => width
|
85
88
|
}
|
86
89
|
{
|
@@ -94,7 +97,6 @@ class Cloudinary::Utils
|
|
94
97
|
:eo => :end_offset,
|
95
98
|
:f => :fetch_format,
|
96
99
|
:g => :gravity,
|
97
|
-
:l => :overlay,
|
98
100
|
:o => :opacity,
|
99
101
|
:p => :prefix,
|
100
102
|
:pg => :page,
|
@@ -102,7 +104,6 @@ class Cloudinary::Utils
|
|
102
104
|
:r => :radius,
|
103
105
|
:af => :audio_frequency,
|
104
106
|
:so => :start_offset,
|
105
|
-
:u => :underlay,
|
106
107
|
:vc => :video_codec,
|
107
108
|
:vs => :video_sampling,
|
108
109
|
:x => :x,
|
@@ -137,6 +138,84 @@ class Cloudinary::Utils
|
|
137
138
|
transformations.reject(&:blank?).join("/")
|
138
139
|
end
|
139
140
|
|
141
|
+
# Parse layer options
|
142
|
+
# @return [string] layer transformation string
|
143
|
+
# @private
|
144
|
+
def self.process_layer(layer)
|
145
|
+
if layer.is_a? Hash
|
146
|
+
layer = symbolize_keys layer
|
147
|
+
public_id = layer[:public_id]
|
148
|
+
format = layer[:format]
|
149
|
+
resource_type = layer[:resource_type] || "image"
|
150
|
+
type = layer[:type] || "upload"
|
151
|
+
text = layer[:text]
|
152
|
+
text_style = nil
|
153
|
+
components = []
|
154
|
+
|
155
|
+
unless public_id.blank?
|
156
|
+
public_id = public_id.gsub("/", ":")
|
157
|
+
public_id = "#{public_id}.#{format}" unless format.nil?
|
158
|
+
end
|
159
|
+
|
160
|
+
if text.blank? && resource_type != "text"
|
161
|
+
if public_id.blank?
|
162
|
+
raise(CloudinaryException, "Must supply public_id for resource_type layer_parameter")
|
163
|
+
end
|
164
|
+
if resource_type == "subtitles"
|
165
|
+
text_style = text_style(layer)
|
166
|
+
end
|
167
|
+
|
168
|
+
else
|
169
|
+
resource_type = "text"
|
170
|
+
type = nil
|
171
|
+
# // type is ignored for text layers
|
172
|
+
text_style = text_style(layer)
|
173
|
+
unless text.blank?
|
174
|
+
unless public_id.blank? ^ text_style.blank?
|
175
|
+
raise(CloudinaryException, "Must supply either style parameters or a public_id when providing text parameter in a text overlay/underlay")
|
176
|
+
end
|
177
|
+
text = smart_escape smart_escape(text, %r"([,/])")
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
181
|
+
components.push(resource_type) if resource_type != "image"
|
182
|
+
components.push(type) if type != "upload"
|
183
|
+
components.push(text_style)
|
184
|
+
components.push(public_id)
|
185
|
+
components.push(text)
|
186
|
+
layer = components.reject(&:blank?).join(":")
|
187
|
+
end
|
188
|
+
layer
|
189
|
+
end
|
190
|
+
private_class_method :process_layer
|
191
|
+
|
192
|
+
LAYER_KEYWORD_PARAMS ={
|
193
|
+
:font_weight => "normal",
|
194
|
+
:font_style => "normal",
|
195
|
+
:text_decoration => "none",
|
196
|
+
:text_align => nil,
|
197
|
+
:stroke => "none"
|
198
|
+
}
|
199
|
+
|
200
|
+
def self.text_style(layer)
|
201
|
+
font_family = layer[:font_family]
|
202
|
+
font_size = layer[:font_size]
|
203
|
+
keywords = []
|
204
|
+
LAYER_KEYWORD_PARAMS.each do |attr, default_value|
|
205
|
+
attr_value = layer[attr] || default_value
|
206
|
+
keywords.push(attr_value) unless attr_value == default_value
|
207
|
+
end
|
208
|
+
letter_spacing = layer[:letter_spacing]
|
209
|
+
keywords.push("letter_spacing_#{letter_spacing}") unless letter_spacing.blank?
|
210
|
+
if !font_size.blank? || !font_family.blank? || !keywords.empty?
|
211
|
+
raise(CloudinaryException, "Must supply font_family for text in overlay/underlay") if font_family.blank?
|
212
|
+
raise(CloudinaryException, "Must supply font_size for text in overlay/underlay") if font_size.blank?
|
213
|
+
keywords.unshift(font_size)
|
214
|
+
keywords.unshift(font_family)
|
215
|
+
keywords.reject(&:blank?).join("_")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
140
219
|
def self.api_string_to_sign(params_to_sign)
|
141
220
|
params_to_sign.map{|k,v| [k.to_s, v.is_a?(Array) ? v.join(",") : v]}.reject{|k,v| v.nil? || v == ""}.sort_by(&:first).map{|k,v| "#{k}=#{v}"}.join("&")
|
142
221
|
end
|
@@ -151,7 +230,7 @@ class Cloudinary::Utils
|
|
151
230
|
|
152
231
|
type = options.delete(:type)
|
153
232
|
|
154
|
-
options[:fetch_format] ||= options.delete(:format) if type ==
|
233
|
+
options[:fetch_format] ||= options.delete(:format) if type.to_s == "fetch"
|
155
234
|
transformation = self.generate_transformation_string(options)
|
156
235
|
|
157
236
|
resource_type = options.delete(:resource_type)
|
@@ -184,10 +263,11 @@ class Cloudinary::Utils
|
|
184
263
|
type ||= source.storage_type
|
185
264
|
source = format.blank? ? source.filename : source.full_public_id
|
186
265
|
end
|
266
|
+
type = type.to_s unless type.nil?
|
187
267
|
resource_type ||= "image"
|
188
268
|
source = source.to_s
|
189
269
|
if !force_remote
|
190
|
-
return original_source if (type.nil? || type ==
|
270
|
+
return original_source if (type.nil? || type == "asset") && source.match(%r(^https?:/)i)
|
191
271
|
if source.start_with?("/")
|
192
272
|
if source.start_with?("/images/")
|
193
273
|
source = source.sub(%r(/images/), '')
|
@@ -196,11 +276,11 @@ class Cloudinary::Utils
|
|
196
276
|
end
|
197
277
|
end
|
198
278
|
@metadata ||= defined?(Cloudinary::Static) ? Cloudinary::Static.metadata : {}
|
199
|
-
if type ==
|
279
|
+
if type == "asset" && @metadata["images/#{source}"]
|
200
280
|
return original_source if !Cloudinary.config.static_image_support
|
201
281
|
source = @metadata["images/#{source}"]["public_id"]
|
202
282
|
source += File.extname(original_source) if !format
|
203
|
-
elsif type ==
|
283
|
+
elsif type == "asset"
|
204
284
|
return original_source # requested asset, but no metadata - probably local file. return.
|
205
285
|
end
|
206
286
|
end
|
@@ -214,11 +294,16 @@ class Cloudinary::Utils
|
|
214
294
|
transformation = transformation.gsub(%r(([^:])//), '\1/')
|
215
295
|
if sign_url
|
216
296
|
to_sign = [transformation, sign_version && version, source_to_sign].reject(&:blank?).join("/")
|
297
|
+
i = 0
|
298
|
+
while to_sign != CGI.unescape(to_sign) && i <10
|
299
|
+
to_sign = CGI.unescape(to_sign)
|
300
|
+
i = i + 1
|
301
|
+
end
|
217
302
|
signature = 's--' + Base64.urlsafe_encode64(Digest::SHA1.digest(to_sign + secret))[0,8] + '--'
|
218
303
|
end
|
219
304
|
|
220
305
|
prefix = unsigned_download_url_prefix(source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname, secure, secure_distribution)
|
221
|
-
|
306
|
+
source = [prefix, resource_type, type, signature, transformation, version, source].reject(&:blank?).join("/")
|
222
307
|
end
|
223
308
|
|
224
309
|
def self.finalize_source(source, format, url_suffix)
|
@@ -369,8 +454,8 @@ class Cloudinary::Utils
|
|
369
454
|
end
|
370
455
|
|
371
456
|
# Based on CGI::unescape. In addition does not escape / :
|
372
|
-
def self.smart_escape(string)
|
373
|
-
string.gsub(
|
457
|
+
def self.smart_escape(string, unsafe = /([^a-zA-Z0-9_.\-\/:]+)/)
|
458
|
+
string.gsub(unsafe) do
|
374
459
|
'%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
|
375
460
|
end
|
376
461
|
end
|
@@ -468,18 +553,60 @@ class Cloudinary::Utils
|
|
468
553
|
value.nil? || value == "" || value == []
|
469
554
|
end
|
470
555
|
|
556
|
+
def self.symbolize_keys(h)
|
557
|
+
new_h = Hash.new
|
558
|
+
if (h.respond_to? :keys)
|
559
|
+
h.keys.each do |key|
|
560
|
+
new_h[(key.to_sym rescue key)] = h[key]
|
561
|
+
end
|
562
|
+
end
|
563
|
+
new_h
|
564
|
+
end
|
565
|
+
|
566
|
+
|
567
|
+
def self.symbolize_keys!(h)
|
568
|
+
if (h.respond_to? :keys) && (h.respond_to? :delete)
|
569
|
+
h.keys.each do |key|
|
570
|
+
value = h.delete(key)
|
571
|
+
h[(key.to_sym rescue key)] = value
|
572
|
+
end
|
573
|
+
end
|
574
|
+
h
|
575
|
+
end
|
576
|
+
|
577
|
+
|
578
|
+
def self.deep_symbolize_keys(object)
|
579
|
+
case object
|
580
|
+
when Hash
|
581
|
+
result = {}
|
582
|
+
object.each do |key, value|
|
583
|
+
key = key.to_sym rescue key
|
584
|
+
result[key] = deep_symbolize_keys(value)
|
585
|
+
end
|
586
|
+
result
|
587
|
+
when Array
|
588
|
+
object.map{|e| deep_symbolize_keys(e)}
|
589
|
+
else
|
590
|
+
object
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
471
594
|
private
|
595
|
+
|
472
596
|
def self.number_pattern
|
473
597
|
"([0-9]*)\\.([0-9]+)|([0-9]+)"
|
474
598
|
end
|
599
|
+
private_class_method :number_pattern
|
475
600
|
|
476
601
|
def self.offset_any_pattern
|
477
602
|
"(#{number_pattern})([%pP])?"
|
478
603
|
end
|
604
|
+
private_class_method :offset_any_pattern
|
479
605
|
|
480
606
|
def self.offset_any_pattern_re
|
481
607
|
/((([0-9]*)\.([0-9]+)|([0-9]+))([%pP])?)\.\.((([0-9]*)\.([0-9]+)|([0-9]+))([%pP])?)/
|
482
608
|
end
|
609
|
+
private_class_method :offset_any_pattern_re
|
483
610
|
|
484
611
|
# Split a range into the start and end values
|
485
612
|
def self.split_range(range) # :nodoc:
|
@@ -494,10 +621,12 @@ class Cloudinary::Utils
|
|
494
621
|
nil
|
495
622
|
end
|
496
623
|
end
|
624
|
+
private_class_method :split_range
|
497
625
|
|
498
626
|
# Normalize an offset value
|
499
627
|
# @param [String] value a decimal value which may have a 'p' or '%' postfix. E.g. '35%', '0.4p'
|
500
628
|
# @return [Object|String] a normalized String of the input value if possible otherwise the value itself
|
629
|
+
# @private
|
501
630
|
def self.norm_range_value(value) # :nodoc:
|
502
631
|
offset = /^#{offset_any_pattern}$/.match( value.to_s)
|
503
632
|
if offset
|
@@ -506,6 +635,7 @@ class Cloudinary::Utils
|
|
506
635
|
end
|
507
636
|
value
|
508
637
|
end
|
638
|
+
private_class_method :norm_range_value
|
509
639
|
|
510
640
|
# A video codec parameter can be either a String or a Hash.
|
511
641
|
#
|
@@ -514,6 +644,7 @@ class Cloudinary::Utils
|
|
514
644
|
# @return [String] <code><codec> : <profile> : [<level>]]</code> if a Hash was provided
|
515
645
|
# or the param if a String was provided.
|
516
646
|
# Returns NIL if param is not a Hash or String
|
647
|
+
# @private
|
517
648
|
def self.process_video_params(param)
|
518
649
|
case param
|
519
650
|
when Hash
|
@@ -534,21 +665,6 @@ class Cloudinary::Utils
|
|
534
665
|
nil
|
535
666
|
end
|
536
667
|
end
|
537
|
-
|
538
|
-
def self.deep_symbolize_keys(object)
|
539
|
-
case object
|
540
|
-
when Hash
|
541
|
-
result = {}
|
542
|
-
object.each do |key, value|
|
543
|
-
key = key.to_sym rescue key
|
544
|
-
result[key] = deep_symbolize_keys(value)
|
545
|
-
end
|
546
|
-
result
|
547
|
-
when Array
|
548
|
-
object.map{|e| deep_symbolize_keys(e)}
|
549
|
-
else
|
550
|
-
object
|
551
|
-
end
|
552
|
-
end
|
668
|
+
private_class_method :process_video_params
|
553
669
|
|
554
670
|
end
|