cloudinary 1.14.0 → 1.17.1

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
  SHA256:
3
- metadata.gz: 74a24f6c79eb085bd0f6bccdf71bfba55cf83b5f27f31153681af45e207a6090
4
- data.tar.gz: 3d2ed94607da0f4edd8cebb48c281f4a53483ac6d6952ca5002b656a4906dfe1
3
+ metadata.gz: e74e0f92ef1143c670e497a22d7b78c638f57d7a35a51585c7a895e654bb95e1
4
+ data.tar.gz: 64c6b47d7fe482f4cbc7a82a7024a3c18ab51529dc52224067bd120d29e239c1
5
5
  SHA512:
6
- metadata.gz: fc3d2a7de323d029a24f4fe19069aee0f44deb6fd325fd1b0387d77045dcab2fdaa1f05edeb650f49a0a93150af2e7019e9098506567f7e7ea91b20a312cd3b5
7
- data.tar.gz: e111b64de35d948c5fcb316d21a9123e779e9be6701de3b58fa2a49604eb73693ac200d1f13f3145b92e4b7892fb107ab663729472d0ec029bfd5b206a9d857e
6
+ metadata.gz: 784f4de3203258629ee5843fd80d105e6ad59727a43299c5742ae9af25bdd02389b5cc990c563d542a5463970a9d4ae27c9abe99747518962b0a017273c14c85
7
+ data.tar.gz: da26474dc9fa48717859e648f3620416c02717169a7bd1347e7d2636e6e86b9e39313a8ae5077b9f39c994c465a0d887b5d90d16d0ee0aa58e210757607f1dd3
@@ -0,0 +1,24 @@
1
+ ### Brief Summary of Changes
2
+ <!--
3
+ Provide some context as to what was changed, from an implementation standpoint.
4
+ -->
5
+
6
+ #### What does this PR address?
7
+ [ ] Gitub issue (Add reference - #XX)
8
+ [ ] Refactoring
9
+ [ ] New feature
10
+ [ ] Bug fix
11
+ [ ] Adds more tests
12
+
13
+ #### Are tests included?
14
+ [ ] Yes
15
+ [ ] No
16
+
17
+ #### Reviewer, Please Note:
18
+ <!--
19
+ List anything here that the reviewer should pay special attention to. This might
20
+ include, for example:
21
+ • Dependence on other PRs
22
+ • Reference to other Cloudinary SDKs
23
+ • Changes that seem arbitrary without further explanations
24
+ -->
@@ -12,4 +12,8 @@ matrix:
12
12
  rvm: ruby-2.5.3
13
13
  before_install:
14
14
  - gem install bundler
15
+
16
+ before_script: >
17
+ export CLOUDINARY_URL=$(bash tools/get_test_cloud.sh);
18
+ echo cloud_name: "$(echo $CLOUDINARY_URL | cut -d'@' -f2)"
15
19
  script: bundle exec rspec
@@ -1,4 +1,61 @@
1
1
 
2
+ 1.17.1 / 2020-08-25
3
+ ===================
4
+
5
+ * Fix options handling issue in SassC
6
+
7
+ 1.17.0 / 2020-08-21
8
+ ===================
9
+
10
+ New functionality and features
11
+ ------------------------------
12
+
13
+ * Add support for `eval` upload parameter
14
+ * Add support for 32-char signature length
15
+
16
+ Other Changes
17
+ -------------
18
+
19
+ * Fix escaping of query string characters in CarrierWave integration
20
+ * Fix detection integration test
21
+ * Integrate with sub-account test service
22
+ * Add pull request template
23
+
24
+ 1.16.1 / 2020-07-06
25
+ ===================
26
+
27
+ * Detect data URLs with suffix in mime type
28
+ * Fix `Invalid regular expression` error in Safari
29
+
30
+ 1.16.0 / 2020-06-29
31
+ ===================
32
+
33
+ New functionality and features
34
+ ------------------------------
35
+
36
+ * Add support for uploading `StringIO`
37
+
38
+ Other Changes
39
+ -------------
40
+
41
+ * Set default cache storage to `file` in `CarrierWave`
42
+ * Fix `normalize_expression` to ignore predefined variables
43
+ * Fix sample projects
44
+
45
+ 1.15.0 / 2020-06-11
46
+ ===================
47
+
48
+ New functionality and features
49
+ ------------------------------
50
+
51
+ * Add support for `accessibility_analysis` parameter
52
+
53
+ Other Changes
54
+ -------------
55
+ * Fix `download` function in `Cloudinary::CarrierWave`
56
+ * Fix handling of empty value in `if` parameter
57
+ * Fix consumption of configuration from environment variables
58
+
2
59
  1.14.0 / 2020-05-06
3
60
  ===================
4
61
 
data/Rakefile CHANGED
@@ -1,55 +1,13 @@
1
1
  require 'bundler'
2
2
  require 'fileutils'
3
- require 'tmpdir'
4
- require 'rest_client'
5
- require 'json'
6
- require 'rubygems/package'
7
-
8
3
  require 'rspec/core/rake_task'
4
+
9
5
  RSpec::Core::RakeTask.new(:spec)
10
6
  task :default => :spec
11
7
 
12
8
  Bundler::GemHelper.install_tasks
13
9
 
14
- namespace :cloudinary do
15
- desc "Fetch the latest JavaScript library files and create the JavaScript index files"
16
- task :fetch_assets do
17
- index_files = %w[jquery.ui.widget.js jquery.iframe-transport.js jquery.fileupload.js jquery.cloudinary.js]
18
- processing_files = %w[canvas-to-blob.min.js load-image.all.min.js jquery.fileupload-process.js jquery.fileupload-image.js jquery.fileupload-validate.js]
19
- files = index_files + processing_files
20
-
21
- release = JSON(RestClient.get("https://api.github.com/repos/cloudinary/cloudinary_js/releases/latest"))
22
-
23
- FileUtils.rm_rf 'vendor/assets'
24
- html_folder = 'vendor/assets/html'
25
- FileUtils.mkdir_p html_folder
26
- js_folder = 'vendor/assets/javascripts/cloudinary'
27
- FileUtils.mkdir_p js_folder
28
-
29
- puts "Fetching cloudinary_js version #{release["tag_name"]}\n\n"
30
- sio = StringIO.new(RestClient.get(release["tarball_url"]).body)
31
- file =Zlib::GzipReader.new(sio)
32
- tar = Gem::Package::TarReader.new(file)
33
- tar.each_entry do |entry|
34
- name = File.basename(entry.full_name)
35
- if files.include? name
36
- js_full_name = File.join(js_folder, name)
37
- puts "Adding #{js_full_name}"
38
- File.write js_full_name, entry.read
39
- elsif name == 'cloudinary_cors.html'
40
- html_full_name = File.join(html_folder, name)
41
- puts "Adding #{html_full_name}"
42
- File.write html_full_name, entry.read
43
- end
44
- end
45
- puts "Creating 'index.js' and 'processing.js' files"
46
- File.open("vendor/assets/javascripts/cloudinary/index.js", "w") do |f|
47
- index_files.each { |name| f.puts "//= require ./#{name}" }
48
- end
49
- File.open("vendor/assets/javascripts/cloudinary/processing.js", "w") do |f|
50
- processing_files.each { |name| f.puts "//= require ./#{name}" }
51
- end
52
- end
10
+ path = File.expand_path(__dir__)
11
+ Dir.glob("#{path}/lib/tasks/**/*.rake").each { |f| import f }
53
12
 
54
- end
55
13
  task :build => "cloudinary:fetch_assets"
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
 
34
34
  s.add_development_dependency "sqlite3"
35
35
  s.add_development_dependency "rspec", '>=3.5'
36
+ s.add_development_dependency "rspec-retry"
36
37
  s.add_development_dependency "rails", "~>5.2" if RUBY_VERSION >= "2.2.2"
37
38
 
38
39
  s.add_development_dependency "railties", "<= 4.2.7" if RUBY_VERSION <= "1.9.3"
@@ -64,19 +64,7 @@ module Cloudinary
64
64
  first_time = @@config.nil?
65
65
  @@config ||= OpenStruct.new((YAML.load(ERB.new(IO.read(config_dir.join("cloudinary.yml"))).result)[config_env] rescue {}))
66
66
 
67
- # Heroku support
68
- if first_time && ENV["CLOUDINARY_CLOUD_NAME"]
69
- set_config(
70
- "cloud_name" => ENV["CLOUDINARY_CLOUD_NAME"],
71
- "api_key" => ENV["CLOUDINARY_API_KEY"],
72
- "api_secret" => ENV["CLOUDINARY_API_SECRET"],
73
- "secure_distribution" => ENV["CLOUDINARY_SECURE_DISTRIBUTION"],
74
- "private_cdn" => ENV["CLOUDINARY_PRIVATE_CDN"].to_s == 'true',
75
- "secure" => ENV["CLOUDINARY_SECURE"].to_s == 'true'
76
- )
77
- elsif first_time && ENV["CLOUDINARY_URL"]
78
- config_from_url(ENV["CLOUDINARY_URL"])
79
- end
67
+ config_from_env if first_time
80
68
 
81
69
  set_config(new_config) if new_config
82
70
  yield(@@config) if block_given?
@@ -140,18 +128,34 @@ module Cloudinary
140
128
  end
141
129
 
142
130
  private
143
-
131
+
132
+ def self.config_from_env
133
+ # Heroku support
134
+ if ENV["CLOUDINARY_CLOUD_NAME"]
135
+ config_keys = ENV.keys.select! { |key| key.start_with? "CLOUDINARY_" }
136
+ config_keys -= ["CLOUDINARY_URL"] # ignore it when explicit options are passed
137
+ config_keys.each do |full_key|
138
+ conf_key = full_key["CLOUDINARY_".length..-1].downcase # convert "CLOUDINARY_CONFIG_NAME" to "config_name"
139
+ conf_val = ENV[full_key]
140
+ conf_val = conf_val == 'true' if %w[true false].include?(conf_val) # cast relevant boolean values
141
+ set_config(conf_key => conf_val)
142
+ end
143
+ elsif ENV["CLOUDINARY_URL"]
144
+ config_from_url(ENV["CLOUDINARY_URL"])
145
+ end
146
+ end
147
+
144
148
  def self.config_env
145
149
  return ENV["CLOUDINARY_ENV"] if ENV["CLOUDINARY_ENV"]
146
150
  return Rails.env if defined? Rails::env
147
151
  nil
148
152
  end
149
-
153
+
150
154
  def self.config_dir
151
- return Pathname.new(ENV["CLOUDINARY_CONFIG_DIR"]) if ENV["CLOUDINARY_CONFIG_DIR"]
155
+ return Pathname.new(ENV["CLOUDINARY_CONFIG_DIR"]) if ENV["CLOUDINARY_CONFIG_DIR"]
152
156
  self.app_root.join("config")
153
157
  end
154
-
158
+
155
159
  def self.set_config(new_config)
156
160
  new_config.each{|k,v| @@config.send(:"#{k}=", v) if !v.nil?}
157
161
  end
@@ -78,7 +78,7 @@ class Cloudinary::Api
78
78
  resource_type = options[:resource_type] || "image"
79
79
  type = options[:type] || "upload"
80
80
  uri = "resources/#{resource_type}/#{type}/#{public_id}"
81
- call_api(:get, uri,
81
+ call_api(:get, uri,
82
82
  only(options,
83
83
  :cinemagraph_analysis,
84
84
  :colors,
@@ -90,7 +90,8 @@ class Cloudinary::Api
90
90
  :pages,
91
91
  :phash,
92
92
  :quality_analysis,
93
- :derived_next_cursor
93
+ :derived_next_cursor,
94
+ :accessibility_analysis
94
95
  ), options)
95
96
  end
96
97
 
@@ -9,6 +9,7 @@ module Cloudinary::CarrierWave
9
9
 
10
10
  def self.included(base)
11
11
  base.storage Cloudinary::CarrierWave::Storage
12
+ base.cache_storage = :file if base.cache_storage.blank?
12
13
  base.extend ClassMethods
13
14
  base.class_attribute :metadata
14
15
  base.class_attribute :storage_type, instance_reader: false
@@ -1,10 +1,11 @@
1
1
  module Cloudinary::CarrierWave
2
2
  def download!(uri, *args)
3
- return super if !self.cloudinary_should_handle_remote?
3
+ return super unless self.cloudinary_should_handle_remote?
4
4
  if respond_to?(:process_uri)
5
5
  uri = process_uri(uri)
6
6
  else # Backward compatibility with old CarrierWave
7
- uri = URI.parse(Utils.smart_escape(Utils.smart_unescape(uri)))
7
+ remote_url_unsafe_chars = /([^a-zA-Z0-9_.\-\/:?&=]+)/ # In addition allow query string characters: "?","&" and "="
8
+ uri = URI.parse(Cloudinary::Utils.smart_escape(Cloudinary::Utils.smart_unescape(uri), remote_url_unsafe_chars))
8
9
  end
9
10
  return if uri.to_s.blank?
10
11
  self.original_filename = @cache_id = @filename = File.basename(uri.path).gsub(/[^a-zA-Z0-9\.\-\+_]/, '')
@@ -1,7 +1,8 @@
1
1
  class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
2
2
 
3
3
  def store!(file)
4
- return if !uploader.enable_processing
4
+ return unless uploader.enable_processing
5
+
5
6
  if uploader.is_main_uploader?
6
7
  case file
7
8
  when Cloudinary::CarrierWave::PreloadedCloudinaryFile
@@ -438,7 +438,7 @@ begin
438
438
  # @return [::SassC::Script::Value::String]
439
439
  def cloudinary_url(public_id, sass_options = {})
440
440
  options = {}
441
- sass_options.to_h.each { |k, v| options[k.value] = v.value }
441
+ sass_options.to_h.each { |k, v| options[k.value.to_sym] = v.value }
442
442
  url = Cloudinary::Utils.cloudinary_url(public_id.value, {:type => :asset}.merge(options))
443
443
  ::SassC::Script::Value::String.new("url(#{url})")
444
444
  end
@@ -1,6 +1,6 @@
1
1
  class Cloudinary::Railtie < Rails::Railtie
2
2
  rake_tasks do
3
- Dir[File.join(File.dirname(__FILE__),'../tasks/*.rake')].each { |f| load f }
3
+ Dir[File.join(File.dirname(__FILE__),'../tasks/**/*.rake')].each { |f| load f }
4
4
  end
5
5
  config.after_initialize do |app|
6
6
  ActionView::Base.send :include, CloudinaryHelper
@@ -37,6 +37,7 @@ class Cloudinary::Uploader
37
37
  :eager_async => Cloudinary::Utils.as_safe_bool(options[:eager_async]),
38
38
  :eager_notification_url => options[:eager_notification_url],
39
39
  :exif => Cloudinary::Utils.as_safe_bool(options[:exif]),
40
+ :eval => options[:eval],
40
41
  :face_coordinates => Cloudinary::Utils.encode_double_array(options[:face_coordinates]),
41
42
  :faces => Cloudinary::Utils.as_safe_bool(options[:faces]),
42
43
  :folder => options[:folder],
@@ -64,6 +65,7 @@ class Cloudinary::Uploader
64
65
  :unique_filename => Cloudinary::Utils.as_safe_bool(options[:unique_filename]),
65
66
  :upload_preset => options[:upload_preset],
66
67
  :use_filename => Cloudinary::Utils.as_safe_bool(options[:use_filename]),
68
+ :accessibility_analysis => Cloudinary::Utils.as_safe_bool(options[:accessibility_analysis])
67
69
  }
68
70
  params
69
71
  end
@@ -77,6 +79,9 @@ class Cloudinary::Uploader
77
79
  params = build_upload_params(options)
78
80
  if file.is_a?(Pathname)
79
81
  params[:file] = File.open(file, "rb")
82
+ elsif file.is_a?(StringIO)
83
+ file.rewind
84
+ params[:file] = Cloudinary::Blob.new(file.read, options)
80
85
  elsif file.respond_to?(:read) || Cloudinary::Utils.is_remote?(file)
81
86
  params[:file] = file
82
87
  else
@@ -248,7 +253,7 @@ class Cloudinary::Uploader
248
253
  end
249
254
  end
250
255
 
251
- # options may include 'exclusive' (boolean) which causes clearing this tag from all other resources
256
+ # options may include 'exclusive' (boolean) which causes clearing this tag from all other resources
252
257
  def self.add_tag(tag, public_ids = [], options = {})
253
258
  exclusive = options.delete(:exclusive)
254
259
  command = exclusive ? "set_exclusive" : "add"
@@ -139,7 +139,10 @@ class Cloudinary::Utils
139
139
  zoom
140
140
  ].map(&:to_sym)
