cloudinary 1.0.68 → 1.0.69

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 CHANGED
@@ -1,3 +1,12 @@
1
+ = Version 1.0.69 - 2014-02-25
2
+ * Admin API update method.
3
+ * Admin API listing by moderation kind and status.
4
+ * Support moderation status in admin API listing.
5
+ * Support moderation flag in upload.
6
+ * New upload and update API parameters: moderation, ocr, raw_conversion, categorization, detection, similarity_search and auto_tagging.
7
+ * Allow CloudinaryHelper to be included into standalone classes.
8
+ * Added support for Sequel models using CarrierWave.
9
+
1
10
  = Version 1.0.68 - 2014-02-16
2
11
  * Support for uploading large raw files.
3
12
  * Correct support for image_tag and image_path override.
@@ -36,20 +36,26 @@ class Cloudinary::Api
36
36
  type = options[:type]
37
37
  uri = "resources/#{resource_type}"
38
38
  uri += "/#{type}" if !type.blank?
39
- call_api(:get, uri, only(options, :next_cursor, :max_results, :prefix, :tags, :context, :direction), options)
39
+ call_api(:get, uri, only(options, :next_cursor, :max_results, :prefix, :tags, :context, :moderations, :direction), options)
40
40
  end
41
41
 
42
42
  def self.resources_by_tag(tag, options={})
43
43
  resource_type = options[:resource_type] || "image"
44
44
  uri = "resources/#{resource_type}/tags/#{tag}"
45
- call_api(:get, uri, only(options, :next_cursor, :max_results, :tags, :context, :direction), options)
45
+ call_api(:get, uri, only(options, :next_cursor, :max_results, :tags, :context, :moderations, :direction), options)
46
+ end
47
+
48
+ def self.resources_by_moderation(kind, status, options={})
49
+ resource_type = options[:resource_type] || "image"
50
+ uri = "resources/#{resource_type}/moderations/#{kind}/#{status}"
51
+ call_api(:get, uri, only(options, :next_cursor, :max_results, :tags, :context, :moderations, :direction), options)
46
52
  end
47
53
 
48
54
  def self.resources_by_ids(public_ids, options={})
49
55
  resource_type = options[:resource_type] || "image"
50
56
  type = options[:type] || "upload"
51
57
  uri = "resources/#{resource_type}/#{type}"
52
- call_api(:get, uri, only(options, :tags, :context).merge(:public_ids => public_ids), options)
58
+ call_api(:get, uri, only(options, :tags, :context, :moderations).merge(:public_ids => public_ids), options)
53
59
  end
54
60
 
55
61
  def self.resource(public_id, options={})
@@ -59,6 +65,25 @@ class Cloudinary::Api
59
65
  call_api(:get, uri, only(options, :colors, :exif, :faces, :image_metadata, :pages, :max_results), options)
60
66
  end
61
67
 
68
+ def self.update(public_id, options={})
69
+ resource_type = options[:resource_type] || "image"
70
+ type = options[:type] || "upload"
71
+ uri = "resources/#{resource_type}/#{type}/#{public_id}"
72
+ update_options = {
73
+ :tags => options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
74
+ :context => Cloudinary::Utils.encode_hash(options[:context]),
75
+ :face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
76
+ :moderation_status => options[:moderation_status],
77
+ :raw_convert => options[:raw_convert],
78
+ :ocr => options[:ocr],
79
+ :categorization => options[:categorization],
80
+ :detection => options[:detection],
81
+ :similarity_search => options[:similarity_search],
82
+ :auto_tagging => options[:auto_tagging] && options[:auto_tagging].to_f
83
+ }
84
+ call_api(:post, uri, update_options, options)
85
+ end
86
+
62
87
  def self.delete_resources(public_ids, options={})
63
88
  resource_type = options[:resource_type] || "image"
64
89
  type = options[:type] || "upload"
@@ -64,6 +64,11 @@ class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
64
64
  store_cloudinary_identifier(version, filename)
65
65
  end
66
66
 
67
+ # Updates the model mounter identifier with version information.
68
+ #
69
+ # Carrierwave uses hooks when integrating with ORMs so it's important to
70
+ # update the identifier in a way that does not trigger hooks again or else
71
+ # you'll get stuck in a loop.
67
72
  def store_cloudinary_identifier(version, filename)
68
73
  name = "v#{version}/#{filename}"
69
74
  model_class = uploader.model.class
