cloudinary 1.0.32 → 1.0.33
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/cloudinary.gemspec +1 -0
- data/lib/cloudinary.rb +6 -0
- data/lib/cloudinary/api.rb +140 -0
- data/lib/cloudinary/helper.rb +4 -0
- data/lib/cloudinary/utils.rb +25 -4
- data/lib/cloudinary/version.rb +1 -1
- data/spec/api_spec.rb +139 -0
- data/spec/logo.png +0 -0
- data/spec/utils_spec.rb +19 -0
- metadata +23 -2
data/cloudinary.gemspec
CHANGED
data/lib/cloudinary.rb
CHANGED
@@ -6,6 +6,7 @@ require "uri"
|
|
6
6
|
require "cloudinary/version"
|
7
7
|
require "cloudinary/utils"
|
8
8
|
require "cloudinary/uploader"
|
9
|
+
require "cloudinary/api"
|
9
10
|
require "cloudinary/downloader"
|
10
11
|
require "cloudinary/blob"
|
11
12
|
require "cloudinary/static"
|
@@ -41,6 +42,11 @@ module Cloudinary
|
|
41
42
|
"private_cdn" => !uri.path.blank?,
|
42
43
|
"secure_distribution" => uri.path[1..-1]
|
43
44
|
)
|
45
|
+
uri.query.to_s.split("&").each do
|
46
|
+
|param|
|
47
|
+
key, value = param.split("=")
|
48
|
+
set_config(key=>URI.decode(value))
|
49
|
+
end
|
44
50
|
end
|
45
51
|
|
46
52
|
set_config(new_config) if new_config
|
@@ -0,0 +1,140 @@
|
|
1
|
+
class Cloudinary::Api
|
2
|
+
class Error < StandardError; end
|
3
|
+
class NotFound < Error; end
|
4
|
+
class NotAllowed < Error; end
|
5
|
+
class AlreadyExists < Error; end
|
6
|
+
class RateLimited < Error; end
|
7
|
+
class BadRequest < Error; end
|
8
|
+
class GeneralError < Error; end
|
9
|
+
class AuthorizationRequired < Error; end
|
10
|
+
class Response < Hash
|
11
|
+
attr_reader :rate_limit_reset_at, :rate_limit_remaining, :rate_limit_allowed
|
12
|
+
def initialize(response)
|
13
|
+
self.update(Cloudinary::Api.send(:parse_json_response, response))
|
14
|
+
@rate_limit_allowed = response.headers[:x_featureratelimit_limit].to_i
|
15
|
+
@rate_limit_reset_at = Time.parse(response.headers[:x_featureratelimit_reset])
|
16
|
+
@rate_limit_remaining = response.headers[:x_featureratelimit_remaining].to_i
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def self.resource_types(options={})
|
22
|
+
call_api(:get, "resources", {}, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.resources(options={})
|
26
|
+
resource_type = options[:resource_type] || "image"
|
27
|
+
type = options[:type]
|
28
|
+
uri = "resources/#{resource_type}"
|
29
|
+
uri += "/#{type}" if !type.blank?
|
30
|
+
call_api(:get, uri, only(options, :next_cursor, :max_results, :prefix), options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.resources_by_tag(tag, options={})
|
34
|
+
resource_type = options[:resource_type] || "image"
|
35
|
+
uri = "resources/#{resource_type}/tags/#{tag}"
|
36
|
+
call_api(:get, uri, only(options, :next_cursor, :max_results), options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.resource(public_id, options={})
|
40
|
+
resource_type = options[:resource_type] || "image"
|
41
|
+
type = options[:type] || "upload"
|
42
|
+
uri = "resources/#{resource_type}/#{type}/#{public_id}"
|
43
|
+
call_api(:get, uri, {}, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.delete_resources(public_ids, options={})
|
47
|
+
resource_type = options[:resource_type] || "image"
|
48
|
+
type = options[:type] || "upload"
|
49
|
+
uri = "resources/#{resource_type}/#{type}"
|
50
|
+
call_api(:delete, uri, {:public_ids=>public_ids}, options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.delete_resources_by_prefix(type, prefix, options={})
|
54
|
+
resource_type = options[:resource_type] || "image"
|
55
|
+
uri = "resources/#{resource_type}/#{type}"
|
56
|
+
call_api(:delete, uri, {:prefix=>prefix}, options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.delete_derived_resources(derived_resource_ids, options={})
|
60
|
+
uri = "derived_resources"
|
61
|
+
call_api(:delete, uri, {:derived_resource_ids=>derived_resource_ids}, options)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.tags(options={})
|
65
|
+
resource_type = options[:resource_type] || "image"
|
66
|
+
uri = "tags/#{resource_type}"
|
67
|
+
call_api(:get, uri, only(options, :next_cursor, :max_results, :prefix), options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.transformations(options={})
|
71
|
+
call_api(:get, "transformations", only(options, :next_cursor, :max_results), options)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.transformation(transformation, options={})
|
75
|
+
call_api(:get, "transformations/#{transformation_string(transformation)}", only(options, :max_results), options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.delete_transformation(transformation, options={})
|
79
|
+
call_api(:delete, "transformations/#{transformation_string(transformation)}", {}, options)
|
80
|
+
end
|
81
|
+
|
82
|
+
# updates - currently only supported update is the "allowed_for_strict" boolean flag
|
83
|
+
def self.update_transformation(transformation, updates, options={})
|
84
|
+
call_api(:put, "transformations/#{transformation_string(transformation)}", only(updates, :allowed_for_strict), options)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.create_transformation(name, definition, options={})
|
88
|
+
call_api(:post, "transformations/#{name}", {:transformation=>transformation_string(definition)}, options)
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
def self.call_api(method, uri, params, options)
|
94
|
+
cloudinary = options[:upload_prefix] || Cloudinary.config.upload_prefix || "https://api.cloudinary.com"
|
95
|
+
cloud_name = options[:cloud_name] || Cloudinary.config.cloud_name || raise("Must supply cloud_name")
|
96
|
+
api_key = options[:api_key] || Cloudinary.config.api_key || raise("Must supply api_key")
|
97
|
+
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise("Must supply api_secret")
|
98
|
+
api_url = [cloudinary, "v1_1", cloud_name, uri].join("/")
|
99
|
+
# Add authentication
|
100
|
+
api_url.sub!(%r(^(https?://)), "\\1#{api_key}:#{api_secret}@")
|
101
|
+
|
102
|
+
RestClient::Request.execute(:method => method, :url => api_url, :payload => params.reject{|k, v| v.nil? || v==""}, :timeout=>60) do
|
103
|
+
|response, request, tmpresult|
|
104
|
+
return Response.new(response) if response.code == 200
|
105
|
+
exception_class = case response.code
|
106
|
+
when 400 then BadRequest
|
107
|
+
when 401 then AuthorizationRequired
|
108
|
+
when 403 then NotAllowed
|
109
|
+
when 404 then NotFound
|
110
|
+
when 409 then AlreadyExists
|
111
|
+
when 420 then RateLimited
|
112
|
+
when 500 then GeneralError
|
113
|
+
else raise GeneralError.new("Server returned unexpected status code - #{response.code} - #{response.body}")
|
114
|
+
end
|
115
|
+
json = parse_json_response(response)
|
116
|
+
raise exception_class.new(json["error"]["message"])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.parse_json_response(response)
|
121
|
+
return Cloudinary::Utils.json_decode(response.body)
|
122
|
+
rescue => e
|
123
|
+
# Error is parsing json
|
124
|
+
raise GeneralError.new("Error parsing server response (#{response.code}) - #{response.body}. Got - #{e}")
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.only(hash, *keys)
|
128
|
+
result = {}
|
129
|
+
keys.each do
|
130
|
+
|key|
|
131
|
+
result[key] = hash[key] if hash.include?(key)
|
132
|
+
result[key] = hash[key.to_s] if hash.include?(key.to_s)
|
133
|
+
end
|
134
|
+
result
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.transformation_string(transformation)
|
138
|
+
transformation = transformation.is_a?(String) ? transformation : Cloudinary::Utils.generate_transformation_string(transformation.clone)
|
139
|
+
end
|
140
|
+
end
|
data/lib/cloudinary/helper.rb
CHANGED
@@ -154,6 +154,10 @@ module CloudinaryHelper
|
|
154
154
|
def cl_zip_download_url(tag, options = {})
|
155
155
|
Cloudinary::Utils.zip_download_url(tag, options)
|
156
156
|
end
|
157
|
+
|
158
|
+
def cl_signed_download_url(public_id, options = {})
|
159
|
+
Cloudinary::Utils.signed_download_url(public_id, options)
|
160
|
+
end
|
157
161
|
|
158
162
|
def self.included(base)
|
159
163
|
ActionView::Helpers::FormBuilder.send(:include, Cloudinary::FormBuilder)
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -1,12 +1,21 @@
|
|
1
1
|
# Copyright Cloudinary
|
2
2
|
require 'digest/sha1'
|
3
3
|
require 'zlib'
|
4
|
+
require 'aws_cf_signer'
|
4
5
|
|
5
6
|
class Cloudinary::Utils
|
6
7
|
SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net"
|
7
8
|
|
8
9
|
# Warning: options are being destructively updated!
|
9
10
|
def self.generate_transformation_string(options={})
|
11
|
+
if options.is_a?(Array)
|
12
|
+
return options.map{|base_transformation| generate_transformation_string(base_transformation.clone)}.join("/")
|
13
|
+
end
|
14
|
+
# Symbolize keys
|
15
|
+
options.keys.each do |key|
|
16
|
+
options[key.to_sym] = options.delete(key) if key.is_a?(String)
|
17
|
+
end
|
18
|
+
|
10
19
|
size = options.delete(:size)
|
11
20
|
options[:width], options[:height] = size.split("x") if size
|
12
21
|
width = options[:width]
|
@@ -35,10 +44,12 @@ class Cloudinary::Utils
|
|
35
44
|
|
36
45
|
effect = options.delete(:effect)
|
37
46
|
effect = Array(effect).flatten.join(":") if effect.is_a?(Array) || effect.is_a?(Hash)
|
47
|
+
|
48
|
+
angle = build_array(options.delete(:angle)).join(".")
|
38
49
|
|
39
|
-
params = {:w=>width, :h=>height, :t=>named_transformation, :c=>crop, :b=>background, :e=>effect}
|
50
|
+
params = {:w=>width, :h=>height, :t=>named_transformation, :c=>crop, :b=>background, :e=>effect, :a=>angle}
|
40
51
|
{ :x=>:x, :y=>:y, :r=>:radius, :d=>:default_image, :g=>:gravity, :q=>:quality,
|
41
|
-
:p=>:prefix, :
|
52
|
+
:p=>:prefix, :l=>:overlay, :u=>:underlay, :f=>:fetch_format, :dn=>:density, :pg=>:page
|
42
53
|
}.each do
|
43
54
|
|param, option|
|
44
55
|
params[param] = options.delete(option)
|
@@ -144,7 +155,7 @@ class Cloudinary::Utils
|
|
144
155
|
def self.private_download_url(public_id, format, options = {})
|
145
156
|
api_key = options[:api_key] || Cloudinary.config.api_key || raise("Must supply api_key")
|
146
157
|
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise("Must supply api_secret")
|
147
|
-
cloudinary_params = {:timestamp=>Time.now.to_i, :public_id=>public_id, :format=>format}.reject{|k, v| v.blank?}
|
158
|
+
cloudinary_params = {:timestamp=>Time.now.to_i, :public_id=>public_id, :format=>format, :type=>options[:type]}.reject{|k, v| v.blank?}
|
148
159
|
cloudinary_params[:signature] = Cloudinary::Utils.api_sign_request(cloudinary_params, api_secret)
|
149
160
|
cloudinary_params[:api_key] = api_key
|
150
161
|
return Cloudinary::Utils.cloudinary_api_url("download", options) + "?" + cloudinary_params.to_query
|
@@ -159,7 +170,17 @@ class Cloudinary::Utils
|
|
159
170
|
return Cloudinary::Utils.cloudinary_api_url("download_tag.zip", options) + "?" + cloudinary_params.to_query
|
160
171
|
end
|
161
172
|
|
162
|
-
|
173
|
+
def self.signed_download_url(public_id, options = {})
|
174
|
+
aws_private_key_path = options[:aws_private_key_path] || Cloudinary.config.aws_private_key_path || raise("Must supply aws_private_key_path")
|
175
|
+
aws_key_pair_id = options[:aws_key_pair_id] || Cloudinary.config.aws_key_pair_id || raise("Must supply aws_key_pair_id")
|
176
|
+
authenticated_distribution = options[:authenticated_distribution] || Cloudinary.config.authenticated_distribution || raise("Must supply authenticated_distribution")
|
177
|
+
@signers ||= Hash.new{|h,k| path, id = k; h[k] = AwsCfSigner.new(path, id)}
|
178
|
+
signer = @signers[[aws_private_key_path, aws_key_pair_id]]
|
179
|
+
url = Cloudinary::Utils.cloudinary_url(public_id, options.merge(:secure=>true, :secure_distribution=>authenticated_distribution, :private_cdn=>true))
|
180
|
+
expires_at = options[:expires_at] || (Time.now+3600)
|
181
|
+
signer.sign(url, :ending => expires_at)
|
182
|
+
end
|
183
|
+
|
163
184
|
def self.asset_file_name(path)
|
164
185
|
data = Rails.root.join(path).read(:mode=>"rb")
|
165
186
|
ext = path.extname
|
data/lib/cloudinary/version.rb
CHANGED
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cloudinary'
|
3
|
+
|
4
|
+
describe Cloudinary::Api do
|
5
|
+
break puts("Please setup environment for api test to run") if Cloudinary.config.api_secret.blank?
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@api = Cloudinary::Api
|
9
|
+
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test", :tags=>"api_test_tag", :eager=>[:width=>100,:crop=>:scale])
|
10
|
+
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test2", :tags=>"api_test_tag", :eager=>[:width=>100,:crop=>:scale])
|
11
|
+
@api.delete_transformation("api_test_transformation") rescue nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should allow listing resource_types" do
|
15
|
+
@api.resource_types()["resource_types"].should include("image")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should allow listing resources" do
|
19
|
+
resource = @api.resources()["resources"].find{|resource| resource["public_id"] == "api_test"}
|
20
|
+
resource.should_not be_blank
|
21
|
+
resource["type"].should == "upload"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should allow listing resources with cursor" do
|
25
|
+
result = @api.resources(:max_results=>1)
|
26
|
+
result["resources"].should_not be_blank
|
27
|
+
result["resources"].length.should == 1
|
28
|
+
result["next_cursor"].should_not be_blank
|
29
|
+
result2 = @api.resources(:max_results=>1, :next_cursor=>result["next_cursor"])
|
30
|
+
result2["resources"].should_not be_blank
|
31
|
+
result2["resources"].length.should == 1
|
32
|
+
result2["resources"][0]["public_id"].should_not == result["resources"][0]["public_id"]
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
it "should allow listing resources by type" do
|
37
|
+
resource = @api.resources(:type=>"upload")["resources"].find{|resource| resource["public_id"] == "api_test"}
|
38
|
+
resource.should_not be_blank
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should allow listing resources by prefix" do
|
42
|
+
public_ids = @api.resources(:type=>"upload", :prefix=>"api_test")["resources"].map{|resource| resource["public_id"]}
|
43
|
+
public_ids.should include("api_test", "api_test2")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should allow listing resources by tag" do
|
47
|
+
resource = @api.resources_by_tag("api_test_tag")["resources"].find{|resource| resource["public_id"] == "api_test"}
|
48
|
+
resource.should_not be_blank
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should allow get resource metadata" do
|
52
|
+
resource = @api.resource("api_test")
|
53
|
+
resource.should_not be_blank
|
54
|
+
resource["public_id"].should == "api_test"
|
55
|
+
resource["bytes"].should == 3381
|
56
|
+
resource["derived"].length.should == 1
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow deleting derived resource" do
|
60
|
+
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test3", :eager=>[:width=>101,:crop=>:scale])
|
61
|
+
resource = @api.resource("api_test3")
|
62
|
+
resource.should_not be_blank
|
63
|
+
resource["derived"].length.should == 1
|
64
|
+
derived_resource_id = resource["derived"][0]["id"]
|
65
|
+
@api.delete_derived_resources(derived_resource_id)
|
66
|
+
resource = @api.resource("api_test3")
|
67
|
+
resource.should_not be_blank
|
68
|
+
resource["derived"].length.should == 0
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should allow deleting resources" do
|
72
|
+
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test3")
|
73
|
+
resource = @api.resource("api_test3")
|
74
|
+
resource.should_not be_blank
|
75
|
+
@api.delete_resources(["apit_test", "api_test2", "api_test3"])
|
76
|
+
lambda{@api.resource("api_test3")}.should raise_error(Cloudinary::Api::NotFound)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should allow listing tags" do
|
80
|
+
tags = @api.tags()["tags"]
|
81
|
+
tags.should include('api_test_tag')
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should allow listing tag by prefix" do
|
85
|
+
tags = @api.tags(:prefix=>"api_test")["tags"]
|
86
|
+
tags.should include('api_test_tag')
|
87
|
+
tags = @api.tags(:prefix=>"api_test_no_such_tag")["tags"]
|
88
|
+
tags.should be_blank
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should allow listing transformations" do
|
92
|
+
transformation = @api.transformations()["transformations"].find{|transformation| transformation["name"] == "c_scale,w_100"}
|
93
|
+
transformation.should_not be_blank
|
94
|
+
transformation["used"].should == true
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should allow getting transformation metadata" do
|
98
|
+
transformation = @api.transformation("c_scale,w_100")
|
99
|
+
transformation.should_not be_blank
|
100
|
+
transformation["info"].should == ["crop"=>"scale", "width"=>100]
|
101
|
+
transformation = @api.transformation("crop"=>"scale", "width"=>100)
|
102
|
+
transformation.should_not be_blank
|
103
|
+
transformation["info"].should == ["crop"=>"scale", "width"=>100]
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should allow updating transformation allowed_for_strict" do
|
107
|
+
@api.update_transformation("c_scale,w_100", :allowed_for_strict=>true)
|
108
|
+
transformation = @api.transformation("c_scale,w_100")
|
109
|
+
transformation.should_not be_blank
|
110
|
+
transformation["allowed_for_strict"].should == true
|
111
|
+
@api.update_transformation("c_scale,w_100", :allowed_for_strict=>false)
|
112
|
+
transformation = @api.transformation("c_scale,w_100")
|
113
|
+
transformation.should_not be_blank
|
114
|
+
transformation["allowed_for_strict"].should == false
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should allow creating named transformation" do
|
118
|
+
@api.create_transformation("api_test_transformation", "crop"=>"scale", "width"=>102)
|
119
|
+
transformation = @api.transformation("api_test_transformation")
|
120
|
+
transformation.should_not be_blank
|
121
|
+
transformation["allowed_for_strict"].should == true
|
122
|
+
transformation["info"].should == ["crop"=>"scale", "width"=>102]
|
123
|
+
transformation["used"].should == false
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should allow deleting named transformation" do
|
127
|
+
@api.create_transformation("api_test_transformation2", "crop"=>"scale", "width"=>103)
|
128
|
+
@api.transformation("api_test_transformation2")
|
129
|
+
@api.delete_transformation("api_test_transformation2")
|
130
|
+
lambda{@api.transformation("api_test_transformation2")}.should raise_error(Cloudinary::Api::NotFound)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should allow deleting implicit transformation" do
|
134
|
+
@api.transformation("c_scale,w_100")
|
135
|
+
@api.delete_transformation("c_scale,w_100")
|
136
|
+
lambda{@api.transformation("c_scale,w_100")}.should raise_error(Cloudinary::Api::NotFound)
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
data/spec/logo.png
ADDED
Binary file
|
data/spec/utils_spec.rb
CHANGED
@@ -104,6 +104,12 @@ describe Cloudinary::Utils do
|
|
104
104
|
result.should == "http://res.cloudinary.com/test123/image/upload/c_fill,w_200,x_100,y_100/r_10/c_crop,w_100/test"
|
105
105
|
end
|
106
106
|
|
107
|
+
it "should support array of tranformations" do
|
108
|
+
options = [{:x=>100, :y=>100, :width=>200, :crop=>:fill}, {:radius=>10}]
|
109
|
+
result = Cloudinary::Utils.generate_transformation_string(options)
|
110
|
+
result.should == "c_fill,w_200,x_100,y_100/r_10"
|
111
|
+
end
|
112
|
+
|
107
113
|
it "should not include empty tranformations" do
|
108
114
|
options = {:transformation=>[{}, {:x=>100, :y=>100, :crop=>:fill}, {}]}
|
109
115
|
result = Cloudinary::Utils.cloudinary_url("test", options)
|
@@ -191,6 +197,11 @@ describe Cloudinary::Utils do
|
|
191
197
|
result = Cloudinary::Utils.cloudinary_url("test", options)
|
192
198
|
options.should == {}
|
193
199
|
result.should == "http://res.cloudinary.com/test123/image/upload/a_55/test"
|
200
|
+
|
201
|
+
options = {:angle=>["auto", "55"]}
|
202
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
203
|
+
options.should == {}
|
204
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/a_auto.55/test"
|
194
205
|
end
|
195
206
|
|
196
207
|
it "should support format for fetch urls" do
|
@@ -273,4 +284,12 @@ describe Cloudinary::Utils do
|
|
273
284
|
options.should == {}
|
274
285
|
result.should == "http://a2.hello.com/test123/image/upload/test"
|
275
286
|
end
|
287
|
+
|
288
|
+
it "should support string param" do
|
289
|
+
options = {"effect"=>{"sepia"=>10}}
|
290
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
291
|
+
options.should == {}
|
292
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/e_sepia:10/test"
|
293
|
+
end
|
294
|
+
|
276
295
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.33
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-08-05 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rest-client
|
@@ -29,6 +29,22 @@ dependencies:
|
|
29
29
|
- - ! '>='
|
30
30
|
- !ruby/object:Gem::Version
|
31
31
|
version: '0'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: aws_cf_signer
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
32
48
|
- !ruby/object:Gem::Dependency
|
33
49
|
name: rspec
|
34
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,6 +77,7 @@ files:
|
|
61
77
|
- Rakefile
|
62
78
|
- cloudinary.gemspec
|
63
79
|
- lib/cloudinary.rb
|
80
|
+
- lib/cloudinary/api.rb
|
64
81
|
- lib/cloudinary/blob.rb
|
65
82
|
- lib/cloudinary/carrier_wave.rb
|
66
83
|
- lib/cloudinary/carrier_wave/error.rb
|
@@ -80,6 +97,8 @@ files:
|
|
80
97
|
- lib/cloudinary/utils.rb
|
81
98
|
- lib/cloudinary/version.rb
|
82
99
|
- lib/tasks/cloudinary.rake
|
100
|
+
- spec/api_spec.rb
|
101
|
+
- spec/logo.png
|
83
102
|
- spec/spec_helper.rb
|
84
103
|
- spec/utils_spec.rb
|
85
104
|
- vendor/assets/javascripts/cloudinary/index.js
|
@@ -113,5 +132,7 @@ signing_key:
|
|
113
132
|
specification_version: 3
|
114
133
|
summary: Client library for easily using the Cloudinary service
|
115
134
|
test_files:
|
135
|
+
- spec/api_spec.rb
|
136
|
+
- spec/logo.png
|
116
137
|
- spec/spec_helper.rb
|
117
138
|
- spec/utils_spec.rb
|