141
141
 
142
- REMOTE_URL_REGEX = %r(^ftp:|^https?:|^s3:|^gs:|^data:([\w-]+\/[\w-]+)?(;[\w-]+=[\w-]+)*;base64,([a-zA-Z0-9\/+\n=]+)$)
142
+ REMOTE_URL_REGEX = %r(^ftp:|^https?:|^s3:|^gs:|^data:([\w-]+\/[\w-]+(\+[\w-]+)?)?(;[\w-]+=[\w-]+)*;base64,([a-zA-Z0-9\/+\n=]+)$)
143
+
144
+ LONG_URL_SIGNATURE_LENGTH = 32
145
+ SHORT_URL_SIGNATURE_LENGTH = 8
143
146
 
144
147
  def self.extract_config_params(options)
145
148
  options.select{|k,v| URL_KEYS.include?(k)}
@@ -302,15 +305,11 @@ class Cloudinary::Utils
302
305
  # Translates the condition if provided.
303
306
  # @return [string] "if_" + ifValue
304
307
  # @private
305
- def self.process_if(ifValue)
306
- if ifValue
307
- ifValue = normalize_expression(ifValue)
308
-
309
- ifValue = "if_" + ifValue
310
- end
308
+ def self.process_if(if_value)
309
+ "if_" + normalize_expression(if_value) unless if_value.to_s.empty?
311
310
  end