@@ -83,11 +88,14 @@ class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
83
88
  else
84
89
  uploader.model.set(column, name)
85
90
  end
91
+ elsif defined?(Sequel::Model) && uploader.model.is_a?(Sequel::Model)
92
+ # Sequel support
93
+ uploader.model.this.update(column => name)
86
94
  elsif model_class.respond_to?(:update_all) && uploader.model.respond_to?(:_id)
87
95
  model_class.where(:_id=>uploader.model._id).update_all(column=>name)
88
96
  uploader.model.send :write_attribute, column, name
89
97
  else
90
- raise CloudinaryException, "Only ActiveRecord and Mongoid are supported at the moment!"
98
+ raise CloudinaryException, "Only ActiveRecord, Mongoid and Sequel are supported at the moment!"
91
99
  end
92
100
  end
93
101
  end
@@ -195,6 +195,9 @@ module CloudinaryHelper
195
195
  def self.included(base)
196
196
  ActionView::Helpers::FormBuilder.send(:include, Cloudinary::FormBuilder)
197
197
  base.class_eval do
198
+ if !method_defined?(:image_tag)
199
+ include ActionView::Helpers::AssetTagHelper
200
+ end
198
201
  if defined?(Rails) && !Rails.version.start_with?("2") && Cloudinary.config.enhance_image_tag
199
202
  alias_method_chain :image_tag, :cloudinary
200
203
  alias_method_chain :image_path, :cloudinary
@@ -38,10 +38,17 @@ class Cloudinary::Uploader
38
38
  :eager_async=>Cloudinary::Utils.as_safe_bool(options[:eager_async]),
39
39
  :proxy=>options[:proxy],
40
40
  :folder=>options[:folder],
41
+ :allowed_formats => Cloudinary::Utils.build_array(options[:allowed_formats]).join(","),
41
42
  :tags=>options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
42
- :allowed_formats => Cloudinary::Utils.build_array(options[:allowed_formats]).join(","),
43
43
  :context => Cloudinary::Utils.encode_hash(options[:context]),
44
- :face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates])}
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
+ :detection => options[:detection],
50
+ :similarity_search => options[:similarity_search],
51
+ :auto_tagging => options[:auto_tagging] && options[:auto_tagging].to_f}
45
52
  params
46
53
  end
47
54
 
@@ -59,44 +66,44 @@ class Cloudinary::Uploader
59
66
  end
60
67
  end
61
68
 
62
- # Upload large raw files. Note that public_id should include an extension for best results.
63
- def self.upload_large(file, public_id, options={})
64
- if file.is_a?(Pathname) || !file.respond_to?(:read)
65
- file = File.open(file, "rb")
66
- end
67
- upload = upload_id = nil
68
- index = 1
69
- while !file.eof?
70
- buffer = file.read(20_000_000)
71
- upload = upload_large_part(Cloudinary::Blob.new(buffer), public_id, options.merge(:upload_id=>upload_id, :part_number=>index, :final=>file.eof?))
72
- upload_id = upload["upload_id"]
73
- index += 1
74
- end
75
- upload
76
- end
77
-
78
-
79
- # Upload large raw files. Note that public_id should include an extension for best results.
80
- def self.upload_large_part(file, public_id, options={})
81
- call_api("upload_large", options.merge(:resource_type=>:raw)) do
82
- params = {
83
- :timestamp=>Time.now.to_i,
84
- :type=>options[:type],
85
- :public_id=> public_id,
86
- :backup=>options[:backup],
87
- :final=>options[:final],
88
- :part_number=>options[:part_number],
89
- :upload_id=>options[:upload_id]
90
- }
91
- if file.is_a?(Pathname) || !file.respond_to?(:read)
92
- params[:file] = File.open(file, "rb")
93
- else
94
- params[:file] = file
95
- end
96
- [params, [:file]]
97
- end
98
- end
99
-
69
+ # Upload large raw files. Note that public_id should include an extension for best results.
70
+ def self.upload_large(file, public_id, options={})
71
+ if file.is_a?(Pathname) || !file.respond_to?(:read)
72
+ file = File.open(file, "rb")
73
+ end
74
+ upload = upload_id = nil
75
+ index = 1
76
+ while !file.eof?
77
+ buffer = file.read(20_000_000)
78
+ upload = upload_large_part(Cloudinary::Blob.new(buffer), public_id, options.merge(:upload_id=>upload_id, :part_number=>index, :final=>file.eof?))
79
+ upload_id = upload["upload_id"]
80
+ index += 1
81
+ end
82
+ upload
83
+ end
84
+
85
+
86
+ # Upload large raw files. Note that public_id should include an extension for best results.
87
+ def self.upload_large_part(file, public_id, options={})
88
+ call_api("upload_large", options.merge(:resource_type=>:raw)) do
89
+ params = {
90
+ :timestamp=>Time.now.to_i,
91
+ :type=>options[:type],
92
+ :public_id=> public_id,
93
+ :backup=>options[:backup],
94
+ :final=>options[:final],
95
+ :part_number=>options[:part_number],
96
+ :upload_id=>options[:upload_id]
97
+ }
98
+ if file.is_a?(Pathname) || !file.respond_to?(:read)
99
+ params[:file] = File.open(file, "rb")
100
+ else
101
+ params[:file] = file
102
+ end
103
+ [params, [:file]]
104
+ end
105
+ end
106
+
100
107
  def self.destroy(public_id, options={})
