This repository has been archived by the owner on May 7, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.rb
180 lines (155 loc) · 5.58 KB
/
api.rb
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
module Harvard::LibraryCloud
require 'faraday'
require 'json'
class API
def initialize base_uri = 'https://api.lib.harvard.edu/v2/'
@base_uri = base_uri
end
def get_base_uri
@base_uri
end
def send_and_receive path, opts
connection = build_request path, opts
execute connection
end
# +build_request+ accepts a path and options hash,
# then prepares a normalized hash to return for sending
# to a solr connection driver.
# +build_request+ sets up the uri/query string
# and converts the +data+ arg to form-urlencoded,
# if the +data+ arg is a hash.
# returns a hash with the following keys:
# :method
# :params
# :headers
# :data
# :uri
# :path
# :query
def build_request path, opts
raise "path must be a string or symbol, not #{path.inspect}" unless [String,Symbol].include?(path.class)
path = path.to_s
opts[:method] ||= :get
raise "The :data option can only be used if :method => :post" if opts[:method] != :post and opts[:data]
if !opts[:params].nil? && opts[:params][:preserve_original]
params = opts[:params]
else
params = params_to_lc(opts[:params]) unless opts[:params].nil? || opts[:params].empty?
end
Faraday.new(:url => @base_uri + path) do |faraday|
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
faraday.params = params ||= {}
end
end
def execute connection
raw_response = begin
response = connection.get
{ status: response.status.to_i, headers: response.headers, body: response.body.force_encoding('utf-8') }
rescue Errno::ECONNREFUSED, Faraday::Error::ConnectionFailed
raise RSolr::Error::ConnectionRefused, connection.inspect
rescue Faraday::Error => e
raise RSolr::Error::Http.new(connection, e.response)
end
# We are assuming the response is JSON
adapt_response(connection, raw_response) unless raw_response.nil?
end
def params_to_lc params
results = {}
# Restrict all results
results[:inDRS] = 'true'
results[:accessFlag] = 'P'
# Don't support sort parameters for now
# results[:sort] = sort_params_to_lc(params[:sort]) if params[:sort]
if params[:search_field] == 'all_fields'
search_term = params[:q].to_s
#escape special characters in search_term for LC API
special_chars = Regexp.escape('~!^()-[]{}\"/')
search_term = search_term.gsub(/[#{special_chars}]+/){|match| puts "\\" + match}
#these double characters cause issues (2 spaces, &&, ||)
search_term = search_term.gsub(/ +/, " ").gsub(/&+/, "&").gsub(/\|+/, "|")
results[:q] = search_term if search_term && search_term.length > 0
else
if params[:q]
#check if this is a recordIdentifier request
m = /\{\!lucene\}identifier:(.*)$/.match(params[:q])
if m
results[:recordIdentifier] = m[1].gsub('"', '')
else
results[params[:search_field]] = params[:q]
end
end
end
#add date start/end params
if params['range'] && params['range']['originDate']
startYear = -10000
if params['range']['originDate']['begin'] && params['range']['originDate']['begin'].to_s != ''
begin
if Integer(params['range']['originDate']['begin'])
results['dates.start'] = params['range']['originDate']['begin']
startYear = Integer(params['range']['originDate']['begin'])
end
rescue
end
end
if params['range']['originDate']['end'] && params['range']['originDate']['end'].to_s != ''
begin
if Integer(params['range']['originDate']['end'])
endYear = Integer(params['range']['originDate']['end'])
if endYear >= startYear
results['dates.end'] = params['range']['originDate']['end']
end
end
rescue
end
end
end
results[:start] = params[:start] if params[:start]
results[:limit] = params[:rows] if params[:rows]
results[:facets] = facet_params_to_lc(params['facet.field']) if params['facet.field']
results[:recordIdentifier] = params['recordIdentifier'] if params['recordIdentifier']
results.merge!(facet_query_params_to_lc(params[:fq])) if params[:fq]
results
end
def facet_params_to_lc facet_field
if facet_field.kind_of?(Array)
facet_field.map do |x|
# "{!ex=genre_single}genre"
m = facet_param_formatted(x)
end.join(',')
else
facet_param_formatted(facet_field)
end
end
#parse field name from Blacklight formatted field name
def facet_param_formatted facet_field
m = /\{.*\}(\S+)$/.match(facet_field)
if m
m[1]
else
facet_field
end
end
def facet_query_params_to_lc fq
results = {}
fq.each do |x|
#parse facet name and vaule from QS param
m = /\{!term f=(\S*).*\}(.*)$/.match(x)
#only use _exact params for certain facets due to bug in LC API
if m[1] == 'subject' || m[1] == 'originPlace' || m[1] == 'seriesTitle'
results[m[1]] = m[2]
else
results[m[1] + '_exact'] = m[2]
end
end if fq
results
end
def sort_params_to_lc sort
sort
end
def adapt_response connection, raw_response
JSON.parse raw_response[:body]
end
end
end