312
311
 
313
- EXP_REGEXP = Regexp.new(PREDEFINED_VARS.keys.join("|")+'|('+CONDITIONAL_OPERATORS.keys.reverse.map { |k| Regexp.escape(k) }.join('|')+')(?=[ _])')
312
+ EXP_REGEXP = Regexp.new('(?<!\$)('+PREDEFINED_VARS.keys.join("|")+')'+'|('+CONDITIONAL_OPERATORS.keys.reverse.map { |k| Regexp.escape(k) }.join('|')+')(?=[ _])')
314
313
  EXP_REPLACEMENT = PREDEFINED_VARS.merge(CONDITIONAL_OPERATORS)
315
314
 
316
315
  def self.normalize_expression(expression)
@@ -501,6 +500,7 @@ class Cloudinary::Utils
501
500
  url_suffix = options.delete(:url_suffix)
502
501
  use_root_path = config_option_consume(options, :use_root_path)
503
502
  auth_token = config_option_consume(options, :auth_token)
503
+ long_url_signature = config_option_consume(options, :long_url_signature)
504
504
  unless auth_token == false
505
505
  auth_token = Cloudinary::AuthToken.merge_auth_token(Cloudinary.config.auth_token, auth_token)
506
506
  end
@@ -545,7 +545,7 @@ class Cloudinary::Utils
545
545
  raise(CloudinaryException, "Must supply api_secret") if (secret.nil? || secret.empty?)
