cloudinary 1.0.69 → 1.0.70
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/CHANGELOG +7 -0
- data/lib/cloudinary/carrier_wave/storage.rb +1 -1
- data/lib/cloudinary/uploader.rb +256 -245
- data/lib/cloudinary/version.rb +1 -1
- data/spec/uploader_spec.rb +5 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
= Version 1.0.70 - 2014-03-25
|
2
|
+
* Support upload_large without public_id.
|
3
|
+
* Remove public_id from method parameters.
|
4
|
+
* Backward compatibility for old upload_large API.
|
5
|
+
* Issue #95 - exception when using storage_type :private
|
6
|
+
* Updating to jQuery plugin v1.0.13.
|
7
|
+
|
1
8
|
= Version 1.0.69 - 2014-02-25
|
2
9
|
* Admin API update method.
|
3
10
|
* Admin API listing by moderation kind and status.
|
@@ -6,7 +6,7 @@ class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
|
|
6
6
|
case file
|
7
7
|
when Cloudinary::CarrierWave::PreloadedCloudinaryFile
|
8
8
|
storage_type = uploader.class.storage_type || "upload"
|
9
|
-
raise CloudinaryException, "Uploader configured for type #{storage_type} but resource of type #{file.type} given." if storage_type != file.type
|
9
|
+
raise CloudinaryException, "Uploader configured for type #{storage_type} but resource of type #{file.type} given." if storage_type.to_s != file.type
|
10
10
|
if uploader.public_id && uploader.auto_rename_preloaded?
|
11
11
|
@stored_version = file.version
|
12
12
|
uploader.rename(nil, true)
|
data/lib/cloudinary/uploader.rb
CHANGED
@@ -1,82 +1,93 @@
|
|
1
|
-
# Copyright Cloudinary
|
2
|
-
require 'rest_client'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
class Cloudinary::Uploader
|
6
|
-
|
7
|
-
def self.build_eager(eager)
|
8
|
-
return nil if eager.nil?
|
9
|
-
Cloudinary::Utils.build_array(eager).map do
|
10
|
-
|transformation, format|
|
11
|
-
transformation = transformation.clone
|
12
|
-
format = transformation.delete(:format) || format
|
13
|
-
[Cloudinary::Utils.generate_transformation_string(transformation), format].compact.join("/")
|
14
|
-
end.join("|")
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.build_upload_params(options)
|
18
|
-
params = {:timestamp=>Time.now.to_i,
|
19
|
-
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone),
|
20
|
-
:public_id=> options[:public_id],
|
21
|
-
:callback=> options[:callback],
|
22
|
-
:format=>options[:format],
|
23
|
-
:type=>options[:type],
|
24
|
-
:backup=>Cloudinary::Utils.as_safe_bool(options[:backup]),
|
25
|
-
:faces=>Cloudinary::Utils.as_safe_bool(options[:faces]),
|
26
|
-
:exif=>Cloudinary::Utils.as_safe_bool(options[:exif]),
|
27
|
-
:colors=>Cloudinary::Utils.as_safe_bool(options[:colors]),
|
28
|
-
:image_metadata=>Cloudinary::Utils.as_safe_bool(options[:image_metadata]),
|
29
|
-
:invalidate=>Cloudinary::Utils.as_safe_bool(options[:invalidate]),
|
30
|
-
:eager=>build_eager(options[:eager]),
|
31
|
-
:headers=>build_custom_headers(options[:headers]),
|
32
|
-
:use_filename=>Cloudinary::Utils.as_safe_bool(options[:use_filename]),
|
33
|
-
:unique_filename=>Cloudinary::Utils.as_safe_bool(options[:unique_filename]),
|
34
|
-
:overwrite=>Cloudinary::Utils.as_safe_bool(options[:overwrite]),
|
35
|
-
:discard_original_filename=>Cloudinary::Utils.as_safe_bool(options[:discard_original_filename]),
|
36
|
-
:notification_url=>options[:notification_url],
|
37
|
-
:eager_notification_url=>options[:eager_notification_url],
|
38
|
-
:eager_async=>Cloudinary::Utils.as_safe_bool(options[:eager_async]),
|
39
|
-
:proxy=>options[:proxy],
|
40
|
-
:folder=>options[:folder],
|
1
|
+
# Copyright Cloudinary
|
2
|
+
require 'rest_client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Cloudinary::Uploader
|
6
|
+
|
7
|
+
def self.build_eager(eager)
|
8
|
+
return nil if eager.nil?
|
9
|
+
Cloudinary::Utils.build_array(eager).map do
|
10
|
+
|transformation, format|
|
11
|
+
transformation = transformation.clone
|
12
|
+
format = transformation.delete(:format) || format
|
13
|
+
[Cloudinary::Utils.generate_transformation_string(transformation), format].compact.join("/")
|
14
|
+
end.join("|")
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.build_upload_params(options)
|
18
|
+
params = {:timestamp=>Time.now.to_i,
|
19
|
+
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone),
|
20
|
+
:public_id=> options[:public_id],
|
21
|
+
:callback=> options[:callback],
|
22
|
+
:format=>options[:format],
|
23
|
+
:type=>options[:type],
|
24
|
+
:backup=>Cloudinary::Utils.as_safe_bool(options[:backup]),
|
25
|
+
:faces=>Cloudinary::Utils.as_safe_bool(options[:faces]),
|
26
|
+
:exif=>Cloudinary::Utils.as_safe_bool(options[:exif]),
|
27
|
+
:colors=>Cloudinary::Utils.as_safe_bool(options[:colors]),
|
28
|
+
:image_metadata=>Cloudinary::Utils.as_safe_bool(options[:image_metadata]),
|
29
|
+
:invalidate=>Cloudinary::Utils.as_safe_bool(options[:invalidate]),
|
30
|
+
:eager=>build_eager(options[:eager]),
|
31
|
+
:headers=>build_custom_headers(options[:headers]),
|
32
|
+
:use_filename=>Cloudinary::Utils.as_safe_bool(options[:use_filename]),
|
33
|
+
:unique_filename=>Cloudinary::Utils.as_safe_bool(options[:unique_filename]),
|
34
|
+
:overwrite=>Cloudinary::Utils.as_safe_bool(options[:overwrite]),
|
35
|
+
:discard_original_filename=>Cloudinary::Utils.as_safe_bool(options[:discard_original_filename]),
|
36
|
+
:notification_url=>options[:notification_url],
|
37
|
+
:eager_notification_url=>options[:eager_notification_url],
|
38
|
+
:eager_async=>Cloudinary::Utils.as_safe_bool(options[:eager_async]),
|
39
|
+
:proxy=>options[:proxy],
|
40
|
+
:folder=>options[:folder],
|
41
41
|
:allowed_formats => Cloudinary::Utils.build_array(options[:allowed_formats]).join(","),
|
42
|
-
:tags=>options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
|
43
|
-
:context => Cloudinary::Utils.encode_hash(options[:context]),
|
44
|
-
:face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
|
45
|
-
:moderation => options[:moderation],
|
46
|
-
:raw_convert => options[:raw_convert],
|
47
|
-
:ocr => options[:ocr],
|
48
|
-
:categorization => options[:categorization],
|
42
|
+
:tags=>options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
|
43
|
+
:context => Cloudinary::Utils.encode_hash(options[:context]),
|
44
|
+
:face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
|
45
|
+
:moderation => options[:moderation],
|
46
|
+
:raw_convert => options[:raw_convert],
|
47
|
+
:ocr => options[:ocr],
|
48
|
+
:categorization => options[:categorization],
|
49
49
|
:detection => options[:detection],
|
50
50
|
:similarity_search => options[:similarity_search],
|
51
|
-
:auto_tagging => options[:auto_tagging] && options[:auto_tagging].to_f}
|
52
|
-
params
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.upload(file, options={})
|
56
|
-
call_api("upload", options) do
|
57
|
-
params = build_upload_params(options)
|
58
|
-
if file.is_a?(Pathname)
|
59
|
-
params[:file] = File.open(file, "rb")
|
60
|
-
elsif file.respond_to?(:read) || file =~ /^https?:|^s3:|^data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$/
|
61
|
-
params[:file] = file
|
62
|
-
else
|
63
|
-
params[:file] = File.open(file, "rb")
|
64
|
-
end
|
65
|
-
[params, [:file]]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
51
|
+
:auto_tagging => options[:auto_tagging] && options[:auto_tagging].to_f}
|
52
|
+
params
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.upload(file, options={})
|
56
|
+
call_api("upload", options) do
|
57
|
+
params = build_upload_params(options)
|
58
|
+
if file.is_a?(Pathname)
|
59
|
+
params[:file] = File.open(file, "rb")
|
60
|
+
elsif file.respond_to?(:read) || file =~ /^https?:|^s3:|^data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$/
|
61
|
+
params[:file] = file
|
62
|
+
else
|
63
|
+
params[:file] = File.open(file, "rb")
|
64
|
+
end
|
65
|
+
[params, [:file]]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
69
|
# Upload large raw files. Note that public_id should include an extension for best results.
|
70
|
-
def self.upload_large(file,
|
70
|
+
def self.upload_large(file, public_id_or_options={}, old_options={})
|
71
|
+
if public_id_or_options.is_a?(Hash)
|
72
|
+
options = public_id_or_options
|
73
|
+
public_id = options[:public_id]
|
74
|
+
else
|
75
|
+
public_id = public_id_or_options
|
76
|
+
options = old_options
|
77
|
+
end
|
71
78
|
if file.is_a?(Pathname) || !file.respond_to?(:read)
|
79
|
+
filename = file
|
72
80
|
file = File.open(file, "rb")
|
81
|
+
else
|
82
|
+
filename = "cloudinaryfile"
|
73
83
|
end
|
74
84
|
upload = upload_id = nil
|
75
85
|
index = 1
|
76
86
|
while !file.eof?
|
77
87
|
buffer = file.read(20_000_000)
|
78
|
-
upload = upload_large_part(Cloudinary::Blob.new(buffer
|
79
|
-
upload_id = upload["upload_id"]
|
88
|
+
upload = upload_large_part(Cloudinary::Blob.new(buffer, :original_filename=>filename), options.merge(:public_id=>public_id, :upload_id=>upload_id, :part_number=>index, :final=>file.eof?))
|
89
|
+
upload_id = upload["upload_id"]
|
90
|
+
public_id = upload["public_id"]
|
80
91
|
index += 1
|
81
92
|
end
|
82
93
|
upload
|
@@ -84,12 +95,12 @@ class Cloudinary::Uploader
|
|
84
95
|
|
85
96
|
|
86
97
|
# Upload large raw files. Note that public_id should include an extension for best results.
|
87
|
-
def self.upload_large_part(file,
|
98
|
+
def self.upload_large_part(file, options={})
|
88
99
|
call_api("upload_large", options.merge(:resource_type=>:raw)) do
|
89
100
|
params = {
|
90
101
|
:timestamp=>Time.now.to_i,
|
91
102
|
:type=>options[:type],
|
92
|
-
:public_id=>
|
103
|
+
:public_id=>options[:public_id],
|
93
104
|
:backup=>options[:backup],
|
94
105
|
:final=>options[:final],
|
95
106
|
:part_number=>options[:part_number],
|
@@ -103,179 +114,179 @@ class Cloudinary::Uploader
|
|
103
114
|
[params, [:file]]
|
104
115
|
end
|
105
116
|
end
|
117
|
+
|
118
|
+
def self.destroy(public_id, options={})
|
119
|
+
call_api("destroy", options) do
|
120
|
+
{
|
121
|
+
:timestamp=>Time.now.to_i,
|
122
|
+
:type=>options[:type],
|
123
|
+
:public_id=> public_id,
|
124
|
+
:invalidate=>options[:invalidate],
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.rename(from_public_id, to_public_id, options={})
|
130
|
+
call_api("rename", options) do
|
131
|
+
{
|
132
|
+
:timestamp=>Time.now.to_i,
|
133
|
+
:type=>options[:type],
|
134
|
+
:overwrite=>options[:overwrite],
|
135
|
+
:from_public_id=>from_public_id,
|
136
|
+
:to_public_id=>to_public_id,
|
137
|
+
}
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.exists?(public_id, options={})
|
142
|
+
cloudinary_url = Cloudinary::Utils.cloudinary_url(public_id, options)
|
143
|
+
begin
|
144
|
+
RestClient::Request.execute(:method => :head, :url => cloudinary_url, :timeout=>5).code.to_s =~ /2\d{2}/
|
145
|
+
rescue RestClient::ResourceNotFound => e
|
146
|
+
return false
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.explicit(public_id, options={})
|
152
|
+
call_api("explicit", options) do
|
153
|
+
{
|
154
|
+
:timestamp=>Time.now.to_i,
|
155
|
+
:type=>options[:type],
|
156
|
+
:public_id=> public_id,
|
157
|
+
:callback=> options[:callback],
|
158
|
+
:eager=>build_eager(options[:eager]),
|
159
|
+
:headers=>build_custom_headers(options[:headers]),
|
160
|
+
:tags=>options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
|
161
|
+
:face_coordinates => options[:face_coordinates] && Cloudinary::Utils.encode_double_array(options[:face_coordinates])
|
162
|
+
}
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
TEXT_PARAMS = [:public_id, :font_family, :font_size, :font_color, :text_align, :font_weight, :font_style, :background, :opacity, :text_decoration, :line_spacing]
|
167
|
+
def self.text(text, options={})
|
168
|
+
call_api("text", options) do
|
169
|
+
params = {:timestamp => Time.now.to_i, :text=>text}
|
170
|
+
TEXT_PARAMS.each{|k| params[k] = options[k] if !options[k].nil?}
|
171
|
+
params
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.generate_sprite(tag, options={})
|
176
|
+
version_store = options.delete(:version_store)
|
177
|
+
|
178
|
+
result = call_api("sprite", options) do
|
179
|
+
{
|
180
|
+
:timestamp=>Time.now.to_i,
|
181
|
+
:tag=>tag,
|
182
|
+
:async=>options[:async],
|
183
|
+
:notification_url=>options[:notification_url],
|
184
|
+
:transformation => Cloudinary::Utils.generate_transformation_string(options.merge(:fetch_format=>options[:format]))
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
if version_store == :file && result && result["version"]
|
189
|
+
if defined?(Rails) && defined?(Rails.root)
|
190
|
+
FileUtils.mkdir_p("#{Rails.root}/tmp/cloudinary")
|
191
|
+
File.open("#{Rails.root}/tmp/cloudinary/cloudinary_sprite_#{tag}.version", "w"){|file| file.print result["version"].to_s}
|
192
|
+
end
|
193
|
+
end
|
194
|
+
return result
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.multi(tag, options={})
|
198
|
+
call_api("multi", options) do
|
199
|
+
{
|
200
|
+
:timestamp=>Time.now.to_i,
|
201
|
+
:tag=>tag,
|
202
|
+
:format=>options[:format],
|
203
|
+
:async=>options[:async],
|
204
|
+
:notification_url=>options[:notification_url],
|
205
|
+
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone)
|
206
|
+
}
|
207
|
+
end
|
208
|
+
end
|
106
209
|
|
107
|
-
def self.
|
108
|
-
call_api("
|
109
|
-
{
|
110
|
-
:timestamp=>Time.now.to_i,
|
111
|
-
:
|
112
|
-
:
|
113
|
-
:
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
:
|
144
|
-
:type=>options[:type]
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
end
|
185
|
-
|
186
|
-
def self.
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
:tag=>tag,
|
191
|
-
:format=>options[:format],
|
192
|
-
:async=>options[:async],
|
193
|
-
:notification_url=>options[:notification_url],
|
194
|
-
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone)
|
195
|
-
}
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def self.explode(public_id, options={})
|
200
|
-
call_api("explode", options) do
|
201
|
-
{
|
202
|
-
:timestamp=>Time.now.to_i,
|
203
|
-
:public_id=>public_id,
|
204
|
-
:type=>options[:type],
|
205
|
-
:format=>options[:format],
|
206
|
-
:notification_url=>options[:notification_url],
|
207
|
-
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone)
|
208
|
-
}
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
# options may include 'exclusive' (boolean) which causes clearing this tag from all other resources
|
213
|
-
def self.add_tag(tag, public_ids = [], options = {})
|
214
|
-
exclusive = options.delete(:exclusive)
|
215
|
-
command = exclusive ? "set_exclusive" : "add"
|
216
|
-
return self.call_tags_api(tag, command, public_ids, options)
|
217
|
-
end
|
218
|
-
|
219
|
-
def self.remove_tag(tag, public_ids = [], options = {})
|
220
|
-
return self.call_tags_api(tag, "remove", public_ids, options)
|
221
|
-
end
|
222
|
-
|
223
|
-
def self.replace_tag(tag, public_ids = [], options = {})
|
224
|
-
return self.call_tags_api(tag, "replace", public_ids, options)
|
225
|
-
end
|
226
|
-
|
227
|
-
private
|
228
|
-
|
229
|
-
def self.call_tags_api(tag, command, public_ids = [], options = {})
|
230
|
-
return call_api("tags", options) do
|
231
|
-
{
|
232
|
-
:timestamp=>Time.now.to_i,
|
233
|
-
:tag=>tag,
|
234
|
-
:public_ids => Cloudinary::Utils.build_array(public_ids),
|
235
|
-
:command => command,
|
236
|
-
:type => options[:type]
|
237
|
-
}
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
def self.call_api(action, options)
|
242
|
-
options = options.clone
|
243
|
-
return_error = options.delete(:return_error)
|
244
|
-
api_key = options[:api_key] || Cloudinary.config.api_key || raise(CloudinaryException, "Must supply api_key")
|
245
|
-
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise(CloudinaryException, "Must supply api_secret")
|
246
|
-
|
247
|
-
params, non_signable = yield
|
248
|
-
non_signable ||= []
|
249
|
-
|
250
|
-
params[:signature] = Cloudinary::Utils.api_sign_request(params.reject{|k,v| non_signable.include?(k)}, api_secret)
|
251
|
-
params[:api_key] = api_key
|
252
|
-
|
253
|
-
result = nil
|
254
|
-
|
255
|
-
api_url = Cloudinary::Utils.cloudinary_api_url(action, options)
|
256
|
-
|
257
|
-
RestClient::Request.execute(:method => :post, :url => api_url, :payload => params.reject{|k, v| v.nil? || v==""}, :timeout=>60, :headers => {"User-Agent" => Cloudinary::USER_AGENT}) do
|
258
|
-
|response, request, tmpresult|
|
259
|
-
raise CloudinaryException, "Server returned unexpected status code - #{response.code} - #{response.body}" if ![200,400,401,403,404,500].include?(response.code)
|
260
|
-
begin
|
261
|
-
result = Cloudinary::Utils.json_decode(response.body)
|
262
|
-
rescue => e
|
263
|
-
# Error is parsing json
|
264
|
-
raise CloudinaryException, "Error parsing server response (#{response.code}) - #{response.body}. Got - #{e}"
|
265
|
-
end
|
266
|
-
if result["error"]
|
267
|
-
if return_error
|
268
|
-
result["error"]["http_code"] = response.code
|
269
|
-
else
|
270
|
-
raise CloudinaryException, result["error"]["message"]
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
result
|
276
|
-
end
|
277
|
-
|
278
|
-
def self.build_custom_headers(headers)
|
279
|
-
Array(headers).map{|*a| a.join(": ")}.join("\n")
|
280
|
-
end
|
281
|
-
end
|
210
|
+
def self.explode(public_id, options={})
|
211
|
+
call_api("explode", options) do
|
212
|
+
{
|
213
|
+
:timestamp=>Time.now.to_i,
|
214
|
+
:public_id=>public_id,
|
215
|
+
:type=>options[:type],
|
216
|
+
:format=>options[:format],
|
217
|
+
:notification_url=>options[:notification_url],
|
218
|
+
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone)
|
219
|
+
}
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# options may include 'exclusive' (boolean) which causes clearing this tag from all other resources
|
224
|
+
def self.add_tag(tag, public_ids = [], options = {})
|
225
|
+
exclusive = options.delete(:exclusive)
|
226
|
+
command = exclusive ? "set_exclusive" : "add"
|
227
|
+
return self.call_tags_api(tag, command, public_ids, options)
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.remove_tag(tag, public_ids = [], options = {})
|
231
|
+
return self.call_tags_api(tag, "remove", public_ids, options)
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.replace_tag(tag, public_ids = [], options = {})
|
235
|
+
return self.call_tags_api(tag, "replace", public_ids, options)
|
236
|
+
end
|
237
|
+
|
238
|
+
private
|
239
|
+
|
240
|
+
def self.call_tags_api(tag, command, public_ids = [], options = {})
|
241
|
+
return call_api("tags", options) do
|
242
|
+
{
|
243
|
+
:timestamp=>Time.now.to_i,
|
244
|
+
:tag=>tag,
|
245
|
+
:public_ids => Cloudinary::Utils.build_array(public_ids),
|
246
|
+
:command => command,
|
247
|
+
:type => options[:type]
|
248
|
+
}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def self.call_api(action, options)
|
253
|
+
options = options.clone
|
254
|
+
return_error = options.delete(:return_error)
|
255
|
+
api_key = options[:api_key] || Cloudinary.config.api_key || raise(CloudinaryException, "Must supply api_key")
|
256
|
+
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise(CloudinaryException, "Must supply api_secret")
|
257
|
+
|
258
|
+
params, non_signable = yield
|
259
|
+
non_signable ||= []
|
260
|
+
|
261
|
+
params[:signature] = Cloudinary::Utils.api_sign_request(params.reject{|k,v| non_signable.include?(k)}, api_secret)
|
262
|
+
params[:api_key] = api_key
|
263
|
+
|
264
|
+
result = nil
|
265
|
+
|
266
|
+
api_url = Cloudinary::Utils.cloudinary_api_url(action, options)
|
267
|
+
|
268
|
+
RestClient::Request.execute(:method => :post, :url => api_url, :payload => params.reject{|k, v| v.nil? || v==""}, :timeout=>60, :headers => {"User-Agent" => Cloudinary::USER_AGENT}) do
|
269
|
+
|response, request, tmpresult|
|
270
|
+
raise CloudinaryException, "Server returned unexpected status code - #{response.code} - #{response.body}" if ![200,400,401,403,404,500].include?(response.code)
|
271
|
+
begin
|
272
|
+
result = Cloudinary::Utils.json_decode(response.body)
|
273
|
+
rescue => e
|
274
|
+
# Error is parsing json
|
275
|
+
raise CloudinaryException, "Error parsing server response (#{response.code}) - #{response.body}. Got - #{e}"
|
276
|
+
end
|
277
|
+
if result["error"]
|
278
|
+
if return_error
|
279
|
+
result["error"]["http_code"] = response.code
|
280
|
+
else
|
281
|
+
raise CloudinaryException, result["error"]["message"]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
result
|
287
|
+
end
|
288
|
+
|
289
|
+
def self.build_custom_headers(headers)
|
290
|
+
Array(headers).map{|*a| a.join(": ")}.join("\n")
|
291
|
+
end
|
292
|
+
end
|
data/lib/cloudinary/version.rb
CHANGED
data/spec/uploader_spec.rb
CHANGED
@@ -133,4 +133,9 @@ describe Cloudinary::Uploader do
|
|
133
133
|
it "should support requesting auto_tagging" do
|
134
134
|
lambda{Cloudinary::Uploader.upload("spec/logo.png", {:auto_tagging => 0.5})}.should raise_error(CloudinaryException, /Must use/)
|
135
135
|
end
|
136
|
+
|
137
|
+
it "should support upload_large" do
|
138
|
+
result = Cloudinary::Uploader.upload_large("spec/logo.png")
|
139
|
+
result["public_id"].should match(/^[a-z0-9]+.png$/)
|
140
|
+
end
|
136
141
|
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.70
|
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: 2014-
|
14
|
+
date: 2014-03-25 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rest-client
|