cloudinary 1.25.0 → 1.27.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/CHANGELOG.md +22 -0
- data/cloudinary.gemspec +7 -1
- data/lib/active_storage/service/cloudinary_service.rb +1 -1
- data/lib/cloudinary/api.rb +169 -0
- data/lib/cloudinary/search.rb +57 -2
- data/lib/cloudinary/search_folders.rb +5 -0
- data/lib/cloudinary/uploader.rb +18 -4
- data/lib/cloudinary/utils.rb +26 -16
- data/lib/cloudinary/version.rb +1 -1
- data/lib/cloudinary.rb +1 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46b21a3d7dd2411acaaeb35016f2ff7b648aeae5c1d077870f38e858ce1abedf
|
4
|
+
data.tar.gz: 5825bea0988e97e71df1d93fde04739b502230cda987f90415cb46f55df8b6b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24c1334398c9c24ce9b0b536e991fb76aa633e1bda93b5e8dcccc1d2ac2f747e4645f52b61ad3b6db7bb9a59a092df602c35b964a05661c151fb6026cd1954c0
|
7
|
+
data.tar.gz: f8f3cdbe7b7374532f5dae2f5dca3543697a2fb2398050b4a7874d6527b3e87ffc84970684aefe25c65f255ba9ec89e15470e28658c28287df781e4ee2144799
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
1.27.0 / 2023-07-31
|
2
|
+
==================
|
3
|
+
|
4
|
+
New functionality and features
|
5
|
+
------------------------------
|
6
|
+
|
7
|
+
* Add support for `visual_search` Admin API
|
8
|
+
* Add support for Search URL
|
9
|
+
* Add support for `SearchFolders` API
|
10
|
+
* Add support for `media_metadata` API parameter
|
11
|
+
|
12
|
+
1.26.0 / 2023-06-01
|
13
|
+
==================
|
14
|
+
|
15
|
+
New functionality and features
|
16
|
+
------------------------------
|
17
|
+
|
18
|
+
* Add support for related assets Admin APIs
|
19
|
+
* Add support for expressions in `start_offset` and `end_offset` parameters
|
20
|
+
* Add support for Conditional Metadata Rules API
|
21
|
+
* Add support for large files in Active Storage
|
22
|
+
|
1
23
|
1.25.0 / 2023-01-04
|
2
24
|
==================
|
3
25
|
|
data/cloudinary.gemspec
CHANGED
@@ -39,8 +39,12 @@ Gem::Specification.new do |s|
|
|
39
39
|
else
|
40
40
|
s.add_development_dependency "rake", "<= 12.2.1"
|
41
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
|
42
47
|
|
43
|
-
s.add_development_dependency "sqlite3"
|
44
48
|
s.add_development_dependency "rspec", '>=3.5'
|
45
49
|
s.add_development_dependency "rspec-retry"
|
46
50
|
|
@@ -57,6 +61,8 @@ Gem::Specification.new do |s|
|
|
57
61
|
|
58
62
|
if RUBY_VERSION <= "2.4.0"
|
59
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"
|
60
66
|
else
|
61
67
|
s.add_development_dependency "simplecov", "> 0.18.0"
|
62
68
|
end
|
@@ -39,7 +39,7 @@ module ActiveStorage
|
|
39
39
|
begin
|
40
40
|
extra_headers = checksum.nil? ? {} : {Headers::CONTENT_MD5 => checksum}
|
41
41
|
options = @options.merge(options)
|
42
|
-
Cloudinary::Uploader.
|
42
|
+
Cloudinary::Uploader.upload_large(
|
43
43
|
io,
|
44
44
|
public_id: public_id_internal(key),
|
45
45
|
resource_type: resource_type(io, key),
|
data/lib/cloudinary/api.rb
CHANGED
@@ -207,6 +207,19 @@ class Cloudinary::Api
|
|
207
207
|
call_api(:get, uri, params, options)
|
208
208
|
end
|
209
209
|
|
210
|
+
# Find images based on their visual content.
|
211
|
+
#
|
212
|
+
# @param [Hash] options The optional parameters.
|
213
|
+
#
|
214
|
+
# @return [Cloudinary::Api::Response]
|
215
|
+
#
|
216
|
+
# @raise [Cloudinary::Api::Error]
|
217
|
+
def self.visual_search(options = {})
|
218
|
+
uri = "resources/visual_search"
|
219
|
+
params = only(options, :image_url, :image_asset_id, :text)
|
220
|
+
call_api(:get, uri, params, options)
|
221
|
+
end
|
222
|
+
|
210
223
|
# Returns the details of the specified asset and all its derived assets.
|
211
224
|
#
|
212
225
|
# Note that if you only need details about the original asset,
|
@@ -406,6 +419,76 @@ class Cloudinary::Api
|
|
406
419
|
call_api(:delete, uri, params, options)
|
407
420
|
end
|
408
421
|
|
422
|
+
# Relates an asset to other assets by public IDs.
|
423
|
+
#
|
424
|
+
# @param [String] public_id The public ID of the asset.
|
425
|
+
# @param [String|Array] assets_to_relate The array of up to 10 fully_qualified_public_ids given as
|
426
|
+
# resource_type/type/public_id.
|
427
|
+
# @param [Hash] options The optional parameters. See the
|
428
|
+
# {https://cloudinary.com/documentation/admin_api#add_related_assets Admin API} documentation.
|
429
|
+
#
|
430
|
+
# @return [Cloudinary::Api::Response]
|
431
|
+
#
|
432
|
+
# @raise [Cloudinary::Api::Error]
|
433
|
+
def self.add_related_assets(public_id, assets_to_relate, options={})
|
434
|
+
resource_type = options[:resource_type] || "image"
|
435
|
+
type = options[:type] || "upload"
|
436
|
+
uri = "resources/related_assets/#{resource_type}/#{type}/#{public_id}"
|
437
|
+
params = {:assets_to_relate => Cloudinary::Utils.build_array(assets_to_relate)}
|
438
|
+
call_api(:post, uri, params, options)
|
439
|
+
end
|
440
|
+
|
441
|
+
# Relates an asset to other assets by asset IDs.
|
442
|
+
#
|
443
|
+
# @param [String] asset_id The asset ID of the asset to update.
|
444
|
+
# @param [String|Array] assets_to_relate The array of up to 10 asset IDs.
|
445
|
+
# @param [Hash] options The optional parameters. See the
|
446
|
+
# {https://cloudinary.com/documentation/admin_api#add_related_assets_by_asset_id Admin API} documentation.
|
447
|
+
#
|
448
|
+
# @return [Cloudinary::Api::Response]
|
449
|
+
#
|
450
|
+
# @raise [Cloudinary::Api::Error]
|
451
|
+
def self.add_related_assets_by_asset_ids(asset_id, assets_to_relate, options={})
|
452
|
+
uri = "resources/related_assets/#{asset_id}"
|
453
|
+
params = {:assets_to_relate => Cloudinary::Utils.build_array(assets_to_relate)}
|
454
|
+
call_api(:post, uri, params, options)
|
455
|
+
end
|
456
|
+
|
457
|
+
# Unrelates an asset from other assets by public IDs.
|
458
|
+
#
|
459
|
+
# @param [String] public_id The public ID of the asset.
|
460
|
+
# @param [String|Array] assets_to_unrelate The array of up to 10 fully_qualified_public_ids given as
|
461
|
+
# resource_type/type/public_id.
|
462
|
+
# @param [Hash] options The optional parameters. See the
|
463
|
+
# {https://cloudinary.com/documentation/admin_api#delete_related_assets Admin API} documentation.
|
464
|
+
#
|
465
|
+
# @return [Cloudinary::Api::Response]
|
466
|
+
#
|
467
|
+
# @raise [Cloudinary::Api::Error]
|
468
|
+
def self.delete_related_assets(public_id, assets_to_unrelate, options={})
|
469
|
+
resource_type = options[:resource_type] || "image"
|
470
|
+
type = options[:type] || "upload"
|
471
|
+
uri = "resources/related_assets/#{resource_type}/#{type}/#{public_id}"
|
472
|
+
params = {:assets_to_unrelate => Cloudinary::Utils.build_array(assets_to_unrelate)}
|
473
|
+
call_api(:delete, uri, params, options)
|
474
|
+
end
|
475
|
+
|
476
|
+
# Unrelates an asset from other assets by asset IDs.
|
477
|
+
#
|
478
|
+
# @param [String] asset_id The asset ID of the asset to update.
|
479
|
+
# @param [String|Array] assets_to_unrelate The array of up to 10 asset IDs.
|
480
|
+
# @param [Hash] options The optional parameters. See the
|
481
|
+
# {https://cloudinary.com/documentation/admin_api#delete_related_assets_by_asset_id Admin API} documentation.
|
482
|
+
#
|
483
|
+
# @return [Cloudinary::Api::Response]
|
484
|
+
#
|
485
|
+
# @raise [Cloudinary::Api::Error]
|
486
|
+
def self.delete_related_assets_by_asset_ids(asset_id, assets_to_unrelate, options={})
|
487
|
+
uri = "resources/related_assets/#{asset_id}"
|
488
|
+
params = {:assets_to_unrelate => Cloudinary::Utils.build_array(assets_to_unrelate)}
|
489
|
+
call_api(:delete, uri, params, options)
|
490
|
+
end
|
491
|
+
|
409
492
|
# Lists all the tags currently used for a specified asset type.
|
410
493
|
#
|
411
494
|
# @param [Hash] options The optional parameters. See the
|
@@ -1077,6 +1160,75 @@ class Cloudinary::Api
|
|
1077
1160
|
call_metadata_api(:put, uri, params, options)
|
1078
1161
|
end
|
1079
1162
|
|
1163
|
+
# Lists all metadata rules definitions.
|
1164
|
+
#
|
1165
|
+
# @param [Hash] options The optional parameters.
|
1166
|
+
#
|
1167
|
+
# @return [Cloudinary::Api::Response]
|
1168
|
+
#
|
1169
|
+
# @raise [Cloudinary::Api::Error]
|
1170
|
+
#
|
1171
|
+
# @see https://cloudinary.com/documentation/conditional_metadata_rules_api#get_metadata_rules
|
1172
|
+
def self.list_metadata_rules(options = {})
|
1173
|
+
call_metadata_rules_api(:get, [], {}, options)
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
|
1177
|
+
# Creates a new metadata rule definition.
|
1178
|
+
#
|
1179
|
+
# @param [Hash] rule The rule to add.
|
1180
|
+
# @param [Hash] options The optional parameters.
|
1181
|
+
#
|
1182
|
+
# @return [Cloudinary::Api::Response]
|
1183
|
+
#
|
1184
|
+
# @raise [Cloudinary::Api::Error]
|
1185
|
+
#
|
1186
|
+
# @see https://cloudinary.com/documentation/conditional_metadata_rules_api#create_a_metadata_rule
|
1187
|
+
def self.add_metadata_rule(rule, options = {})
|
1188
|
+
params = only(rule, :metadata_field_id, :condition, :result, :name)
|
1189
|
+
|
1190
|
+
call_metadata_rules_api(:post, [], params, options)
|
1191
|
+
end
|
1192
|
+
|
1193
|
+
# Updates a metadata rule by external ID.
|
1194
|
+
#
|
1195
|
+
# Updates an existing metadata rule definition. Expects a JSON object which defines the updated rule.
|
1196
|
+
#
|
1197
|
+
# @param [String] external_id The ID of the rule to update.
|
1198
|
+
# @param [Hash] rule The rule definition.
|
1199
|
+
# @param [Hash] options The optional parameters.
|
1200
|
+
#
|
1201
|
+
# @return [Cloudinary::Api::Response]
|
1202
|
+
#
|
1203
|
+
# @raise [Cloudinary::Api::Error]
|
1204
|
+
#
|
1205
|
+
# @see https://cloudinary.com/documentation/conditional_metadata_rules_api#update_a_metadata_rule_by_id
|
1206
|
+
def self.update_metadata_rule(external_id, rule, options = {})
|
1207
|
+
uri = [external_id]
|
1208
|
+
params = only(rule, :metadata_field_id, :condition, :result, :name, :state)
|
1209
|
+
|
1210
|
+
call_metadata_rules_api(:put, uri, params, options)
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
# Deletes a metadata rule definition by external ID.
|
1214
|
+
#
|
1215
|
+
# The rule should no longer be considered a valid candidate for all other endpoints
|
1216
|
+
# (it will not show up in the list of rules, etc).
|
1217
|
+
#
|
1218
|
+
# @param [String] external_id The ID of the rule to delete.
|
1219
|
+
# @param [Hash] options The optional parameters.
|
1220
|
+
#
|
1221
|
+
# @return [Cloudinary::Api::Response]
|
1222
|
+
#
|
1223
|
+
# @raise [Cloudinary::Api::Error]
|
1224
|
+
#
|
1225
|
+
# @see https://cloudinary.com/documentation/conditional_metadata_rules_api#delete_a_metadata_rule_by_id
|
1226
|
+
def self.delete_metadata_rule(external_id, options = {})
|
1227
|
+
uri = [external_id]
|
1228
|
+
|
1229
|
+
call_metadata_rules_api(:delete, uri, {}, options)
|
1230
|
+
end
|
1231
|
+
|
1080
1232
|
protected
|
1081
1233
|
|
1082
1234
|
# Execute a call api for input params.
|
@@ -1128,6 +1280,22 @@ class Cloudinary::Api
|
|
1128
1280
|
call_api(method, uri, params, options)
|
1129
1281
|
end
|
1130
1282
|
|
1283
|
+
# Protected function that assists with performing an API call to the metadata_rules part of the Admin API.
|
1284
|
+
#
|
1285
|
+
# @protected
|
1286
|
+
# @param [Symbol] method The HTTP method. Valid methods: get, post, put, delete
|
1287
|
+
# @param [Array] uri REST endpoint of the API (without 'metadata_rules')
|
1288
|
+
# @param [Hash] params Query/body parameters passed to the method
|
1289
|
+
# @param [Hash] options Additional options. Can be an override of the configuration, headers, etc.
|
1290
|
+
# @return [Cloudinary::Api::Response] Returned response from Cloudinary
|
1291
|
+
# @raise [Cloudinary::Api::Error]
|
1292
|
+
def self.call_metadata_rules_api(method, uri, params, options)
|
1293
|
+
options[:content_type] = :json
|
1294
|
+
uri = ["metadata_rules", uri].reject(&:empty?).join("/")
|
1295
|
+
|
1296
|
+
call_api(method, uri, params, options)
|
1297
|
+
end
|
1298
|
+
|
1131
1299
|
# Prepares optional parameters for asset/assetByAssetId API calls.
|
1132
1300
|
# @param [Hash] options Additional options
|
1133
1301
|
# @return [Object] Optional parameters
|
@@ -1138,6 +1306,7 @@ class Cloudinary::Api
|
|
1138
1306
|
:faces,
|
1139
1307
|
:quality_analysis,
|
1140
1308
|
:image_metadata,
|
1309
|
+
:media_metadata,
|
1141
1310
|
:phash,
|
1142
1311
|
:pages,
|
1143
1312
|
:cinemagraph_analysis,
|
data/lib/cloudinary/search.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
1
|
class Cloudinary::Search
|
2
|
+
ENDPOINT = 'resources'
|
3
|
+
|
2
4
|
SORT_BY = :sort_by
|
3
5
|
AGGREGATE = :aggregate
|
4
6
|
WITH_FIELD = :with_field
|
5
7
|
KEYS_WITH_UNIQUE_VALUES = [SORT_BY, AGGREGATE, WITH_FIELD].freeze
|
6
8
|
|
9
|
+
TTL = 300 # Used for search URLs
|
10
|
+
|
7
11
|
def initialize
|
8
12
|
@query_hash = {
|
9
13
|
SORT_BY => {},
|
10
14
|
AGGREGATE => {},
|
11
15
|
WITH_FIELD => {}
|
12
16
|
}
|
17
|
+
|
18
|
+
@endpoint = self.class::ENDPOINT
|
19
|
+
|
20
|
+
@ttl = self.class::TTL
|
13
21
|
end
|
14
22
|
|
15
23
|
## implicitly generate an instance delegate the method
|
@@ -69,11 +77,21 @@ class Cloudinary::Search
|
|
69
77
|
self
|
70
78
|
end
|
71
79
|
|
80
|
+
# Sets the time to live of the search URL.
|
81
|
+
#
|
82
|
+
# @param [Object] ttl The time to live in seconds.
|
83
|
+
#
|
84
|
+
# @return [Cloudinary::Search]
|
85
|
+
def ttl(ttl)
|
86
|
+
@ttl = ttl
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
72
90
|
# Returns the query as an hash.
|
73
91
|
#
|
74
92
|
# @return [Hash]
|
75
93
|
def to_h
|
76
|
-
@query_hash.each_with_object({}) do |(key, value), query|
|
94
|
+
@query_hash.sort.each_with_object({}) do |(key, value), query|
|
77
95
|
next if value.nil? || ((value.is_a?(Array) || value.is_a?(Hash)) && value.blank?)
|
78
96
|
|
79
97
|
query[key] = KEYS_WITH_UNIQUE_VALUES.include?(key) ? value.values : value
|
@@ -82,7 +100,44 @@ class Cloudinary::Search
|
|
82
100
|
|
83
101
|
def execute(options = {})
|
84
102
|
options[:content_type] = :json
|
85
|
-
uri =
|
103
|
+
uri = "#{@endpoint}/search"
|
86
104
|
Cloudinary::Api.call_api(:post, uri, to_h, options)
|
87
105
|
end
|
106
|
+
|
107
|
+
# Creates a signed Search URL that can be used on the client side.
|
108
|
+
#
|
109
|
+
# @param [Integer] ttl The time to live in seconds.
|
110
|
+
# @param [String] next_cursor Starting position.
|
111
|
+
# @param [Hash] options Additional url delivery options.
|
112
|
+
#
|
113
|
+
# @return [String] The resulting Search URL
|
114
|
+
def to_url(ttl = nil, next_cursor = nil, options = {})
|
115
|
+
api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise(CloudinaryException, "Must supply api_secret")
|
116
|
+
|
117
|
+
ttl = ttl || @ttl
|
118
|
+
query = self.to_h
|
119
|
+
|
120
|
+
_next_cursor = query.delete(:next_cursor)
|
121
|
+
next_cursor = _next_cursor if next_cursor.nil?
|
122
|
+
|
123
|
+
b64query = Base64.urlsafe_encode64(JSON.generate(query))
|
124
|
+
|
125
|
+
prefix = Cloudinary::Utils.build_distribution_domain(options)
|
126
|
+
|
127
|
+
signature = Cloudinary::Utils.hash("#{ttl}#{b64query}#{api_secret}", :sha256, :hexdigest)
|
128
|
+
|
129
|
+
next_cursor = "/#{next_cursor}" if !next_cursor.nil? && !next_cursor.empty?
|
130
|
+
|
131
|
+
"#{prefix}/search/#{signature}/#{ttl}/#{b64query}#{next_cursor}"
|
132
|
+
end
|
133
|
+
|
134
|
+
# Sets the API endpoint.
|
135
|
+
#
|
136
|
+
# @param [String] endpoint the endpoint to set.
|
137
|
+
#
|
138
|
+
# @return [Cloudinary::Search]
|
139
|
+
def endpoint(endpoint)
|
140
|
+
@endpoint = endpoint
|
141
|
+
self
|
142
|
+
end
|
88
143
|
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# The Cloudinary API folders search method allows you fine control on filtering and retrieving information on all the
|
2
|
+
# folders in your cloud with the help of query expressions in a Lucene-like query language.
|
3
|
+
class Cloudinary::SearchFolders < Cloudinary::Search
|
4
|
+
ENDPOINT = 'folders'
|
5
|
+
end
|
data/lib/cloudinary/uploader.rb
CHANGED
@@ -47,6 +47,7 @@ class Cloudinary::Uploader
|
|
47
47
|
:filename_override => options[:filename_override],
|
48
48
|
:headers => build_custom_headers(options[:headers]),
|
49
49
|
:image_metadata => Cloudinary::Utils.as_safe_bool(options[:image_metadata]),
|
50
|
+
:media_metadata => Cloudinary::Utils.as_safe_bool(options[:media_metadata]),
|
50
51
|
:invalidate => Cloudinary::Utils.as_safe_bool(options[:invalidate]),
|
51
52
|
:moderation => options[:moderation],
|
52
53
|
:notification_url => options[:notification_url],
|
@@ -62,6 +63,7 @@ class Cloudinary::Uploader
|
|
62
63
|
:responsive_breakpoints => Cloudinary::Utils.generate_responsive_breakpoints_string(options[:responsive_breakpoints]),
|
63
64
|
:return_delete_token => Cloudinary::Utils.as_safe_bool(options[:return_delete_token]),
|
64
65
|
:similarity_search => options[:similarity_search],
|
66
|
+
:visual_search => Cloudinary::Utils.as_safe_bool(options[:visual_search]),
|
65
67
|
:tags => options[:tags] && Cloudinary::Utils.build_array(options[:tags]).join(","),
|
66
68
|
:timestamp => (options[:timestamp] || Time.now.to_i),
|
67
69
|
:transformation => Cloudinary::Utils.generate_transformation_string(options.clone),
|
@@ -108,26 +110,38 @@ class Cloudinary::Uploader
|
|
108
110
|
public_id = public_id_or_options
|
109
111
|
options = old_options
|
110
112
|
end
|
113
|
+
|
114
|
+
options.merge(:public_id => public_id)
|
115
|
+
|
111
116
|
if Cloudinary::Utils.is_remote?(file)
|
112
|
-
return upload(file, options
|
113
|
-
|
117
|
+
return upload(file, options)
|
118
|
+
end
|
119
|
+
|
120
|
+
if file.is_a?(Pathname) || !file.respond_to?(:read)
|
114
121
|
filename = file
|
115
122
|
file = File.open(file, "rb")
|
116
123
|
else
|
117
124
|
filename = "cloudinaryfile"
|
118
125
|
end
|
119
126
|
|
127
|
+
chunk_size = options[:chunk_size] || 20_000_000
|
128
|
+
|
129
|
+
if file.size < chunk_size
|
130
|
+
return upload(file, options)
|
131
|
+
end
|
132
|
+
|
120
133
|
filename = options[:filename] if options[:filename]
|
121
134
|
|
122
135
|
unique_upload_id = Cloudinary::Utils.random_public_id
|
123
136
|
upload = nil
|
124
137
|
index = 0
|
125
|
-
|
138
|
+
|
126
139
|
until file.eof?
|
127
140
|
buffer = file.read(chunk_size)
|
128
141
|
current_loc = index*chunk_size
|
129
142
|
range = "bytes #{current_loc}-#{current_loc+buffer.size - 1}/#{file.size}"
|
130
|
-
upload = upload_large_part(Cloudinary::Blob.new(buffer, :original_filename => filename),
|
143
|
+
upload = upload_large_part(Cloudinary::Blob.new(buffer, :original_filename => filename),
|
144
|
+
options.merge(:unique_upload_id => unique_upload_id, :content_range => range))
|
131
145
|
index += 1
|
132
146
|
end
|
133
147
|
upload
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -524,18 +524,10 @@ class Cloudinary::Utils
|
|
524
524
|
version = options.delete(:version)
|
525
525
|
force_version = config_option_consume(options, :force_version, true)
|
526
526
|
format = options.delete(:format)
|
527
|
-
cloud_name = config_option_consume(options, :cloud_name) || raise(CloudinaryException, "Must supply cloud_name in tag or in configuration")
|
528
527
|
|
529
|
-
secure = options.delete(:secure)
|
530
|
-
ssl_detected = options.delete(:ssl_detected)
|
531
|
-
secure = ssl_detected || Cloudinary.config.secure if secure.nil?
|
532
|
-
private_cdn = config_option_consume(options, :private_cdn)
|
533
|
-
secure_distribution = config_option_consume(options, :secure_distribution)
|
534
|
-
cname = config_option_consume(options, :cname)
|
535
528
|
shorten = config_option_consume(options, :shorten)
|
536
529
|
force_remote = options.delete(:force_remote)
|
537
|
-
|
538
|
-
secure_cdn_subdomain = config_option_consume(options, :secure_cdn_subdomain)
|
530
|
+
|
539
531
|
sign_url = config_option_consume(options, :sign_url)
|
540
532
|
secret = config_option_consume(options, :api_secret)
|
541
533
|
sign_version = config_option_consume(options, :sign_version) # Deprecated behavior
|
@@ -558,7 +550,7 @@ class Cloudinary::Utils
|
|
558
550
|
type = type.to_s unless type.nil?
|
559
551
|
resource_type ||= "image"
|
560
552
|
source = source.to_s
|
561
|
-
|
553
|
+
unless force_remote
|
562
554
|
static_support = Cloudinary.config.static_file_support || Cloudinary.config.static_image_support
|
563
555
|
return original_source if !static_support && type == "asset"
|
564
556
|
return original_source if (type.nil? || type == "asset") && source.match(%r(^https?:/)i)
|
@@ -594,7 +586,9 @@ class Cloudinary::Utils
|
|
594
586
|
signature = "s--#{signature[0, long_url_signature ? LONG_URL_SIGNATURE_LENGTH : SHORT_URL_SIGNATURE_LENGTH ]}--"
|
595
587
|
end
|
596
588
|
|
597
|
-
|
589
|
+
options[:source] = source
|
590
|
+
prefix = build_distribution_domain(options)
|
591
|
+
|
598
592
|
source = [prefix, resource_type, type, signature, transformation, version, source].reject(&:blank?).join("/")
|
599
593
|
if sign_url && auth_token && !auth_token.empty?
|
600
594
|
auth_token[:url] = URI.parse(source).path
|
@@ -707,6 +701,22 @@ class Cloudinary::Utils
|
|
707
701
|
prefix
|
708
702
|
end
|
709
703
|
|
704
|
+
def self.build_distribution_domain(options = {})
|
705
|
+
cloud_name = config_option_consume(options, :cloud_name) || raise(CloudinaryException, "Must supply cloud_name in tag or in configuration")
|
706
|
+
|
707
|
+
source = options.delete(:source)
|
708
|
+
secure = options.delete(:secure)
|
709
|
+
ssl_detected = options.delete(:ssl_detected)
|
710
|
+
secure = ssl_detected || Cloudinary.config.secure if secure.nil?
|
711
|
+
private_cdn = config_option_consume(options, :private_cdn)
|
712
|
+
secure_distribution = config_option_consume(options, :secure_distribution)
|
713
|
+
cname = config_option_consume(options, :cname)
|
714
|
+
cdn_subdomain = config_option_consume(options, :cdn_subdomain)
|
715
|
+
secure_cdn_subdomain = config_option_consume(options, :secure_cdn_subdomain)
|
716
|
+
|
717
|
+
unsigned_download_url_prefix(source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname, secure, secure_distribution)
|
718
|
+
end
|
719
|
+
|
710
720
|
# Creates a base URL for the cloudinary api
|
711
721
|
#
|
712
722
|
# @param [Object] path Resource name
|
@@ -1175,11 +1185,13 @@ class Cloudinary::Utils
|
|
1175
1185
|
# @private
|
1176
1186
|
def self.norm_range_value(value) # :nodoc:
|
1177
1187
|
offset = /^#{offset_any_pattern}$/.match( value.to_s)
|
1188
|
+
|
1178
1189
|
if offset
|
1179
|
-
modifier
|
1180
|
-
|
1190
|
+
modifier = offset[5].present? ? 'p' : ''
|
1191
|
+
"#{offset[1]}#{modifier}"
|
1192
|
+
else
|
1193
|
+
normalize_expression(value)
|
1181
1194
|
end
|
1182
|
-
value
|
1183
1195
|
end
|
1184
1196
|
private_class_method :norm_range_value
|
1185
1197
|
|
@@ -1371,6 +1383,4 @@ class Cloudinary::Utils
|
|
1371
1383
|
algorithm = ALGORITHM_SIGNATURE[signature_algorithm] || raise("Unsupported algorithm '#{signature_algorithm}'")
|
1372
1384
|
algorithm.public_send(hash_method, input)
|
1373
1385
|
end
|
1374
|
-
|
1375
|
-
private_class_method :hash
|
1376
1386
|
end
|
data/lib/cloudinary/version.rb
CHANGED
data/lib/cloudinary.rb
CHANGED
@@ -28,6 +28,7 @@ module Cloudinary
|
|
28
28
|
autoload :Static, "cloudinary/static"
|
29
29
|
autoload :CarrierWave, "cloudinary/carrier_wave"
|
30
30
|
autoload :Search, "cloudinary/search"
|
31
|
+
autoload :SearchFolders, "cloudinary/search_folders"
|
31
32
|
|
32
33
|
CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net"
|
33
34
|
AKAMAI_SHARED_CDN = "res.cloudinary.com"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.27.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nadav Soferman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-07-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws_cf_signer
|
@@ -235,6 +235,7 @@ files:
|
|
235
235
|
- lib/cloudinary/railtie.rb
|
236
236
|
- lib/cloudinary/responsive.rb
|
237
237
|
- lib/cloudinary/search.rb
|
238
|
+
- lib/cloudinary/search_folders.rb
|
238
239
|
- lib/cloudinary/static.rb
|
239
240
|
- lib/cloudinary/uploader.rb
|
240
241
|
- lib/cloudinary/utils.rb
|
@@ -276,8 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
277
|
- !ruby/object:Gem::Version
|
277
278
|
version: '0'
|
278
279
|
requirements: []
|
279
|
-
|
280
|
-
rubygems_version: 2.7.6
|
280
|
+
rubygems_version: 3.4.12
|
281
281
|
signing_key:
|
282
282
|
specification_version: 4
|
283
283
|
summary: Client library for easily using the Cloudinary service
|