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 CHANGED
@@ -1,4 +1,4 @@
1
1
  pkg
2
2
  .project
3
3
  .rvmrc
4
-
4
+ assets/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Rakefile CHANGED
@@ -1,3 +1,8 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
3
 
4
+ task :fetch_assets do
5
+ system "/bin/rm -rf assets; mkdir -p assets; cd assets; curl -L https://github.com/cloudinary/cloudinary_js/tarball/master | tar zxvf - --strip=1"
6
+ end
7
+
8
+ task :build=>:fetch_assets
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(args.first)
166
+ if args.first && !args.first.is_a?(Hash)
133
167
  super
134
168
  else
135
- return nil if blank?
136
- options = self.class.version_names.blank? ? {} : self.transformation
137
- Cloudinary::Utils.cloudinary_url(self.my_filename, options.clone)
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 ||= model.read_uploader(mounted_as)
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 || ("#{self.public_id}.#{self.format}")
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 blank?
169
- self.filename.blank? && self.stored_filename.blank?
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
- # Do nothing
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
- (uploader.filename || uploader.stored_filename) ? uploader.my_filename : nil
312
+ uploader.my_identifier
238
313
  end
239
314
  end
240
315
  end
@@ -81,12 +81,9 @@ module CloudinaryHelper
81
81
  form_options[:method] = :post
82
82
  form_options[:multipart] = true
83
83
 
84
- options[:timestamp] = Time.now.to_i
85
- options[:callback] = callback_url
86
- options[:transformation] = Cloudinary::Utils.generate_transformation_string(options[:transformation]) if options[:transformation]
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
- options.each do |name, value|
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
@@ -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| Rails.root.join(dir)}.select(&:exist?)
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(Rails.root)
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
- Rails.root.join(METADATA_FILE)
41
+ self.root.join(METADATA_FILE)
38
42
  end
39
43
 
40
44
  def self.metadata_trash_file_path
41
- Rails.root.join(METADATA_TRASH_FILE)
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 = Rails.root.join(path).read(:mode=>"rb")
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)
@@ -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 = {:timestamp=>Time.now.to_i,
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
@@ -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
@@ -1,4 +1,4 @@
1
1
  # Copyright Cloudinary
2
2
  module Cloudinary
3
- VERSION = "1.0.9"
3
+ VERSION = "1.0.10"
4
4
  end
@@ -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
@@ -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.9
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-16 00:00:00 +03:00
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