diff --git a/blacklight-cornell/app/assets/javascripts/aeon/request.js b/blacklight-cornell/app/assets/javascripts/aeon/request.js index 7540c79f8..f1e228545 100644 --- a/blacklight-cornell/app/assets/javascripts/aeon/request.js +++ b/blacklight-cornell/app/assets/javascripts/aeon/request.js @@ -34,16 +34,19 @@ function buildRequestForItem(_, element, multipleFlag) { location = '', callnumber = '', copy = '', + loc_code = '', } = itemdata[req] ?? {}; + // DACCESS-512 combine location fields but make sure they are unique, do not use code field it contains 'rmc' on kheel items + const fields = [ { name: `ItemVolume`, value: `${enumeration} ${chron}` }, - { name: `Location`, value: cslocation + ' ' + location}, + { name: `Location`, value: cleanLocation(cslocation + ' ' + location + ' ' + loc_code) }, { name: `CallNumber`, value: callnumber }, { name: `ItemInfo1`, value: chron }, { name: `ItemNumber`, value: barcode }, { name: `ItemIssue`, value: copy }, - { name: `Site`, value: (cslocation + ' ' + location).toLowerCase().includes('rmc') ? 'RMC' : 'KHEEL' }, + { name: `Site`, value: /kheel|ilr/i.test(cslocation + ' ' + location + ' ' + loc_code) ? 'KHEEL' : 'RMC' }, ]; $("#RequestForm").append(``); const ext = multipleFlag ? `_${req}` : ''; @@ -81,6 +84,25 @@ function doSubmit(_) { return true; } +/** + * Cleans the location fields for all items by removing duplicate words + * may have duplicates due to the variety of ways location is stored for different items + * @param {string} location - original string cslocation + ' ' + location + ' ' + loc_code + * @returns {string} - cleaned location string + */ +function cleanLocation(location) { + const parts = location.split(' '); + const newLocation = [...new Set(parts)]; + newLocationstr = newLocation.join(' '); + + // if "Rare and Manuscript Collections" is a location, then ensure 'rmc' is included so routing rules work + // necessary for: 'sasa,rare' 'hote,rare' 'was,rare' 'ech,rare' etc. + if (newLocationstr.includes("Rare and Manuscript Collections") && !newLocationstr.includes('rmc')) { + newLocationstr += ' rmc'; + } + return newLocationstr; +} + /** * Handles the click event on a checkbox. * Moves the item to the selected items box when a checkbox is checked or unchecked. diff --git a/blacklight-cornell/app/assets/stylesheets/cornell/_availability.scss b/blacklight-cornell/app/assets/stylesheets/cornell/_availability.scss index a353e4db1..ce244fd3b 100644 --- a/blacklight-cornell/app/assets/stylesheets/cornell/_availability.scss +++ b/blacklight-cornell/app/assets/stylesheets/cornell/_availability.scss @@ -27,6 +27,12 @@ .fa { margin-right: .25rem; } + a { + display: inline; + } + .url_findingaid_link { + margin-bottom: .5rem; + } } .list-unstyled { padding: 0; diff --git a/blacklight-cornell/app/assets/stylesheets/cornell/_facets.scss b/blacklight-cornell/app/assets/stylesheets/cornell/_facets.scss index d0bd060e6..1bd860177 100644 --- a/blacklight-cornell/app/assets/stylesheets/cornell/_facets.scss +++ b/blacklight-cornell/app/assets/stylesheets/cornell/_facets.scss @@ -1,7 +1,6 @@ .facets { background: white; ul { - margin: 0 0 5px 10px; padding: 0; list-style: none; } @@ -111,9 +110,18 @@ // ------------------------------------ // Indent child lists - default has no indentation -#facets ul.facet-hierarchy ul { - padding-left: 1.2rem; - margin-bottom: .3rem; +#facets ul.facet-hierarchy { + ul { + padding-left: 1.2rem; + margin-bottom: .3rem; + } + .h-leaf { + padding-left: 1.4rem; + } +} + +.facet-hierarchy .twiddle > .toggle-handle .toggle-icon { + margin-top: 0; } // PUBLICATION YEAR diff --git a/blacklight-cornell/app/controllers/aeon_controller.rb b/blacklight-cornell/app/controllers/aeon_controller.rb index 810c9dbb8..57725c374 100644 --- a/blacklight-cornell/app/controllers/aeon_controller.rb +++ b/blacklight-cornell/app/controllers/aeon_controller.rb @@ -23,12 +23,13 @@ def scan_aeon end def set_variables - @finding_aid = params[:finding] || '' + # @finding_aid = params[:finding] || '' @bibid = params[:id] _, @document = search_service.fetch(params[:id]) @title = @document['fulltitle_display'] @author = @document['author_display'] @re506 = @document['restrictions_display']&.first&.delete_suffix("'") || '' + @finding_aids = @document['url_findingaid_display'] @disclaimer = 'Once your order is reviewed by our staff you will then be sent an invoice. ' \ 'Your invoice will include information on how to pay for your order. You must pre-pay; ' \ 'staff cannot fulfill your request until you pay the charges.' diff --git a/blacklight-cornell/app/controllers/browse_controller.rb b/blacklight-cornell/app/controllers/browse_controller.rb index 9a890680e..65fe05a07 100644 --- a/blacklight-cornell/app/controllers/browse_controller.rb +++ b/blacklight-cornell/app/controllers/browse_controller.rb @@ -199,12 +199,13 @@ def info } query_params[:fq] = "headingTypeDesc:\"#{params[:headingtype]}\"" if params[:headingtype].present? solr_response = solr.get 'browse', :params => query_params - @heading_document = solr_response['response']['docs'][0] + solr_doc = solr_response['response']['docs'][0] + @heading_document = solr_doc.present? ? HeadingSolrDocument.new(solr_doc) : nil params[:authq].gsub!('%20', ' ') # Get Library of Congress local name and format facet for Author and Subject heading - if @heading_document.present? && ['Author', 'Subject'].include?(params[:browse_type]) + if @heading_document.present? if params[:browse_type] == 'Author' loc_url = get_author_loc_url elsif params[:browse_type] == 'Subject' @@ -214,9 +215,9 @@ def info end @loc_localname = !loc_url.blank? ? loc_url.split('/').last.inspect : '' - @formats = get_formats(params[:authq], params[:headingtype]) + @formats = get_formats(params[:authq]) else - @formats = [] + @formats = {} end respond_to do |format| @@ -283,119 +284,23 @@ def get_subject_loc_url '' end - def get_formats(query,htype) - qparam_hash = define_search_fields(query,htype) - if qparam_hash.empty? - formats = [] + def get_formats(query) + browse_fields = @heading_document.browse_fields + if browse_fields.empty? + {} else - solr = RSolr.connect :url => ENV["SOLR_URL"] - solr_response = solr.get 'select', :params => { - :q => qparam_hash[:q], - :rows => 0, - :q_row => qparam_hash[:qr], - :op_row => qparam_hash[:or], - :search_field_row => qparam_hash[:sfr], - :mm => 1 - } + query = browse_fields.map { |field| "#{field}:\"#{query}\"" }.join(' OR ') + solr = RSolr.connect :url => ENV['SOLR_URL'] + solr_response = solr.get 'select', + :params => { + :q => query, + :rows => 0, + :mm => 1 + } - formats = solr_response['facet_counts']['facet_fields']['format'] + format_facet_counts = solr_response['facet_counts']['facet_fields']['format'] + Hash[*format_facet_counts] end - - # uri = "https://digital.library.cornell.edu/catalog.json?utf8=%E2%9C%93&q=#{query}&search_field=all_fields&rows=3" - # url = Addressable::URI.parse(URI.escape(uri)) - # url.normalize - # portal_response = JSON.load(open(url.to_s)) - # if portal_response['response']['pages']['total_count'] > 0 - # formats << "Digital Collections" - # formats << portal_response['response']['pages']['total_count'] - # end - f_count = 0 - tmp_array = [] - formats.each do |f| - if f.class == String - tmp_string = pluralize_format(f) + " (" + number_with_delimiter(formats[f_count + 1], :delimiter => ',').to_s + ")" - tmp_array << tmp_string - end - f_count = f_count + 1 - end - - return tmp_array.sort - end - - def pluralize_format(format) - case format - when "Book" - format = "Books" - when "Journal/Periodical" - format = "Journals/Periodicals" - when "Manuscript/Archive" - format = "Manuscripts/Archives" - when "Map" - format = "Maps" - when "Musical Score" - format = "Musical Scores" - when "Non-musical Recording" - format = "Non-musical Recordings" - when "Video" - format = "Videos" - when "Computer File" - format = "Computer Files" - when "Database" - format = "Databases" - when "Musical Recording" - format = "Musical Recordings" - when "Thesis" - format = "Theses" - when "Microform" - format = "Microforms" - end - return format - end - - def define_search_fields(query,htype) - temp_hash = {} - if htype == "Personal Name" - temp_hash = {:q => '(((+author_pers_browse:"' + query + '") OR author_pers_browse:"' + query + '") OR ((+subject_pers_browse:"' + query + '") OR subject_pers_browse:"' + query + '"))', - :qr => [query, query], - :or => ["AND", "AND"], - :sfr => ["author_pers_browse", "subject_pers_browse"]} - elsif htype == "Corporate Name" - temp_hash = {:q => '(((+author_corp_browse:"' + query + '") OR author_corp_browse:"' + query + '") OR ((+subject_corp_browse:"' + query + '") OR subject_corp_browse:"' + query + '"))', - :qr => [query, query], - :or => ["AND", "AND"], - :sfr => ["author_corp_browse", "subject_corp_browse"]} - elsif htype == "Event" - temp_hash = {:q => '(((+author_event_browse:"' + query + '") OR author_event_browse:"' + query + '") OR ((+subject_event_browse:"' + query + '") OR subject_event_browse:"' + query + '"))', - :qr => [query, query], - :or => ["AND", "AND"], - :sfr => ["author_event_browse", "subject_event_browse"]} - elsif htype == "Chronological Term" - temp_hash = {:q => '((+subject_era_browse:"' + query + '") OR subject_era_browse:"' + query + '")', - :qr => [query, query], - :or => ["AND"], - :sfr => ["subject_era_browse"]} - elsif htype == "Genre/Form Term" - temp_hash = {:q => '((+subject_genr_browse:"' + query + '") OR subject_genr_browse:"' + query + '")', - :qr => [query], - :or => ["AND"], - :sfr => ["subject_genr_browse"]} - elsif htype == "Geographic Name" - temp_hash = {:q => '((+subject_geo_browse:"' + query + '") OR subject_geo_browse:"' + query + '")', - :qr => [query], - :or => ["AND"], - :sfr => ["subject_geo_browse"]} - elsif htype == "Topical Term" - temp_hash = {:q => '((+subject_topic_browse:"' + query + '") OR subject_topic_browse:"' + query + '")', - :qr => [query], - :or => ["AND"], - :sfr => ["subject_topic_browse"]} - elsif htype == "Work" - temp_hash = {:q => '((+subject_work_browse:"' + query + '") OR subject_work_browse:"' + query + '")', - :qr => [query], - :or => ["AND"], - :sfr => ["subject_work_browse"]} - end - return temp_hash end private diff --git a/blacklight-cornell/app/controllers/catalog_controller.rb b/blacklight-cornell/app/controllers/catalog_controller.rb index 5c78d0029..ebfe897ee 100644 --- a/blacklight-cornell/app/controllers/catalog_controller.rb +++ b/blacklight-cornell/app/controllers/catalog_controller.rb @@ -17,20 +17,6 @@ class CatalogController < ApplicationController #prepend_before_action :set_return_path end - # Ensure that the configuration file is present - begin - SEARCH_API_CONFIG = YAML.load_file("#{::Rails.root}/config/search_apis.yml") - rescue Errno::ENOENT - puts <<-eos - - ****************************************************************************** - Your search_apis.yml config file is missing. - See config/search_apis.yml.example - ****************************************************************************** - - eos - end - # DACCESS-215 def index if query_has_pub_date_facet? && !params.key?(:q) @@ -962,7 +948,7 @@ def folio_request(url) token = folio_token if url && token headers = { - 'X-Okapi-Tenant' => ENV['TENANT_ID'], + 'X-Okapi-Tenant' => ENV['OKAPI_TENANT'], 'x-okapi-token' => token, :accept => 'application/json, application/vnd.api+json' } diff --git a/blacklight-cornell/app/controllers/search_controller.rb b/blacklight-cornell/app/controllers/search_controller.rb index fecbcdffd..3d9343767 100644 --- a/blacklight-cornell/app/controllers/search_controller.rb +++ b/blacklight-cornell/app/controllers/search_controller.rb @@ -18,36 +18,11 @@ def index unless params["q"].nil? @query = params["q"] @query.slice! "doi:" - original_query = @query - - # Modify query for improved Solr search (and to match Blacklight changes) (DISCOVERYACCESS-1103) - if @query.empty? - # no action, pass through - # Something about the Summon engine causes the search to choke if the query is empty. - # All the other engines are fine with either empty or a single space character, and - # forcing to the space allows the Summon empty query to work. - @query = " " - # Only do the following if the query isn't already quoted - else - # @query = objectify_query @query - if @query.include?('"') - @query = checkMixedQuotedBento(@query).join(" ") - log_debug_info("#{__FILE__}:#{__LINE__}", - ["original_query:", original_query], - ["query:", @query]) - end - @query = @query - end Rails.logger.debug("#{__FILE__}:#{__LINE__} #{@query}") - titem = BentoSearch::ResultItem.new searcher = BentoSearch::ConcurrentSearcher.new(:solr, :ebsco_eds, :bestbet, :digitalCollections, :libguides, :institutionalRepositories) - searcher.search(@query, :oq => original_query, :per_page => 3) + searcher.search(@query, :per_page => 3) @results = searcher.results.dup - #@results = searcher.results - - # Reset query to make it show up properly for the user on the results page - @query = original_query # In order to treat multiple formats separately but only run one Solr query to retrieve # them all, we have to store the query result in the custom_data object ... @@ -79,17 +54,16 @@ def index session[:search][:search_field] = "all_fields" session[:search][:controller] = "search" session[:search][:action] = "index" - # session[:search][:counter] = ? - # session[:search][:total] = ? - #Rails.logger.warn "mjc12test: session(ss): #{session[:search]}" render "single_search/index" end + # TODO: Can this be deleted, or should it be fixed? https://culibrary.atlassian.net/browse/DACCESS-515 def single_search Appsignal.increment_counter("single_search_index", 1) begin @engine = BentoSearch.get_engine(params[:engine]) + # TODO: Handle when params[:engine] == 'solr' rescue BentoSearch::NoSuchEngine => e # DA-5405 @engine = params[:engine] @@ -145,7 +119,7 @@ def sort_panes(results, display_type, max_scores) if display_type == "fixed" # Pre-populate top4 with our chosen formats and remove them from the results - top4 << ["Journal", results.delete("Journal")] + top4 << ["Journal/Periodical", results.delete("Journal/Periodical")] top4 << ["Database", results.delete("Database")] end @@ -260,142 +234,4 @@ def facet_solr_results(unfaceted_results) return output, max_relevancy_scores end - - # - # def get_catalog_host req_host - # ch = Rails.configuration.cornell_catalog - # # for hosts like "es287-dev" - # if (/.*-dev/).match(req_host) - # ch = req_host.gsub(/.*-dev/,"catalog-int"); - # end - # if (/search.*/).match(req_host) - # ch = req_host.gsub(/search/,"newcatalog"); - # end - # Rails.logger.debug("#{__FILE__}:#{__LINE__} #{ch}") - # return ch - # end - - # Modify query for improved Solr search (and to match Blacklight changes) (DISCOVERYACCESS-1103) - def objectify_query(search_query) - - # Don't do anything for already-quoted queries or single-term queries - if search_query !~ /[\"\'].*?[\"\']/ and - search_query !~ /[AND|OR|NOT]/ and - search_query =~ /\w.+?\s\w.+?/ - # create modified query: (+x +y +z) OR "x y z" - new_query = search_query.split.map { |w| "#{w}" }.join(" ") - # (have to use double quotes; single returns an incorrect result set from Solr!) - search_query = "(#{new_query}) OR phrase:\"#{search_query}\"" - else - search_query - end - end - - # Modify query for improved Solr search (and to match Blacklight changes) (DISCOVERYACCESS-1103) - def self.transform_query(search_query) - # Don't do anything for already-quoted queries or single-term queries - if search_query !~ /[\"\'].*?[\"\']/ and - search_query !~ /AND|OR|NOT/ - #search_query =~ /\w.+?\s\w.+?/ - # create modified query: (+x +y +z) OR "x y z" - new_query = search_query.split.map { |w| "\"#{w}\"" }.join(" AND ") - Rails.logger.info("BENTO = #{new_query}") - # (have to use double quotes; single returns an incorrect result set from Solr!) - search_query = "(#{new_query}) OR phrase:\"#{search_query}\"" - else - if search_query.first == "'" and search_query.last == "'" - search_query = search_query.gsub("'", "") - search_query = "(#{search_query}) OR phrase:\"#{search_query}\"" - end - search_query - end - end - - def checkMixedQuotedBento(query) - returnArray = [] - addFieldsArray = [] - if query.first == '"' and query.last == '"' - if query.count('"') > 2 - returnArray = parseQuotedQueryBento(query) - returnArray.each do |token| - if token.first == '"' - token = "+quoted:" + token - else - token = "+" + token - end - - addFieldsArray << token - end - returnArray = addFieldsArray - return returnArray - else - returnArray << query - return returnArray - end - else - clearArray = [] - returnArray = parseQuotedQueryBento(query) - returnArray.each do |token| - if token.first == '"' - clearArray << "+quoted:" + token - else - clearArray << "+" + token - end - end - returnArray = clearArray - return returnArray - end - end - - def parseQuotedQueryBento(quotedQuery) - queryArray = [] - token_string = "" - length_counter = 0 - quote_flag = 0 - quotedQuery.each_char do |x| - length_counter = length_counter + 1 - if x != '"' and x != " " - token_string = token_string + x - end - if x == " " - if quote_flag != 0 - token_string = token_string + x - else - queryArray << token_string - token_string = "" - end - end - if x == '"' and quote_flag == 0 - if token_string != "" - queryArray << token_string - token_string = x - quote_flag = 1 - else - token_string = x - quote_flag = 1 - end - end - if x == '"' and quote_flag == 1 - if token_string != "" and token_string != '"' - token_string = token_string + x - queryArray << token_string - token_string = "" - quote_flag = 0 - end - end - if length_counter == quotedQuery.size - queryArray << token_string - end - end - cleanArray = [] - queryArray.each do |toke| - if toke != "" - if !toke.blank? - cleanArray << toke.rstrip - end - end - end - queryArray = cleanArray - return queryArray - end end diff --git a/blacklight-cornell/app/helpers/aeon_helper.rb b/blacklight-cornell/app/helpers/aeon_helper.rb index f2c1c55b9..9cfebd4da 100644 --- a/blacklight-cornell/app/helpers/aeon_helper.rb +++ b/blacklight-cornell/app/helpers/aeon_helper.rb @@ -354,14 +354,38 @@ def generate_hidden_inputs(content) tag.input(type: 'hidden', name: key, value: value) end.join.html_safe end -end -def generate_hidden_inputs_for_login(params_hash) - params_hash.map do |key, value| - if key == 'Request' - value.map { |val| tag.input(type: 'hidden', name: key, value: val) }.join.html_safe - else - tag.input(type: 'hidden', name: key, value: value) - end - end.join.html_safe + def generate_hidden_inputs_for_login(params_hash) + params_hash.map do |key, value| + if key == 'Request' + value.map { |val| tag.input(type: 'hidden', name: key, value: val) }.join.html_safe + else + tag.input(type: 'hidden', name: key, value: value) + end + end.join.html_safe + end + + # Generates HTML for displaying finding aids with icons and links. + # + # @param finding_aids [Array] An array of finding aid strings, each containing a URL + # and a label separated by a '|'. + # @return [String] The generated HTML for the finding aids, or an empty string if no finding aids are provided. + def finding_aids_display(finding_aids) + return '' if finding_aids.nil? + + finding_aids.map do |finding_aid| + url, label = finding_aid.split('|') + next if url.blank? + + cleaned_url = url.end_with?('/track') ? url.chomp('/track') : url + label = label.presence || cleaned_url + <<~HTML.strip +