546
546
  to_sign = [transformation, sign_version && version, source_to_sign].reject(&:blank?).join("/")
547
547
  to_sign = fully_unescape(to_sign)
548
- signature = 's--' + Base64.urlsafe_encode64(Digest::SHA1.digest(to_sign + secret))[0,8] + '--'
548
+ signature = compute_signature(to_sign, secret, long_url_signature)
549
549
  end
550
550
 
551
551
  prefix = unsigned_download_url_prefix(source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname, secure, secure_distribution)
@@ -1136,4 +1136,24 @@ class Cloudinary::Utils
1136
1136
  def self.is_remote?(url)
1137
1137
  REMOTE_URL_REGEX === url
1138
1138
  end
1139
+
1140
+ # Computes a short or long signature based on a message and secret
1141
+ # @param [String] message The string to sign
1142
+ # @param [String] secret A secret that will be added to the message when signing
1143
+ # @param [Boolean] long_signature Whether to create a short or long signature
1144
+ # @return [String] Properly formatted signature
1145
+ def self.compute_signature(message, secret, long_url_signature)
1146
+ combined_message_secret = message + secret
1147
+
1148
+ algo, signature_length =
1149
+ if long_url_signature
1150
+ [Digest::SHA256, LONG_URL_SIGNATURE_LENGTH]
1151
+ else
1152
+ [Digest::SHA1, SHORT_URL_SIGNATURE_LENGTH]
1153
+ end
1154
+
1155
+ "s--#{Base64.urlsafe_encode64(algo.digest(combined_message_secret))[0, signature_length]}--"
1156
+ end
1157
+
1158
+ private_class_method :compute_signature
1139
1159
  end
