cloudinary 1.0.72 → 1.0.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/CHANGELOG +10 -0
- data/cloudinary.gemspec +1 -0
- data/lib/cloudinary.rb +2 -1
- data/lib/cloudinary/api.rb +1 -1
- data/lib/cloudinary/helper.rb +86 -64
- data/lib/cloudinary/static.rb +1 -1
- data/lib/cloudinary/uploader.rb +13 -13
- data/lib/cloudinary/utils.rb +22 -5
- data/lib/cloudinary/version.rb +1 -1
- data/spec/api_spec.rb +12 -11
- data/spec/cloudinary_helper_spec.rb +48 -0
- data/spec/uploader_spec.rb +18 -5
- data/spec/utils_spec.rb +12 -0
- metadata +22 -14
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmFlNDk5YjhhMmM0MmE0YTFhM2Y1MDVkMjAyOGYyMDc5ZDhmZWM4OA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTNlOTg2MTRkNzVkNTc5M2FiNWQwMmU0NTQyMDc4Yzc0OTQ0NjE3MQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NjdlMTRkOWNiNDQ2ZWE5NTJkZDc0ZmQwMTE0MGIyMjcxZTAzMTNjYjA5Mjhl
|
10
|
+
Mzk1NTdmNzI0ODg1OGM5YzUzNzNhOThiYTQ5ZDNjYmRlZWQwZTQwYTlkMzE0
|
11
|
+
YTRhMmI0MDFlMzc2NjI3OWQ5ZWVkMTlkZjRiZWM3ZDNhNTAwZDM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZmEwZGU0NzU3MTg2MWM4MWEwMDlmNTFmZTUxNDMzOWRhNTkxN2Q1YTE0YzNj
|
14
|
+
YTAxYzBiNDA2ZjQ4OTVkYjY1NTViNWE1YWZjYzM0N2NhMWQyZWEwZGUwMDY1
|
15
|
+
NGVkNjMyNTFhNWQ3ZDFkYjg2M2ZkNzJlNWMzNTk0MzM1Yzk0Yjg=
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
= Version 1.0.73 - 2014-06-30
|
2
|
+
* Support dpr transformation parameter.
|
3
|
+
* Support automatic dpr (for HiDPI) and automatic width (for responsive).
|
4
|
+
* Accept timestamp parameter in upload method options.
|
5
|
+
* Support pHash info in admin API.
|
6
|
+
* Support the multiple upload flag directly in cl_image_upload_tag.
|
7
|
+
* 'secure' configuration parameter from environment variable.
|
8
|
+
* Make api_key and api_secret optional in unsigned upload.
|
9
|
+
* Support the case Rails is defined but Rails.root isn't.
|
10
|
+
|
1
11
|
= Version 1.0.72 - 2014-04-15
|
2
12
|
* Fixing broken sign_request.
|
3
13
|
|
data/cloudinary.gemspec
CHANGED
data/lib/cloudinary.rb
CHANGED
@@ -50,7 +50,8 @@ module Cloudinary
|
|
50
50
|
"api_key" => ENV["CLOUDINARY_API_KEY"],
|
51
51
|
"api_secret" => ENV["CLOUDINARY_API_SECRET"],
|
52
52
|
"secure_distribution" => ENV["CLOUDINARY_SECURE_DISTRIBUTION"],
|
53
|
-
"private_cdn" => ENV["CLOUDINARY_PRIVATE_CDN"].to_s == 'true'
|
53
|
+
"private_cdn" => ENV["CLOUDINARY_PRIVATE_CDN"].to_s == 'true',
|
54
|
+
"secure" => ENV["CLOUDINARY_SECURE"].to_s == 'true'
|
54
55
|
)
|
55
56
|
elsif first_time && ENV["CLOUDINARY_URL"]
|
56
57
|
config_from_url(ENV["CLOUDINARY_URL"])
|
data/lib/cloudinary/api.rb
CHANGED
@@ -62,7 +62,7 @@ class Cloudinary::Api
|
|
62
62
|
resource_type = options[:resource_type] || "image"
|
63
63
|
type = options[:type] || "upload"
|
64
64
|
uri = "resources/#{resource_type}/#{type}/#{public_id}"
|
65
|
-
call_api(:get, uri, only(options, :colors, :exif, :faces, :image_metadata, :pages, :max_results), options)
|
65
|
+
call_api(:get, uri, only(options, :colors, :exif, :faces, :image_metadata, :pages, :phash, :max_results), options)
|
66
66
|
end
|
67
67
|
|
68
68
|
def self.update(public_id, options={})
|
data/lib/cloudinary/helper.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'digest/md5'
|
2
2
|
module CloudinaryHelper
|
3
|
+
CL_BLANK = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
|
4
|
+
|
3
5
|
# Stand-in for Rails image_tag helper that accepts various options for transformations.
|
4
6
|
#
|
5
|
-
# source:: the public ID, possibly with a file type extension. If there is no extension, the
|
7
|
+
# source:: the public ID, possibly with a file type extension. If there is no extension, the
|
6
8
|
# :format option is expected to indicate what the extension is. This value can contain
|
7
9
|
# the version, or not.
|
8
10
|
# options:: Options you would normally pass to image_tag as well as Cloudinary-specific options
|
@@ -29,17 +31,33 @@ module CloudinaryHelper
|
|
29
31
|
options[:height] = options.delete(:html_height) if options.include?(:html_height)
|
30
32
|
options[:size] = options.delete(:html_size) if options.include?(:html_size)
|
31
33
|
options[:border] = options.delete(:html_border) if options.include?(:html_border)
|
32
|
-
|
33
|
-
|
34
|
+
responsive_placeholder = Cloudinary::Utils.config_option_consume(options, :responsive_placeholder)
|
35
|
+
hidpi = options.delete(:hidpi)
|
36
|
+
responsive = options.delete(:responsive)
|
37
|
+
if hidpi || responsive
|
38
|
+
options["data-src"] = source
|
39
|
+
extra_class = responsive ? "cld-responsive" : "cld-hidpi"
|
40
|
+
options[:class] = [options[:class], extra_class].compact.join(" ")
|
41
|
+
source = responsive_placeholder
|
42
|
+
end
|
43
|
+
if source
|
44
|
+
image_tag_without_cloudinary(source, options)
|
45
|
+
else
|
46
|
+
content_tag 'img', nil, options
|
47
|
+
end
|
34
48
|
end
|
35
49
|
|
50
|
+
def cl_blank
|
51
|
+
CL_BLANK
|
52
|
+
end
|
53
|
+
|
36
54
|
# Works similarly to cl_image_tag, however just generates the URL of the image
|
37
55
|
def cl_image_path(source, options = {})
|
38
56
|
options = options.clone
|
39
57
|
url = cloudinary_url_internal(source, options)
|
40
|
-
image_path_without_cloudinary(url)
|
58
|
+
image_path_without_cloudinary(url)
|
41
59
|
end
|
42
|
-
|
60
|
+
|
43
61
|
def image_tag_with_cloudinary(*args)
|
44
62
|
source, options = args
|
45
63
|
cl_image_tag(source, {:type=>:asset}.merge(options || {}))
|
@@ -50,61 +68,61 @@ module CloudinaryHelper
|
|
50
68
|
cl_image_path(source, {:type=>:asset}.merge(options || {}))
|
51
69
|
end
|
52
70
|
|
53
|
-
def fetch_image_tag(profile, options = {})
|
71
|
+
def fetch_image_tag(profile, options = {})
|
54
72
|
cl_image_tag(profile, {:type=>:fetch}.merge(options))
|
55
73
|
end
|
56
|
-
|
57
|
-
def facebook_profile_image_tag(profile, options = {})
|
74
|
+
|
75
|
+
def facebook_profile_image_tag(profile, options = {})
|
58
76
|
cl_image_tag(profile, {:type=>:facebook}.merge(options))
|
59
77
|
end
|
60
|
-
|
61
|
-
def facebook_profile_image_path(profile, options = {})
|
78
|
+
|
79
|
+
def facebook_profile_image_path(profile, options = {})
|
62
80
|
cl_image_path(profile, {:type=>:facebook}.merge(options))
|
63
81
|
end
|
64
82
|
|
65
|
-
def gravatar_profile_image_tag(email, options = {})
|
83
|
+
def gravatar_profile_image_tag(email, options = {})
|
66
84
|
cl_image_tag(Digest::MD5.hexdigest(email.strip.downcase), {:type=>:gravatar, :format=>:jpg}.merge(options))
|
67
85
|
end
|
68
|
-
|
69
|
-
def gravatar_profile_image_path(email, options = {})
|
86
|
+
|
87
|
+
def gravatar_profile_image_path(email, options = {})
|
70
88
|
cl_image_path(Digest::MD5.hexdigest(email.strip.downcase), {:type=>:gravatar, :format=>:jpg}.merge(options))
|
71
89
|
end
|
72
90
|
|
73
|
-
def twitter_profile_image_tag(profile, options = {})
|
91
|
+
def twitter_profile_image_tag(profile, options = {})
|
74
92
|
cl_image_tag(profile, {:type=>:twitter}.merge(options))
|
75
93
|
end
|
76
|
-
|
77
|
-
def twitter_profile_image_path(profile, options = {})
|
94
|
+
|
95
|
+
def twitter_profile_image_path(profile, options = {})
|
78
96
|
cl_image_path(profile, {:type=>:twitter}.merge(options))
|
79
97
|
end
|
80
98
|
|
81
|
-
def twitter_name_profile_image_tag(profile, options = {})
|
99
|
+
def twitter_name_profile_image_tag(profile, options = {})
|
82
100
|
cl_image_tag(profile, {:type=>:twitter_name}.merge(options))
|
83
101
|
end
|
84
|
-
|
85
|
-
def twitter_name_profile_image_path(profile, options = {})
|
102
|
+
|
103
|
+
def twitter_name_profile_image_path(profile, options = {})
|
86
104
|
cl_image_path(profile, {:type=>:twitter_name}.merge(options))
|
87
105
|
end
|
88
|
-
|
89
|
-
def gplus_profile_image_tag(profile, options = {})
|
106
|
+
|
107
|
+
def gplus_profile_image_tag(profile, options = {})
|
90
108
|
cl_image_tag(profile, {:type=>:gplus}.merge(options))
|
91
109
|
end
|
92
|
-
|
93
|
-
def gplus_profile_image_path(profile, options = {})
|
110
|
+
|
111
|
+
def gplus_profile_image_path(profile, options = {})
|
94
112
|
cl_image_path(profile, {:type=>:gplus}.merge(options))
|
95
113
|
end
|
96
114
|
|
97
115
|
def cl_sprite_url(source, options = {})
|
98
116
|
options = options.clone
|
99
|
-
|
117
|
+
|
100
118
|
version_store = options.delete(:version_store)
|
101
119
|
if options[:version].blank? && (version_store == :file) && defined?(Rails) && defined?(Rails.root)
|
102
120
|
file_name = "#{Rails.root}/tmp/cloudinary/cloudinary_sprite_#{source.sub(/\..*/, '')}.version"
|
103
121
|
if File.exists?(file_name)
|
104
|
-
options[:version] = File.read(file_name).chomp
|
122
|
+
options[:version] = File.read(file_name).chomp
|
105
123
|
end
|
106
|
-
end
|
107
|
-
|
124
|
+
end
|
125
|
+
|
108
126
|
options[:format] = "css" unless source.ends_with?(".css")
|
109
127
|
cloudinary_url_internal(source, options.merge(:type=>:sprite))
|
110
128
|
end
|
@@ -118,23 +136,23 @@ module CloudinaryHelper
|
|
118
136
|
form_options = options.delete(:form) || {}
|
119
137
|
form_options[:method] = :post
|
120
138
|
form_options[:multipart] = true
|
121
|
-
|
122
|
-
params = Cloudinary::Uploader.build_upload_params(options.merge(:callback=>callback_url))
|
123
|
-
params[:signature] = Cloudinary::Utils.api_sign_request(params, Cloudinary.config.api_secret)
|
139
|
+
|
140
|
+
params = Cloudinary::Uploader.build_upload_params(options.merge(:callback=>callback_url))
|
141
|
+
params[:signature] = Cloudinary::Utils.api_sign_request(params, Cloudinary.config.api_secret)
|
124
142
|
params[:api_key] = Cloudinary.config.api_key
|
125
|
-
|
126
|
-
api_url = Cloudinary::Utils.cloudinary_api_url("upload",
|
143
|
+
|
144
|
+
api_url = Cloudinary::Utils.cloudinary_api_url("upload",
|
127
145
|
{:resource_type => options.delete(:resource_type), :upload_prefix => options.delete(:upload_prefix)})
|
128
146
|
|
129
147
|
form_tag(api_url, form_options) do
|
130
148
|
content = []
|
131
|
-
|
149
|
+
|
132
150
|
params.each do |name, value|
|
133
151
|
content << hidden_field_tag(name, value, :id => nil) if value.present?
|
134
152
|
end
|
135
|
-
|
153
|
+
|
136
154
|
content << capture(&block)
|
137
|
-
|
155
|
+
|
138
156
|
content.join("\n").html_safe
|
139
157
|
end
|
140
158
|
end
|
@@ -143,29 +161,29 @@ module CloudinaryHelper
|
|
143
161
|
def cloudinary_js_config
|
144
162
|
params = {}
|
145
163
|
CLOUDINARY_JS_CONFIG_PARAMS.each do
|
146
|
-
|param|
|
164
|
+
|param|
|
147
165
|
value = Cloudinary.config.send(param)
|
148
166
|
params[param] = value if !value.nil?
|
149
|
-
end
|
150
|
-
content_tag("script", "$.cloudinary.config(#{params.to_json});".html_safe, :type=>"text/javascript")
|
167
|
+
end
|
168
|
+
content_tag("script", "$.cloudinary.config(#{params.to_json});".html_safe, :type=>"text/javascript")
|
151
169
|
end
|
152
170
|
|
153
171
|
def cloudinary_url(source, options = {})
|
154
172
|
cloudinary_url_internal(source, options.clone)
|
155
173
|
end
|
156
|
-
|
174
|
+
|
157
175
|
def cl_image_upload(object_name, method, options={})
|
158
176
|
cl_image_upload_tag("#{object_name}[#{method}]", options)
|
159
177
|
end
|
160
|
-
|
178
|
+
|
161
179
|
def cl_unsigned_image_upload(object_name, method, upload_preset, options={})
|
162
180
|
cl_unsigned_image_upload_tag("#{object_name}[#{method}]", upload_preset, options)
|
163
181
|
end
|
164
|
-
|
182
|
+
|
165
183
|
def cl_upload_url(options={})
|
166
184
|
Cloudinary::Utils.cloudinary_api_url("upload", {:resource_type=>:auto}.merge(options))
|
167
185
|
end
|
168
|
-
|
186
|
+
|
169
187
|
def cl_upload_tag_params(options={})
|
170
188
|
cloudinary_params = Cloudinary::Uploader.build_upload_params(options)
|
171
189
|
cloudinary_params[:callback] = build_callback_url(options)
|
@@ -175,23 +193,27 @@ module CloudinaryHelper
|
|
175
193
|
return Cloudinary::Utils.sign_request(cloudinary_params, options).to_json
|
176
194
|
end
|
177
195
|
end
|
178
|
-
|
196
|
+
|
179
197
|
def cl_image_upload_tag(field, options={})
|
180
|
-
html_options = options.delete(:html) || {}
|
198
|
+
html_options = options.delete(:html) || {}
|
199
|
+
if options.delete(:multiple)
|
200
|
+
html_options[:multiple] = true
|
201
|
+
field = "#{ field }[]" unless field.to_s[-2..-1] == "[]"
|
202
|
+
end
|
181
203
|
|
182
|
-
tag_options = html_options.merge(:type=>"file", :name=>"file",
|
204
|
+
tag_options = html_options.merge(:type=>"file", :name=>"file",
|
183
205
|
:"data-url"=>cl_upload_url(options),
|
184
206
|
:"data-form-data"=>cl_upload_tag_params(options),
|
185
207
|
:"data-cloudinary-field"=>field,
|
186
|
-
:"class" => [html_options[:class], "cloudinary-fileupload"].flatten.compact
|
208
|
+
:"class" => [html_options[:class], "cloudinary-fileupload"].flatten.compact
|
187
209
|
).reject{|k,v| v.blank?}
|
188
210
|
content_tag("input", nil, tag_options)
|
189
211
|
end
|
190
|
-
|
212
|
+
|
191
213
|
def cl_unsigned_image_upload_tag(field, upload_preset, options={})
|
192
214
|
cl_image_upload_tag(field, options.merge(:unsigned => true, :upload_preset => upload_preset))
|
193
215
|
end
|
194
|
-
|
216
|
+
|
195
217
|
def cl_private_download_url(public_id, format, options = {})
|
196
218
|
Cloudinary::Utils.private_download_url(public_id, format, options)
|
197
219
|
end
|
@@ -203,7 +225,7 @@ module CloudinaryHelper
|
|
203
225
|
def cl_signed_download_url(public_id, options = {})
|
204
226
|
Cloudinary::Utils.signed_download_url(public_id, options)
|
205
227
|
end
|
206
|
-
|
228
|
+
|
207
229
|
def self.included(base)
|
208
230
|
ActionView::Helpers::FormBuilder.send(:include, Cloudinary::FormBuilder)
|
209
231
|
base.class_eval do
|
@@ -219,22 +241,22 @@ module CloudinaryHelper
|
|
219
241
|
end
|
220
242
|
end
|
221
243
|
end
|
222
|
-
|
244
|
+
|
223
245
|
private
|
224
246
|
def cloudinary_url_internal(source, options = {})
|
225
247
|
options[:ssl_detected] = request.ssl? if defined?(request) && request && request.respond_to?(:ssl?)
|
226
|
-
if defined?(CarrierWave::Uploader::Base) && source.is_a?(CarrierWave::Uploader::Base)
|
248
|
+
if defined?(CarrierWave::Uploader::Base) && source.is_a?(CarrierWave::Uploader::Base)
|
227
249
|
if source.version_name.present?
|
228
|
-
options[:transformation] = Cloudinary::Utils.build_array(source.transformation) + Cloudinary::Utils.build_array(options[:transformation])
|
229
|
-
end
|
230
|
-
options.reverse_merge!(
|
250
|
+
options[:transformation] = Cloudinary::Utils.build_array(source.transformation) + Cloudinary::Utils.build_array(options[:transformation])
|
251
|
+
end
|
252
|
+
options.reverse_merge!(
|
231
253
|
:resource_type => Cloudinary::Utils.resource_type_for_format(source.filename || source.format),
|
232
254
|
:type => source.storage_type,
|
233
255
|
:format => source.format)
|
234
|
-
source = source.full_public_id
|
256
|
+
source = source.full_public_id
|
235
257
|
end
|
236
258
|
Cloudinary::Utils.cloudinary_url(source, options)
|
237
|
-
end
|
259
|
+
end
|
238
260
|
|
239
261
|
def build_callback_url(options)
|
240
262
|
callback_path = options.delete(:callback_cors) || Cloudinary.config.callback_cors || "/cloudinary_cors.html"
|
@@ -248,7 +270,7 @@ module CloudinaryHelper
|
|
248
270
|
callback_url << callback_path
|
249
271
|
end
|
250
272
|
callback_url
|
251
|
-
end
|
273
|
+
end
|
252
274
|
end
|
253
275
|
|
254
276
|
module Cloudinary::FormBuilder
|
@@ -263,14 +285,14 @@ end
|
|
263
285
|
if defined? ActionView::Helpers::AssetUrlHelper
|
264
286
|
module ActionView::Helpers::AssetUrlHelper
|
265
287
|
alias :original_path_to_asset :path_to_asset
|
266
|
-
|
288
|
+
|
267
289
|
def path_to_asset(source, options={})
|
268
290
|
options ||= {}
|
269
291
|
if Cloudinary.config.enhance_image_tag && options[:type] == :image
|
270
292
|
source = Cloudinary::Utils.cloudinary_url(source, options.merge(:type=>:asset))
|
271
293
|
end
|
272
294
|
original_path_to_asset(source, options)
|
273
|
-
end
|
295
|
+
end
|
274
296
|
end
|
275
297
|
end
|
276
298
|
|
@@ -289,10 +311,10 @@ begin
|
|
289
311
|
original_image_path(Cloudinary::Utils.cloudinary_url(img, :type=>:asset))
|
290
312
|
else
|
291
313
|
original_image_path(img)
|
292
|
-
end
|
293
|
-
end
|
314
|
+
end
|
315
|
+
end
|
294
316
|
end
|
295
|
-
end
|
317
|
+
end
|
296
318
|
rescue LoadError
|
297
319
|
# no sass rails support. Ignore.
|
298
320
|
end
|
@@ -305,11 +327,11 @@ begin
|
|
305
327
|
options = {}
|
306
328
|
sass_options.each{|k, v| options[k.to_sym] = v.value}
|
307
329
|
url = Cloudinary::Utils.cloudinary_url(public_id.value, {:type=>:asset}.merge(options))
|
308
|
-
Sass::Script::String.new("url(#{url})")
|
330
|
+
Sass::Script::String.new("url(#{url})")
|
309
331
|
end
|
310
332
|
declare :cloudinary_url, [:string], :var_kwargs => true
|
311
333
|
end
|
312
334
|
rescue LoadError
|
313
335
|
# no sass support. Ignore.
|
314
336
|
end
|
315
|
-
|
337
|
+
|
data/lib/cloudinary/static.rb
CHANGED
data/lib/cloudinary/uploader.rb
CHANGED
@@ -19,10 +19,10 @@ class Cloudinary::Uploader
|
|
19
19
|
options = options.clone
|
20
20
|
options.keys.each{|key| options[key.to_sym] = options.delete(key) if key.is_a?(String)}
|
21
21
|
|
22
|
-
params = {:timestamp=>Time.now.to_i,
|
22
|
+
params = {:timestamp=>(options[:timestamp] || Time.now.to_i),
|
23
23
|
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone),
|
24
|
-
:public_id=>
|
25
|
-
:callback=>
|
24
|
+
:public_id=>options[:public_id],
|
25
|
+
:callback=>options[:callback],
|
26
26
|
:format=>options[:format],
|
27
27
|
:type=>options[:type],
|
28
28
|
:backup=>Cloudinary::Utils.as_safe_bool(options[:backup]),
|
@@ -108,7 +108,7 @@ class Cloudinary::Uploader
|
|
108
108
|
def self.upload_large_part(file, options={})
|
109
109
|
call_api("upload_large", options.merge(:resource_type=>:raw)) do
|
110
110
|
params = {
|
111
|
-
:timestamp=>Time.now.to_i,
|
111
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
112
112
|
:type=>options[:type],
|
113
113
|
:public_id=>options[:public_id],
|
114
114
|
:backup=>options[:backup],
|
@@ -128,7 +128,7 @@ class Cloudinary::Uploader
|
|
128
128
|
def self.destroy(public_id, options={})
|
129
129
|
call_api("destroy", options) do
|
130
130
|
{
|
131
|
-
:timestamp=>Time.now.to_i,
|
131
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
132
132
|
:type=>options[:type],
|
133
133
|
:public_id=> public_id,
|
134
134
|
:invalidate=>options[:invalidate],
|
@@ -139,7 +139,7 @@ class Cloudinary::Uploader
|
|
139
139
|
def self.rename(from_public_id, to_public_id, options={})
|
140
140
|
call_api("rename", options) do
|
141
141
|
{
|
142
|
-
:timestamp=>Time.now.to_i,
|
142
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
143
143
|
:type=>options[:type],
|
144
144
|
:overwrite=>options[:overwrite],
|
145
145
|
:from_public_id=>from_public_id,
|
@@ -161,7 +161,7 @@ class Cloudinary::Uploader
|
|
161
161
|
def self.explicit(public_id, options={})
|
162
162
|
call_api("explicit", options) do
|
163
163
|
{
|
164
|
-
:timestamp=>Time.now.to_i,
|
164
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
165
165
|
:type=>options[:type],
|
166
166
|
:public_id=> public_id,
|
167
167
|
:callback=> options[:callback],
|
@@ -187,7 +187,7 @@ class Cloudinary::Uploader
|
|
187
187
|
|
188
188
|
result = call_api("sprite", options) do
|
189
189
|
{
|
190
|
-
:timestamp=>Time.now.to_i,
|
190
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
191
191
|
:tag=>tag,
|
192
192
|
:async=>options[:async],
|
193
193
|
:notification_url=>options[:notification_url],
|
@@ -207,7 +207,7 @@ class Cloudinary::Uploader
|
|
207
207
|
def self.multi(tag, options={})
|
208
208
|
call_api("multi", options) do
|
209
209
|
{
|
210
|
-
:timestamp=>Time.now.to_i,
|
210
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
211
211
|
:tag=>tag,
|
212
212
|
:format=>options[:format],
|
213
213
|
:async=>options[:async],
|
@@ -220,7 +220,7 @@ class Cloudinary::Uploader
|
|
220
220
|
def self.explode(public_id, options={})
|
221
221
|
call_api("explode", options) do
|
222
222
|
{
|
223
|
-
:timestamp=>Time.now.to_i,
|
223
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
224
224
|
:public_id=>public_id,
|
225
225
|
:type=>options[:type],
|
226
226
|
:format=>options[:format],
|
@@ -250,7 +250,7 @@ class Cloudinary::Uploader
|
|
250
250
|
def self.call_tags_api(tag, command, public_ids = [], options = {})
|
251
251
|
return call_api("tags", options) do
|
252
252
|
{
|
253
|
-
:timestamp=>Time.now.to_i,
|
253
|
+
:timestamp=>(options[:timestamp] || Time.now.to_i),
|
254
254
|
:tag=>tag,
|
255
255
|
:public_ids => Cloudinary::Utils.build_array(public_ids),
|
256
256
|
:command => command,
|
@@ -262,13 +262,13 @@ class Cloudinary::Uploader
|
|
262
262
|
def self.call_api(action, options)
|
263
263
|
options = options.clone
|
264
264
|
return_error = options.delete(:return_error)
|
265
|
-
api_key = options[:api_key] || Cloudinary.config.api_key || raise(CloudinaryException, "Must supply api_key")
|
266
|
-
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise(CloudinaryException, "Must supply api_secret")
|
267
265
|
|
268
266
|
params, non_signable = yield
|
269
267
|
non_signable ||= []
|
270
268
|
|
271
269
|
unless options[:unsigned]
|
270
|
+
api_key = options[:api_key] || Cloudinary.config.api_key || raise(CloudinaryException, "Must supply api_key")
|
271
|
+
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise(CloudinaryException, "Must supply api_secret")
|
272
272
|
params[:signature] = Cloudinary::Utils.api_sign_request(params.reject{|k,v| non_signable.include?(k)}, api_secret)
|
273
273
|
params[:api_key] = api_key
|
274
274
|
end
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -7,6 +7,7 @@ require 'aws_cf_signer'
|
|
7
7
|
class Cloudinary::Utils
|
8
8
|
# @deprecated Use Cloudinary::SHARED_CDN
|
9
9
|
SHARED_CDN = Cloudinary::SHARED_CDN
|
10
|
+
DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION = {:width => :auto, :crop => :limit}
|
10
11
|
|
11
12
|
# Warning: options are being destructively updated!
|
12
13
|
def self.generate_transformation_string(options={})
|
@@ -18,9 +19,11 @@ class Cloudinary::Utils
|
|
18
19
|
options[key.to_sym] = options.delete(key) if key.is_a?(String)
|
19
20
|
end
|
20
21
|
|
22
|
+
responsive_width = config_option_consume(options, :responsive_width)
|
21
23
|
size = options.delete(:size)
|
22
24
|
options[:width], options[:height] = size.split("x") if size
|
23
25
|
width = options[:width]
|
26
|
+
width = width.to_s if width.is_a?(Symbol)
|
24
27
|
height = options[:height]
|
25
28
|
has_layer = !options[:overlay].blank? || !options[:underlay].blank?
|
26
29
|
|
@@ -28,10 +31,10 @@ class Cloudinary::Utils
|
|
28
31
|
angle = build_array(options.delete(:angle)).join(".")
|
29
32
|
|
30
33
|
no_html_sizes = has_layer || !angle.blank? || crop.to_s == "fit" || crop.to_s == "limit" || crop.to_s == "lfill"
|
31
|
-
options.delete(:width) if width && (width.to_f < 1 || no_html_sizes)
|
32
|
-
options.delete(:height) if height && (height.to_f < 1 || no_html_sizes)
|
34
|
+
options.delete(:width) if width && (width.to_f < 1 || no_html_sizes || width == "auto" || responsive_width)
|
35
|
+
options.delete(:height) if height && (height.to_f < 1 || no_html_sizes || responsive_width)
|
33
36
|
|
34
|
-
width=height=nil if crop.nil? && !has_layer
|
37
|
+
width=height=nil if crop.nil? && !has_layer && width != "auto"
|
35
38
|
|
36
39
|
background = options.delete(:background)
|
37
40
|
background = background.sub(/^#/, 'rgb:') if background
|
@@ -61,8 +64,9 @@ class Cloudinary::Utils
|
|
61
64
|
border = nil
|
62
65
|
end
|
63
66
|
flags = build_array(options.delete(:flags)).join(".")
|
67
|
+
dpr = config_option_consume(options, :dpr)
|
64
68
|
|
65
|
-
params = {:w=>width, :h=>height, :t=>named_transformation, :c=>crop, :b=>background, :e=>effect, :a=>angle, :bo=>border, :fl=>flags, :co=>color}
|
69
|
+
params = {:w=>width, :h=>height, :t=>named_transformation, :c=>crop, :b=>background, :e=>effect, :a=>angle, :bo=>border, :fl=>flags, :co=>color, :dpr=>dpr}
|
66
70
|
{ :x=>:x, :y=>:y, :r=>:radius, :d=>:default_image, :g=>:gravity, :q=>:quality, :cs=>:color_space, :o=>:opacity,
|
67
71
|
:p=>:prefix, :l=>:overlay, :u=>:underlay, :f=>:fetch_format, :dn=>:density, :pg=>:page, :dl=>:delay
|
68
72
|
}.each do
|
@@ -73,7 +77,20 @@ class Cloudinary::Utils
|
|
73
77
|
transformation = params.reject{|k,v| v.blank?}.map{|k,v| [k.to_s, v]}.sort_by(&:first).map{|k,v| "#{k}_#{v}"}.join(",")
|
74
78
|
raw_transformation = options.delete(:raw_transformation)
|
75
79
|
transformation = [transformation, raw_transformation].reject(&:blank?).join(",")
|
76
|
-
|
80
|
+
transformations = base_transformations << transformation
|
81
|
+
if responsive_width
|
82
|
+
responsive_width_transformation = Cloudinary.config.responsive_width_transformation || DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION
|
83
|
+
transformations << generate_transformation_string(responsive_width_transformation.clone)
|
84
|
+
end
|
85
|
+
|
86
|
+
if width.to_s == "auto" || responsive_width
|
87
|
+
options[:responsive] = true
|
88
|
+
end
|
89
|
+
if dpr.to_s == "auto"
|
90
|
+
options[:hidpi] = true
|
91
|
+
end
|
92
|
+
|
93
|
+
transformations.reject(&:blank?).join("/")
|
77
94
|
end
|
78
95
|
|
79
96
|
def self.api_string_to_sign(params_to_sign)
|
data/lib/cloudinary/version.rb
CHANGED
data/spec/api_spec.rb
CHANGED
@@ -5,11 +5,12 @@ describe Cloudinary::Api do
|
|
5
5
|
break puts("Please setup environment for api test to run") if Cloudinary.config.api_secret.blank?
|
6
6
|
|
7
7
|
before(:all) do
|
8
|
+
@timestamp_tag = "api_test_tag_#{Time.now.to_i}"
|
8
9
|
@api = Cloudinary::Api
|
9
10
|
Cloudinary::Uploader.destroy("api_test")
|
10
11
|
Cloudinary::Uploader.destroy("api_test2")
|
11
|
-
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test", :tags=>"api_test_tag", :context => "key=value", :eager=>[:width=>100,:crop=>:scale])
|
12
|
-
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test2", :tags=>"api_test_tag", :context => "key=value", :eager=>[:width=>100,:crop=>:scale])
|
12
|
+
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test", :tags=> ["api_test_tag", @timestamp_tag], :context => "key=value", :eager=>[:width=>100,:crop=>:scale])
|
13
|
+
Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test2", :tags=> ["api_test_tag", @timestamp_tag], :context => "key=value", :eager=>[:width=>100,:crop=>:scale])
|
13
14
|
@api.delete_transformation("api_test_transformation") rescue nil
|
14
15
|
@api.delete_transformation("api_test_transformation2") rescue nil
|
15
16
|
@api.delete_transformation("api_test_transformation3") rescue nil
|
@@ -44,20 +45,20 @@ describe Cloudinary::Api do
|
|
44
45
|
it "should allow listing resources by type" do
|
45
46
|
resource = @api.resources(:type=>"upload", :tags=>true)["resources"].find{|resource| resource["public_id"] == "api_test"}
|
46
47
|
resource.should_not be_blank
|
47
|
-
resource["tags"].should == ["api_test_tag"]
|
48
|
+
resource["tags"].should == ["api_test_tag", @timestamp_tag]
|
48
49
|
end
|
49
50
|
|
50
51
|
it "should allow listing resources by prefix" do
|
51
52
|
resources = @api.resources(:type=>"upload", :prefix=>"api_test", :tags => true, :context => true)["resources"]
|
52
53
|
resources.map{|resource| resource["public_id"]}.should include("api_test", "api_test2")
|
53
|
-
resources.map{|resource| resource["tags"]}.should include(["api_test_tag"])
|
54
|
+
resources.map{|resource| resource["tags"]}.should include(["api_test_tag", @timestamp_tag])
|
54
55
|
resources.map{|resource| resource["context"]}.should include({"custom" => {"key" => "value"}})
|
55
56
|
end
|
56
57
|
|
57
58
|
it "should allow listing resources by tag" do
|
58
59
|
resources = @api.resources_by_tag("api_test_tag", :tags => true, :context => true)["resources"]
|
59
60
|
resources.find{|resource| resource["public_id"] == "api_test"}.should_not be_blank
|
60
|
-
resources.map{|resource| resource["tags"]}.should include(["api_test_tag"])
|
61
|
+
resources.map{|resource| resource["tags"]}.should include(["api_test_tag", @timestamp_tag])
|
61
62
|
resources.map{|resource| resource["context"]}.should include({"custom" => {"key" => "value"}})
|
62
63
|
end
|
63
64
|
|
@@ -65,7 +66,7 @@ describe Cloudinary::Api do
|
|
65
66
|
resources = @api.resources_by_ids(["api_test", "api_test2"], :tags => true, :context => true)["resources"]
|
66
67
|
resources.length.should == 2
|
67
68
|
resources.find{|resource| resource["public_id"] == "api_test"}.should_not be_blank
|
68
|
-
resources.map{|resource| resource["tags"]}.should include(["api_test_tag"])
|
69
|
+
resources.map{|resource| resource["tags"]}.should include(["api_test_tag", @timestamp_tag])
|
69
70
|
resources.map{|resource| resource["context"]}.should include({"custom" => {"key" => "value"}})
|
70
71
|
end
|
71
72
|
|
@@ -79,16 +80,16 @@ describe Cloudinary::Api do
|
|
79
80
|
end
|
80
81
|
|
81
82
|
it "should allow listing resources in both directions" do
|
82
|
-
asc_resources = @api.
|
83
|
-
desc_resources = @api.
|
83
|
+
asc_resources = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => "asc")["resources"]
|
84
|
+
desc_resources = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => "desc")["resources"]
|
84
85
|
# NOTE: this assumes the full list fits in a page which is the case unless resources with 'api_test' prefix were
|
85
86
|
# uploaded to the account against which this test runs
|
86
87
|
asc_resources.reverse.should == desc_resources
|
87
|
-
asc_resources_alt = @api.
|
88
|
-
desc_resources_alt = @api.
|
88
|
+
asc_resources_alt = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => 1)["resources"]
|
89
|
+
desc_resources_alt = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => -1)["resources"]
|
89
90
|
asc_resources_alt.reverse.should == desc_resources_alt
|
90
91
|
asc_resources.should == asc_resources_alt
|
91
|
-
lambda{@api.
|
92
|
+
lambda{@api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => "anythingelse")["resources"]}.should raise_error(Cloudinary::Api::BadRequest)
|
92
93
|
end
|
93
94
|
|
94
95
|
it "should allow get resource metadata" do
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cloudinary'
|
3
|
+
require 'action_view'
|
4
|
+
require 'cloudinary/helper'
|
5
|
+
|
6
|
+
helper_class = Class.new do
|
7
|
+
include CloudinaryHelper
|
8
|
+
end
|
9
|
+
|
10
|
+
describe CloudinaryHelper do
|
11
|
+
let(:helper) { helper_class.new }
|
12
|
+
|
13
|
+
|
14
|
+
context "#cl_image_upload_tag" do
|
15
|
+
let(:options) { {} }
|
16
|
+
subject(:input) { helper.cl_image_upload_tag(:image_id, options) }
|
17
|
+
|
18
|
+
before do
|
19
|
+
Cloudinary::Utils.stub(:cloudinary_api_url)
|
20
|
+
Cloudinary::Utils.stub(:sign_request)
|
21
|
+
helper.stub(:build_callback_url)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allow multiple upload" do
|
25
|
+
options[:multiple] = true
|
26
|
+
expect(input).to include('data-cloudinary-field="image_id[]"')
|
27
|
+
expect(input).to include('multiple="multiple"')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "#cl_image_tag" do
|
32
|
+
subject(:input) { helper.cl_image_tag("sample.jpg", options) }
|
33
|
+
|
34
|
+
context "responsive_width" do
|
35
|
+
let(:options) { {responsive_width: true, cloud_name: "test"} }
|
36
|
+
it "should use data-src for responsive_width" do
|
37
|
+
expect(input).to eq("<img class=\"cld-responsive\" data-src=\"http://res.cloudinary.com/test/image/upload/c_limit,w_auto/sample.jpg\"></img>")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "dpr_auto" do
|
42
|
+
let(:options) { {dpr: :auto, cloud_name: "test"} }
|
43
|
+
it "should use data-src for dpr auto" do
|
44
|
+
expect(input).to eq("<img class=\"cld-hidpi\" data-src=\"http://res.cloudinary.com/test/image/upload/dpr_auto/sample.jpg\"></img>")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/uploader_spec.rb
CHANGED
@@ -135,10 +135,23 @@ describe Cloudinary::Uploader do
|
|
135
135
|
result["public_id"].should match(/^[a-z0-9]+.png$/)
|
136
136
|
end
|
137
137
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
138
|
+
context "unsigned" do
|
139
|
+
after do
|
140
|
+
Cloudinary.class_variable_set(:@@config, nil)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should support unsigned uploading using presets", :upload_preset => true do
|
144
|
+
preset = Cloudinary::Api.create_upload_preset(:folder => "upload_folder", :unsigned => true)
|
145
|
+
|
146
|
+
Cloudinary.config.api_key = nil
|
147
|
+
Cloudinary.config.api_secret = nil
|
148
|
+
|
149
|
+
result = Cloudinary::Uploader.unsigned_upload("spec/logo.png", preset["name"])
|
150
|
+
result["public_id"].should match(/^upload_folder\/[a-z0-9]+$/)
|
151
|
+
|
152
|
+
Cloudinary.class_variable_set(:@@config, nil)
|
153
|
+
|
154
|
+
Cloudinary::Api.delete_upload_preset(preset["name"])
|
155
|
+
end
|
143
156
|
end
|
144
157
|
end
|
data/spec/utils_spec.rb
CHANGED
@@ -465,4 +465,16 @@ describe Cloudinary::Utils do
|
|
465
465
|
params = Cloudinary::Utils.sign_request({:public_id=>"folder/file", :version=>"1234"})
|
466
466
|
params.should == {:public_id=>"folder/file", :version=>"1234", :signature=>"7a3349cbb373e4812118d625047ede50b90e7b67", :api_key=>"1234"}
|
467
467
|
end
|
468
|
+
|
469
|
+
it "should support responsive width" do
|
470
|
+
options = {:width=>100, :height=>100, :crop=>:crop, :responsive_width=>true}
|
471
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
472
|
+
options.should == {responsive: true}
|
473
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/c_crop,h_100,w_100/c_limit,w_auto/test"
|
474
|
+
Cloudinary.config.responsive_width_transformation = {width: :auto, crop: :pad}
|
475
|
+
options = {:width=>100, :height=>100, :crop=>:crop, :responsive_width=>true}
|
476
|
+
result = Cloudinary::Utils.cloudinary_url("test", options)
|
477
|
+
options.should == {responsive: true}
|
478
|
+
result.should == "http://res.cloudinary.com/test123/image/upload/c_crop,h_100,w_100/c_pad,w_auto/test"
|
479
|
+
end
|
468
480
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.73
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Nadav Soferman
|
@@ -11,12 +10,11 @@ authors:
|
|
11
10
|
autorequire:
|
12
11
|
bindir: bin
|
13
12
|
cert_chain: []
|
14
|
-
date: 2014-
|
13
|
+
date: 2014-06-30 00:00:00.000000000 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: rest-client
|
18
17
|
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
18
|
requirements:
|
21
19
|
- - ! '>='
|
22
20
|
- !ruby/object:Gem::Version
|
@@ -24,7 +22,6 @@ dependencies:
|
|
24
22
|
type: :runtime
|
25
23
|
prerelease: false
|
26
24
|
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
none: false
|
28
25
|
requirements:
|
29
26
|
- - ! '>='
|
30
27
|
- !ruby/object:Gem::Version
|
@@ -32,7 +29,6 @@ dependencies:
|
|
32
29
|
- !ruby/object:Gem::Dependency
|
33
30
|
name: aws_cf_signer
|
34
31
|
requirement: !ruby/object:Gem::Requirement
|
35
|
-
none: false
|
36
32
|
requirements:
|
37
33
|
- - ! '>='
|
38
34
|
- !ruby/object:Gem::Version
|
@@ -40,7 +36,6 @@ dependencies:
|
|
40
36
|
type: :runtime
|
41
37
|
prerelease: false
|
42
38
|
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
39
|
requirements:
|
45
40
|
- - ! '>='
|
46
41
|
- !ruby/object:Gem::Version
|
@@ -48,7 +43,6 @@ dependencies:
|
|
48
43
|
- !ruby/object:Gem::Dependency
|
49
44
|
name: rspec
|
50
45
|
requirement: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
46
|
requirements:
|
53
47
|
- - ! '>='
|
54
48
|
- !ruby/object:Gem::Version
|
@@ -56,7 +50,20 @@ dependencies:
|
|
56
50
|
type: :development
|
57
51
|
prerelease: false
|
58
52
|
version_requirements: !ruby/object:Gem::Requirement
|
59
|
-
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: actionpack
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
67
|
requirements:
|
61
68
|
- - ! '>='
|
62
69
|
- !ruby/object:Gem::Version
|
@@ -101,12 +108,14 @@ files:
|
|
101
108
|
- lib/cloudinary/version.rb
|
102
109
|
- lib/tasks/cloudinary.rake
|
103
110
|
- spec/api_spec.rb
|
111
|
+
- spec/cloudinary_helper_spec.rb
|
104
112
|
- spec/docx.docx
|
105
113
|
- spec/favicon.ico
|
106
114
|
- spec/logo.png
|
107
115
|
- spec/spec_helper.rb
|
108
116
|
- spec/uploader_spec.rb
|
109
117
|
- spec/utils_spec.rb
|
118
|
+
- vendor/assets/html/cloudinary_cors.html
|
110
119
|
- vendor/assets/javascripts/cloudinary/canvas-to-blob.min.js
|
111
120
|
- vendor/assets/javascripts/cloudinary/index.js
|
112
121
|
- vendor/assets/javascripts/cloudinary/jquery.cloudinary.js
|
@@ -118,34 +127,33 @@ files:
|
|
118
127
|
- vendor/assets/javascripts/cloudinary/jquery.ui.widget.js
|
119
128
|
- vendor/assets/javascripts/cloudinary/load-image.min.js
|
120
129
|
- vendor/assets/javascripts/cloudinary/processing.js
|
121
|
-
- vendor/assets/html/cloudinary_cors.html
|
122
130
|
homepage: http://cloudinary.com
|
123
131
|
licenses:
|
124
132
|
- MIT
|
133
|
+
metadata: {}
|
125
134
|
post_install_message:
|
126
135
|
rdoc_options: []
|
127
136
|
require_paths:
|
128
137
|
- lib
|
129
138
|
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
139
|
requirements:
|
132
140
|
- - ! '>='
|
133
141
|
- !ruby/object:Gem::Version
|
134
142
|
version: '0'
|
135
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
-
none: false
|
137
144
|
requirements:
|
138
145
|
- - ! '>='
|
139
146
|
- !ruby/object:Gem::Version
|
140
147
|
version: '0'
|
141
148
|
requirements: []
|
142
149
|
rubyforge_project: cloudinary
|
143
|
-
rubygems_version:
|
150
|
+
rubygems_version: 2.2.2
|
144
151
|
signing_key:
|
145
|
-
specification_version:
|
152
|
+
specification_version: 4
|
146
153
|
summary: Client library for easily using the Cloudinary service
|
147
154
|
test_files:
|
148
155
|
- spec/api_spec.rb
|
156
|
+
- spec/cloudinary_helper_spec.rb
|
149
157
|
- spec/docx.docx
|
150
158
|
- spec/favicon.ico
|
151
159
|
- spec/logo.png
|