Skip to content

Commit 2b71892

Browse files
authored
Merge pull request #229 from MITLibraries/use-31-primo-views
Initial tabbed Primo/TIMDEX interface
2 parents 5ec7532 + b2d9762 commit 2b71892

File tree

7 files changed

+675
-403
lines changed

7 files changed

+675
-403
lines changed

app/controllers/search_controller.rb

Lines changed: 91 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,59 +15,102 @@ def results
1515
# inject session preference for boolean type if it is present
1616
params[:booleanType] = cookies[:boolean_type] || 'AND'
1717

18-
# hand off to Enhancer chain
18+
# Determine which tab to load - default to primo unless gdt is enabled
19+
@active_tab = if Flipflop.enabled?(:gdt)
20+
'gdt' # Keep existing GDT behavior unchanged
21+
else
22+
params[:tab] || 'primo' # Default to primo for new tabbed interface
23+
end
1924
@enhanced_query = Enhancer.new(params).enhanced_query
2025

21-
# hand off enhanced query to builder
22-
query = QueryBuilder.new(@enhanced_query).query
26+
# Route to appropriate search based on active tab
27+
if Flipflop.enabled?(:gdt)
28+
# Keep existing GDT behavior unchanged
29+
load_gdt_results
30+
else
31+
case @active_tab
32+
when 'primo'
33+
load_primo_results
34+
when 'timdex'
35+
load_timdex_results
36+
end
37+
end
38+
end
2339

24-
# Create cache key for this query
25-
# Sorting query hash to ensure consistent key generation regardless of the parameter order
26-
sorted_query = query.sort_by { |k, v| k.to_sym }.to_h
27-
cache_key = Digest::MD5.hexdigest(sorted_query.to_s)
40+
private
2841

29-
# builder hands off to wrapper which returns raw results here
30-
# We are using two difference caches to allow for Geo and USE to be cached separately. This ensures we don't have
31-
# cache key collission for these two different query types. In practice, the likelihood of this happening is low,
32-
# as the query parameters are different for each type and they won't often be run with the same cache backend other
33-
# than locally, but this is a safeguard.
34-
# The response type is a GraphQL::Client::Response, which is not directly serializable, so we convert it to a hash.
35-
response = if Flipflop.enabled?(:gdt)
36-
Rails.cache.fetch("#{cache_key}/geo", expires_in: 12.hours) do
37-
raw = execute_geospatial_query(query)
38-
{
39-
data: raw.data.to_h,
40-
errors: raw.errors.details.to_h
41-
}
42-
end
43-
else
44-
Rails.cache.fetch("#{cache_key}/use", expires_in: 12.hours) do
45-
raw = TimdexBase::Client.query(TimdexSearch::BaseQuery, variables: query)
46-
{
47-
data: raw.data.to_h,
48-
errors: raw.errors.details.to_h
49-
}
50-
end
51-
end
42+
def load_gdt_results
43+
query = QueryBuilder.new(@enhanced_query).query
44+
45+
response = cache_timdex_query(query)
5246

5347
# Handle errors
5448
@errors = extract_errors(response)
55-
56-
# Analayze results
57-
# The @pagination instance variable includes info about next/previous pages (where they exist) to assist the UI.
5849
@pagination = Analyzer.new(@enhanced_query, response).pagination if @errors.nil?
59-
60-
# Display results
6150
@results = extract_results(response)
6251
@filters = extract_filters(response)
6352
end
6453

65-
private
54+
def load_primo_results
55+
begin
56+
primo_search = PrimoSearch.new
57+
per_page = params[:per_page] || 20
58+
primo_response = primo_search.search(params[:q], per_page)
59+
60+
@results = NormalizePrimoResults.new(primo_response, params[:q]).normalize
61+
62+
# Basic pagination for now.
63+
if @results.present?
64+
@pagination = {
65+
hits: @results.count,
66+
start: 1,
67+
end: @results.count
68+
}
69+
end
70+
71+
rescue StandardError => e
72+
@errors = handle_primo_errors(e)
73+
end
74+
end
75+
76+
def load_timdex_results
77+
query = QueryBuilder.new(@enhanced_query).query
78+
response = cache_timdex_query(query)
79+
80+
@errors = extract_errors(response)
81+
@pagination = Analyzer.new(@enhanced_query, response).pagination if @errors.nil?
82+
@results = extract_results(response)
83+
end
6684

6785
def active_filters
6886
ENV.fetch('ACTIVE_FILTERS', '').split(',').map(&:strip)
6987
end
7088

89+
def cache_timdex_query(query)
90+
# Create cache key for this query
91+
# Sorting query hash to ensure consistent key generation regardless of the parameter order
92+
sorted_query = query.sort_by { |k, v| k.to_sym }.to_h
93+
cache_key = Digest::MD5.hexdigest(sorted_query.to_s)
94+
95+
# builder hands off to wrapper which returns raw results here
96+
# We are using two difference caches to allow for Geo and USE to be cached separately. This ensures we don't have
97+
# cache key collision for these two different query types. In practice, the likelihood of this happening is low,
98+
# as the query parameters are different for each type and they won't often be run with the same cache backend other
99+
# than locally, but this is a safeguard.
100+
# The response type is a GraphQL::Client::Response, which is not directly serializable, so we convert it to a hash.
101+
Rails.cache.fetch("#{cache_key}/#{@active_tab}", expires_in: 12.hours) do
102+
raw = if @active_tab == 'gdt'
103+
execute_geospatial_query(query)
104+
elsif @active_tab == 'timdex'
105+
TimdexBase::Client.query(TimdexSearch::BaseQuery, variables: query)
106+
end
107+
{
108+
data: raw.data.to_h,
109+
errors: raw.errors.details.to_h
110+
}
111+
end
112+
end
113+
71114
def execute_geospatial_query(query)
72115
if query['geobox'] == 'true' && query[:geodistance] == 'true'
73116
TimdexBase::Client.query(TimdexSearch::AllQuery, variables: query)
@@ -214,4 +257,16 @@ def validate_geobox_values!
214257
flash[:error] = 'Maximum latitude cannot exceed minimum latitude.'
215258
redirect_to root_url
216259
end
260+
261+
def handle_primo_errors(error)
262+
Rails.logger.error("Primo search error: #{error.message}")
263+
264+
if error.is_a?(ArgumentError)
265+
[{ 'message' => 'Primo search is not properly configured.' }]
266+
elsif error.is_a?(HTTP::TimeoutError)
267+
[{ 'message' => 'The Primo service is currently slow to respond. Please try again.' }]
268+
else
269+
[{ 'message' => error.message }]
270+
end
271+
end
217272
end

0 commit comments

Comments
 (0)