@@ -1,4 +1,4 @@
1
1
  # Copyright Cloudinary
2
2
  module Cloudinary
3
- VERSION = "1.14.0"
3
+ VERSION = "1.17.1"
4
4
  end
@@ -0,0 +1,48 @@
1
+ require 'tmpdir'
2
+ require 'rest_client'
3
+ require 'json'
4
+ require 'rubygems/package'
5
+
6
+ unless Rake::Task.task_defined?('cloudinary:fetch_assets') # prevent double-loading/execution
7
+ namespace :cloudinary do
8
+ desc "Fetch the latest JavaScript library files and create the JavaScript index files"
9
+ task :fetch_assets do
10
+ index_files = %w[jquery.ui.widget.js jquery.iframe-transport.js jquery.fileupload.js jquery.cloudinary.js]
11
+ processing_files = %w[canvas-to-blob.min.js load-image.all.min.js jquery.fileupload-process.js jquery.fileupload-image.js jquery.fileupload-validate.js]
12
+ files = index_files + processing_files
13
+
14
+ release = JSON(RestClient.get("https://api.github.com/repos/cloudinary/cloudinary_js/releases/latest"))
15
+
16
+ FileUtils.rm_rf 'vendor/assets'
17
+ html_folder = 'vendor/assets/html'
18
+ FileUtils.mkdir_p html_folder
19
+ js_folder = 'vendor/assets/javascripts/cloudinary'
20
+ FileUtils.mkdir_p js_folder
21
+
22
+ puts "Fetching cloudinary_js version #{release["tag_name"]}\n\n"
23
+ sio = StringIO.new(RestClient.get(release["tarball_url"]).body)
24
+ file = Zlib::GzipReader.new(sio)
25
+ tar = Gem::Package::TarReader.new(file)
26
+ tar.each_entry do |entry|
27
+ name = File.basename(entry.full_name)
28
+ if files.include? name
29
+ js_full_name = File.join(js_folder, name)
30
+ puts "Adding #{js_full_name}"
31
+ File.write js_full_name, entry.read
32
+ elsif name == 'cloudinary_cors.html'
33
+ html_full_name = File.join(html_folder, name)
34
+ puts "Adding #{html_full_name}"
35
+ File.write html_full_name, entry.read
36
+ end
37
+ end
38
+ puts "Creating 'index.js' and 'processing.js' files"
39
+ File.open("vendor/assets/javascripts/cloudinary/index.js", "w") do |f|
40
+ index_files.each { |name| f.puts "//= require ./#{name}" }
41
+ end
42
+ File.open("vendor/assets/javascripts/cloudinary/processing.js", "w") do |f|
43
+ processing_files.each { |name| f.puts "//= require ./#{name}" }
44
+ end
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ API_ENDPOINT="https://sub-account-testing.cloudinary.com/create_sub_account"
4
+
5
+ SDK_NAME="${1}"
6
+
7
+ CLOUD_DETAILS=$(curl -sS -d "{\"prefix\" : \"${SDK_NAME}\"}" "${API_ENDPOINT}")
8
+
9
+ echo "${CLOUD_DETAILS}" | ruby -e "require 'json'; c=JSON.parse(ARGF.read)['payload']; puts 'cloudinary://' + c['cloudApiKey'] + ':'+ c['cloudApiSecret'] + '@' + c['cloudName']"
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
4
+
5
+ RUBY_VER=$(ruby -v | head -n 1 | cut -d ' ' -f 2);
6
+ SDK_VER=$(grep -oiP '(?<=VERSION = ")([a-zA-Z0-9\-.]+)(?=")' lib/cloudinary/version.rb)
7
+
8
+
9
+ bash "${DIR}"/allocate_test_cloud.sh "Ruby ${RUBY_VER} SDK ${SDK_VER}"
@@ -12,6 +12,8 @@ QUOTE=
12
12
 
