cloudinary 1.28.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 +8 -14
- data/CHANGELOG.md +51 -0
- data/README.md +7 -5
- data/cloudinary.gemspec +21 -51
- data/lib/active_storage/service/cloudinary_service.rb +6 -2
- data/lib/cloudinary/account_api.rb +76 -25
- data/lib/cloudinary/analytics.rb +157 -0
- data/lib/cloudinary/api.rb +63 -36
- 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/railtie.rb +3 -1
- data/lib/cloudinary/search.rb +18 -3
- data/lib/cloudinary/uploader.rb +70 -90
- data/lib/cloudinary/utils.rb +39 -55
- data/lib/cloudinary/version.rb +1 -1
- data/lib/cloudinary/video_helper.rb +3 -2
- 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
@@ -1,22 +1,16 @@
|
|
1
|
-
dist:
|
1
|
+
dist: jammy
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
-
|
5
|
-
- 2.
|
6
|
-
- 3.0
|
4
|
+
- 3.1.4
|
5
|
+
- 3.2.2
|
6
|
+
- 3.3.0
|
7
7
|
|
8
8
|
matrix:
|
9
9
|
include:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
- gem install bundler -v 1.17.3
|
15
|
-
- name: "Ruby 2.5.9"
|
16
|
-
dist: xenial
|
17
|
-
rvm: ruby-2.5.9
|
18
|
-
before_install:
|
19
|
-
- gem install bundler -v 2.3.26
|
10
|
+
# There is an OpenSSL issue on Jammy with Ruby 3.0
|
11
|
+
- name: "Ruby: 3.0.6"
|
12
|
+
dist: focal
|
13
|
+
rvm: 3.0.6
|
20
14
|
|
21
15
|
before_script: >
|
22
16
|
export CLOUDINARY_URL=$(bash tools/get_test_cloud.sh);
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,54 @@
|
|
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
|
+
|
34
|
+
1.29.0 / 2024-02-26
|
35
|
+
==================
|
36
|
+
|
37
|
+
New functionality and features
|
38
|
+
------------------------------
|
39
|
+
|
40
|
+
* Add support for `context` parameter in `url_for_direct_upload`
|
41
|
+
* Add support for `use_fetch_format` parameter in `cl_video_tag`
|
42
|
+
* Add support for `fields` parameter in Search and Admin APIs
|
43
|
+
* Add support for access keys management in Account Provisioning API
|
44
|
+
|
45
|
+
Other Changes
|
46
|
+
-------------
|
47
|
+
|
48
|
+
* Avoid early loading of `ActionView::Base`
|
49
|
+
* Fix `sqlite3` dependency version
|
50
|
+
* Add Rails 7.x to supported versions on `README.md`
|
51
|
+
|
1
52
|
1.28.0 / 2023-11-06
|
2
53
|
==================
|
3
54
|
|
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
|
-
| SDK Version | Rails 5.x | Rails 6.x |
|
46
|
-
|
47
|
-
| 1.x |
|
46
|
+
| SDK Version | Rails 5.x | Rails 6.x | Rails 7.x |
|
47
|
+
|-------------|-----------|-----------|-----------|
|
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 >= "2.7.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
|
@@ -81,7 +83,9 @@ module ActiveStorage
|
|
81
83
|
# through direct upload (client side js), filename is missing, and that leads to inconsistent/broken URLs.
|
82
84
|
# To avoid that, we explicitly pass file format in options.
|
83
85
|
options[:format] = ext_for_file(key) if options[:resource_type] == "raw"
|
86
|
+
context = options.delete(:context)
|
84
87
|
options[:context] = {active_storage_key: key}
|
88
|
+
options[:context].reverse_merge!(context) if context.respond_to?(:merge)
|
85
89
|
options.delete(:file)
|
86
90
|
payload[:url] = api_uri("upload", options)
|
87
91
|
end
|
@@ -147,7 +151,7 @@ module ActiveStorage
|
|
147
151
|
|
148
152
|
# Return the partial content in the byte +range+ of the file at the +key+.
|
149
153
|
def download_chunk(key, range)
|
150
|
-
url = Cloudinary::Utils.
|
154
|
+
url = Cloudinary::Utils.cloudinary_url(public_id(key), resource_type: resource_type(nil, key))
|
151
155
|
uri = URI(url)
|
152
156
|
instrument :download, key: key do
|
153
157
|
req = Net::HTTP::Get.new(uri)
|
@@ -13,10 +13,10 @@ class Cloudinary::AccountApi
|
|
13
13
|
# @param [Object] options additional options
|
14
14
|
def self.create_sub_account(name, cloud_name = nil, custom_attributes = {}, enabled = nil, base_account = nil, options = {})
|
15
15
|
params = {
|
16
|
-
name:
|
17
|
-
cloud_name:
|
18
|
-
custom_attributes:
|
19
|
-
enabled:
|
16
|
+
name: name,
|
17
|
+
cloud_name: cloud_name,
|
18
|
+
custom_attributes: custom_attributes,
|
19
|
+
enabled: enabled,
|
20
20
|
base_sub_account_id: base_account
|
21
21
|
}
|
22
22
|
|
@@ -35,10 +35,10 @@ class Cloudinary::AccountApi
|
|
35
35
|
# @param [Object] options additional options
|
36
36
|
def self.update_sub_account(sub_account_id, name = nil, cloud_name = nil, custom_attributes = nil, enabled = nil, options = {})
|
37
37
|
params = {
|
38
|
-
name:
|
39
|
-
cloud_name:
|
38
|
+
name: name,
|
39
|
+
cloud_name: cloud_name,
|
40
40
|
custom_attributes: custom_attributes,
|
41
|
-
enabled:
|
41
|
+
enabled: enabled
|
42
42
|
}
|
43
43
|
|
44
44
|
call_account_api(:put, ['sub_accounts', sub_account_id], params, options.merge(content_type: :json))
|
@@ -53,8 +53,8 @@ class Cloudinary::AccountApi
|
|
53
53
|
def self.sub_accounts(enabled = nil, ids = [], prefix = nil, options = {})
|
54
54
|
params = {
|
55
55
|
enabled: enabled,
|
56
|
-
ids:
|
57
|
-
prefix:
|
56
|
+
ids: ids,
|
57
|
+
prefix: prefix
|
58
58
|
}
|
59
59
|
|
60
60
|
call_account_api(:get, 'sub_accounts', params, options.merge(content_type: :json))
|
@@ -84,9 +84,9 @@ class Cloudinary::AccountApi
|
|
84
84
|
# @param [Object] options additional options
|
85
85
|
def self.create_user(name, email, role, sub_account_ids = [], options = {})
|
86
86
|
params = {
|
87
|
-
name:
|
88
|
-
email:
|
89
|
-
role:
|
87
|
+
name: name,
|
88
|
+
email: email,
|
89
|
+
role: role,
|
90
90
|
sub_account_ids: sub_account_ids
|
91
91
|
}
|
92
92
|
|
@@ -111,9 +111,9 @@ class Cloudinary::AccountApi
|
|
111
111
|
# @param [Object] options additional options
|
112
112
|
def self.update_user(user_id, name = nil, email = nil, role = nil, sub_account_ids = nil, options = {})
|
113
113
|
params = {
|
114
|
-
name:
|
115
|
-
email:
|
116
|
-
role:
|
114
|
+
name: name,
|
115
|
+
email: email,
|
116
|
+
role: role,
|
117
117
|
sub_account_ids: sub_account_ids
|
118
118
|
}
|
119
119
|
|
@@ -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
|
-
ids:
|
139
|
-
prefix:
|
147
|
+
ids: user_ids,
|
148
|
+
prefix: prefix,
|
140
149
|
sub_account_id: sub_account_id,
|
141
|
-
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))
|
@@ -210,16 +222,55 @@ class Cloudinary::AccountApi
|
|
210
222
|
call_account_api(:get, ['user_groups', group_id, 'users'], {}, options.merge(content_type: :json))
|
211
223
|
end
|
212
224
|
|
225
|
+
# Lists access keys.
|
226
|
+
#
|
227
|
+
# @param [String] sub_account_id The ID of the sub-account.
|
228
|
+
# @param [Object] options Additional options.
|
229
|
+
def self.access_keys(sub_account_id, options = {})
|
230
|
+
params = Cloudinary::Api.only(options, :page_size, :page, :sort_by, :sort_order)
|
231
|
+
call_account_api(:get, ['sub_accounts', sub_account_id, 'access_keys'], params, options)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Generates access key.
|
235
|
+
#
|
236
|
+
# @param [String] sub_account_id The ID of the sub-account.
|
237
|
+
# @param [String] name The display name as shown in the management console.
|
238
|
+
# @param [Boolean] enabled Whether to create the access key as enabled (default is enabled).
|
239
|
+
# @param [Object] options Additional options.
|
240
|
+
def self.generate_access_key(sub_account_id, name = nil, enabled = nil, options = {})
|
241
|
+
params = {
|
242
|
+
name: name,
|
243
|
+
enabled: enabled,
|
244
|
+
}
|
245
|
+
call_account_api(:post, ['sub_accounts', sub_account_id, 'access_keys'], params, options.merge(content_type: :json))
|
246
|
+
end
|
247
|
+
|
248
|
+
# Updates access key.
|
249
|
+
#
|
250
|
+
# @param [String] sub_account_id The ID of the sub-account.
|
251
|
+
# @param [String] api_key The API key.
|
252
|
+
# @param [String] name The display name as shown in the management console.
|
253
|
+
# @param [Boolean] enabled Enable or disable the access key.
|
254
|
+
# @param [Object] options Additional options.
|
255
|
+
def self.update_access_key(sub_account_id, api_key, name = nil, enabled = nil, options = {})
|
256
|
+
params = {
|
257
|
+
name: name,
|
258
|
+
enabled: enabled,
|
259
|
+
}
|
260
|
+
call_account_api(:put, ['sub_accounts', sub_account_id, 'access_keys', api_key], params, options.merge(content_type: :json))
|
261
|
+
end
|
262
|
+
|
213
263
|
def self.call_account_api(method, uri, params, options)
|
214
264
|
account_id = options[:account_id] || Cloudinary.account_config.account_id || raise('Must supply account_id')
|
215
265
|
api_key = options[:provisioning_api_key] || Cloudinary.account_config.provisioning_api_key || raise('Must supply provisioning api_key')
|
216
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'
|
217
268
|
|
218
269
|
params.reject! { |_, v| v.nil? }
|
219
270
|
auth = { :key => api_key, :secret => api_secret }
|
220
271
|
|
221
272
|
call_cloudinary_api(method, uri, auth, params, options) do |cloudinary, inner_uri|
|
222
|
-
[cloudinary,
|
273
|
+
[cloudinary, api_version, 'provisioning', 'accounts', account_id, inner_uri]
|
223
274
|
end
|
224
275
|
end
|
225
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
|