cloudinary 1.3.0 → 1.4.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: 675877dafeb654d86f21a603814835b907b0b560
4
- data.tar.gz: 0afd3a11251a44cbc84293ded02975cd1473b01b
3
+ metadata.gz: 7a96fb520a45441c0cc40d980dc03836c6b7ffc4
4
+ data.tar.gz: 29924a2fa48916d03132b9bf6a080749471b558d
5
5
  SHA512:
6
- metadata.gz: d33e51978a4d8e65e5c7bb1463d8fe1c17ffbf8e4c099fb5b9cf4160877e69c6bd60698507e6718d1457ee713b4168d5782058a9399c3f5b67522e3c0bb16e02
7
- data.tar.gz: 1833b23e9d849a38ddc2d88844d89b33bb903c0e4acfcc6ede358995338df7fbb8922887fd924e96ae6be9f46964db69f3bdfe9f2b45036444d511647eedef0f
6
+ metadata.gz: 86b21f0e18c8759c79162d2b8f2cde2f1fd8807eae924c4fa6906f698f4a92e518763328a91dc36022c62edbf8772bad6b5f3885b41e4457831d1f11dcdd0d56
7
+ data.tar.gz: 94b7b4a747cb5bab25112cf0ac2041df8fa48009efbbc7f5719fe2df809ea3ae0d0f823928a3b0c6862839f4f3124db8ab3f0e6b2f2de52500d168570d118cb4
@@ -1,4 +1,11 @@
1
1
 
2
+ 1.4.0 / 2017-01-30
3
+ ==================
4
+
5
+ * Add Akamai token generator
6
+ * Merge pull request #201 from nashby/fix-image-formats
7
+ * Remove video formats from the image formats array.
8
+
2
9
  1.3.0 / 2016-12-22
3
10
  ==================
4
11
 
@@ -0,0 +1,50 @@
1
+ require 'openssl'
2
+
3
+ module Cloudinary
4
+ module Akamai
5
+ SEPARATOR = '~'
6
+
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ def generate_token(options)
13
+ key = options[:key] || Cloudinary.config.akamai_key
14
+ throw "Missing akamai_key configuration" unless key
15
+ name = options[:token_name] || "__cld_token__"
16
+ start = options[:start_time]
17
+ expiration = options[:end_time]
18
+ ip = options[:ip]
19
+ acl = options[:acl]
20
+ window = options[:window]
21
+
22
+ start = Time.new.getgm.to_i if start == 'now'
23
+ unless expiration
24
+ if window
25
+ expiration = (start || Time.new.getgm.to_i) + window
26
+ else
27
+ throw 'Must provide either end_time or window'
28
+ end
29
+ end
30
+
31
+ token = []
32
+ token << "ip=#{ip}" if ip
33
+ token << "st=#{start}" if start
34
+ token << "exp=#{expiration}"
35
+ token << "acl=#{acl}"
36
+ auth = digest(token.join(SEPARATOR), key)
37
+ token << "hmac=#{auth}"
38
+ "#{name}=#{token.join(SEPARATOR)}"
39
+ end
40
+
41
+ private
42
+
43
+ def digest(message, key = Cloudinary.config.akamai_key)
44
+ bin_key = Array(key).pack("H*")
45
+ digest = OpenSSL::Digest::SHA256.new
46
+ OpenSSL::HMAC.hexdigest(digest, bin_key, message)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -5,8 +5,10 @@ require 'uri'
5
5
  require 'aws_cf_signer'
6
6
  require 'json'
7
7
  require 'cgi'
8
+ require 'cloudinary/akamai'
8
9
 
9
10
  class Cloudinary::Utils
11
+ include Cloudinary::Akamai
10
12
  # @deprecated Use Cloudinary::SHARED_CDN
11
13
  SHARED_CDN = Cloudinary::SHARED_CDN
12
14
  DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION = {:width => :auto, :crop => :limit}
@@ -626,7 +628,7 @@ class Cloudinary::Utils
626
628
  end
627
629
  end
628
630
 
629
- IMAGE_FORMATS = %w(ai bmp bpg djvu eps eps3 flif gif h264 hdp hpx ico j2k jp2 jpc jpe jpg miff mka mp4 pdf png psd svg tif tiff wdp webm webp zip )
631
+ IMAGE_FORMATS = %w(ai bmp bpg djvu eps eps3 flif gif hdp hpx ico j2k jp2 jpc jpe jpg miff pdf png psd svg tif tiff wdp webp zip )
630
632
 
631
633
  AUDIO_FORMATS = %w(aac aifc aiff flac m4a mp3 ogg wav)
632
634
 
@@ -1,4 +1,4 @@
1
1
  # Copyright Cloudinary
2
2
  module Cloudinary
3
- VERSION = "1.3.0"
3
+ VERSION = "1.4.0"
4
4
  end
@@ -373,6 +373,10 @@ describe Cloudinary::Api do
373
373
  Cloudinary::Api.subfolders("test_folder1")
374
374
  end
375
375
 
376
+ it "should throw if folder is missing" do
377
+ Cloudinary::Api.subfolders("I_do_not_exist")
378
+ end
379
+
376
380
  describe '.restore' do
377
381
  it 'should restore a deleted resource' do
378
382
  expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :public_ids] => "api_test_restore", [:url] => /.*\/restore$/))
@@ -7,12 +7,46 @@ include Cloudinary
7
7
  describe Utils do
8
8
 
9
9
  it 'should parse integer range values' do
10
- expect(Utils.instance_eval {norm_range_value("200")}).to eq( "200")
10
+ expect(Utils.instance_eval { norm_range_value("200") }).to eq("200")
11
11
  end