13
13
  NEW_VERSION=
14
14
 
15
+ UPDATE_ONLY=false
16
+
15
17
  function echo_err
16
18
  {
17
19
  echo "$@" 1>&2;
@@ -23,6 +25,7 @@ function usage
23
25
  echo " -v | --version <version> set a new version"
24
26
  echo " -c | --current show current version"
25
27
  echo " -d | --dry-run print the commands without executing them"
28
+ echo " -u | --update-only only update the version"
26
29
  echo " -h | --help print this information and exit"
27
30
  echo
28
31
  echo "For example: $0 -v 1.2.3"
@@ -30,7 +33,7 @@ function usage
30
33
 
31
34
  function process_arguments
32
35
  {
33
- while [ "$1" != "" ]; do
36
+ while [[ "$1" != "" ]]; do
34
37
  case $1 in
35
38
  -v | --version )
36
39
  shift
@@ -53,6 +56,11 @@ function process_arguments
53
56
  echo "Dry Run"
54
57
  echo ""
55
58
  ;;
59
+ -u | --update-only )
60
+ UPDATE_ONLY=true
61
+ echo "Only update version"
62
+ echo ""
63
+ ;;
56
64
  -h | --help )
57
65
  usage; return 0
58
66
  ;;
@@ -72,7 +80,7 @@ function pushd
72
80
  # Intentionally make popd silent
73
81
  function popd
74
82
  {
75
- command popd "$@" > /dev/null
83
+ command popd > /dev/null
76
84
  }
77
85
 
78
86
  # Check if one version is less than or equal than other
@@ -82,7 +90,7 @@ function popd
82
90
  # ver_lte 1.2.4 1.2.3 && echo "yes" || echo "no" # no
83
91
  function ver_lte
