Skip to content

Commit

Permalink
custom searches and implementation of beta v2 api
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy Wells committed Oct 14, 2009
1 parent 71fc18f commit f0bdcdc
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 22 deletions.
82 changes: 65 additions & 17 deletions lib/dnz/client.rb
Expand Up @@ -23,7 +23,7 @@ class Client

APIS = {
:search => 'records/${version}.xml/',
:custom_search => 'custom_searches/${version}/${title}.xml'
:custom_search => 'custom_searches/${version}/${custom_search}.xml'
}

ARGS = {
Expand All @@ -37,9 +37,43 @@ class Client
:direction,
:facets,
:facet_num_results,
:facet_start,
:facet_start
]),
:custom_search => Set.new([
:custom_search,
:search_text,
:api_key,
:num_results,
:start,
:sort,
:direction
])
}
},
:v2 => {
:search => Set.new([
:search_text,
:api_key,
:num_results,
:start,
:sort,
:direction,
:facets,
:facet_num_results,
:facet_start
]),
:custom_search => Set.new([
:custom_search,
:search_text,
:api_key,
:num_results,
:start,
:sort,
:direction,
:facets,
:facet_num_results,
:facet_start
])
}
}

# List of available facets that can be passed to search
Expand All @@ -56,7 +90,7 @@ class Client
# search.results.each do |result|
# puts result.title
# end
def initialize(api_key, base_url = 'http://api.digitalnz.org', version = 'v1')
def initialize(api_key, version = 'v1', base_url = 'http://api.digitalnz.org')
@api_key = api_key
@base_url = base_url
@version = version
Expand Down Expand Up @@ -110,16 +144,8 @@ def fetch(api, options = {})
validate_options(api, options)

options = options.reverse_merge(:api_key => self.api_key)

#api_url = APIS[url]
#matches = (/\$\{(.*?)\}/)
#
#
#

# qs = options.map{|k,v| '%s=%s' % [k,v] }.join('&')
qs = options.to_query
url = self.base_url + '/' + APIS[api].gsub('${version}', self.version) + '?' + qs

url = create_url(api, options)

begin
open(url)
Expand All @@ -133,13 +159,35 @@ def fetch(api, options = {})
end

private

def create_url(api, options)
options = options.symbolize_keys
options[:version] = self.version

path = APIS[api].dup
variable_regex = /\$\{(.+?)\}/m

while match = variable_regex.match(path)
variable_name = $1.to_sym

if options.has_key?(variable_name)
path.sub!(variable_regex, options.delete(variable_name))
else
raise ArgumentError.new("Required argument missing: #{variable_name}")
end
end

url = self.base_url + '/' + path
url + '?' + options.to_query
end

def validate_options(path, options = {})
options = options.symbolize_keys

version_args = ARGS[@version.to_sym]

if version_args.has_key?(path) && !Set.new(options.keys).subset?(version_args[path])

if !version_args
raise ArgumentError.new("Invalid version API call: #{@version}, #{path}")
elsif version_args.has_key?(path) && !Set.new(options.keys).subset?(version_args[path])
raise ArgumentError.new("Valid options for #{path} are: #{version_args[path].to_a.join(', ')}, provided: #{options.keys.join(', ')}")
end
end
Expand Down
26 changes: 22 additions & 4 deletions lib/dnz/search.rb
Expand Up @@ -18,6 +18,7 @@ module DNZ
# search = client.search('text')
# puts "%d results found on %d pages" % [search.result_count, search.pages]
class Search
# The total number of results returned by the search
attr_reader :result_count

extend DNZ::Memoizable
Expand Down Expand Up @@ -88,6 +89,10 @@ def to_s
:pages => self.pages
}.inspect
end

def custom_search?
!@search_options.has_key?(:custom_search)
end

private

Expand Down Expand Up @@ -127,12 +132,19 @@ def parsed_search_options
def doc
@doc ||= Nokogiri::XML(@xml)
end

def execute_action
if custom_search?
:search
else
:custom_search
end
end

def execute
@doc = nil
@results = nil
@facets = nil
@xml = @client.send(:fetch, :search, parsed_search_options)
reset

@xml = @client.send(:fetch, execute_action, parsed_search_options)

parse_attributes
parse_facets
Expand All @@ -141,6 +153,12 @@ def execute

self
end

def reset
@doc = nil
@results = nil
@facets = nil
end

def paginate_results
@results = WillPaginate::Collection.create(self.page, num_results_requested, self.result_count) do |pager|
Expand Down
85 changes: 85 additions & 0 deletions spec/dnz/client_spec.rb
Expand Up @@ -10,6 +10,91 @@
@search = mock(:search)
DNZ::Search.stub!(:new).and_return(@search)
end

describe 'APIs' do
describe 'v1' do
before do
@version = 'v1'
@client = Client.new('abc', @version)
@client.stub!(:open) # make sure open is never called
end

describe 'search' do
[:search_text,:api_key,:num_results,:start,:sort,:direction,:facets,:facet_num_results,:facet_start].each do |option|
it "should allow #{option}" do
lambda do
@client.send(:fetch, :search, {option => "test"})
end.should_not raise_error(ArgumentError)
end
end
end

describe 'custom_search' do
it 'should require custom_search' do
lambda do
@client.send(:fetch, :custom_search, {})
end.should raise_error(ArgumentError, "Required argument missing: custom_search")
end

[:search_text,:api_key,:num_results,:start,:sort,:direction].each do |option|
it "should allow #{option}" do
lambda do
@client.send(:fetch, :custom_search, {:custom_search => "test", option => "test"})
end.should_not raise_error(ArgumentError)
end
end
[:facets,:facet_num_results,:facet_start].each do |option|
it "should not allow #{option}" do
lambda do
@client.send(:fetch, :custom_search, {:custom_search => "test", option => "test"})
end.should raise_error(ArgumentError)
end
end
end
end

describe 'v2' do
before do
@version = 'v2'
@client = Client.new('abc', @version)
@client.stub!(:open) # make sure open is never called
end

describe 'search' do
[:search_text,:api_key,:num_results,:start,:sort,:direction,:facets,:facet_num_results,:facet_start].each do |option|
it "should allow #{option}" do
lambda do
@client.send(:fetch, :search, {})
end.should_not raise_error(ArgumentError)
end
end
end

describe 'custom_search' do
it 'should require custom_search' do
lambda do
@client.send(:fetch, :custom_search, {})
end.should raise_error(ArgumentError, "Required argument missing: custom_search")
end

[:search_text,:api_key,:num_results,:start,:sort,:direction].each do |option|
it "should allow #{option}" do
lambda do
@client.send(:fetch, :custom_search, {:custom_search => "test", option => "test"})
end.should_not raise_error(ArgumentError)
end
end
[:facets,:facet_num_results,:facet_start].each do |option|
it "should allow #{option}" do
lambda do
@client.send(:fetch, :custom_search, {:custom_search => "test", option => "test"})
end.should_not raise_error(ArgumentError)
end
end
end
end
end


describe '#search' do
it 'should create a new search object and return it' do
Expand Down
3 changes: 2 additions & 1 deletion spec/spec.opts
@@ -1,4 +1,5 @@
--colour
--format progress
--loadby mtime
--reverse
--reverse
--debugger

0 comments on commit f0bdcdc

Please sign in to comment.