101
108
  call_api("destroy", options) do
102
109
  {
@@ -1,4 +1,4 @@
1
1
  # Copyright Cloudinary
2
2
  module Cloudinary
3
- VERSION = "1.0.68"
3
+ VERSION = "1.0.69"
4
4
  end
data/spec/api_spec.rb CHANGED
@@ -202,5 +202,59 @@ describe Cloudinary::Api do
202
202
  resource.should_not be_blank
203
203
  resource["derived"].length.should == 0
204
204
  end
205
+
206
+ it "should support setting manual moderation status" do
207
+ result = Cloudinary::Uploader.upload("spec/logo.png", {:moderation => :manual})
208
+ result["moderation"][0]["status"].should == "pending"
209
+ result["moderation"][0]["kind"].should == "manual"
210
+ api_result = Cloudinary::Api.update(result["public_id"], {:moderation_status => :approved})
211
+ api_result["moderation"][0]["status"].should == "approved"
212
+ api_result["moderation"][0]["kind"].should == "manual"
213
+ end
214
+
215
+ it "should support requesting ocr info" do
216
+ result = Cloudinary::Uploader.upload("spec/logo.png")
217
+ lambda{Cloudinary::Api.update(result["public_id"], {:ocr => :illegal})}.should raise_error(Cloudinary::Api::BadRequest, /^Illegal value/)
218
+ end
219
+
220
+ it "should support requesting raw conversion" do
221
+ result = Cloudinary::Uploader.upload("spec/docx.docx", :resource_type => :raw)
222
+ lambda{Cloudinary::Api.update(result["public_id"], {:resource_type => :raw, :raw_convert => :illegal})}.should raise_error(Cloudinary::Api::BadRequest, /^Illegal value/)
223
+ end
224
+
225
+ it "should support requesting categorization" do
226
+ result = Cloudinary::Uploader.upload("spec/logo.png")
227
+ lambda{Cloudinary::Api.update(result["public_id"], {:categorization => :illegal})}.should raise_error(Cloudinary::Api::BadRequest, /^Illegal value/)
228
+ end
229
+
230
+ it "should support requesting detection" do
231
+ result = Cloudinary::Uploader.upload("spec/logo.png")
232
+ lambda{Cloudinary::Api.update(result["public_id"], {:detection => :illegal})}.should raise_error(Cloudinary::Api::BadRequest, /^Illegal value/)
233
+ end
234
+
235
+ it "should support requesting ocr info" do
236
+ result = Cloudinary::Uploader.upload("spec/logo.png")
237
+ lambda{Cloudinary::Api.update(result["public_id"], {:auto_tagging => 0.5})}.should raise_error(Cloudinary::Api::BadRequest, /^Must use/)
238
+ end
239
+
240
+ it "should support listing by moderation kind and value" do
241
+ result1 = Cloudinary::Uploader.upload("spec/logo.png", {:moderation => :manual})
242
+ result2 = Cloudinary::Uploader.upload("spec/logo.png", {:moderation => :manual})
243
+ result3 = Cloudinary::Uploader.upload("spec/logo.png", {:moderation => :manual})
244
+ Cloudinary::Api.update(result1["public_id"], {:moderation_status => :approved})
245
+ Cloudinary::Api.update(result2["public_id"], {:moderation_status => :rejected})
246
+ approved = Cloudinary::Api.resources_by_moderation(:manual, :approved, :max_results => 1000)["resources"].map{|r| r["public_id"]}
247
+ approved.should include(result1["public_id"])
248
+ approved.should_not include(result2["public_id"])
249
+ approved.should_not include(result3["public_id"])
250
+ rejected = Cloudinary::Api.resources_by_moderation(:manual, :rejected, :max_results => 1000)["resources"].map{|r| r["public_id"]}
251
+ rejected.should include(result2["public_id"])
252
+ rejected.should_not include(result1["public_id"])
253
+ rejected.should_not include(result3["public_id"])
254
+ pending = Cloudinary::Api.resources_by_moderation(:manual, :pending, :max_results => 1000)["resources"].map{|r| r["public_id"]}
255
+ pending.should include(result3["public_id"])
256
+ pending.should_not include(result1["public_id"])
257
+ pending.should_not include(result2["public_id"])
258
+ end
205
259
 
206
260
  end
data/spec/docx.docx ADDED
Binary file
@@ -70,34 +70,34 @@ describe Cloudinary::Uploader do
70
70
  end
71
71
 
72
72
  it "should correctly handle unique_filename" do
73
- result = Cloudinary::Uploader.upload("spec/logo.png", use_filename: true)
73
+ result = Cloudinary::Uploader.upload("spec/logo.png", :use_filename => true)
74
74
  result["public_id"].should match(/logo_[a-zA-Z0-9]{6}/)
75
- result = Cloudinary::Uploader.upload("spec/logo.png", use_filename: true, unique_filename: false)
75
+ result = Cloudinary::Uploader.upload("spec/logo.png", :use_filename => true, :unique_filename => false)
76
76
  result["public_id"].should == "logo"
77
77
  end
78
78
 
79
79
  it "should allow whitelisted formats if allowed_formats", :allowed=>true do
80
- result = Cloudinary::Uploader.upload("spec/logo.png", allowed_formats: ["png"])
80
+ result = Cloudinary::Uploader.upload("spec/logo.png", :allowed_formats => ["png"])
81
81
  result["format"].should == "png"
82
82
  end
83
83
 
84
84
  it "should prevent non whitelisted formats from being uploaded if allowed_formats is specified", :allowed=>true do
85
- lambda{Cloudinary::Uploader.upload("spec/logo.png", allowed_formats: ["jpg"])}.should raise_error
85
+ lambda{Cloudinary::Uploader.upload("spec/logo.png", :allowed_formats => ["jpg"])}.should raise_error
86
86
  end
87
87
 
88
88
  it "should allow non whitelisted formats if type is specified and convert to that type", :allowed=>true do
89
- result = Cloudinary::Uploader.upload("spec/logo.png", allowed_formats: ["jpg"], format: "jpg")
89
+ result = Cloudinary::Uploader.upload("spec/logo.png", :allowed_formats => ["jpg"], :format => "jpg")
90
90
  result["format"].should == "jpg"
91
91
  end
92
92
 
93
93
  it "should allow sending face coordinates" do
94
94
  coordinates = [[120, 30, 109, 150], [121, 31, 110, 151]]
95
- result = Cloudinary::Uploader.upload("spec/logo.png", {face_coordinates: coordinates, faces: true})
95
+ result = Cloudinary::Uploader.upload("spec/logo.png", {:face_coordinates => coordinates, :faces => true})
96
96
  result["faces"].should == coordinates
97
97
 
98
98
  different_coordinates = [[122, 32, 111, 152]]
99
- Cloudinary::Uploader.explicit(result["public_id"], {face_coordinates: different_coordinates, faces: true, type: "upload"})
100
- info = Cloudinary::Api.resource(result["public_id"], {faces: true})
99
+ Cloudinary::Uploader.explicit(result["public_id"], {:face_coordinates => different_coordinates, :faces => true, :type => "upload"})
100
+ info = Cloudinary::Api.resource(result["public_id"], {:faces => true})
101
101
  info["faces"].should == different_coordinates
102
102
  end
103
103
 
@@ -107,4 +107,30 @@ describe Cloudinary::Uploader do
107
107
  info = Cloudinary::Api.resource(result["public_id"], {:context => true})
108
108
  info["context"].should == {"custom" => context}
109
109
  end
110
+
111
+ it "should support requesting manual moderation" do
112
+ result = Cloudinary::Uploader.upload("spec/logo.png", {:moderation => :manual})
113
+ result["moderation"][0]["status"].should == "pending"
114
+ result["moderation"][0]["kind"].should == "manual"
115
+ end
116
+
117
+ it "should support requesting ocr info" do
118
+ lambda{Cloudinary::Uploader.upload("spec/logo.png", {:ocr => :illegal})}.should raise_error(CloudinaryException, /Illegal value/)
119
+ end
120
+
121
+ it "should support requesting raw conversion" do
122
+ lambda{Cloudinary::Uploader.upload("spec/docx.docx", {:resource_type => :raw, :raw_convert => :illegal})}.should raise_error(CloudinaryException, /Illegal value/)
123
+ end
124
+
125
+ it "should support requesting categorization" do
126
+ lambda{Cloudinary::Uploader.upload("spec/logo.png", {:categorization => :illegal})}.should raise_error(CloudinaryException, /Illegal value/)
127
+ end
128
+
129
+ it "should support requesting detection" do
130
+ lambda{Cloudinary::Uploader.upload("spec/logo.png", {:detection => :illegal})}.should raise_error(CloudinaryException, /Illegal value/)
131
+ end
132
+
133
+ it "should support requesting auto_tagging" do
134
+ lambda{Cloudinary::Uploader.upload("spec/logo.png", {:auto_tagging => 0.5})}.should raise_error(CloudinaryException, /Must use/)
135
+ end
110
136
  end
data/spec/utils_spec.rb CHANGED
@@ -441,23 +441,23 @@ describe Cloudinary::Utils do
441
441
  end
442
442
 
443
443
  it "should correctly sign URLs", :signed => true do
444
- options = {version: 1234, transformation: {crop: "crop", width: 10, height: 20}, sign_url: true}
444
+ options = {:version => 1234, :transformation => {:crop => "crop", :width => 10, :height => 20}, :sign_url => true}
445
445
  expected = "http://res.cloudinary.com/test123/image/upload/s--MaRXzoEC--/c_crop,h_20,w_10/v1234/image.jpg"
446
446
  actual = Cloudinary::Utils.cloudinary_url("image.jpg", options)
447
447
  actual.should == expected
448
448
 
449
- options = {version: 1234, sign_url: true}
449
+ options = {:version => 1234, :sign_url => true}
450
450
  expected = "http://res.cloudinary.com/test123/image/upload/s--ZlgFLQcO--/v1234/image.jpg"
451
451
  actual = Cloudinary::Utils.cloudinary_url("image.jpg", options)
452
452
  actual.should == expected
453
453
 
454
- options = {transformation: {crop: "crop", width: 10, height: 20}, sign_url: true}
454
+ options = {:transformation => {:crop => "crop", :width => 10, :height => 20}, :sign_url => true}
455
455
  expected = "http://res.cloudinary.com/test123/image/upload/s--Ai4Znfl3--/c_crop,h_20,w_10/image.jpg"
456
456
  actual = Cloudinary::Utils.cloudinary_url("image.jpg", options)
457
457
  actual.should == expected
458
458
 
459
459
  expected = "http://res.cloudinary.com/test123/image/fetch/s--_GAUclyB--/v1234/http://google.com/path/to/image.png"
460
- actual = Cloudinary::Utils.cloudinary_url("http://google.com/path/to/image.png", type: "fetch", version: 1234, sign_url: true)
460
+ actual = Cloudinary::Utils.cloudinary_url("http://google.com/path/to/image.png", :type => "fetch", :version => 1234, :sign_url => true)
461
461
  actual.should == expected
462
462
  end
463
463
  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.68
4
+ version: 1.0.69
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-02-16 00:00:00.000000000 Z
14
+ date: 2014-02-25 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rest-client
@@ -101,6 +101,7 @@ files:
101
101
  - lib/cloudinary/version.rb
102
102
  - lib/tasks/cloudinary.rake
103
103
  - spec/api_spec.rb
104
+ - spec/docx.docx
104
105
  - spec/favicon.ico
105
106
  - spec/logo.png
106
107
  - spec/spec_helper.rb
@@ -145,6 +146,7 @@ specification_version: 3
145
146
  summary: Client library for easily using the Cloudinary service
146
147
  test_files:
147
148
  - spec/api_spec.rb
149
+ - spec/docx.docx
148
150
  - spec/favicon.ico
149
151
  - spec/logo.png
150
152
  - spec/spec_helper.rb