84
92
  {
85
- [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
93
+ [[ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]]
86
94
  }
87
95
 
88
96
  # Extract the last entry or entry for a given version
@@ -108,6 +116,10 @@ function verify_dependencies
108
116
  return 1
109
117
  fi
110
118
 
119
+ if [[ "${UPDATE_ONLY}" = true ]]; then
120
+ return 0;
121
+ fi
122
+
111
123
  if [[ -z "$(type -t git-changelog)" ]]
112
124
  then
113
125
  echo_err "git-extras packages is not installed."
@@ -127,25 +139,26 @@ function safe_replace
127
139
 
128
140
  grep -q "${old}" "${file}" || { echo_err "${old} was not found in ${file}"; return 1; }
129
141
 
130
- ${CMD_PREFIX} sed -E -i '.bak' "${QUOTE}s/${old}/${new}/${QUOTE}" "${file}"
142
+ ${CMD_PREFIX} sed -i.bak -e "${QUOTE}s/${old}/${new}/${QUOTE}" -- "${file}" && rm -- "${file}.bak"
131
143
  }
132
144
 
133
145
  function current_version
134
146
  {
135
- grep -oiP '(?<=VERSION = ")([0-9.]+[^ ]*)(?=")' lib/cloudinary/version.rb
147
+ grep -oiP '(?<=VERSION = ")([a-zA-Z0-9\-.]+)(?=")' lib/cloudinary/version.rb
136
148
  }
137
149
 
138
150
  function update_version
139
151
  {
140
- if [ -z "${NEW_VERSION}" ]; then
152
+ if [[ -z "${NEW_VERSION}" ]]; then
141
153
  usage; return 1
142
154
  fi
143
155
 
144
156
  # Enter git root
145
157
  pushd $(git rev-parse --show-toplevel)
158
+
146
159
  local current_version=$(current_version)
147
160
 
148
- if [ -z "${current_version}" ]; then
161
+ if [[ -z "${current_version}" ]]; then
149
162
  echo_err "Failed getting current version, please check directory structure and/or contact developer"
150
163
  return 1
151
164
  fi
@@ -166,12 +179,17 @@ function update_version
166
179
  lib/cloudinary/version.rb\
167
180
  || return 1
168
181
 
169
- ${CMD_PREFIX} git changelog -t ${NEW_VERSION} || true
182
+ if [[ "${UPDATE_ONLY}" = true ]]; then
183
+ popd;
184
+ return 0;
185
+ fi
186
+
187
+ ${CMD_PREFIX} git changelog -t "${NEW_VERSION}" || true
170
188
 
171
189
  echo ""
172
190
  echo "# After editing CHANGELOG.md, optionally review changes and issue these commands:"
173
191
  echo git add lib/cloudinary/version.rb CHANGELOG.md
174
- echo git commit -m \"Version ${NEW_VERSION}\"
192
+ echo git commit -m "\"Version ${NEW_VERSION}\""
175
193
  echo sed -e "'1,/^${NEW_VERSION//./\\.}/d'" \
176
194
  -e "'/^=/d'" \
177
195
  -e "'/^$/d'" \
@@ -180,7 +198,7 @@ function update_version
180
198
  \| git tag -a "'${NEW_VERSION}'" --file=-
181
199
 
182
200
  # Don't run those commands on dry run
183
- [ -n "${CMD_PREFIX}" ] && { popd; return 0; }
201
+ [[ -n "${CMD_PREFIX}" ]] && { popd; return 0; }
184
202
 
185
203
  echo ""
186
204
  read -p "Run the above commands automatically? (y/N): " confirm && [[ ${confirm} == [yY] || ${confirm} == [yY][eE][sS] ]] || { popd; return 0; }
@@ -197,6 +215,6 @@ function update_version
197
215
  popd
198
216
  }
199
217
 
218
+ process_arguments "$@"
200
219
  verify_dependencies
201
- process_arguments $*
202
220
  update_version
@@ -1403,7 +1403,8 @@ var slice = [].slice,
1403
1403
  "*": "mul",
1404
1404
  "/": "div",
1405
1405
  "+": "add",
1406
- "-": "sub"
1406
+ "-": "sub",
1407
+ "^": "pow",
1407
1408
  };
1408
1409
 
1409
1410
 
@@ -1472,30 +1473,33 @@ var slice = [].slice,
1472
1473
  return new this(expressionStr);
1473
1474
  };
1474
1475
 
1475
-
1476
1476
  /**
1477
1477
  * Normalize a string expression
1478
1478
  * @function Cloudinary#normalize
1479
1479
  * @param {string} expression a expression, e.g. "w gt 100", "width_gt_100", "width > 100"
1480
1480
  * @return {string} the normalized form of the value expression, e.g. "w_gt_100"
1481
1481
  */
