cloudinary 1.8.3 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0fd535c0bc5341c9ba6dc09a32f24b59886cbee9
4
- data.tar.gz: 410e9129e4990f62ebbeeb2fe20cdf340db91277
3
+ metadata.gz: c78db40dfbd0f2a2fa579c3817208c11c89136be
4
+ data.tar.gz: c1f15ae49d99c4c1edb404cd6c49eb4a6c992a58
5
5
  SHA512:
6
- metadata.gz: 808f9c7439fb2c6e0f2b3b9fba6bb92d96d08b9e3436723a22cdfa974bf1c4b6d64a3c1ea43a73d0fb46c09f20355c42c1922723535ba2246f10003776d7bc30
7
- data.tar.gz: f04de4f7cd51a3e25b1f0b48153774f62ec0644a532eb48fc2db8b373a6e962507cce4db6025f17a2e8095bf0828fb992e53c4c2dd43068155938480bdb80ba8
6
+ metadata.gz: e8b61e2b1660f36ed2f4cb2b85a38010b8135455e1c1ad743dfe3f267c695c7f88195d038a7548fbe2f6c6d63a005dd458e396ba1f33370c937cf424f5ad14b0
7
+ data.tar.gz: dbec90b6f71bbad87e31740e419d225bd8804a012310ee55121661d93a48e4d136ae1b86e8ed80b86111d9f004dde54399c72e3f39138686b77616fc7624b92e
@@ -1,4 +1,18 @@
1
1
 
2
+ 1.9.0 / 2018-02-27
3
+ ==================
4
+
5
+ New functionality and features
6
+ ------------------------------
7
+
8
+ * Add `access_control` parameter to `upload` and `update`
9
+ * Add `format` to CarrierWave plug-in's `PreloadedFile`
10
+
11
+ Other Changes
12
+ -------------
13
+
14
+ * Fix upload categorization test
15
+
2
16
  1.8.3 / 2018-02-04
3
17
  ==================
4
18
 
@@ -93,6 +93,7 @@ class Cloudinary::Api
93
93
  type = options[:type] || "upload"
94
94
  uri = "resources/#{resource_type}/#{type}/#{public_id}"
