lib/cloudinary/search.rb in cloudinary-1.26.0 vs lib/cloudinary/search.rb in cloudinary-1.27.0
- old
+ new
@@ -1,17 +1,25 @@
class Cloudinary::Search
+ ENDPOINT = 'resources'
+
SORT_BY = :sort_by
AGGREGATE = :aggregate
WITH_FIELD = :with_field
KEYS_WITH_UNIQUE_VALUES = [SORT_BY, AGGREGATE, WITH_FIELD].freeze
+ TTL = 300 # Used for search URLs
+
def initialize
@query_hash = {
SORT_BY => {},
AGGREGATE => {},
WITH_FIELD => {}
}
+
+ @endpoint = self.class::ENDPOINT
+
+ @ttl = self.class::TTL
end
## implicitly generate an instance delegate the method
def self.method_missing(method_name, *arguments)
instance = new
@@ -67,22 +75,69 @@
def with_field(value)
@query_hash[WITH_FIELD][value] = value
self
end
+ # Sets the time to live of the search URL.
+ #
+ # @param [Object] ttl The time to live in seconds.
+ #
+ # @return [Cloudinary::Search]
+ def ttl(ttl)
+ @ttl = ttl
+ self
+ end
+
# Returns the query as an hash.
#
# @return [Hash]
def to_h
- @query_hash.each_with_object({}) do |(key, value), query|
+ @query_hash.sort.each_with_object({}) do |(key, value), query|
next if value.nil? || ((value.is_a?(Array) || value.is_a?(Hash)) && value.blank?)
query[key] = KEYS_WITH_UNIQUE_VALUES.include?(key) ? value.values : value
end
end
def execute(options = {})
options[:content_type] = :json
- uri = 'resources/search'
+ uri = "#{@endpoint}/search"
Cloudinary::Api.call_api(:post, uri, to_h, options)
+ end
+
+ # Creates a signed Search URL that can be used on the client side.
+ #
+ # @param [Integer] ttl The time to live in seconds.
+ # @param [String] next_cursor Starting position.
+ # @param [Hash] options Additional url delivery options.
+ #
+ # @return [String] The resulting Search URL
+ def to_url(ttl = nil, next_cursor = nil, options = {})
+ api_secret = options[:api_secret] || Cloudinary.config.api_secret || raise(CloudinaryException, "Must supply api_secret")
+
+ ttl = ttl || @ttl
+ query = self.to_h
+
+ _next_cursor = query.delete(:next_cursor)
+ next_cursor = _next_cursor if next_cursor.nil?
+
+ b64query = Base64.urlsafe_encode64(JSON.generate(query))
+
+ prefix = Cloudinary::Utils.build_distribution_domain(options)
+
+ signature = Cloudinary::Utils.hash("#{ttl}#{b64query}#{api_secret}", :sha256, :hexdigest)
+
+ next_cursor = "/#{next_cursor}" if !next_cursor.nil? && !next_cursor.empty?
+
+ "#{prefix}/search/#{signature}/#{ttl}/#{b64query}#{next_cursor}"
+ end
+
+ # Sets the API endpoint.
+ #
+ # @param [String] endpoint the endpoint to set.
+ #
+ # @return [Cloudinary::Search]
+ def endpoint(endpoint)
+ @endpoint = endpoint
+ self
end
end