cloudinary 1.0.9 → 1.0.10
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.
- data/.gitignore +1 -1
- data/.rspec +2 -0
- data/Rakefile +5 -0
- data/cloudinary.gemspec +2 -1
- data/lib/cloudinary.rb +1 -1
- data/lib/cloudinary/carrier_wave.rb +102 -27
- data/lib/cloudinary/helper.rb +61 -7
- data/lib/cloudinary/static.rb +9 -5
- data/lib/cloudinary/uploader.rb +20 -15
- data/lib/cloudinary/utils.rb +3 -3
- data/lib/cloudinary/version.rb +1 -1
- data/spec/spec_helper.rb +11 -0
- data/spec/utils_spec.rb +169 -0
- metadata +24 -4
data/.gitignore
CHANGED
data/.rspec
ADDED
data/Rakefile
CHANGED
data/cloudinary.gemspec
CHANGED
@@ -13,10 +13,11 @@ Gem::Specification.new do |s|
|
|
13
13
|
|
14
14
|
s.rubyforge_project = "cloudinary"
|
15
15
|
|
16
|
-
s.files = `git ls-files`.split("\n")
|
16
|
+
s.files = `git ls-files`.split("\n") + Dir.glob("assets/*/*")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.add_dependency "rest-client"
|
22
|
+
s.add_development_dependency "rspec"
|
22
23
|
end
|
data/lib/cloudinary.rb
CHANGED
@@ -5,7 +5,7 @@ require "cloudinary/utils"
|
|
5
5
|
require "cloudinary/uploader"
|
6
6
|
require "cloudinary/downloader"
|
7
7
|
require "cloudinary/blob"
|
8
|
-
require "cloudinary/static"
|
8
|
+
require "cloudinary/static" if defined?(::ActiveSupport)
|
9
9
|
require 'active_support'
|
10
10
|
require "cloudinary/missing"
|
11
11
|
require "cloudinary/carrier_wave" if defined?(::CarrierWave)
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# Copyright Cloudinary
|
2
2
|
require 'pp'
|
3
3
|
module Cloudinary::CarrierWave
|
4
|
+
CLOUDINARY_PATH = /^([^\/]+)\/upload\/v(\d+)\/([^\/]+)#([^\/]+)$/
|
5
|
+
|
4
6
|
class UploadError < StandardError
|
5
7
|
attr_reader :http_code
|
6
8
|
def initialize(message, http_code)
|
@@ -55,8 +57,40 @@ module Cloudinary::CarrierWave
|
|
55
57
|
base.storage Cloudinary::CarrierWave::Storage
|
56
58
|
base.extend ClassMethods
|
57
59
|
base.send(:attr_accessor, :metadata)
|
60
|
+
base.send(:alias_method, :original_cache!, :cache!)
|
61
|
+
base.send(:alias_method, :original_cache_name, :cache_name)
|
62
|
+
base.send(:alias_method, :original_retrieve_from_cache!, :retrieve_from_cache!)
|
63
|
+
base.send(:include, Override)
|
58
64
|
end
|
59
65
|
|
66
|
+
module Override
|
67
|
+
def cache!(new_file)
|
68
|
+
if new_file.is_a?(String) && new_file.match(CLOUDINARY_PATH)
|
69
|
+
@file = CloudinaryFile.new(new_file)
|
70
|
+
self.original_filename = @cache_id = @my_filename = @filename = @file.original_filename
|
71
|
+
else
|
72
|
+
original_cache!(new_file)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def retrieve_from_cache!(new_file)
|
77
|
+
if new_file.is_a?(String) && new_file.match(CLOUDINARY_PATH)
|
78
|
+
@file = CloudinaryFile.new(new_file)
|
79
|
+
self.original_filename = @cache_id = @my_filename = @filename = @file.original_filename
|
80
|
+
else
|
81
|
+
original_retrieve_from_cache!(new_file)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def cache_name
|
86
|
+
if @file.is_a?(CloudinaryFile)
|
87
|
+
return @file.to_s
|
88
|
+
else
|
89
|
+
return original_cache_name
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
60
94
|
def set_or_yell(hash, attr, value)
|
61
95
|
raise "conflicting transformation on #{attr} #{value}!=#{hash[attr]}" if hash[attr]
|
62
96
|
hash[attr] = value
|
@@ -129,12 +163,13 @@ module Cloudinary::CarrierWave
|
|
129
163
|
end
|
130
164
|
|
131
165
|
def url(*args)
|
132
|
-
if
|
166
|
+
if args.first && !args.first.is_a?(Hash)
|
133
167
|
super
|
134
168
|
else
|
135
|
-
return nil if blank?
|
136
|
-
options =
|
137
|
-
|
169
|
+
return nil if self.my_identifier.blank?
|
170
|
+
options = args.extract_options!
|
171
|
+
options = options.merge(self.class.version_names.blank? ? {} : self.transformation)
|
172
|
+
Cloudinary::Utils.cloudinary_url(self.my_filename, options)
|
138
173
|
end
|
139
174
|
end
|
140
175
|
|
@@ -143,16 +178,17 @@ module Cloudinary::CarrierWave
|
|
143
178
|
end
|
144
179
|
|
145
180
|
def stored_filename
|
146
|
-
@stored_filename
|
181
|
+
@stored_filename = model.read_uploader(mounted_as) if @stored_filename.blank?
|
182
|
+
@stored_filename
|
147
183
|
end
|
148
184
|
|
149
185
|
def my_filename
|
150
|
-
@my_filename ||= stored_filename
|
186
|
+
@my_filename ||= stored_filename.present? ? stored_filename : ("#{self.public_id}.#{self.format}")
|
151
187
|
end
|
152
188
|
|
153
189
|
def public_id
|
154
190
|
return @public_id if @public_id
|
155
|
-
if stored_filename
|
191
|
+
if stored_filename.present?
|
156
192
|
last_dot = stored_filename.rindex(".")
|
157
193
|
@public_id = last_dot ? stored_filename[0, last_dot] : stored_filename
|
158
194
|
end
|
@@ -165,8 +201,18 @@ module Cloudinary::CarrierWave
|
|
165
201
|
@file = RemoteFile.new(uri, @filename)
|
166
202
|
end
|
167
203
|
|
168
|
-
def
|
169
|
-
self.filename
|
204
|
+
def my_identifier
|
205
|
+
(self.filename || self.stored_filename.present?) ? self.my_filename : nil
|
206
|
+
end
|
207
|
+
|
208
|
+
class RemoveableFile
|
209
|
+
def initialize(identifier)
|
210
|
+
@public_id = identifier.split("/").last.split(".").first
|
211
|
+
end
|
212
|
+
|
213
|
+
def delete
|
214
|
+
Cloudinary::Uploader.destroy(@public_id)
|
215
|
+
end
|
170
216
|
end
|
171
217
|
|
172
218
|
class RemoteFile
|
@@ -181,10 +227,33 @@ module Cloudinary::CarrierWave
|
|
181
227
|
end
|
182
228
|
end
|
183
229
|
|
230
|
+
class CloudinaryFile
|
231
|
+
attr_reader :original_filename, :version
|
232
|
+
def initialize(file_info)
|
233
|
+
resource_type, @version, @original_filename, @signature = file_info.scan(CLOUDINARY_PATH).first
|
234
|
+
raise "Cloudinary CarrierWave integration supports images only" if resource_type != "image"
|
235
|
+
public_id = @original_filename[0..(@original_filename.rindex(".")-1)]
|
236
|
+
expected_signature = Cloudinary::Utils.api_sign_request({:public_id=>public_id, :version=>version}, Cloudinary.config.api_secret)
|
237
|
+
if @signature != expected_signature
|
238
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.cloudinary_signature_error", :public_id=>public_id, :default=>"Invalid signature for #{public_id}")
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def to_s
|
243
|
+
"image/upload/v#{@version}/#{@original_filename}##{@signature}"
|
244
|
+
end
|
245
|
+
|
246
|
+
def delete
|
247
|
+
# Do nothing. This is a virtual file.
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
184
251
|
class Storage < ::CarrierWave::Storage::Abstract
|
185
252
|
def store!(file)
|
186
253
|
# Moved to identifier...
|
187
254
|
if uploader.class.version_names.blank?
|
255
|
+
return store_cloudinary_version(file.version) if file.is_a?(CloudinaryFile)
|
256
|
+
|
188
257
|
# This is the toplevel, need to upload the actual file.
|
189
258
|
params = uploader.transformation.dup
|
190
259
|
params[:return_error] = true
|
@@ -206,35 +275,41 @@ module Cloudinary::CarrierWave
|
|
206
275
|
raise UploadError.new(uploader.metadata["error"]["message"], uploader.metadata["error"]["http_code"])
|
207
276
|
end
|
208
277
|
|
209
|
-
if uploader.metadata["version"]
|
210
|
-
|
211
|
-
name = "v#{uploader.metadata["version"]}/#{identifier.split("/").last}"
|
212
|
-
model_class = uploader.model.class
|
213
|
-
if defined?(ActiveRecord::Base) && uploader.model.is_a?(ActiveRecord::Base)
|
214
|
-
primary_key = model_class.primary_key.to_sym
|
215
|
-
model_class.update_all({uploader.mounted_as=>name}, {primary_key=>uploader.model.send(primary_key)})
|
216
|
-
uploader.model.send :write_attribute, uploader.mounted_as, name
|
217
|
-
elsif model_class.respond_to?(:update_all) && uploader.model.respond_to?(:_id)
|
218
|
-
# Mongoid support
|
219
|
-
model_class.where(:_id=>uploader.model._id).update_all(uploader.mounted_as=>name)
|
220
|
-
uploader.model.send :write_attribute, uploader.mounted_as, name
|
221
|
-
else
|
222
|
-
raise "Only ActiveRecord and Mongoid are supported at the moment!"
|
223
|
-
end
|
224
|
-
end
|
278
|
+
store_cloudinary_version(uploader.metadata["version"]) if uploader.metadata["version"]
|
225
279
|
# Will throw an exception on error
|
226
280
|
else
|
227
281
|
raise "nested versions are not allowed." if (uploader.class.version_names.length > 1)
|
228
282
|
# Do nothing
|
229
283
|
end
|
284
|
+
nil
|
285
|
+
end
|
286
|
+
|
287
|
+
def store_cloudinary_version(version)
|
288
|
+
name = "v#{version}/#{identifier.split("/").last}"
|
289
|
+
model_class = uploader.model.class
|
290
|
+
if defined?(ActiveRecord::Base) && uploader.model.is_a?(ActiveRecord::Base)
|
291
|
+
primary_key = model_class.primary_key.to_sym
|
292
|
+
model_class.update_all({uploader.mounted_as=>name}, {primary_key=>uploader.model.send(primary_key)})
|
293
|
+
uploader.model.send :write_attribute, uploader.mounted_as, name
|
294
|
+
elsif model_class.respond_to?(:update_all) && uploader.model.respond_to?(:_id)
|
295
|
+
# Mongoid support
|
296
|
+
model_class.where(:_id=>uploader.model._id).update_all(uploader.mounted_as=>name)
|
297
|
+
uploader.model.send :write_attribute, uploader.mounted_as, name
|
298
|
+
else
|
299
|
+
raise "Only ActiveRecord and Mongoid are supported at the moment!"
|
300
|
+
end
|
230
301
|
end
|
231
302
|
|
232
303
|
def retrieve!(identifier)
|
233
|
-
|
304
|
+
if uploader.class.version_names.blank?
|
305
|
+
return RemoveableFile.new(identifier)
|
306
|
+
else
|
307
|
+
return nil # Version files should not be deleted.
|
308
|
+
end
|
234
309
|
end
|
235
310
|
|
236
311
|
def identifier
|
237
|
-
|
312
|
+
uploader.my_identifier
|
238
313
|
end
|
239
314
|
end
|
240
315
|
end
|
data/lib/cloudinary/helper.rb
CHANGED
@@ -81,12 +81,9 @@ module CloudinaryHelper
|
|
81
81
|
form_options[:method] = :post
|
82
82
|
form_options[:multipart] = true
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
options[:tags] = Cloudinary::Utils.build_array(options[:tags]).join(",") if options[:tags]
|
88
|
-
options[:signature] = Cloudinary::Utils.api_sign_request(options, Cloudinary.config.api_secret)
|
89
|
-
options[:api_key] = Cloudinary.config.api_key
|
84
|
+
params = Cloudinary::Uploader.build_upload_params(options.merge(:callback=>callback_url))
|
85
|
+
params[:signature] = Cloudinary::Utils.api_sign_request(params, Cloudinary.config.api_secret)
|
86
|
+
params[:api_key] = Cloudinary.config.api_key
|
90
87
|
|
91
88
|
api_url = Cloudinary::Utils.cloudinary_api_url("upload",
|
92
89
|
{:resource_type => options.delete(:resource_type), :upload_prefix => options.delete(:upload_prefix)})
|
@@ -94,7 +91,7 @@ module CloudinaryHelper
|
|
94
91
|
form_tag(api_url, form_options) do
|
95
92
|
content = []
|
96
93
|
|
97
|
-
|
94
|
+
params.each do |name, value|
|
98
95
|
content << hidden_field_tag(name, value)
|
99
96
|
end
|
100
97
|
|
@@ -104,10 +101,67 @@ module CloudinaryHelper
|
|
104
101
|
end
|
105
102
|
end
|
106
103
|
|
104
|
+
CLOUDINARY_JS_CONFIG_PARAMS = [:api_key, :cloud_name, :private_cdn, :secure_distribution, :cdn_subdomain]
|
105
|
+
def cloudinary_js_config
|
106
|
+
params = {}
|
107
|
+
CLOUDINARY_JS_CONFIG_PARAMS.each{|param| params[param] = Cloudinary.config.send(param)}
|
108
|
+
content_tag("script", "$.cloudinary.config(#{params.to_json});".html_safe, :type=>"text/javascript")
|
109
|
+
end
|
110
|
+
|
107
111
|
def cloudinary_url(source, options = {})
|
108
112
|
options[:secure] = request.ssl? if !options.include?(:secure) && defined?(request) && request && request.respond_to?(:ssl?)
|
109
113
|
Cloudinary::Utils.cloudinary_url(source, options)
|
110
114
|
end
|
115
|
+
|
116
|
+
def cl_image_upload(object_name, method, options={})
|
117
|
+
cl_image_upload_tag("#{object_name}[#{method}]", options)
|
118
|
+
end
|
119
|
+
|
120
|
+
def cl_image_upload_tag(field, options={})
|
121
|
+
html_options = options.delete(:html) || {}
|
122
|
+
cloudinary_upload_url = Cloudinary::Utils.cloudinary_api_url("upload", {:resource_type=>:auto}.merge(options))
|
123
|
+
|
124
|
+
api_key = options[:api_key] || Cloudinary.config.api_key || raise("Must supply api_key")
|
125
|
+
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise("Must supply api_secret")
|
126
|
+
|
127
|
+
cloudinary_params = Cloudinary::Uploader.build_upload_params(options)
|
128
|
+
cloudinary_params[:callback] = build_callback_url(options)
|
129
|
+
cloudinary_params[:signature] = Cloudinary::Utils.api_sign_request(cloudinary_params, api_secret)
|
130
|
+
cloudinary_params[:api_key] = api_key
|
131
|
+
|
132
|
+
tag_options = html_options.merge(:type=>"file", :name=>"file",
|
133
|
+
:"data-url"=>cloudinary_upload_url,
|
134
|
+
:"data-form-data"=>cloudinary_params.reject{|k, v| v.blank?}.to_json,
|
135
|
+
:"data-cloudinary-field"=>field,
|
136
|
+
:"class" => [html_options[:class], "cloudinary-fileupload"].flatten.compact
|
137
|
+
).reject{|k,v| v.blank?}
|
138
|
+
content_tag("input", nil, tag_options)
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.included(base)
|
142
|
+
ActionView::Helpers::FormBuilder.send(:include, Cloudinary::FormBuilder)
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
def build_callback_url(options)
|
147
|
+
callback_path = options.delete(:callback_cors) || Cloudinary.config.callback_cors || "/cloudinary_cors.html"
|
148
|
+
if !callback_path.match(/^https?:\/\//)
|
149
|
+
callback_url = request.scheme + "://"
|
150
|
+
callback_url << request.host
|
151
|
+
if request.scheme == "https" && request.port != 443 ||
|
152
|
+
request.scheme == "http" && request.port != 80
|
153
|
+
callback_url << ":#{request.port}"
|
154
|
+
end
|
155
|
+
callback_url << callback_path
|
156
|
+
end
|
157
|
+
callback_url
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
module Cloudinary::FormBuilder
|
162
|
+
def cl_image_upload(method, options={})
|
163
|
+
@template.cl_image_upload(@object_name, method, objectify_options(options))
|
164
|
+
end
|
111
165
|
end
|
112
166
|
|
113
167
|
ActionView::Base.send :include, CloudinaryHelper
|
data/lib/cloudinary/static.rb
CHANGED
@@ -9,7 +9,7 @@ class Cloudinary::Static
|
|
9
9
|
def self.discover
|
10
10
|
ignore_files = Cloudinary.config.ignore_files || IGNORE_FILES
|
11
11
|
relative_dirs = Cloudinary.config.statis_image_dirs || STATIC_IMAGE_DIRS
|
12
|
-
dirs = relative_dirs.map{|dir|
|
12
|
+
dirs = relative_dirs.map{|dir| self.root.join(dir)}.select(&:exist?)
|
13
13
|
dirs.each do
|
14
14
|
|dir|
|
15
15
|
dir.find do
|
@@ -23,7 +23,7 @@ class Cloudinary::Static
|
|
23
23
|
elsif SUPPORTED_IMAGES.none?{|pattern| pattern.is_a?(String) ? pattern == file : file.match(pattern)}
|
24
24
|
next
|
25
25
|
else
|
26
|
-
relative_path = path.relative_path_from(
|
26
|
+
relative_path = path.relative_path_from(self.root)
|
27
27
|
public_path = path.relative_path_from(dir.dirname)
|
28
28
|
yield(relative_path, public_path)
|
29
29
|
end
|
@@ -33,12 +33,16 @@ class Cloudinary::Static
|
|
33
33
|
|
34
34
|
UTC = ActiveSupport::TimeZone["UTC"]
|
35
35
|
|
36
|
+
def self.root
|
37
|
+
defined?(Rails) ? Rails.root : Pathname.new(".")
|
38
|
+
end
|
39
|
+
|
36
40
|
def self.metadata_file_path
|
37
|
-
|
41
|
+
self.root.join(METADATA_FILE)
|
38
42
|
end
|
39
43
|
|
40
44
|
def self.metadata_trash_file_path
|
41
|
-
|
45
|
+
self.root.join(METADATA_TRASH_FILE)
|
42
46
|
end
|
43
47
|
|
44
48
|
def self.metadata(metadata_file = metadata_file_path, hash=true)
|
@@ -73,7 +77,7 @@ class Cloudinary::Static
|
|
73
77
|
|path, public_path|
|
74
78
|
next if found_paths.include?(path)
|
75
79
|
found_paths << path
|
76
|
-
data =
|
80
|
+
data = self.root.join(path).read(:mode=>"rb")
|
77
81
|
ext = path.extname
|
78
82
|
format = ext[1..-1]
|
79
83
|
md5 = Digest::MD5.hexdigest(data)
|
data/lib/cloudinary/uploader.rb
CHANGED
@@ -4,23 +4,28 @@ require 'json'
|
|
4
4
|
|
5
5
|
class Cloudinary::Uploader
|
6
6
|
|
7
|
+
def self.build_upload_params(options)
|
8
|
+
params = {:timestamp=>Time.now.to_i,
|
9
|
+
:transformation => Cloudinary::Utils.generate_transformation_string(options),
|
10
|
+
:public_id=> options[:public_id],
|
11
|
+
:callback=> options[:callback],
|
12
|
+
:format=>options[:format],
|
13
|
+
:type=>options[:type],
|
14
|
+
:tags=>options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(",")}
|
15
|
+
if options[:eager]
|
16
|
+
params[:eager] = options[:eager].map do
|
17
|
+
|transformation, format|
|
18
|
+
transformation = transformation.clone
|
19
|
+
format = transformation.delete(:format) || format
|
20
|
+
[Cloudinary::Utils.generate_transformation_string(transformation), format].compact.join("/")
|
21
|
+
end.join("|")
|
22
|
+
end
|
23
|
+
params
|
24
|
+
end
|
25
|
+
|
7
26
|
def self.upload(file, options={})
|
8
27
|
call_api("upload", options) do
|
9
|
-
params =
|
10
|
-
:transformation => Cloudinary::Utils.generate_transformation_string(options),
|
11
|
-
:public_id=> options[:public_id],
|
12
|
-
:callback=> options[:callback],
|
13
|
-
:format=>options[:format],
|
14
|
-
:type=>options[:type],
|
15
|
-
:tags=>options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(",")}
|
16
|
-
if options[:eager]
|
17
|
-
params[:eager] = options[:eager].map do
|
18
|
-
|transformation, format|
|
19
|
-
transformation = transformation.clone
|
20
|
-
format = transformation.delete(:format) || format
|
21
|
-
[Cloudinary::Utils.generate_transformation_string(transformation), format].compact.join("/")
|
22
|
-
end.join("|")
|
23
|
-
end
|
28
|
+
params = build_upload_params(options)
|
24
29
|
if file.respond_to?(:read) || file =~ /^https?:/
|
25
30
|
params[:file] = file
|
26
31
|
else
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -7,10 +7,10 @@ class Cloudinary::Utils
|
|
7
7
|
|
8
8
|
# Warning: options are being destructively updated!
|
9
9
|
def self.generate_transformation_string(options={})
|
10
|
+
size = options.delete(:size)
|
11
|
+
options[:width], options[:height] = size.split("x") if size
|
10
12
|
width = options[:width]
|
11
13
|
height = options[:height]
|
12
|
-
size = options.delete(:size)
|
13
|
-
width, height = size.split("x") if size
|
14
14
|
options.delete(:width) if width && width.to_f < 1
|
15
15
|
options.delete(:height) if height && height.to_f < 1
|
16
16
|
|
@@ -71,7 +71,7 @@ class Cloudinary::Utils
|
|
71
71
|
return source
|
72
72
|
end
|
73
73
|
end
|
74
|
-
@metadata ||= Cloudinary::Static.metadata
|
74
|
+
@metadata ||= defined?(Cloudinary::Static) ? Cloudinary::Static.metadata : {}
|
75
75
|
if @metadata["images/#{source}"]
|
76
76
|
return source if !Cloudinary.config.static_image_support
|
77
77
|
type = :asset
|
data/lib/cloudinary/version.rb
CHANGED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
end
|
data/spec/utils_spec.rb
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cloudinary'
|
3
|
+
|
4
|
+
describe Cloudinary::Utils do
|
5
|
+
before(:each) do
|
6
|
+
Cloudinary.config do
|
7
|
+
|config|
|
8
|
+
config.cloud_name = "test123"
|
9
|
+
config.secure_distribution = nil
|
10
|
+
config.private_cdn = false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should use cloud_name from config" do
|
15
|
+
result = Cloudinary::Utils.cloudinary_url("test")
|
16
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/test"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should allow overriding cloud_name in options" do
|
20
|
+
options = {:cloud_name=>"test321"}
|
21
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
22
|
+
options.should == {}
|
23
|
+
result.should == "http://res.cloudinary.com/test321/image/upload/test"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should use default secure distribution if secure=true" do
|
27
|
+
options = {:secure=>true}
|
28
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
29
|
+
options.should == {}
|
30
|
+
result.should == "https://d3jpl91pxevbkh.cloudfront.net/test123/image/upload/test"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should allow overriding secure distribution if secure=true" do
|
34
|
+
options = {:secure=>true, :secure_distribution=>"something.else.com"}
|
35
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
36
|
+
options.should == {}
|
37
|
+
result.should == "https://something.else.com/test123/image/upload/test"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should take secure distribution from config if secure=true" do
|
41
|
+
Cloudinary.config.secure_distribution = "config.secure.distribution.com"
|
42
|
+
options = {:secure=>true}
|
43
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
44
|
+
options.should == {}
|
45
|
+
result.should == "https://config.secure.distribution.com/test123/image/upload/test"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should raise exception if secure is given with private_cdn and no secure_distribution" do
|
49
|
+
Cloudinary.config.private_cdn = true
|
50
|
+
lambda {Cloudinary::Utils.cloudinary_url("test", :secure=>true)}.should raise_error
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should use format from options" do
|
54
|
+
options = {:format=>:jpg}
|
55
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
56
|
+
options.should == {}
|
57
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/test.jpg"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should use width and height from options only if crop is given" do
|
61
|
+
options = {:width=>100, :height=>100}
|
62
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
63
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/test"
|
64
|
+
options.should == {:width=>100, :height=>100}
|
65
|
+
options = {:width=>100, :height=>100, :crop=>:crop}
|
66
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
67
|
+
options.should == {:width=>100, :height=>100}
|
68
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/c_crop,h_100,w_100/test"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should use x, y, radius, prefix, gravity and quality from options" do
|
72
|
+
options = {:x=>1, :y=>2, :radius=>3, :gravity=>:center, :quality=>0.4, :prefix=>"a"}
|
73
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
74
|
+
options.should == {}
|
75
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/g_center,p_a,q_0.4,r_3,x_1,y_2/test"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should support named tranformation" do
|
79
|
+
options = {:transformation=>"blip"}
|
80
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
81
|
+
options.should == {}
|
82
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/t_blip/test"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should support array of named tranformations" do
|
86
|
+
options = {:transformation=>["blip", "blop"]}
|
87
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
88
|
+
options.should == {}
|
89
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/t_blip.blop/test"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should support base tranformation" do
|
93
|
+
options = {:transformation=>{:x=>100, :y=>100, :crop=>:fill}, :crop=>:crop, :width=>100}
|
94
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
95
|
+
options.should == {:width=>100}
|
96
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/c_fill,x_100,y_100/c_crop,w_100/test"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should support array of base tranformations" do
|
100
|
+
options = {:transformation=>[{:x=>100, :y=>100, :width=>200, :crop=>:fill}, {:radius=>10}], :crop=>:crop, :width=>100}
|
101
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
102
|
+
options.should == {:width=>100}
|
103
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/c_fill,w_200,x_100,y_100/r_10/c_crop,w_100/test"
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should not include empty tranformations" do
|
107
|
+
options = {:transformation=>[{}, {:x=>100, :y=>100, :crop=>:fill}, {}]}
|
108
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
109
|
+
options.should == {}
|
110
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/c_fill,x_100,y_100/test"
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should support size" do
|
114
|
+
options = {:size=>"10x10", :crop=>:crop}
|
115
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
116
|
+
options.should == {:width=>"10", :height=>"10"}
|
117
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/c_crop,h_10,w_10/test"
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should use type from options" do
|
121
|
+
options = {:type=>:facebook}
|
122
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
123
|
+
options.should == {}
|
124
|
+
result.should == "http://res.cloudinary.com/test123/image/facebook/test"
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should use resource_type from options" do
|
128
|
+
options = {:resource_type=>:raw}
|
129
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
130
|
+
options.should == {}
|
131
|
+
result.should == "http://res.cloudinary.com/test123/raw/upload/test"
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should ignore http links only if type is not given or is asset" do
|
135
|
+
options = {:type=>nil}
|
136
|
+
result = Cloudinary::Utils.cloudinary_url("http://test", options)
|
137
|
+
options.should == {}
|
138
|
+
result.should == "http://test"
|
139
|
+
options = {:type=>:asset}
|
140
|
+
result = Cloudinary::Utils.cloudinary_url("http://test", options)
|
141
|
+
options.should == {}
|
142
|
+
result.should == "http://test"
|
143
|
+
options = {:type=>:fetch}
|
144
|
+
result = Cloudinary::Utils.cloudinary_url("http://test", options)
|
145
|
+
options.should == {}
|
146
|
+
result.should == "http://res.cloudinary.com/test123/image/fetch/http://test"
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should use allow absolute links to /images" do
|
150
|
+
options = {}
|
151
|
+
result = Cloudinary::Utils.cloudinary_url("/images/test", options)
|
152
|
+
options.should == {}
|
153
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/test"
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should use ignore absolute links not to /images" do
|
157
|
+
options = {}
|
158
|
+
result = Cloudinary::Utils.cloudinary_url("/js/test", options)
|
159
|
+
options.should == {}
|
160
|
+
result.should == "/js/test"
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should escape fetch urls" do
|
164
|
+
options = {:type=>:fetch}
|
165
|
+
result = Cloudinary::Utils.cloudinary_url("http://blah.com/hello?a=b", options)
|
166
|
+
options.should == {}
|
167
|
+
result.should == "http://res.cloudinary.com/test123/image/fetch/http://blah.com/hello%3Fa%3Db"
|
168
|
+
end
|
169
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.0.
|
5
|
+
version: 1.0.10
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Nadav Soferman
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2012-04-
|
15
|
+
date: 2012-04-18 00:00:00 +03:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -26,6 +26,17 @@ dependencies:
|
|
26
26
|
version: "0"
|
27
27
|
type: :runtime
|
28
28
|
version_requirements: *id001
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: rspec
|
31
|
+
prerelease: false
|
32
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: "0"
|
38
|
+
type: :development
|
39
|
+
version_requirements: *id002
|
29
40
|
description: Client library for easily using the Cloudinary service
|
30
41
|
email:
|
31
42
|
- nadav.soferman@cloudinary.com
|
@@ -39,6 +50,7 @@ extra_rdoc_files: []
|
|
39
50
|
|
40
51
|
files:
|
41
52
|
- .gitignore
|
53
|
+
- .rspec
|
42
54
|
- Gemfile
|
43
55
|
- README.md
|
44
56
|
- Rakefile
|
@@ -57,6 +69,13 @@ files:
|
|
57
69
|
- lib/cloudinary/utils.rb
|
58
70
|
- lib/cloudinary/version.rb
|
59
71
|
- lib/tasks/cloudinary.rake
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
- spec/utils_spec.rb
|
74
|
+
- assets/html/cloudinary_cors.html
|
75
|
+
- assets/js/jquery.cloudinary.js
|
76
|
+
- assets/js/jquery.fileupload.js
|
77
|
+
- assets/js/jquery.iframe-transport.js
|
78
|
+
- assets/js/jquery.ui.widget.js
|
60
79
|
has_rdoc: true
|
61
80
|
homepage: http://cloudinary.com
|
62
81
|
licenses: []
|
@@ -85,5 +104,6 @@ rubygems_version: 1.6.2
|
|
85
104
|
signing_key:
|
86
105
|
specification_version: 3
|
87
106
|
summary: Client library for easily using the Cloudinary service
|
88
|
-
test_files:
|
89
|
-
|
107
|
+
test_files:
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
- spec/utils_spec.rb
|