1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
module VagrantCloud
class Search
# @return [Account]
attr_reader :account
# Create a new search instance
#
# @param [String] access_token Authentication token
# @param [Account] account Account instance
# @param [Client] client Client instance
# @return [Search]
def initialize(access_token: nil, account: nil, client: nil)
args = {access_token: access_token, account: account, client: client}.compact
if args.size > 1
raise ArgumentError,
"Search accepts `access_token`, `account`, or `client` but received multiple (#{args.keys.join(", ")})"
end
if client
if !client.is_a?(Client)
raise TypeError,
"Expecting type `#{Client.name}` but received `#{client.class.name}`"
end
@account = Account.new(client: client)
elsif account
if !account.is_a?(Account)
raise TypeError,
"Expecting type `#{Account.name}` but received `#{account.class.name}`"
end
@account = account
else
@account = Account.new(access_token: access_token)
end
@params = {}
@lock = Mutex.new
end
# Requests a search based on the given parameters
#
# @param [String] query
# @param [String] provider
# @param [String] sort
# @param [String] order
# @param [String] limit
# @param [String] page
# @return [Response::Search]
def search(query: Data::Nil, architecture: Data::Nil, provider: Data::Nil, sort: Data::Nil, order: Data::Nil, limit: Data::Nil, page: Data::Nil)
@lock.synchronize do
@params = {
query: query,
architecture: architecture,
provider: provider,
sort: sort,
order: order,
limit: limit,
page: page
}
execute
end
end
# Request the next page of the search results
#
# @param [Response::Search]
def next_page
@lock.synchronize do
if @params.empty?
raise ArgumentError, "No active search currently cached"
end
page = @params[:page].to_i
page = 1 if page < 1
@params[:page] = page + 1
execute
end
end
# Request the previous page of the search results
#
# @param [Response::Search]
def prev_page
@lock.synchronize do
if @params.empty?
raise ArgumentError, "No active search currently cached"
end
page = @params[:page].to_i - 1
@params[:page] = page < 1 ? 1 : page
execute
end
end
# @return [Boolean] Search terms are stored
def active?
!@params.empty?
end
# Clear the currently cached search parameters
#
# @return [self]
def clear!
@lock.synchronize { @params.clear }
self
end
# Seed the parameters
#
# @return [self]
def seed(**params)
@lock.synchronize { @params = params }
self
end
# Generate a new instance seeded with search
# parameters from given response
#
# @param [Response::Search] response Search response
# @yieldparam [Search] Seeded search instance
# @return [Object] result of given block
def from_response(response)
s = self.class.new(account: account)
yield s.seed(**response.search_parameters)
end
protected
# @return [Response::Search]
def execute
r = account.client.search(**@params)
Response::Search.new(account: account, params: @params, **r)
end
end
end
|