1482
-
1483
1482
  Expression.normalize = function(expression) {
1484
- var operators, pattern, replaceRE;
1483
+ var operators, operatorsPattern, operatorsReplaceRE, predefinedVarsPattern, predefinedVarsReplaceRE;
1485
1484
  if (expression == null) {
1486
1485
  return expression;
1487
1486
  }
1488
1487
  expression = String(expression);
1489
- operators = "\\|\\||>=|<=|&&|!=|>|=|<|/|-|\\+|\\*";
1490
- pattern = "((" + operators + ")(?=[ _])|" + Object.keys(Expression.PREDEFINED_VARS).join("|") + ")";
1491
- replaceRE = new RegExp(pattern, "g");
1492
- expression = expression.replace(replaceRE, function(match) {
1493
- return Expression.OPERATORS[match] || Expression.PREDEFINED_VARS[match];
1494
- });
1488
+ operators = "\\|\\||>=|<=|&&|!=|>|=|<|/|-|\\+|\\*|\\^";
1489
+
1490
+ // operators
1491
+ operatorsPattern = "((" + operators + ")(?=[ _]))";
1492
+ operatorsReplaceRE = new RegExp(operatorsPattern, "g");
1493
+ expression = expression.replace(operatorsReplaceRE, match => Expression.OPERATORS[match]);
1494
+
1495
+ // predefined variables
1496
+ predefinedVarsPattern = "(" + Object.keys(Expression.PREDEFINED_VARS).join("|") + ")";
1497
+ predefinedVarsReplaceRE = new RegExp(predefinedVarsPattern, "g");
1498
+ expression = expression.replace(predefinedVarsReplaceRE, (match, p1, offset) => (expression[offset - 1] === '$' ? match : Expression.PREDEFINED_VARS[match]));
1499
+
1495
1500
  return expression.replace(/[ _]+/g, '_');
1496
1501
  };
1497
1502
 
1498
-
1499
1503
  /**
1500
1504
  * Serialize the expression
1501
1505
  * @return {string} the expression as a string
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudinary
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.0
4
+ version: 1.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nadav Soferman
8
8
  - Itai Lahan
9
9
  - Tal Lev-Ami
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-05-06 00:00:00.000000000 Z
13
+ date: 2020-08-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws_cf_signer
@@ -110,6 +110,20 @@ dependencies:
110
110
  - - ">="
111
111
  - !ruby/object:Gem::Version
112
112
  version: '3.5'
113
+ - !ruby/object:Gem::Dependency
114
+ name: rspec-retry
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
113
127
  - !ruby/object:Gem::Dependency
114
128
  name: rails
115
129
  requirement: !ruby/object:Gem::Requirement
@@ -177,6 +191,7 @@ extra_rdoc_files: []
177
191
  files:
178
192
  - ".github/ISSUE_TEMPLATE/bug_report.md"
179
193
  - ".github/ISSUE_TEMPLATE/feature_request.md"
194
+ - ".github/pull_request_template.md"
180
195
  - ".gitignore"
181
196
  - ".rspec"
182
197
  - ".travis.yml"
@@ -220,7 +235,10 @@ files:
220
235
  - lib/cloudinary/utils.rb
221
236
  - lib/cloudinary/version.rb
222
237
  - lib/cloudinary/video_helper.rb
223
- - lib/tasks/cloudinary.rake
238
+ - lib/tasks/cloudinary/fetch_assets.rake
239
+ - lib/tasks/cloudinary/sync_static.rake
240
+ - tools/allocate_test_cloud.sh
241
+ - tools/get_test_cloud.sh
224
242
  - tools/update_version
225
243
  - vendor/assets/html/cloudinary_cors.html
226
244
  - vendor/assets/javascripts/cloudinary/canvas-to-blob.min.js
@@ -238,7 +256,7 @@ homepage: http://cloudinary.com
238
256
  licenses:
239
257
  - MIT
240
258
  metadata: {}
241
- post_install_message:
259
+ post_install_message:
242
260
  rdoc_options: []
243
261
  require_paths:
244
262
  - lib
@@ -253,8 +271,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
253
271
  - !ruby/object:Gem::Version
254
272
  version: '0'
255
273
  requirements: []
256
- rubygems_version: 3.0.6
257
- signing_key:
274
+ rubygems_version: 3.1.4
275
+ signing_key:
258
276
  specification_version: 4
259
277
  summary: Client library for easily using the Cloudinary service
260
278
  test_files: []