cloudinary 1.8.3 → 1.9.0

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 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