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
|
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, provider: Data::Nil, sort: Data::Nil, order: Data::Nil, limit: Data::Nil, page: Data::Nil)
@lock.synchronize do
@params = {
query: query,
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
|