cloudinary 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|