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