95
95
  update_options = {
96
+ :access_control => Cloudinary::Utils.json_array_param(options[:access_control]),
96
97
  :tags => options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
97
98
  :context => Cloudinary::Utils.encode_context(options[:context]),
98
99
  :face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
@@ -1,7 +1,7 @@
1
1
  class Cloudinary::PreloadedFile
2
2
  PRELOADED_CLOUDINARY_PATH = /^([^\/]+)\/([^\/]+)\/v(\d+)\/([^#]+)#([^\/]+)$/
3
3
 
4
- attr_reader :filename, :version, :public_id, :signature, :resource_type, :type
4
+ attr_reader :filename, :version, :public_id, :signature, :resource_type, :type, :format
5
5
  def initialize(file_info)
6
6
  @resource_type, @type, @version, @filename, @signature = file_info.scan(PRELOADED_CLOUDINARY_PATH).first
7
7
  @public_id, @format = Cloudinary::PreloadedFile.split_format(@filename)
@@ -29,4 +29,4 @@ class Cloudinary::PreloadedFile
29
29
  return [public_id, format]
30
30
  end
31
31
 
32
- end
32
+ end
@@ -18,6 +18,7 @@ class Cloudinary::Uploader
18
18
  options.keys.each { |key| options[key.to_sym] = options.delete(key) if key.is_a?(String) }
19
19
 
20
20
  params = {
21
+ :access_control => Cloudinary::Utils.json_array_param(options[:access_control]),
21
22
  :access_mode => options[:access_mode],
22
23
  :allowed_formats => Cloudinary::Utils.build_array(options[:allowed_formats]).join(","),
23
24
  :async => Cloudinary::Utils.as_safe_bool(options[:async]),
@@ -313,6 +313,20 @@ class Cloudinary::Utils
313
313
  Digest::SHA1.hexdigest("#{to_sign}#{api_secret}")
314
314
  end
315
315
 
316
+ # Returns a JSON array as String.
317
+ # Yields the array before it is converted to JSON format
318
+ # @api private
319
+ # @param [Hash|String|Array<Hash>] data
320
+ # @return [String|nil] a JSON array string or `nil` if data is `nil`
321
+ def self.json_array_param(data)
322
+ return nil if data.nil?
323
+
324
+ data = JSON.parse(data) if data.is_a?(String)
325
+ data = [data] unless data.is_a?(Array)
326
+ data = yield data if block_given?
327
+ JSON.generate(data)
328
+ end
329
+
316
330
  def self.generate_responsive_breakpoints_string(breakpoints)
317
331
  return nil if breakpoints.nil?
318
332
  breakpoints = build_array(breakpoints)
@@ -1,4 +1,4 @@
1
1
  # Copyright Cloudinary
2
2
  module Cloudinary
3
- VERSION = "1.8.3"
3
+ VERSION = "1.9.0"
4
4
  end
@@ -0,0 +1,99 @@
1
+ require 'rspec'
2
+ require 'cloudinary'
3
+ require 'spec_helper'
4
+ require 'time'
5
+
6
+ # Calculates days as seconds
7
+ def days(n)
8
+ n * 3600 * 24
9
+ end
10
+
11
+ describe "Access Control" do
12
+ let (:acl) {{
13
+ :access_type => 'anonymous',
14
+ :start => '2019-02-22 16:20:57 +0200',
15
+ :end => '2019-03-22 00:00 +0200'
16
+ }}
17
+ let (:acl_2) {{
18
+ :access_type => 'anonymous',
19
+ :start => '2019-02-22 16:20:57Z',
20
+ :end => '2019-03-22 00:00 +0200'
21
+ }}
22
+ let (:acl_string) {
23
+ '{"access_type":"anonymous","start":"2019-02-22 16:20:57 +0200","end":"2019-03-22 00:00 +0200"}'
24
+ }
25
+ let (:options) {{
26
+ :public_id => TIMESTAMP_TAG,
27
+ :tags => [TEST_TAG, TIMESTAMP_TAG, 'access_control_test']
28
+ }}
29
+ let(:resource ){
30
+ Cloudinary::Uploader.upload(
31
+ TEST_IMG,
32
+ options)
33
+ }
34
+ describe 'build_upload_params' do
35
+ it "should accept a Hash value" do
36
+ params = Cloudinary::Uploader.build_upload_params access_control: acl
37
+ expect(params).to have_key(:access_control)
38
+ expect(params[:access_control]).to be_a String
39
+ expect(params[:access_control]).to match(/^\[.+\]$/)
40
+
41
+ end
42
+ it "should accept an array of Hash values" do
43
+ params = Cloudinary::Uploader.build_upload_params access_control: [acl, acl_2]
44
+ expect(params).to have_key(:access_control)
45
+ expect(params[:access_control]).to be_a String
46
+ expect(params[:access_control]).to match(/^\[.+\]$/)
47
+ j = JSON.parse(params[:access_control])
48
+ expect(j.length).to be(2)
49
+ expect(j[0]["access_type"]).to eql(acl[:access_type])
50
+ expect(j[0]["start"]).to eql(acl[:start])
51
+ expect(j[0]["end"]).to eql(acl[:end])
52
+ end
53
+ it "should accept a JSON string" do
54
+ params = Cloudinary::Uploader.build_upload_params access_control: acl_string
55
+ expect(params).to have_key(:access_control)
56
+ expect(params[:access_control]).to be_a String
57
+ expect(params[:access_control]).to eql("[#{acl_string}]")
58
+ end
59
+ end
60
+
61
+ describe 'upload' do
62
+ break puts("Please setup environment for api test to run") if Cloudinary.config.api_secret.blank?
63
+ include_context "cleanup", TIMESTAMP_TAG
64
+
65
+ it 'should allow the user to define ACL in the upload parameters' do
66
+ options[:access_control] = [acl]
67
+ expect(RestClient::Request).to receive(:execute).with(
68
+ deep_hash_value( {[:payload, :access_control] => "[#{acl_string}]"})
69
+ ).and_call_original
70
+ expect(resource).to have_key('access_control')
71
+ response_acl = resource["access_control"]
72
+ expect(response_acl.length).to be(1)
73
+ expect(response_acl[0]["access_type"]).to eq("anonymous")
74
+ expect(Time.parse(response_acl[0]["start"])).to eq(Time.parse(acl[:start]))
75
+ expect(Time.parse(response_acl[0]["end"])).to eq(Time.parse(acl[:end]))
76
+ end
77
+ end
78
+ describe 'update' do
79
+ break puts("Please setup environment for api test to run") if Cloudinary.config.api_secret.blank?
80
+ include_context "cleanup", TIMESTAMP_TAG
81
+
82
+ it 'should allow the user to define ACL in the update parameters' do
83
+ resource # upload before setting the expect
84
+ expect(RestClient::Request).to receive(:execute).with(
85
+ deep_hash_value( {[:payload, :access_control] => "[#{acl_string}]"})
86
+ ).and_call_original
87
+ result = Cloudinary::Api.update(
88
+ resource['public_id'],
89
+ :tags => [TEST_TAG, TIMESTAMP_TAG, 'access_control_test'],
90
+ :access_control => acl)
91
+ expect(result).to have_key('access_control')
92
+ response_acl = result["access_control"]
93
+ expect(response_acl.length).to be(1)
94
+ expect(response_acl[0]["access_type"]).to eq("anonymous")
95
+ expect(Time.parse(response_acl[0]["start"])).to eq(Time.parse(acl[:start]))
96
+ expect(Time.parse(response_acl[0]["end"])).to eq(Time.parse(acl[:end]))
97
+ end
98
+ end
99
+ end
@@ -269,7 +269,7 @@ describe Cloudinary::Uploader do
269
269
  end
270
270
 
271
271
  it "should support requesting categorization" do
272
- expect{Cloudinary::Uploader.upload(TEST_IMG, { :categorization => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Illegal value|not a valid|is invalid/)
272
+ expect{Cloudinary::Uploader.upload(TEST_IMG, { :categorization => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Illegal value|not a valid|is not valid/)
273
273
  end
274
274
 
275
275
  it "should support requesting detection" do
@@ -15,4 +15,40 @@ describe Utils do
15
15
  it "should parse a percent range value" do
16
16
  expect(Utils.instance_eval { norm_range_value("20p") }).to eq("20p")
17
17
  end
18
+ describe "json_array_param" do
19
+ let (:data) {{:one => 1, :two => 2, "three" => 3}}
20
+ let (:data_s) {"{\"one\":1,\"two\":2,\"three\":3}"}
21
+ let (:data2) {{:foo => "bar"}}
22
+ let (:data2_s) {"{\"foo\":\"bar\"}"}
23
+ it "should convert a hash to json array" do
24
+ result = Utils.json_array_param(data)
25
+ expect(result).to match(/^\[.+\]$/)
26
+ end
27
+ it "should convert an array of hash to json array" do
28
+ result = Utils.json_array_param([data, data2])
29
+ expect(result).to eql("[#{data_s},#{data2_s}]")
30
+ end
31
+ it "should convert a json string to json array string" do
32
+ result = Utils.json_array_param(data_s)
33
+ expect(result).to eql("[#{data_s}]")
34
+ end
35
+ it "should accept a JSON array string and return it" do
36
+ result = Utils.json_array_param("[#{data_s},#{data2_s}]")
37
+ expect(result).to eql("[#{data_s},#{data2_s}]")
38
+ end
39
+ it "should throw an error if input string is not valid json string" do
40
+ expect{Utils.json_array_param("I'm not a JSON object!")}.to raise_error(JSON::ParserError)
41
+ end
42
+ it "should support a block" do
43
+ hash = {:block => "works"}
44
+ hash_s = '{"block":"works"}'
45
+ result = Utils.json_array_param(data) do |array|
46
+ array[0]['foo'] = 'foobar'
47
+ array.push(hash)
48
+
49
+ end
50
+ expect(result).to include(hash_s)
51
+ expect(result).to include('foobar')
52
+ end
53
+ end
18
54
  end
@@ -727,6 +727,17 @@ describe Cloudinary::Utils do
727
727
  signature = Cloudinary::Utils.api_sign_request({ :public_id => "folder/file", :version => "1234" }, Cloudinary.config.api_secret)
728
728
  preloaded = Cloudinary::PreloadedFile.new("image/upload/v1234/folder/file.jpg#" + signature)
729
729
  expect(preloaded).to be_valid
730
+ [
731
+ [:filename, 'folder/file.jpg'],
732
+ [:version, '1234'],
733
+ [:public_id, 'folder/file'],
734
+ [:signature, signature],
735
+ [:resource_type, 'image'],
736
+ [:type, 'upload'],
737
+ [:format, 'jpg']
738
+ ].each do |attr,value|
739
+ expect(preloaded.send(attr)).to eq(value)
740
+ end
730
741
  end
731
742
 
732
743
  it "should escape public_ids" do
@@ -1,6 +1,6 @@
1
1
 
2
2
  /**
3
- * Cloudinary's JavaScript library - Version 2.4.0
3
+ * Cloudinary's JavaScript library - Version 2.5.0
4
4
  * Copyright Cloudinary
5
5
  * see https://github.com/cloudinary/cloudinary_js
6
6
  *
@@ -3460,9 +3460,9 @@ var slice = [].slice,
3460
3460
 
3461
3461
  })(HtmlTag);
3462
3462
  Cloudinary = (function() {
3463
- var AKAMAI_SHARED_CDN, CF_SHARED_CDN, DEFAULT_POSTER_OPTIONS, DEFAULT_VIDEO_SOURCE_TYPES, OLD_AKAMAI_SHARED_CDN, SHARED_CDN, VERSION, absolutize, applyBreakpoints, cdnSubdomainNumber, closestAbove, cloudinaryUrlPrefix, defaultBreakpoints, finalizeResourceType, findContainerWidth, maxWidth, updateDpr;
3463
+ var AKAMAI_SHARED_CDN, CF_SHARED_CDN, DEFAULT_POSTER_OPTIONS, DEFAULT_VIDEO_SOURCE_TYPES, OLD_AKAMAI_SHARED_CDN, SEO_TYPES, SHARED_CDN, VERSION, absolutize, applyBreakpoints, cdnSubdomainNumber, closestAbove, cloudinaryUrlPrefix, defaultBreakpoints, finalizeResourceType, findContainerWidth, maxWidth, updateDpr;
3464
3464
 
3465
- VERSION = "2.4.0";
3465
+ VERSION = "2.5.0";
3466
3466
 
3467
3467
  CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
3468
3468
 
@@ -3479,6 +3479,14 @@ var slice = [].slice,
3479
3479
 
3480
3480
  DEFAULT_VIDEO_SOURCE_TYPES = ['webm', 'mp4', 'ogv'];
3481
3481
 
3482
+ SEO_TYPES = {
3483
+ "image/upload": "images",
3484
+ "image/private": "private_images",
3485
+ "image/authenticated": "authenticated_images",
3486
+ "raw/upload": "files",
3487
+ "video/upload": "videos"
3488
+ };
3489
+
3482
3490
 
3483
3491
  /**
3484
3492
  * @const {Object} Cloudinary.DEFAULT_IMAGE_PARAMS
@@ -3586,7 +3594,13 @@ var slice = [].slice,
3586
3594
  */
3587
3595
 
3588
3596
  finalizeResourceType = function(resourceType, type, urlSuffix, useRootPath, shorten) {
3589
- var options;
3597
+ var key, options;
3598
+ if (resourceType == null) {
3599
+ resourceType = "image";
3600
+ }
3601
+ if (type == null) {
3602
+ type = "upload";
3603
+ }
3590
3604
  if (Util.isPlainObject(resourceType)) {
3591
3605
  options = resourceType;
3592
3606
  resourceType = options.resource_type;
@@ -3599,17 +3613,17 @@ var slice = [].slice,
3599
3613
  type = 'upload';
3600
3614
  }
3601
3615
  if (urlSuffix != null) {
3602
- if (resourceType === 'image' && type === 'upload') {
3603
- resourceType = "images";
3604
- type = null;
3605
- } else if (resourceType === 'image' && type === 'private') {
3606
- resourceType = 'private_images';
3607
- type = null;
3608
- } else if (resourceType === 'raw' && type === 'upload') {
3609
- resourceType = 'files';
3610
- type = null;
3611
- } else {
3612
- throw new Error("URL Suffix only supported for image/upload and raw/upload");
3616
+ resourceType = SEO_TYPES[resourceType + "/" + type];
3617
+ type = null;
3618
+ if (resourceType == null) {
3619
+ throw new Error("URL Suffix only supported for " + (((function() {
3620
+ var results;
3621
+ results = [];
3622
+ for (key in SEO_TYPES) {
3623
+ results.push(key);
3624
+ }
3625
+ return results;
3626
+ })()).join(', ')));
3613
3627
  }
3614
3628
  }
3615
3629
  if (useRootPath) {
@@ -3674,9 +3688,6 @@ var slice = [].slice,
3674
3688
  if (!options.cloud_name) {
3675
3689
  throw 'Unknown cloud_name';
3676
3690
  }
3677
- if (options.url_suffix && !options.private_cdn) {
3678
- throw 'URL Suffix only supported in private CDN';
3679
- }
3680
3691
  if (publicId.search('/') >= 0 && !publicId.match(/^v[0-9]+/) && !publicId.match(/^https?:\//) && !((ref = options.version) != null ? ref.toString() : void 0)) {
3681
3692
  options.version = 1;
3682
3693
  }
@@ -4702,7 +4713,7 @@ var slice = [].slice,
4702
4713
  TextLayer: TextLayer,
4703
4714
  SubtitlesLayer: SubtitlesLayer,
4704
4715
  Cloudinary: Cloudinary,
4705
- VERSION: "2.4.0",
4716
+ VERSION: "2.5.0",
4706
4717
  CloudinaryJQuery: CloudinaryJQuery
4707
4718
  };
4708
4719
  return cloudinary;
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.8.3
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nadav Soferman
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-02-04 00:00:00.000000000 Z
13
+ date: 2018-02-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws_cf_signer
@@ -169,6 +169,7 @@ files:
169
169
  - lib/cloudinary/version.rb
170
170
  - lib/cloudinary/video_helper.rb
171
171
  - lib/tasks/cloudinary.rake
172
+ - spec/access_control_spec.rb
172
173
  - spec/api_spec.rb
173
174
  - spec/archive_spec.rb
174
175
  - spec/auth_token_spec.rb
@@ -230,6 +231,7 @@ signing_key:
230
231
  specification_version: 4
231
232
  summary: Client library for easily using the Cloudinary service
232
233
  test_files:
234
+ - spec/access_control_spec.rb
233
235
  - spec/api_spec.rb
234
236
  - spec/archive_spec.rb
235
237
  - spec/auth_token_spec.rb