cloudinary 1.29.0 → 2.0.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 +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +33 -0
- data/README.md +5 -3
- data/cloudinary.gemspec +21 -51
- data/lib/active_storage/service/cloudinary_service.rb +4 -2
- data/lib/cloudinary/account_api.rb +21 -8
- data/lib/cloudinary/analytics.rb +157 -0
- data/lib/cloudinary/api.rb +24 -4
- data/lib/cloudinary/auth_token.rb +1 -5
- data/lib/cloudinary/base_api.rb +36 -31
- data/lib/cloudinary/carrier_wave/storage.rb +2 -1
- data/lib/cloudinary/carrier_wave.rb +0 -5
- data/lib/cloudinary/helper.rb +2 -10
- data/lib/cloudinary/migrator.rb +70 -71
- data/lib/cloudinary/uploader.rb +70 -90
- data/lib/cloudinary/utils.rb +31 -54
- data/lib/cloudinary/version.rb +1 -1
- data/lib/cloudinary.rb +3 -9
- data/lib/tasks/cloudinary/fetch_assets.rake +9 -3
- data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +3 -3
- metadata +164 -38
- data/lib/cloudinary/ostruct2.rb +0 -284
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d6f32cb53d97a60e6d0ec304b1dbee2a80e7d1610c9007a9a0331bf80c3f882
|
4
|
+
data.tar.gz: 29863f2c682c9800cef486624985a8d4f8959b7da19ce0f53b4377bdc0312eaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b7ac1b9edaeb3d8faad6dc1d75442f41cadef751400840c27ff176d370ca0739f68eda398c05efe56b7bfaa04376a0154f17840e15ac670fd4cc9d673527cb0
|
7
|
+
data.tar.gz: c3ba9122af7accec3abf2b9388b62be44e1e483a6f229e13ba40d1d283e9eef75c7179235b2674011e7d49d1fc12284c83b59f0dcfb0eed38e73195815123294
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
2.0.0 / 2024-04-08
|
2
|
+
==================
|
3
|
+
|
4
|
+
Breaking Changes
|
5
|
+
----------------
|
6
|
+
|
7
|
+
* Set minimal Ruby version to `3.0`
|
8
|
+
* For older Rubies use version `1.x` of this library
|
9
|
+
* Replace `rest-client` with `faraday`
|
10
|
+
* Set config `secure` to `true` by default
|
11
|
+
* All delivery URLs are set to be `https://` by default
|
12
|
+
* To disable - set `secure` to `false` in config/options
|
13
|
+
* Add support for URL Analytics
|
14
|
+
* Adds analytics signature query parameter to the delivery URLs
|
15
|
+
* To disable - set `analytics` to `false` in config/options
|
16
|
+
* Remove deprecated methods
|
17
|
+
* `Cloudinary::Utils.unsigned_download_url`
|
18
|
+
* use `Cloudinary::Utils.cloudinary_url` instead
|
19
|
+
* `Cloudinary::Utils.signed_download_url`
|
20
|
+
* use `Cloudinary::Utils.cloudinary_url` instead
|
21
|
+
* `Cloudinary::Utils.zip_download_url`
|
22
|
+
* use `Cloudinary::Utils.download_zip_url` instead
|
23
|
+
* `cl_zip_download_url`
|
24
|
+
* use `cl_download_zip_url` instead
|
25
|
+
* Remove deprecated constants
|
26
|
+
|
27
|
+
New functionality and features
|
28
|
+
------------------------------
|
29
|
+
|
30
|
+
* Add support for `analyze` API
|
31
|
+
* Support chunked uploads with CarrierWave
|
32
|
+
* Filter users by last login in `users` Provisioning API
|
33
|
+
|
1
34
|
1.29.0 / 2024-02-26
|
2
35
|
==================
|
3
36
|
|
data/README.md
CHANGED
@@ -40,11 +40,13 @@ the [Ruby on Rails SDK Guide](https://cloudinary.com/documentation/rails_integra
|
|
40
40
|
|
41
41
|
| SDK Version | Ruby 1.9.3 | Ruby 2.x | Ruby 3.x |
|
42
42
|
|-------------|------------|----------|----------|
|
43
|
-
| 1.x |
|
43
|
+
| 1.x | ✔ | ✔ | ✔ |
|
44
|
+
| 2.x | ✘ | ✘ | ✔ |
|
44
45
|
|
45
46
|
| SDK Version | Rails 5.x | Rails 6.x | Rails 7.x |
|
46
47
|
|-------------|-----------|-----------|-----------|
|
47
|
-
| 1.x |
|
48
|
+
| 1.x | ✔ | ✔ | ✔ |
|
49
|
+
| 2.x | ✘ | ✔ | ✔ |
|
48
50
|
|
49
51
|
## Installation
|
50
52
|
|
@@ -64,7 +66,7 @@ require 'cloudinary'
|
|
64
66
|
- [See full documentation](https://cloudinary.com/documentation/rails_image_manipulation).
|
65
67
|
|
66
68
|
```ruby
|
67
|
-
cl_image_tag("sample.jpg", :
|
69
|
+
cl_image_tag("sample.jpg", width: 100, height: 150, crop: "fill")
|
68
70
|
```
|
69
71
|
|
70
72
|
### Upload
|
data/cloudinary.gemspec
CHANGED
@@ -7,63 +7,33 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Cloudinary::VERSION
|
8
8
|
s.authors = ["Nadav Soferman","Itai Lahan","Tal Lev-Ami"]
|
9
9
|
s.email = ["nadav.soferman@cloudinary.com","itai.lahan@cloudinary.com","tal.levami@cloudinary.com"]
|
10
|
-
s.homepage = "
|
10
|
+
s.homepage = "https://cloudinary.com"
|
11
11
|
s.license = "MIT"
|
12
12
|
|
13
13
|
s.summary = %q{Client library for easily using the Cloudinary service}
|
14
14
|
s.description = %q{Client library for easily using the Cloudinary service}
|
15
15
|
|
16
|
-
s.
|
17
|
-
|
18
|
-
s.files = `git ls-files`.split("\n").select { |f| !f.start_with?("test", "spec", "features", "samples") } + Dir.glob("vendor/assets/javascripts/*/*") + Dir.glob("vendor/assets/html/*")
|
16
|
+
s.files = `git ls-files`.split("\n").select { |f| !f.start_with?("test", "spec", "features", "samples") } +
|
17
|
+
Dir.glob("vendor/assets/javascripts/*/*") + Dir.glob("vendor/assets/html/*")
|
19
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
19
|
s.require_paths = ["lib"]
|
21
20
|
|
22
|
-
s.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
s.add_development_dependency "
|
35
|
-
s.add_development_dependency "
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
s.add_development_dependency "rake", "<= 12.2.1"
|
41
|
-
end
|
42
|
-
if RUBY_VERSION >= "3.0.0"
|
43
|
-
s.add_development_dependency "sqlite3"
|
44
|
-
else
|
45
|
-
s.add_development_dependency "sqlite3", "< 1.6.0"
|
46
|
-
end
|
47
|
-
|
48
|
-
s.add_development_dependency "rspec", '>=3.5'
|
49
|
-
s.add_development_dependency "rspec-retry"
|
50
|
-
|
51
|
-
if RUBY_VERSION >= "3.0.0"
|
52
|
-
s.add_development_dependency "rails", "~> 6.0.3"
|
53
|
-
elsif RUBY_VERSION >= "2.2.2"
|
54
|
-
s.add_development_dependency "rails", "~> 5.2"
|
55
|
-
end
|
56
|
-
|
57
|
-
s.add_development_dependency "railties", "<= 4.2.7" if RUBY_VERSION <= "1.9.3"
|
58
|
-
s.add_development_dependency "rspec-rails"
|
59
|
-
|
60
|
-
s.add_development_dependency "rubyzip"
|
61
|
-
|
62
|
-
if RUBY_VERSION <= "2.4.0"
|
63
|
-
s.add_development_dependency "simplecov", "<= 0.17.1" # support testing Ruby 1.9
|
64
|
-
s.add_development_dependency 'loofah', '~>2.19.1'
|
65
|
-
s.add_development_dependency "rails-html-sanitizer", "<1.5.0"
|
66
|
-
else
|
67
|
-
s.add_development_dependency "simplecov", "> 0.18.0"
|
68
|
-
end
|
21
|
+
s.required_ruby_version = '~> 3'
|
22
|
+
|
23
|
+
s.add_dependency "faraday", ">= 2.0.1", "< 3.0.0"
|
24
|
+
s.add_dependency "faraday-multipart", "~> 1.0", ">= 1.0.4"
|
25
|
+
|
26
|
+
s.add_development_dependency 'faraday-follow_redirects', '~> 0.3.0'
|
27
|
+
s.add_development_dependency "rails", ">= 6.1.7", "< 8.0.0"
|
28
|
+
s.add_development_dependency "rexml", ">= 3.2.5", "< 4.0.0"
|
29
|
+
s.add_development_dependency "actionpack", ">= 6.1.7", "< 8.0.0"
|
30
|
+
s.add_development_dependency "nokogiri", ">= 1.12.5", "< 2.0.0"
|
31
|
+
s.add_development_dependency "rake", ">= 13.0.6", "< 14.0.0"
|
32
|
+
s.add_development_dependency "sqlite3", ">= 1.4.2", "< 2.0.0"
|
33
|
+
s.add_development_dependency "rspec", ">= 3.11.2", "< 4.0.0"
|
34
|
+
s.add_development_dependency "rspec-retry", ">= 0.6.2", "< 1.0.0"
|
35
|
+
s.add_development_dependency "railties", ">= 6.0.4", "< 8.0.0"
|
36
|
+
s.add_development_dependency "rspec-rails", ">= 6.0.4", "< 7.0.0"
|
37
|
+
s.add_development_dependency "rubyzip", ">= 2.3.0", "< 3.0.0"
|
38
|
+
s.add_development_dependency "simplecov", ">= 0.21.2", "< 1.0.0"
|
69
39
|
end
|
@@ -39,10 +39,12 @@ module ActiveStorage
|
|
39
39
|
begin
|
40
40
|
extra_headers = checksum.nil? ? {} : {Headers::CONTENT_MD5 => checksum}
|
41
41
|
options = @options.merge(options)
|
42
|
+
resource_type = resource_type(io, key)
|
43
|
+
options[:format] = ext_for_file(key) if resource_type == "raw"
|
42
44
|
Cloudinary::Uploader.upload_large(
|
43
45
|
io,
|
44
46
|
public_id: public_id_internal(key),
|
45
|
-
resource_type: resource_type
|
47
|
+
resource_type: resource_type,
|
46
48
|
context: {active_storage_key: key, checksum: checksum},
|
47
49
|
extra_headers: extra_headers,
|
48
50
|
**options
|
@@ -149,7 +151,7 @@ module ActiveStorage
|
|
149
151
|
|
150
152
|
# Return the partial content in the byte +range+ of the file at the +key+.
|
151
153
|
def download_chunk(key, range)
|
152
|
-
url = Cloudinary::Utils.
|
154
|
+
url = Cloudinary::Utils.cloudinary_url(public_id(key), resource_type: resource_type(nil, key))
|
153
155
|
uri = URI(url)
|
154
156
|
instrument :download, key: key do
|
155
157
|
req = Net::HTTP::Get.new(uri)
|
@@ -127,18 +127,30 @@ class Cloudinary::AccountApi
|
|
127
127
|
call_account_api(:get, ['users', user_id], {}, options.merge(content_type: :json))
|
128
128
|
end
|
129
129
|
|
130
|
-
#
|
131
|
-
#
|
132
|
-
# @param [
|
133
|
-
# @param [String]
|
134
|
-
# @param [String]
|
135
|
-
# @param [
|
130
|
+
# Get a list of the users according to filters.
|
131
|
+
#
|
132
|
+
# @param [Boolean] pending Optional. Limit results to pending users (true), users that are not pending (false), or all users (null)
|
133
|
+
# @param [Array<String>] user_ids Optional. List of user IDs. Up to 100
|
134
|
+
# @param [String] prefix Optional. Search by prefix of the user's name or email. Case-insensitive
|
135
|
+
# @param [String] sub_account_id Optional. Return only users who have access to the given sub-account
|
136
|
+
# @param [Object] options Generic advanced options map, see online documentation.
|
137
|
+
# @option options [Boolean] :last_login Optional. Return only users that last logged in in the specified range of dates (true),
|
138
|
+
# users that didn't last logged in in that range (false), or all users (null).
|
139
|
+
# @option options [Date] :from Optional. Last login start date.
|
140
|
+
# @option options [Date] :to Optional. Last login end date.
|
141
|
+
#
|
142
|
+
# @return [Cloudinary::Api::Response] the users' details.
|
143
|
+
#
|
144
|
+
# @raise [Cloudinary::Api::Error] If the request fails.
|
136
145
|
def self.users(pending = nil, user_ids = [], prefix = nil, sub_account_id = nil, options = {})
|
137
146
|
params = {
|
138
147
|
ids: user_ids,
|
139
148
|
prefix: prefix,
|
140
149
|
sub_account_id: sub_account_id,
|
141
|
-
pending: pending
|
150
|
+
pending: pending,
|
151
|
+
last_login: options[:last_login].to_s,
|
152
|
+
from: Cloudinary::Utils.to_usage_api_date_format(options[:from]),
|
153
|
+
to: Cloudinary::Utils.to_usage_api_date_format(options[:to])
|
142
154
|
}
|
143
155
|
|
144
156
|
call_account_api(:get, 'users', params, options.merge(content_type: :json))
|
@@ -252,12 +264,13 @@ class Cloudinary::AccountApi
|
|
252
264
|
account_id = options[:account_id] || Cloudinary.account_config.account_id || raise('Must supply account_id')
|
253
265
|
api_key = options[:provisioning_api_key] || Cloudinary.account_config.provisioning_api_key || raise('Must supply provisioning api_key')
|
254
266
|
api_secret = options[:provisioning_api_secret] || Cloudinary.account_config.provisioning_api_secret || raise('Must supply provisioning api_secret')
|
267
|
+
api_version = options[:api_version] || Cloudinary.config.api_version || 'v1_1'
|
255
268
|
|
256
269
|
params.reject! { |_, v| v.nil? }
|
257
270
|
auth = { :key => api_key, :secret => api_secret }
|
258
271
|
|
259
272
|
call_cloudinary_api(method, uri, auth, params, options) do |cloudinary, inner_uri|
|
260
|
-
[cloudinary,
|
273
|
+
[cloudinary, api_version, 'provisioning', 'accounts', account_id, inner_uri]
|
261
274
|
end
|
262
275
|
end
|
263
276
|
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudinary
|
4
|
+
module Analytics
|
5
|
+
extend self
|
6
|
+
|
7
|
+
QUERY_KEY = '_a'
|
8
|
+
ALGO_VERSION = 'B' # The version of the algorithm
|
9
|
+
SDK_CODE = 'C' # Cloudinary Ruby SDK
|
10
|
+
|
11
|
+
@product = 'A' # Official SDK. Set to 'B' for integrations.
|
12
|
+
@sdk_code = SDK_CODE
|
13
|
+
@sdk_version = Cloudinary::VERSION
|
14
|
+
@tech_version = "#{RUBY_VERSION[/\d+\.\d+/]}"
|
15
|
+
|
16
|
+
CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
17
|
+
BINARY_PAD_SIZE = 6
|
18
|
+
|
19
|
+
@char_codes = nil
|
20
|
+
@signature = nil
|
21
|
+
|
22
|
+
# Gets the SDK analytics signature query parameter.
|
23
|
+
#
|
24
|
+
# @return [String] The SDK signature query parameter.
|
25
|
+
def sdk_analytics_query_param
|
26
|
+
"#{QUERY_KEY}=#{self.sdk_analytics_signature}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Gets the SDK signature by encoding the SDK version and tech version.
|
30
|
+
#
|
31
|
+
# @return [String] The SDK signature.
|
32
|
+
def sdk_analytics_signature
|
33
|
+
return @signature unless @signature.nil?
|
34
|
+
|
35
|
+
begin
|
36
|
+
@signature = ALGO_VERSION + @product + @sdk_code + encode_version(@sdk_version) + encode_version(@tech_version)
|
37
|
+
rescue RangeError
|
38
|
+
@signature = 'E'
|
39
|
+
end
|
40
|
+
|
41
|
+
@signature
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets the product code.
|
45
|
+
#
|
46
|
+
# Used for integrations.
|
47
|
+
#
|
48
|
+
# @param [String] product The product code to set. 'A' is for the official SDK. 'B' for integrations.
|
49
|
+
#
|
50
|
+
# @return [void]
|
51
|
+
#
|
52
|
+
# @internal
|
53
|
+
def product(product)
|
54
|
+
@product = product
|
55
|
+
end
|
56
|
+
|
57
|
+
# Sets the SDK code.
|
58
|
+
#
|
59
|
+
# Used for integrations.
|
60
|
+
#
|
61
|
+
# @param [String] sdk_code The SDK code to set.
|
62
|
+
#
|
63
|
+
# @return [void]
|
64
|
+
#
|
65
|
+
# @internal
|
66
|
+
def sdk_code(sdk_code)
|
67
|
+
@sdk_code = sdk_code
|
68
|
+
end
|
69
|
+
|
70
|
+
# Sets the SDK version.
|
71
|
+
#
|
72
|
+
# Used for integrations.
|
73
|
+
#
|
74
|
+
# @param [String] sdk_version The SDK version to set (MAJOR.MINOR.PATCH), for example: "1.0.0".
|
75
|
+
#
|
76
|
+
# @return [void]
|
77
|
+
#
|
78
|
+
# @internal
|
79
|
+
def sdk_version(sdk_version)
|
80
|
+
@sdk_version = sdk_version
|
81
|
+
end
|
82
|
+
|
83
|
+
# Sets the tech version.
|
84
|
+
#
|
85
|
+
# Used for integrations.
|
86
|
+
#
|
87
|
+
# @param [String] tech_version The tech version to set (MAJOR.MINOR), for example: "1.0".
|
88
|
+
#
|
89
|
+
# @return [void]
|
90
|
+
#
|
91
|
+
# @internal
|
92
|
+
def tech_version(tech_version)
|
93
|
+
@tech_version = tech_version.split('.').first(2).join('.')
|
94
|
+
end
|
95
|
+
|
96
|
+
# Encodes a semVer-like version string.
|
97
|
+
#
|
98
|
+
# Example:
|
99
|
+
# input: '1.24.0'
|
100
|
+
# explode: ['1','24','0']
|
101
|
+
# pad: ['01','24','00']
|
102
|
+
# reverse: ['00', '24', '01']
|
103
|
+
# implode: '002401'
|
104
|
+
# int: 2401
|
105
|
+
# binary: '100101100001'
|
106
|
+
# padded: '000000100101100001'
|
107
|
+
# str_split: ['000000', '100101', '100001']
|
108
|
+
# getKey: ['A', 'l', 'h']
|
109
|
+
# implode: 'Alh'
|
110
|
+
#
|
111
|
+
# @param [String] version Can be either x.y.z or x.y
|
112
|
+
#
|
113
|
+
# @return [String] A string built from 3 characters of the base64 table
|
114
|
+
#
|
115
|
+
# @raise [RangeError] when version is larger than 43.21.26
|
116
|
+
def encode_version(version)
|
117
|
+
parts = version.split('.')
|
118
|
+
|
119
|
+
padded_parts = parts.map { |part| part.rjust(2, '0') }
|
120
|
+
number = padded_parts.reverse.join.to_i
|
121
|
+
padded_binary = int_to_padded_bin(number, parts.length * BINARY_PAD_SIZE)
|
122
|
+
|
123
|
+
raise RangeError, 'Version must be smaller than 43.21.26' if padded_binary.length % BINARY_PAD_SIZE != 0
|
124
|
+
|
125
|
+
encoded_chars = padded_binary.chars.each_slice(BINARY_PAD_SIZE).map { |slice| get_key(slice.join) }
|
126
|
+
|
127
|
+
encoded_chars.join
|
128
|
+
end
|
129
|
+
|
130
|
+
# Gets the key for binary value.
|
131
|
+
#
|
132
|
+
# @param [String] binary_value The value.
|
133
|
+
#
|
134
|
+
# @return [Array, Object] The key for the binary value.
|
135
|
+
def get_key(binary_value)
|
136
|
+
@char_codes ||= initialize_char_codes
|
137
|
+
|
138
|
+
@char_codes[binary_value] || ''
|
139
|
+
end
|
140
|
+
|
141
|
+
def initialize_char_codes
|
142
|
+
char_codes = {}
|
143
|
+
CHARS.chars.each_with_index { |char, idx| char_codes[int_to_padded_bin(idx, BINARY_PAD_SIZE)] = char }
|
144
|
+
char_codes
|
145
|
+
end
|
146
|
+
|
147
|
+
# Converts integer to left padded binary string.
|
148
|
+
#
|
149
|
+
# @param [Integer] integer The input.
|
150
|
+
# @param [Integer] pad_num The num of padding chars.
|
151
|
+
#
|
152
|
+
# @return [String] The padded binary string.
|
153
|
+
def int_to_padded_bin(integer, pad_num)
|
154
|
+
integer.to_s(2).rjust(pad_num, '0')
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
data/lib/cloudinary/api.rb
CHANGED
@@ -649,7 +649,7 @@ class Cloudinary::Api
|
|
649
649
|
#
|
650
650
|
# @see https://cloudinary.com/documentation/admin_api#update_an_upload_preset
|
651
651
|
def self.update_upload_preset(name, options={})
|
652
|
-
params = Cloudinary::Uploader.build_upload_params(options)
|
652
|
+
params = Cloudinary::Uploader.build_upload_params(options, true)
|
653
653
|
call_api(:put, "upload_presets/#{name}", params.merge(only(options, :unsigned, :disallow_public_id, :live)), options)
|
654
654
|
end
|
655
655
|
|
@@ -664,7 +664,7 @@ class Cloudinary::Api
|
|
664
664
|
#
|
665
665
|
# @see https://cloudinary.com/documentation/admin_api#create_an_upload_preset
|
666
666
|
def self.create_upload_preset(options={})
|
667
|
-
params = Cloudinary::Uploader.build_upload_params(options)
|
667
|
+
params = Cloudinary::Uploader.build_upload_params(options, true)
|
668
668
|
call_api(:post, "upload_presets", params.merge(only(options, :name, :unsigned, :disallow_public_id, :live)), options)
|
669
669
|
end
|
670
670
|
|
@@ -1222,6 +1222,25 @@ class Cloudinary::Api
|
|
1222
1222
|
call_metadata_rules_api(:delete, uri, {}, options)
|
1223
1223
|
end
|
1224
1224
|
|
1225
|
+
# Analyzes an asset with the requested analysis type.
|
1226
|
+
#
|
1227
|
+
# @param [Object] input_type The type of input for the asset to analyze ('uri').
|
1228
|
+
# @param [Object] analysis_type The type of analysis to run ('google_tagging', 'captioning', 'fashion').
|
1229
|
+
# @param [Hash] options The optional parameters.
|
1230
|
+
#
|
1231
|
+
# @return [Cloudinary::Api::Response]
|
1232
|
+
#
|
1233
|
+
# @raise [Cloudinary::Api::Error]
|
1234
|
+
def self.analyze(input_type, analysis_type, options = {})
|
1235
|
+
api_uri = ["analysis", "analyze", input_type]
|
1236
|
+
params = only(options, :uri, :parameters)
|
1237
|
+
params["analysis_type"] = analysis_type
|
1238
|
+
|
1239
|
+
options[:api_version] = 'v2'
|
1240
|
+
|
1241
|
+
call_api(:post, api_uri, params, options)
|
1242
|
+
end
|
1243
|
+
|
1225
1244
|
protected
|
1226
1245
|
|
1227
1246
|
# Execute a call api for input params.
|
@@ -1236,13 +1255,14 @@ class Cloudinary::Api
|
|
1236
1255
|
api_key = options[:api_key] || Cloudinary.config.api_key
|
1237
1256
|
api_secret = options[:api_secret] || Cloudinary.config.api_secret
|
1238
1257
|
oauth_token = options[:oauth_token] || Cloudinary.config.oauth_token
|
1258
|
+
api_version = options[:api_version] || Cloudinary.config.api_version || 'v1_1'
|
1239
1259
|
|
1240
1260
|
validate_authorization(api_key, api_secret, oauth_token)
|
1241
1261
|
|
1242
1262
|
auth = { :key => api_key, :secret => api_secret, :oauth_token => oauth_token }
|
1243
1263
|
|
1244
1264
|
call_cloudinary_api(method, uri, auth, params, options) do |cloudinary, inner_uri|
|
1245
|
-
[cloudinary,
|
1265
|
+
[cloudinary, api_version, cloud_name, inner_uri]
|
1246
1266
|
end
|
1247
1267
|
end
|
1248
1268
|
|
@@ -1254,7 +1274,7 @@ class Cloudinary::Api
|
|
1254
1274
|
return Cloudinary::Utils.json_decode(response.body)
|
1255
1275
|
rescue => e
|
1256
1276
|
# Error is parsing json
|
1257
|
-
raise GeneralError.new("Error parsing server response (#{response.
|
1277
|
+
raise GeneralError.new("Error parsing server response (#{response.status}) - #{response.body}. Got - #{e}")
|
1258
1278
|
end
|
1259
1279
|
|
1260
1280
|
# Protected function that assists with performing an API call to the metadata_fields part of the Admin API.
|
data/lib/cloudinary/base_api.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
require "
|
1
|
+
require "faraday"
|
2
2
|
require "json"
|
3
3
|
|
4
4
|
module Cloudinary::BaseApi
|
5
|
+
@adapter = nil
|
5
6
|
class Error < CloudinaryException; end
|
6
7
|
class NotFound < Error; end
|
7
8
|
class NotAllowed < Error; end
|
@@ -15,17 +16,19 @@ module Cloudinary::BaseApi
|
|
15
16
|
attr_reader :rate_limit_reset_at, :rate_limit_remaining, :rate_limit_allowed
|
16
17
|
|
17
18
|
def initialize(response=nil)
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
unless response
|
20
|
+
return
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
23
|
+
# This sets the instantiated self as the response Hash
|
24
|
+
update Cloudinary::Api.parse_json_response response
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
# According to RFC 2616, header names are case-insensitive.
|
27
|
+
lc_headers = response.headers.transform_keys(&:downcase)
|
28
|
+
|
29
|
+
@rate_limit_allowed = lc_headers["x-featureratelimit-limit"].to_i if lc_headers["x-featureratelimit-limit"]
|
30
|
+
@rate_limit_reset_at = Time.parse(lc_headers["x-featureratelimit-reset"]) if lc_headers["x-featureratelimit-reset"]
|
31
|
+
@rate_limit_remaining = lc_headers["x-featureratelimit-remaining"].to_i if lc_headers["x-featureratelimit-remaining"]
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
@@ -36,28 +39,30 @@ module Cloudinary::BaseApi
|
|
36
39
|
end
|
37
40
|
|
38
41
|
def call_json_api(method, api_url, payload, timeout, headers, proxy = nil, user = nil, password = nil)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
headers: headers,
|
44
|
-
proxy: proxy,
|
45
|
-
user: user,
|
46
|
-
password: password) do |response|
|
47
|
-
return Response.new(response) if response.code == 200
|
48
|
-
exception_class = case response.code
|
49
|
-
when 400 then BadRequest
|
50
|
-
when 401 then AuthorizationRequired
|
51
|
-
when 403 then NotAllowed
|
52
|
-
when 404 then NotFound
|
53
|
-
when 409 then AlreadyExists
|
54
|
-
when 420 then RateLimited
|
55
|
-
when 500 then GeneralError
|
56
|
-
else raise GeneralError.new("Server returned unexpected status code - #{response.code} - #{response.body}")
|
57
|
-
end
|
58
|
-
json = Cloudinary::Api.parse_json_response(response)
|
59
|
-
raise exception_class.new(json["error"]["message"])
|
42
|
+
conn = Faraday.new(url: api_url) do |faraday|
|
43
|
+
faraday.proxy = proxy if proxy
|
44
|
+
faraday.request :json
|
45
|
+
faraday.adapter @adapter || Faraday.default_adapter
|
60
46
|
end
|
47
|
+
|
48
|
+
response = conn.run_request(method.downcase.to_sym, nil, payload, headers) do |req|
|
49
|
+
req.options.timeout = timeout if timeout
|
50
|
+
req.basic_auth(user, password) if user && password
|
51
|
+
end
|
52
|
+
|
53
|
+
return Response.new(response) if response.status == 200
|
54
|
+
exception_class = case response.status
|
55
|
+
when 400 then BadRequest
|
56
|
+
when 401 then AuthorizationRequired
|
57
|
+
when 403 then NotAllowed
|
58
|
+
when 404 then NotFound
|
59
|
+
when 409 then AlreadyExists
|
60
|
+
when 420 then RateLimited
|
61
|
+
when 500 then GeneralError
|
62
|
+
else raise GeneralError.new("Server returned unexpected status code - #{response.status} - #{response.body}")
|
63
|
+
end
|
64
|
+
json = Cloudinary::Api.parse_json_response(response)
|
65
|
+
raise exception_class.new(json["error"]["message"])
|
61
66
|
end
|
62
67
|
|
63
68
|
private
|
@@ -36,7 +36,8 @@ class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
|
|
36
36
|
params[:type]=uploader.class.storage_type
|
37
37
|
|
38
38
|
params[:resource_type] ||= :auto
|
39
|
-
uploader.
|
39
|
+
upload_method = uploader.upload_chunked? ? "upload_large" : "upload"
|
40
|
+
uploader.metadata = Cloudinary::Uploader.send(upload_method, data, params)
|
40
41
|
if uploader.metadata["error"]
|
41
42
|
raise Cloudinary::CarrierWave::UploadError.new(uploader.metadata["error"]["message"], uploader.metadata["error"]["http_code"])
|
42
43
|
end
|
data/lib/cloudinary/helper.rb
CHANGED
@@ -286,13 +286,6 @@ module CloudinaryHelper
|
|
286
286
|
Cloudinary::Utils.private_download_url(public_id, format, options)
|
287
287
|
end
|
288
288
|
|
289
|
-
# Helper method that uses the deprecated ZIP download API.
|
290
|
-
# Replaced by cl_download_zip_url that uses the more advanced and robust archive generation and download API
|
291
|
-
# @deprecated
|
292
|
-
def cl_zip_download_url(tag, options = {})
|
293
|
-
Cloudinary::Utils.zip_download_url(tag, options)
|
294
|
-
end
|
295
|
-
|
296
289
|
# @see {Cloudinary::Utils.download_archive_url}
|
297
290
|
def cl_download_archive_url(options = {})
|
298
291
|
Cloudinary::Utils.download_archive_url(options)
|
@@ -304,13 +297,13 @@ module CloudinaryHelper
|
|
304
297
|
end
|
305
298
|
|
306
299
|
def cl_signed_download_url(public_id, options = {})
|
307
|
-
Cloudinary::Utils.
|
300
|
+
Cloudinary::Utils.cloudinary_url(public_id, options)
|
308
301
|
end
|
309
302
|
|
310
303
|
def self.included(base)
|
311
304
|
ActionView::Helpers::FormBuilder.send(:include, Cloudinary::FormBuilder)
|
312
305
|
base.class_eval do
|
313
|
-
|
306
|
+
unless method_defined?(:image_tag)
|
314
307
|
include ActionView::Helpers::AssetTagHelper
|
315
308
|
end
|
316
309
|
alias_method :image_tag_without_cloudinary, :image_tag unless public_method_defined? :image_tag_without_cloudinary
|
@@ -325,7 +318,6 @@ module CloudinaryHelper
|
|
325
318
|
private
|
326
319
|
|
327
320
|
def cloudinary_url_internal(source, options = {})
|
328
|
-
options[:ssl_detected] = request.ssl? if defined?(request) && request && request.respond_to?(:ssl?)
|
329
321
|
if defined?(CarrierWave::Uploader::Base) && source.is_a?(CarrierWave::Uploader::Base)
|
330
322
|
if source.version_name.present?
|
331
323
|
options[:transformation] = Cloudinary::Utils.build_array(source.transformation) + Cloudinary::Utils.build_array(options[:transformation])
|