12
12
  it "should parse float range values" do
13
- expect(Utils.instance_eval {norm_range_value("200.0")}).to eq("200.0"), "parse a float"
13
+ expect(Utils.instance_eval { norm_range_value("200.0") }).to eq("200.0"), "parse a float"
14
14
  end
15
15
  it "should parse a percent range value" do
16
- expect(Utils.instance_eval {norm_range_value("20p")}).to eq("20p")
16
+ expect(Utils.instance_eval { norm_range_value("20p") }).to eq("20p")
17
+ end
18
+ describe 'Utils.generate_token' do
19
+ config_backup = Cloudinary.config.clone
20
+ before do
21
+ Cloudinary.config.akamai_key = '00112233FF99'
22
+ end
23
+ after do
24
+ Cloudinary.config.each_pair { |k, _| Cloudinary.config.delete_field(k) }
25
+ Cloudinary.config(config_backup.to_h)
26
+ end
27
+ it "should generate an Akamai token with start_time and window" do
28
+ token = Utils.generate_token start_time: 1111111111, acl: '/image/*', window: 300
29
+ expect(token).to eq('__cld_token__=st=1111111111~exp=1111111411~acl=/image/*~hmac=0854e8b6b6a46471a80b2dc28c69bd352d977a67d031755cc6f3486c121b43af')
30
+ end
31
+ it "should generate an Akamai token with window" do
32
+ first_exp = Time.new.getgm.to_i + 300
33
+ # expiration is calculated automatically as now + window
34
+ token = Utils.generate_token acl: '*', window: 300
35
+ second_exp = Time.new.getgm.to_i + 300
36
+ match = /exp=(\d+)/.match(token)
37
+ expect(match[1]).to be_truthy
38
+ expiration = match[1].to_i
39
+ expect(expiration).to be_between(first_exp, second_exp)
40
+ expect(Utils.generate_token acl: '*', end_time: expiration).to eq(token)
41
+ end
42
+
43
+ it "should accept a key" do
44
+ expect(Utils.generate_token acl: '*', end_time: 10000000, key: '00aabbff')
45
+ .to eq('__cld_token__=exp=10000000~acl=*~hmac=030eafb6b19e499659d699b3d43e7595e35e3c0060e8a71904b3b8c8759f4890')
46
+ end
47
+ it "should throw if no end_time or window is provided" do
48
+ expect { Utils.generate_token acl: '*' }.to raise_error
49
+
50
+ end
17
51
  end
18
52
  end
@@ -1,6 +1,6 @@
1
1
 
2
2
  /**
3
- * Cloudinary's JavaScript library - Version 2.1.8
3
+ * Cloudinary's JavaScript library - Version 2.1.9
4
4
  * Copyright Cloudinary
5
5
  * see https://github.com/cloudinary/cloudinary_js
6
6
  *
@@ -1370,7 +1370,7 @@ var slice = [].slice,
1370
1370
  secure: (typeof window !== "undefined" && window !== null ? (ref = window.location) != null ? ref.protocol : void 0 : void 0) === 'https:'
1371
1371
  };
1372
1372
 
1373
- Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive_class", "responsive_use_breakpoints", "responsive_width", "round_dpr", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
1373
+ Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive", "responsive_class", "responsive_use_breakpoints", "responsive_width", "round_dpr", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
1374
1374
 
1375
1375
 
1376
1376
  /**
@@ -2715,10 +2715,12 @@ var slice = [].slice,
2715
2715
  /** @override */
2716
2716
 
2717
2717
  ImageTag.prototype.attributes = function() {
2718
- var attr;
2718
+ var attr, options, srcAttribute;
2719
2719
  attr = ImageTag.__super__.attributes.call(this) || [];
2720
- if (attr['src'] == null) {
2721
- attr['src'] = new Cloudinary(this.getOptions()).url(this.publicId);
2720
+ options = this.getOptions();
2721
+ srcAttribute = options.responsive && !options.client_hints ? 'data-src' : 'src';
2722
+ if (attr[srcAttribute] == null) {
2723
+ attr[srcAttribute] = new Cloudinary(this.getOptions()).url(this.publicId);
2722
2724
  }
2723
2725
  return attr;
2724
2726
  };
@@ -2913,7 +2915,7 @@ var slice = [].slice,
2913
2915
  Cloudinary = (function() {
2914
2916
  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;
2915
2917
 
2916
- VERSION = "2.1.8";
2918
+ VERSION = "2.1.9";
2917
2919
 
2918
2920
  CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
2919
2921
 
@@ -4148,7 +4150,7 @@ var slice = [].slice,
4148
4150
  TextLayer: TextLayer,
4149
4151
  SubtitlesLayer: SubtitlesLayer,
4150
4152
  Cloudinary: Cloudinary,
4151
- VERSION: "2.1.8",
4153
+ VERSION: "2.1.9",
4152
4154
  CloudinaryJQuery: CloudinaryJQuery
4153
4155
  };
4154
4156
  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.3.0
4
+ version: 1.4.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: 2016-12-22 00:00:00.000000000 Z
13
+ date: 2017-01-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws_cf_signer
@@ -129,6 +129,7 @@ files:
129
129
  - Rakefile
130
130
  - cloudinary.gemspec
131
131
  - lib/cloudinary.rb
132
+ - lib/cloudinary/akamai.rb
132
133
  - lib/cloudinary/api.rb
133
134
  - lib/cloudinary/blob.rb
134
135
  - lib/cloudinary/carrier_wave.rb