+ + #{label} +

+ HTML + end.join.html_safe + end end + diff --git a/blacklight-cornell/app/helpers/browse_helper.rb b/blacklight-cornell/app/helpers/browse_helper.rb index 1a33e7769..6cbdddc75 100644 --- a/blacklight-cornell/app/helpers/browse_helper.rb +++ b/blacklight-cornell/app/helpers/browse_helper.rb @@ -1,34 +1,5 @@ module BrowseHelper - def search_field(heading_type) - case heading_type - when 'Personal Name' - 'pers' - when 'Corporate Name' - 'corp' - when 'Event' - 'event' - when 'Geographic Name' - 'geo' - when 'Chronological Term' - 'era' - when 'Genre/Form Term' - 'genr' - when 'Topical Term' - 'topic' - when 'Work' - 'work' - else - 'all_fields' - end - end - - def browse_search_field(browse_type, heading_type) - heading_type = search_field(heading_type) if heading_type - - browse_type - end - def browse_uri_encode (link_url) link_url = link_url.gsub('&','%26') link_url = link_url.gsub('"','%22') @@ -137,75 +108,26 @@ def build_alt_forms(alt_forms) return html.html_safe end - # TODO: Review generated search fields in search links. author_work_browse, for example, is not a valid search field. - def build_search_link(format_type, encoded_heading, search_type) - if search_type == "pers" || search_type == "corp" || search_type == "event" - the_search_field = 'search_field_row[]=author_' + search_type + '_browse&search_field_row[]=subject_' + search_type + '_browse' - return format_the_formats(format_type, encoded_heading, the_search_field, "OR") - else - the_search_field = 'search_field_row[]=subject_' + search_type + '_browse&search_field_row[]=author_' + search_type + '_browse' - return format_the_formats(format_type, encoded_heading, the_search_field, "NOT") - end - return ""#%2F + def build_search_link(format, f_count) + browse_field_count = @heading_document.browse_fields.count + boolean_row = {} + (browse_field_count - 1).times { |i| boolean_row[i + 1] = 'OR' } + search_params = { + advanced_query: 'yes', + search_field: 'advanced', + search_field_row: @heading_document.browse_fields, + boolean_row: boolean_row, + op_row: ['AND'] * browse_field_count, + q_row: [@heading_document['heading']] * browse_field_count, + "f[format]": [format] + } + + format_with_count = "#{pluralize_format(format)} (#{number_with_delimiter(f_count)})" + link_id = "facet_link_#{format.downcase.gsub(/[\/\-\s]/, '_')}" + link_to format_with_count, search_catalog_path(search_params).html_safe, id: link_id end - - def format_the_formats(f_type, encoded_heading, the_search_field, bool) - html = "" - f = f_type.split(" (")[0] - case f - when "Books" - html = '' - html += '' + f_type + '' - when "Journals/Periodicals" - html = '' - html += '' + f_type + '' - when "Manuscripts/Archives" - html = '' - html += '' + f_type + '' - when "Maps" - html = '' - html += '' + f_type + '' - when "Musical Scores" - html = '' - html += '' + f_type + '' - when "Non-musical Recordings" - html = '' - html += '' + f_type + '' - when "Videos" - html = '' - html += '' + f_type + '' - when "Computer Files" - html = '' - html += '' + f_type + '' - when "Databases" - html = '' - html += '' + f_type + '' - when "Musical Recordings" - html = '' - html += '' + f_type + '' - when "Theses" - html = '' - html += '' + f_type + '' - when "Microforms" - html = '' - html += '' + f_type + '' - when "Miscellaneous" - html = '' - html += '' + f_type + '' - end - return html.html_safe + + def pluralize_format(format) + format.split('/').map(&:pluralize).join('/') end end diff --git a/blacklight-cornell/app/helpers/cornell_catalog_helper.rb b/blacklight-cornell/app/helpers/cornell_catalog_helper.rb index 86c25230b..d44f20c75 100644 --- a/blacklight-cornell/app/helpers/cornell_catalog_helper.rb +++ b/blacklight-cornell/app/helpers/cornell_catalog_helper.rb @@ -1431,20 +1431,26 @@ def request_path(group, id, aeon_codes, document, scan) end if ENV['AEON_REQUEST'].blank? && group != 'AEON_SCAN_REQUEST' - aeon_req = "/aeon/#{id.to_s}" + aeon_req = "/aeon/#{id}" else url = group == 'AEON_SCAN_REQUEST' ? ENV['AEON_SCAN_REQUEST'] : ENV['AEON_REQUEST'] aeon_req = url.gsub('~id~', id.to_s).gsub('~libid~',aeon_codes.join('|')) end - if document['url_findingaid_display'] && document['url_findingaid_display'].size > 0 - finding_a = (document['url_findingaid_display'][0]).split('|')[0] - # only replace the placeholder if a finding aid value exists - aeon_req = aeon_req.gsub('~fa~', finding_a) - else - # otherwise remove the finding aid placeholder - aeon_req = aeon_req.gsub('&finding=~fa~', '') - end + # NOTE: In order to support display of multiple finding aids (see, e.g., bib 3272126), + # I'm using a different way of handling the finding aid URLs (the @finding_aids variable + # in the aeon_controller). So I'm not sure if we even need to do the following anymore. + # We should probably test this and remove it if it's not needed. (2/27/2025) + + # If there is a finding aid URL, replace the placeholder in the AEON request URL with it + if document['url_findingaid_display'] && document['url_findingaid_display'].size > 0 + finding_a = (document['url_findingaid_display'][0]).split('|')[0] + # only replace the placeholder if a finding aid value exists + aeon_req = aeon_req.gsub('~fa~', finding_a) + else + # otherwise remove the finding aid placeholder + aeon_req = aeon_req.gsub('&finding=~fa~', '') + end (group == "Circulating" ) ? magic_path : aeon_req end diff --git a/blacklight-cornell/app/helpers/display_helper.rb b/blacklight-cornell/app/helpers/display_helper.rb index 1acaf6db9..0ba33df11 100644 --- a/blacklight-cornell/app/helpers/display_helper.rb +++ b/blacklight-cornell/app/helpers/display_helper.rb @@ -107,13 +107,24 @@ def render_pair_delimited_index_field_value args # * link_to's with trailing
's -- the default -- (url_other_display & # url_toc_display in field listing on item page) + # Renders display links based on the provided arguments. + # + # @param [Hash] args The arguments to render the display link + # @option args [String] :field The field name to fetch the display link configuration + # @option args [Array] :value The array of links to be rendered + # @option args [Hash] :document The Solr document containing the field + # @option args [String] :format The format in which the links should be rendered (raw|default, default: 'default') + # + # @return [String, Array] the rendered display link(s) based on the format + # + # The method processes the links and renders them based on the specified format. + # If the format is 'url' and there is only one link, it returns the URL directly. + # Otherwise, it generates HTML links with appropriate labels and metadata. + # The method also handles different field types and renders them accordingly. def render_display_link args - label = blacklight_config.display_link[args[:field]][:label] - links = args[:value] - #Rails.logger.debug("es287_debug #{__FILE__}:#{__LINE__} links = #{links.inspect}") - links ||= args[:document].fetch(args[:field], :sep => nil) if args[:document] and args[:field] - #Rails.logger.debug("es287_debug #{__FILE__}:#{__LINE__} links = #{links.inspect}") - render_format = args[:format] ? args[:format] : 'default' + label = blacklight_config.dig(:display_link, args[:field], :label) || args[:field] + links = args[:value] || (args[:document] && args[:field] && args[:document].fetch(args[:field], :sep => nil)) + render_format = args[:format] || 'default' value = links.map do |link| #Check to see whether there is metadata at the end of the link @@ -127,20 +138,16 @@ def render_display_link args link_to(process_online_title(label), url.html_safe, {:class => 'online-access', :onclick => "javascript:_paq.push(['trackEvent', 'itemView', 'outlink']);"}) end - #Rails.logger.debug("es287_debug #{__FILE__}:#{__LINE__} field = #{args[:field].inspect}") - #Rails.logger.debug("es287_debug #{__FILE__}:#{__LINE__} render_format = #{render_format.inspect}") - #Rails.logger.debug("es287_debug #{__FILE__}:#{__LINE__} value = #{value.inspect}") if render_format == 'raw' - return value + value else - case args[:field] + case args[:field] when'url_findingaid_display' - return value[0] + value when 'url_bookplate_display' - Rails.logger.debug("es287_debug #{__FILE__}:#{__LINE__} field = #{args[:field].inspect}") - return value.uniq.join(',').html_safe + value.uniq.join(',').html_safe when 'url_other_display' - return value.join('
').html_safe + value.join('
').html_safe else fp = Blacklight::FieldPresenter.new( self, args[:document], blacklight_config.show_fields[args[:field]], :value => label) fp.render diff --git a/blacklight-cornell/app/helpers/single_search_helper.rb b/blacklight-cornell/app/helpers/single_search_helper.rb index 0514e1781..ae3df5d6c 100644 --- a/blacklight-cornell/app/helpers/single_search_helper.rb +++ b/blacklight-cornell/app/helpers/single_search_helper.rb @@ -7,12 +7,6 @@ def render_body_class extra_body_classes.join " " end - def ss_encode (str) - str - #CGI::escape(str) - #str = str.gsub('%','%25') - end - def downcast (str) str.gsub(/\//, '_'). gsub(/::/, '/'). @@ -48,19 +42,19 @@ def bento_all_results_link(key) when "libguides" link = 'http://guides.library.cornell.edu/libguides/home' when "ebsco_eds" - bq = ss_encode(params[:q] || params[:query]) + bq = params[:q] || params[:query] if bq.present? link = "https://discovery.ebsco.com/c/u2yil2/results?q=#{bq}" else link = "https://discovery.ebsco.com/c/u2yil2" end when "digitalCollections" - link = controller.all_items_url(key, ss_encode(params[:q] || params[:query]), BentoSearch.get_engine(key).configuration.blacklight_format) + link = controller.all_items_url(key, params[:q] || params[:query], BentoSearch.get_engine(key).configuration.blacklight_format) else # our app chooses to use 'q' as the query param; the ajax loading controller # uses 'query'.This ordinarily is fine, but since we want this layout to work # for both, we have to look for both, oh well. - link = controller.all_items_url(key, ss_encode(params[:q] || params[:query]), BentoSearch.get_engine(key).configuration.blacklight_format) + link = controller.all_items_url(key, params[:q] || params[:query], BentoSearch.get_engine(key).configuration.blacklight_format) link = request.protocol + request.host_with_port + '/' + link end @@ -69,7 +63,7 @@ def bento_all_results_link(key) def bento_eds_count() eds_total = 0 - bq = ss_encode(params[:q] || params[:query]) + bq = params[:q] || params[:query] if bq.present? searcher = BentoSearch::ConcurrentSearcher.new(:ebsco_eds) searcher.search(bq, :per_page => 0) diff --git a/blacklight-cornell/app/item_decorators/bento_search/article_decorator.rb b/blacklight-cornell/app/item_decorators/bento_search/article_decorator.rb deleted file mode 100644 index 817e9b960..000000000 --- a/blacklight-cornell/app/item_decorators/bento_search/article_decorator.rb +++ /dev/null @@ -1,31 +0,0 @@ -module BentoSearch - class ArticleDecorator < StandardDecorator - - def render_source_info - parts = [] - - if self.source_title.present? - parts << _h.content_tag("span", self.source_title, :class => "source_title") - parts << ". " - elsif self.publisher.present? - parts << _h.content_tag("span", self.publisher, :class => "publisher") - parts << ". " - end - - if text = self.render_citation_details - parts << text << "." - end - - return _h.safe_join(parts, "") - end - # A summary. If config.for_dispaly.prefer_snippets_as_summary is set to true - # then prefers that, otherwise abstract. - # - # Truncates for display. - def render_summary - summary = nil - - end - -end -end diff --git a/blacklight-cornell/app/item_decorators/bento_search/prepends/standard_decorator.rb b/blacklight-cornell/app/item_decorators/bento_search/prepends/standard_decorator.rb new file mode 100644 index 000000000..45859d5d5 --- /dev/null +++ b/blacklight-cornell/app/item_decorators/bento_search/prepends/standard_decorator.rb @@ -0,0 +1,45 @@ +# Based on the Module#prepend pattern in ruby. +# Uses the to_prepare Rails hook in bento_search initializer to inject this module to override BentoSearch::StandardDecorator +module BentoSearch + module Prepends::StandardDecorator + + # Overrides #author_display from gem to handle when author is missing + # How to display a BentoSearch::Author object as a name + def author_display(author) + if author.present? + if (author.first.present? && author.last.present?) + "#{author.last}, #{author.first.slice(0,1)}" + elsif author.display.present? + author.display + elsif author.last.present? + author.last + else + nil + end + else + nil + end + end + + # Overrides #render_source_info from gem to remove citation details and tweak punctuation + # Returns source publication name OR publisher, along with volume/issue/pages + # if present, all wrapped in various tags and labels. Returns html_safe + # with tags. + # + # Experiment to do this in a decorator helper instead of a partial template, + # might be more convenient we think. + def render_source_info + parts = [] + + if self.source_title.present? + parts << _h.content_tag("span", I18n.t("bento_search.published_in"), :class=> "source_label") + parts << _h.content_tag("span", self.source_title, :class => "source_title") + parts << ". " + elsif self.publisher.present? + parts << _h.content_tag("span", self.publisher, :class => "publisher") + end + + return _h.safe_join(parts, "") + end + end +end diff --git a/blacklight-cornell/app/item_decorators/bento_search/standard_decorator.rb b/blacklight-cornell/app/item_decorators/bento_search/standard_decorator.rb deleted file mode 100644 index e0e39897c..000000000 --- a/blacklight-cornell/app/item_decorators/bento_search/standard_decorator.rb +++ /dev/null @@ -1,262 +0,0 @@ -module BentoSearch - class StandardDecorator < DecoratorBase - - - # convenience method that returns true if any of the keys - # are #present? eg - # item.any_present?(:source_title, :authors) === item.source_title.present? || item.authors.present? - # - # note present? is false for nil, empty strings, and empty arrays. - def any_present?(*keys) - keys.each do |key| - return true if self.send(key).present? - end - return false - end - - # How to display a BentoSearch::Author object as a name - def author_display(author) - if author.present? - if (author.first.present? && author.last.present?) - "#{author.last}, #{author.first.slice(0,1)}" - elsif author.display.present? - author.display - elsif author.last.present? - author.last - else - nil - end - else - nil - end - end - - # display multiple authors, with HTML markup, returns html_safe string. - # experimentally trying this as a decorator helper method rather - # than a view partial, not sure which is best. - # - # Will limit to first three authors, with elipsis if there are more. - # - # Over-ride if you want to format authors names differently, or - # show more or less than first 3, etc. - def render_authors_list - parts = [] - - first_three = self.authors.slice(0,3) - - first_three.each_with_index do |author, index| - parts << _h.content_tag("span", :class => "author") do - self.author_display(author) - end - if (index + 1) < first_three.length - parts << "; " - end - end - - if self.authors.length > 3 - parts << I18n.t("bento_search.authors_et_al") - end - - return _h.safe_join(parts, "") - end - - # Returns source publication name OR publisher, along with volume/issue/pages - # if present, all wrapped in various tags and labels. Returns html_safe - # with tags. - # - # Experiment to do this in a decorator helper instead of a partial template, - # might be more convenient we think. - def render_source_info - parts = [] - - if self.source_title.present? - parts << _h.content_tag("span", I18n.t("bento_search.published_in"), :class=> "source_label") - parts << _h.content_tag("span", self.source_title, :class => "source_title") - parts << ". " - elsif self.publisher.present? - parts << _h.content_tag("span", self.publisher, :class => "publisher") - end - - if text = self.render_citation_details - end - - return _h.safe_join(parts, "") - end - - # if enough info is present that there will be non-empty render_source_info - # should be over-ridden to match display_source_info - def has_source_info? - self.any_present?(:source_title, :publisher, :start_page) - end - - # Mix-in a default missing title marker for empty titles - # (Used to combine title and subtitle when those were different fields) - def complete_title - if self.title.present? - self.title - else - I18n.translate("bento_search.missing_title") - end - end - - - - # volume, issue, and page numbers. With prefixed labels from I18n. - # That's it. - def render_citation_details - # \u00A0 is unicode non-breaking space to keep labels and values from - # getting separated. - result_elements = [] - - result_elements.push("#{I18n.t('bento_search.volume')}\u00A0#{volume}") if volume.present? - - result_elements.push("#{I18n.t('bento_search.issue')}\u00A0#{issue}") if issue.present? - - if (! start_page.blank?) && (! end_page.blank?) - result_elements.push html_escape "#{I18n.t('bento_search.pages')}\u00A0#{start_page}-#{end_page}" - elsif ! start_page.blank? - result_elements.push html_escape "#{I18n.t('bento_search.page')}\u00A0#{start_page}" - end - - return nil if result_elements.empty? - - return result_elements.join(", ").html_safe - end - - # A summary. If config.for_dispaly.prefer_snippets_as_summary is set to true - # then prefers that, otherwise abstract. - # - # Truncates for display. - def render_summary - summary = nil - max_chars = (self.display_configuration.try {|h| h["summary_max_chars"]}) || 280 - - - - if self.snippets.length > 0 && !(self.display_configuration.try {|h| h["prefer_abstract_as_summary"]} && self.abstract) - summary = self.snippets.first - self.snippets.slice(1, self.snippets.length).each do |snippet| - summary += ' '.html_safe + snippet if (summary.length + snippet.length) <= max_chars - end - else - summary = _h.bento_truncate( self.abstract, :length => max_chars ) - end - - summary - end - - # A display method, this is like #langauge_str, but will be nil if - # the language_code matches the current default locale, used - # for printing language only when not "English" normally. - # - #(Sorry, will be 'Spanish' never 'Espa~nol", we don't - # have a data source for language names in other languages right now. ) - def display_language - default = I18n.locale.try {|l| l.to_s.gsub(/\-.*$/, '')} || "en" - - this_doc = self.language_obj.try(:iso_639_1) - - return nil if this_doc == default - - self.language_str - end - - # format string to display to user. Uses #format_str if present, - # otherwise finds an i18n label from #format. Returns nil if none - # available. - def display_format - value = self.format_str || - I18n.t(self.format, :scope => [:bento_search, :format], :default => self.format.to_s.titleize) - - return value.blank? ? nil : value - end - - # outputs a date for display, from #publication_date or #year. - # Uses it's own logic to decide whether to output entire date or just - # year, if it has a complete date. (If volume and issue are present, - # just year). - # - # Over-ride in a decorator if you want to always or never or different - # logic for complete date. Or if you want to change the format of the date, - # etc. - def display_date - if self.publication_date - if self.volume && self.issue - # just the year, ma'am - I18n.localize(self.publication_date, :format => "%Y") - else - # whole date, since we got it - I18n.localize(self.publication_date, :format => "%d %b %Y") - end - elsif self.year - self.year.to_s - else - nil - end - end - - # A unique opaque identifier for a record may sometimes be - # required, for instance in Atom. - # - # We here provide a really dumb implementation, if and only if - # the result has an engine_id and unique_id available, (and - # a #root_url is available) by basically concatenating them to - # app base url. - # - # That's pretty lame, probably not resolvable, but best we - # can do without knowing details of host app. You may want - # to over-ride this in a decorator to do something more valid - # in an app-specific way. - # - # yes uri_identifier is like PIN number, deal with it. - def uri_identifier - if self.engine_id.present? && self.unique_id.present? && _h.respond_to?(:root_url) - "#{_h.root_url.chomp("/")}/bento_search_opaque_id/#{CGI.escape self.engine_id}/#{CGI.escape self.unique_id}" - else - nil - end - end - - # Can be used as an id attribute for anchor destination in HTML. - # Will return "#{prefix}_#{index}" -- if prefix is missing, - # will use #engine_id if present. If both are missing, returns nil. - # if index missing, returns nil. - def html_id(prefix, index) - prefix = prefix || self.engine_id - prefix, index = prefix.to_s, index.to_s - - return nil if index.empty? - return nil if prefix.empty? - - return "#{prefix}_#{index}" - end - - - ################### - # turn into a representative OpenURL - # - # use to_openurl_kev to go straight there, - # or to_openurl to get a ruby OpenURL object. - ################### - - - # Returns a ruby OpenURL::ContextObject (NISO Z39.88). - # or nil if none avail. - def to_openurl - return nil if openurl_disabled - - BentoSearch::OpenurlCreator.new(self).to_openurl - end - - # Returns a kev encoded openurl, that is a URL query string representing - # openurl. Or nil if none available. - # - # Right now just calls #to_openurl.kev, can conceivably - # be modified to do things more efficient, without a ruby openurl - # obj. Law of demeter, represent. - def to_openurl_kev - to_openurl.try(:kev) - end - - end -end diff --git a/blacklight-cornell/app/models/bento_search/catalog_searcher.rb b/blacklight-cornell/app/models/bento_search/catalog_searcher.rb new file mode 100644 index 000000000..b7e8b4d72 --- /dev/null +++ b/blacklight-cornell/app/models/bento_search/catalog_searcher.rb @@ -0,0 +1,26 @@ +class BentoSearch::CatalogSearcher + include Blacklight::Searchable + + def initialize(search_params) + @search_params = search_params + end + + def search_response + (response, _deprecated_document_list) = search_service.search_results + response + end + + private + + def blacklight_config + CatalogController.blacklight_config + end + + def search_state + Blacklight::SearchState.new(@search_params, blacklight_config) + end + + def search_service_class + Blacklight::SearchService + end +end diff --git a/blacklight-cornell/app/models/heading_solr_document.rb b/blacklight-cornell/app/models/heading_solr_document.rb new file mode 100644 index 000000000..b710c9f05 --- /dev/null +++ b/blacklight-cornell/app/models/heading_solr_document.rb @@ -0,0 +1,41 @@ +class HeadingSolrDocument + include Blacklight::Solr::Document + + def type + type_for_desc(fetch('headingTypeDesc', '')) + end + + def type_for_desc(heading_type_desc) + case heading_type_desc + when 'Personal Name' + 'pers' + when 'Corporate Name' + 'corp' + when 'Event' + 'event' + when 'Geographic Name' + 'geo' + when 'Chronological Term' + 'era' + when 'Genre/Form Term' + 'genr' + when 'Topical Term' + 'topic' + else + # No headingTypeDesc for authortitle headings + 'work' + end + end + + def browse_fields + return [] unless type.present? + + browse_fields = ["subject_#{type}_browse"] + if ['pers', 'corp', 'event'].include?(type) + browse_fields << "author_#{type}_browse" + elsif type == 'work' + browse_fields << 'authortitle_browse' + end + browse_fields + end +end diff --git a/blacklight-cornell/app/models/search_builder.rb b/blacklight-cornell/app/models/search_builder.rb index 46fe0e94e..06ea0ea18 100644 --- a/blacklight-cornell/app/models/search_builder.rb +++ b/blacklight-cornell/app/models/search_builder.rb @@ -4,7 +4,9 @@ class SearchBuilder < Blacklight::SearchBuilder include Blacklight::Solr::SearchBuilderBehavior include BlacklightRangeLimit::RangeLimitBuilder - self.default_processor_chain += [:sortby_title_when_browsing, :sortby_callnum, :set_fl, :set_fq, :set_query, :homepage_default] + self.default_processor_chain += [:sortby_title_when_browsing, :sortby_callnum, + :set_fl, :set_fq, :set_query, + :homepage_default, :group_bento_results] DEFAULT_BOOLEAN = 'AND' DEFAULT_OP = 'AND' @@ -58,7 +60,7 @@ def set_fq solr_parameters end end - # Sets solr q param from search fields, booleans, and ops (simple and advanced search) + # Sets solr q param from search fields, booleans, and ops (simple, advanced, and bento search) def set_query solr_parameters # Standard blacklight_params from advanced search form: # { @@ -95,8 +97,26 @@ def set_query solr_parameters blacklight_params.delete(:count) end - # Build solr q param for simple search - solr_parameters[:q] = build_simple_search_query(blacklight_params) + # Build solr q param for simple and bento search + solr_parameters[:q] = build_simple_search_query(blacklight_params, bento: blacklight_params[:bento]) + end + end + + # Set result grouping solr parameters for bento search results + def group_bento_results solr_parameters + if blacklight_params[:bento] + # Group results by format_main_facet and remove unnecessary facet values and stats + # format_main_facet is a single-valued field used specially for bento's type-aggregated relevance sorting + # vs catalog's show and index multivalued "format" solr field + solr_parameters.merge!({ + :group => true, + :'group.field' => 'format_main_facet', + :'group.limit' => 3, + :'group.ngroups' => 'true', + :fl => 'id,pub_date_display,format,fulltitle_display,fulltitle_vern_display,author_display,score,pub_info_display,availability_json', + :facet => false, + :stats => false + }) end end @@ -133,12 +153,18 @@ def remove_blank_rows(params) params.merge(cleaned_params) end - def build_simple_search_query(params) - return '' if params[:q].blank? + def build_simple_search_query(params, bento=false) + return '' if params[:q].blank? || !params[:q].is_a?(String) query = clean_q(params[:q]) - search_field = params[:search_field] - set_q_with_search_fields(query: query, search_field: search_field) + + # Ideally, bento and simple search would use the same logic: https://culibrary.atlassian.net/browse/DACCESS-519 + if bento && query =~ /AND|OR|NOT/ + query + else + search_field = params[:search_field] + set_q_with_search_fields(query: query, search_field: search_field) + end end def build_advanced_search_query(params) diff --git a/blacklight-cornell/app/search_engines/bento_search/best_bet_engine.rb b/blacklight-cornell/app/search_engines/bento_search/best_bet_engine.rb index bf67cc1d5..42cea6a96 100644 --- a/blacklight-cornell/app/search_engines/bento_search/best_bet_engine.rb +++ b/blacklight-cornell/app/search_engines/bento_search/best_bet_engine.rb @@ -14,7 +14,8 @@ def search_implementation(args) # 'args' should be a normalized search arguments hash including the following elements: # :query, :per_page, :start, :page, :search_field, :sort, :oq bento_results = BentoSearch::Results.new - q = URI.encode_www_form({:ignore => args[:oq]}).gsub("ignore=","").gsub("+","%20") + # Strip quotes and encode for uri + q = URI.encode_uri_component(args[:query].gsub(/["”“]/, '')) uri = URI.join("https://bestbets.library.cornell.edu/match/", q) best_bet = [] begin diff --git a/blacklight-cornell/app/search_engines/bento_search/digital_collections_engine.rb b/blacklight-cornell/app/search_engines/bento_search/digital_collections_engine.rb index 40095a211..e5e2eacd4 100644 --- a/blacklight-cornell/app/search_engines/bento_search/digital_collections_engine.rb +++ b/blacklight-cornell/app/search_engines/bento_search/digital_collections_engine.rb @@ -22,7 +22,7 @@ def search_implementation(args) base = Addressable::URI.parse("https://digital.library.cornell.edu") uri = URI( base + "catalog.bento") params = { - :q => args[:oq], + :q => args[:query], :utf8 => "✓", :search_field => "all_fields", :rows => 3 diff --git a/blacklight-cornell/app/search_engines/bento_search/ebsco_eds_engine.rb b/blacklight-cornell/app/search_engines/bento_search/ebsco_eds_engine.rb index a8fc5ed83..cc41e2905 100644 --- a/blacklight-cornell/app/search_engines/bento_search/ebsco_eds_engine.rb +++ b/blacklight-cornell/app/search_engines/bento_search/ebsco_eds_engine.rb @@ -21,6 +21,9 @@ class BentoSearch::EbscoEdsEngine client.connect_timeout = client.send_timeout = client.receive_timeout = HttpTimeout end + # TODO: Fix empty query handling: https://culibrary.atlassian.net/browse/DACCESS-520 + # BentoSearch::SearchEngine failed results: #"Unknown error retrieving results.", "ErrorDescription"=>"Unknown Error", "ErrorNumber"=>"106"}> + def search_implementation(args) session = EBSCO::EDS::Session.new({ @@ -33,7 +36,7 @@ def search_implementation(args) results = BentoSearch::Results.new xml, response, exception = nil, nil, nil - q = args[:oq].present? ? args[:oq] : args[:query].present? ? args[:query] : nil + q = args[:query] if q.nil? results.total_items = 0 return results diff --git a/blacklight-cornell/app/search_engines/bento_search/institutional_repositories_engine.rb b/blacklight-cornell/app/search_engines/bento_search/institutional_repositories_engine.rb index abf0e2230..9bc0d32b5 100644 --- a/blacklight-cornell/app/search_engines/bento_search/institutional_repositories_engine.rb +++ b/blacklight-cornell/app/search_engines/bento_search/institutional_repositories_engine.rb @@ -20,10 +20,6 @@ def search_implementation(args) # If not specified, we can maybe default to books for now. format = configuration[:blacklight_format] || 'Institutional Repositories' - qp = { q: args[:oq] }.to_param - # q = URI::encode(args[:oq].gsub(" ","+")) - q = qp[2..-1] - uri = get_solr_url(args) url = Addressable::URI.parse(uri) url.normalize @@ -33,9 +29,10 @@ def search_implementation(args) fq = set_fq() + # RSolr encodes params sent to solr solr = RSolr.connect :url => url.to_s solr_response = solr.get 'select', :params => { - :q => q, + :q => args[:query], :fq => fq, :start => start * per_page, :rows => per_page, @@ -43,7 +40,6 @@ def search_implementation(args) :defType => 'edismax' } - results = solr_response['response']['docs'] results.each do |i| diff --git a/blacklight-cornell/app/search_engines/bento_search/libguides_engine.rb b/blacklight-cornell/app/search_engines/bento_search/libguides_engine.rb index a08368040..23c62801d 100644 --- a/blacklight-cornell/app/search_engines/bento_search/libguides_engine.rb +++ b/blacklight-cornell/app/search_engines/bento_search/libguides_engine.rb @@ -18,10 +18,9 @@ def search_implementation(args) # Format is passed to the engine using the configuration set up in the bento_search initializer # If not specified, we can maybe default to books for now. format = configuration[:blacklight_format] || "Research Guides" - # q = URI::encode(args[:oq].gsub(" ","+")) guides_response = [] path = "http://lgapi-us.libapps.com/1.1/guides/" - st = args[:oq].gsub(" ", "+") + st = args[:query].gsub(/["”“]/, '') escaped = { site_id: 45, search_terms: st, status: 1, key: ENV["LIBGUIDES_API_KEY"] }.to_param guides_url = path + "?" + escaped guides_response = JSON.load(URI.open(guides_url)) diff --git a/blacklight-cornell/app/search_engines/bento_search/solr_engine.rb b/blacklight-cornell/app/search_engines/bento_search/solr_engine.rb index 6d5e14318..138665608 100644 --- a/blacklight-cornell/app/search_engines/bento_search/solr_engine.rb +++ b/blacklight-cornell/app/search_engines/bento_search/solr_engine.rb @@ -1,3 +1,4 @@ +# Used by search#single_search when bento search engine is a blacklight format class BentoSearch::SolrEngine include BentoSearch::SearchEngine @@ -20,6 +21,8 @@ def search_implementation(args) # If not specified, we can maybe default to books for now. format = configuration[:blacklight_format] || 'Book' + # TODO: Should this retrieve results from BentoSearch::CatalogSearcher like in SolrEngineSingle, + # instead of hitting solr directly and bypassing blacklight processing? solr = RSolr.connect :url => configuration.solr_url solr_response = solr.get 'select', :params => { :q => args[:query], @@ -39,10 +42,10 @@ def search_implementation(args) # bento_search does some slightly odd things to author strings in order to display them, # so the raw string coming out of *our* display value turns into nonsense by default # Telling to create a new Author with an explicit 'display' value seems to work. - item.authors << BentoSearch::Author.new({:display => a.split('|')[1][0..-2]}) + item.authors << BentoSearch::Author.new({:display => a}) end item.year = i['pub_date_facet'].to_s - item.link = "http://catalog.library.cornell.edu/catalog/#{i['id']}" + item.link = "/catalog/#{i['id']}" bento_results << item end bento_results.total_items = solr_response['response']['numFound'] @@ -51,5 +54,9 @@ def search_implementation(args) end - + def self.default_configuration + { + :solr_url => ENV['SOLR_URL'] + } + end end diff --git a/blacklight-cornell/app/search_engines/bento_search/solr_engine_single.rb b/blacklight-cornell/app/search_engines/bento_search/solr_engine_single.rb index 6079ef2ba..5230e9d4f 100644 --- a/blacklight-cornell/app/search_engines/bento_search/solr_engine_single.rb +++ b/blacklight-cornell/app/search_engines/bento_search/solr_engine_single.rb @@ -11,44 +11,22 @@ class BentoSearch::SolrEngineSingle # BentoSearch::ResultItem objects for each hit in the current page. See individual class # documentation for more info. def search_implementation(args) - # 'args' should be a normalized search arguments hash including the following elements: # :query, :per_page, :start, :page, :search_field, :sort - Rails.logger.debug("mjc12test: #{self.class.name} called. Query is #{args[:query]}}") - bento_results = BentoSearch::Results.new - # solr search must be transformed to match simple search transformation. - q = SearchController.transform_query args[:query] + log_debug_info("#{__FILE__}:#{__LINE__}", ['args:', args]) - log_debug_info("#{__FILE__}:#{__LINE__}", - ["args:", args], ["q:", q]) + # Use Blacklight::SearchService to get the search results + search_params = { q: args[:query], search_field: 'all_fields', bento: true } + response = BentoSearch::CatalogSearcher.new(search_params).search_response - Rails.logger.debug("mjc12test: BentoSearch::SolrEngineSingle called. #{__FILE__} #{__LINE__} transformed q = #{q}") - #solr = RSolr.connect :url => 'http://da-prod-solr1.library.cornell.edu/solr/blacklight' - Rails.logger.debug("mjc12test: #{self.class.name} #{__FILE__} #{__LINE__} url is #{configuration.solr_url}") - solr = RSolr.connect :url => configuration.solr_url - solr_response = solr.get "select", :params => { - :q => q, - #:fq => "format:\"#{format}\"", - # :rows => args[:per_page], - :rows => 20, # from sample single query; should set this dynamically? - :group => true, - "group.field" => "format_main_facet", - "group.limit" => 3, - "group.ngroups" => "true", - :sort => "score desc, pub_date_sort desc, title_sort asc", - :fl => "id,pub_date_display,format,fulltitle_display,fulltitle_vern_display,author_display,score,pub_info_display,availability_json", - :mm => 1, - #:defType => 'edismax' - } - - Rails.logger.debug("mjc12test: BlacklightEngine2 search called. #{__FILE__} #{__LINE__} solr_response #{solr_response}") # Because all our facets are packaged in a single query, we have to treat this as a single result # in order to have bento_search process it correctly. We'll split up into different facets # once we get back to the controller! + bento_results = BentoSearch::Results.new result = BentoSearch::ResultItem.new - result.custom_data = solr_response["grouped"]["format_main_facet"]["groups"] + result.custom_data = response.group['groups'] bento_results << result bento_results.total_items = 1 - return bento_results + bento_results end end diff --git a/blacklight-cornell/app/views/aeon/_aeon_scan_body.html.erb b/blacklight-cornell/app/views/aeon/_aeon_scan_body.html.erb index 9ac2a0348..a4ff38dd2 100644 --- a/blacklight-cornell/app/views/aeon/_aeon_scan_body.html.erb +++ b/blacklight-cornell/app/views/aeon/_aeon_scan_body.html.erb @@ -51,11 +51,11 @@
- Please enter any deadlines, special requests or questions for library staff. +
@@ -63,11 +63,11 @@
- If you have seen the image you are requesting online, please provide the URL. You may also enter an image ID number, if known. +
@@ -75,8 +75,8 @@
- Enter any notes about this request for your personal reference. +