cloudinary 1.29.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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])
|