Skip to content

Instantly share code, notes, and snippets.

@jkeck
Created January 13, 2012 21:38
Show Gist options
  • Save jkeck/1608835 to your computer and use it in GitHub Desktop.
Save jkeck/1608835 to your computer and use it in GitHub Desktop.
require 'blacklight/catalog'
class CatalogController < ApplicationController
include Blacklight::Catalog
configure_blacklight do |config|
config.default_solr_params = {
:qt => "search",
:per_page => 20
}
# solr fld values given special treatment in the index (search results) view
config.index.show_link = 'title_display'
config.index.record_display_type = "format"
# solr field configuration for document/show views
config.show.html_title = 'title_245a_display'
config.show.vern_html_title = 'vern_title_display'
config.show.heading = 'title_full_display'
config.show.vern_heading = 'vern_title_full_display'
config.show.display_type = 'format'
# solr fields that will be treated as facets by the blacklight application
# The ordering of the field names is the order of the display
#
# Setting a limit will trigger Blacklight's 'more' facet values link.
# * If left unset, then all facet values returned by solr will be displayed.
# * If set to an integer, then "f.somefield.facet.limit" will be added to
# solr request, with actual solr request being +1 your configured limit --
# you configure the number of items you actually want _displayed_ in a page.
# * If set to 'true', then no additional parameters will be sent to solr,
# but any 'sniffed' request limit parameters will be used for paging, with
# paging at requested limit -1. Can sniff from facet.limit or
# f.specific_field.facet.limit solr request params. This 'true' config
# can be used if you set limits in :default_solr_params, or as defaults
# on the solr side in the request handler itself. Request handler defaults
# sniffing requires solr requests to be made with "echoParams=all", for
# app code to actually have it echo'd back to see it.
config.add_facet_field "access_facet", :label => "Access"
config.add_facet_field "author_person_facet", :label => "Author", :limit => 10
config.add_facet_field "author_other_facet", :label => "Organization (as Author)", :limit => 10
config.add_facet_field "building_facet", :label => "Location", :limit => 10
config.add_facet_field "callnum_top_facet", :label => "Call Number", :limit => 10
config.add_facet_field "collection", :label => "Image Collection"
config.add_facet_field "db_az_subject", :label => "Database Subject", :limit => 100
config.add_facet_field "lc_alpha_facet", :label => "Refine Call Number", :limit => 10
config.add_facet_field "lc_b4cutter_facet", :label => "Refine Call Number", :limit => 10
config.add_facet_field "dewey_1digit_facet", :label => "Refine Call Number", :limit => 10
config.add_facet_field "dewey_2digit_facet", :label => "Refine Call Number", :limit => 10
config.add_facet_field "dewey_b4cutter_facet", :label => "Refine Call Number", :limit => 10
config.add_facet_field "gov_doc_type_facet", :label => "Refine Call Number", :limit => 10
config.add_facet_field "era_facet", :label => "Era", :limit => 10
config.add_facet_field "format", :label => "Format"
config.add_facet_field "geographic_facet", :label => "Region", :limit => 10
config.add_facet_field "language", :label => "Language", :limit => 10
config.add_facet_field "medium", :label => "Image Medium", :limit => 10
config.add_facet_field "pub_date_group_facet", :label => "Publication Year", :limit => 10
config.add_facet_field "pub_date", :label => "Refine Pub Year", :limit => 10
config.add_facet_field "topic_facet", :label => "Topic", :limit => 10
# Have BL send all facet field names to Solr, which has been the default
# previously. Simply remove these lines if you'd rather use Solr request
# handler defaults, or have no facets.
config.default_solr_params[:'facet.field'] = config.facet_fields.keys
# solr fields to be displayed in the index (search results) view
# The ordering of the field names is the order of the display
config.add_index_field "title_uniform_display", :label => "Title:"
config.add_index_field "vern_title_uniform_display", :label => "Title:"
config.add_index_field "author_person_display", :label => "Author/Creator:"
config.add_index_field "vern_author_person_display", :label => "Author/Creator:"
config.add_index_field "author_corp_display", :label => "Corporate Author:"
config.add_index_field "vern_author_corp_display", :label => "Corporate Author:"
config.add_index_field "author_meeting_display", :label => "Meeting:"
config.add_index_field "vern_author_meeting_display", :label => "Meeting:"
config.add_index_field "pub_date", :label => "Date:"
config.add_index_field "url_sfx_display", :label => "Online Access:"
# solr fields to be displayed in the show (single result) view
# The ordering of the field names is the order of the display
config.add_show_field "title_full_display", :label => "Title:"
config.add_show_field "vern_title_full_display", :label => "Title:"
config.add_show_field "title_uniform_display", :label => "Uniform Title:"
config.add_show_field "vern_title_uniform_display", :label => "Uniform Title:"
config.add_show_field "title_variant_display", :label => "Alternate Title:"
config.add_show_field "author_person_full_display", :label => "Author/Creator:"
config.add_show_field "vern_author_person_full_display", :label => "Author/Creator:"
config.add_show_field "author_corp_display", :label => "Corporate Author:"
config.add_show_field "vern_author_corp_display", :label => "Corporate Author:"
config.add_show_field "author_meeting_display", :label => "Meeting Author:"
config.add_show_field "vern_author_meeting_display", :label => "Meeting Author:"
config.add_show_field "medium", :label => "Medium:"
config.add_show_field "summary_display", :label => "Description:"
config.add_show_field "topic_display", :label => "Subject:"
config.add_show_field "subject_other_display", :label => "Subject:"
config.add_show_field "physical", :label => "Physical Description:"
config.add_show_field "pub_display", :label => "Publication Info:"
config.add_show_field "possessor", :label => "Owned By:"
config.add_show_field "rights", :label => "Copyright:"
# "fielded" search configuration. Used by pulldown among other places.
# For supported keys in hash, see rdoc for Blacklight::SearchFields
#
# Search fields will inherit the :qt solr request handler from
# config[:default_solr_parameters], OR can specify a different one
# with a :qt key/value. Below examples inherit, except for subject
# that specifies the same :qt as default for our own internal
# testing purposes.
#
# The :key is what will be used to identify this BL search field internally,
# as well as in URLs -- so changing it after deployment may break bookmarked
# urls. A display label will be automatically calculated from the :key,
# or can be specified manually to be different.
# This one uses all the defaults set by the solr request handler. Which
# solr request handler? The one set in config[:default_solr_parameters][:qt],
# since we aren't specifying it otherwise.
config.add_search_field "search", :label => "Everything"
config.add_search_field "search_author", :label => "Author"
config.add_search_field "search_title", :label => "Title"
config.add_search_field "subject_terms", :qt => "search_subject", :label => "Subject terms"
config.add_search_field "call_number", :qt => "search_callnum", :label => "Call number"
config.add_search_field "search_series", :qt => "search_series", :label => "Series", :include_in_simple_select => false
config.add_search_field("author_title") do |field|
field.label = "Author + Title"
field.include_in_simple_select = false
field.solr_local_parameters = {
:qf => "search"
}
end
# "sort results by" select (pulldown)
# label in pulldown is followed by the name of the SOLR field to sort by and
# whether the sort is ascending or descending (it must be asc or desc
# except in the relevancy case).
config.add_sort_field 'score desc, pub_date_sort desc, title_sort asc', :label => 'relevance'
config.add_sort_field 'pub_date_sort desc, title_sort asc', :label => 'year (new to old)'
config.add_sort_field 'pub_date_sort asc, title_sort asc', :label => 'year (old to new)'
config.add_sort_field 'author_sort asc, title_sort asc', :label => 'author'
config.add_sort_field 'title_sort asc, pub_date_sort desc', :label => 'title'
# If there are more than this many search results, no spelling ("did you
# mean") suggestion is offered.
config.spell_max = 5
end
before_filter :check_callnum_search, :check_db_az_search, :check_hidden_context, :only=>:index
before_filter :search_session, :history_session, :set_cache, :except => [:access_data, :opensearch, :nearby, :ajax_hover, :qrc]
before_filter :delete_or_assign_search_session_params, :only=>[:index,:browse]
# We can remove this when we install the BlacklightAdvancedSearch plugin.
#Blacklight.config[:search_fields] << {:key => "advanced", :qt => Blacklight.config[:advanced][:search_field], :display_label => 'Advanced', :include_in_simple_select => false}
require "lib/stanford/nearby_on_shelf"
require "lib/stanford/solr_helper"
require "lib/curated_collections"
include Stanford::SolrHelper
include CuratedCollections
def index
CatalogController.solr_search_params_logic << :database_query_prefix
unless (params[:q].to_s.blank? and params[:f].to_s.blank? and params[:search_field].to_s.blank?)
extra_head_content << view_context.auto_discovery_link_tag(:rss, url_for(params.merge(:format => 'rss')), :title => "RSS for results")
extra_head_content << view_context.auto_discovery_link_tag(:atom, url_for(params.merge(:format => 'atom')), :title => "Atom for results")
end
if params.has_key?(:lookfor)
params[:q] = params[:lookfor]
end
if params[:q].to_s.empty? and params[:f].to_s.empty? and params[:search_field].to_s.empty? and params[:qt].to_s.empty?
@response = get_home_facets
else
# if params[:search_field] == Blacklight.config[:advanced][:search_field] or params[:qt] == Blacklight.config[:advanced][:search_field]
# CatalogController.solr_search_params_logic << :append_advanced_search
# # we use the @advanced_query variable in the UI to determine where we are sometimes.
# @advanced_query = Stanford::AdvancedQueryParser.new(params,Blacklight.config[:advanced])
# end
(@response,@document_list) = get_search_results
end
@filters = params[:f] || []
respond_to do |format|
format.html { save_current_search_params }
format.rss { render :layout => false }
format.atom { render :layout => false }
format.mobile { render :layout => false }
format.contact { render :layout => false }
# Should remove DB calls for format == MOBILE
end
end
#Commenting out for Prod to hide nearby on shelf
# get single document from the solr index
def show
@response, @document = get_solr_response_for_doc_id
@nearby_response = Stanford::NearbyOnShelf.new("static",{:item_display => @document[:item_display],:preferred_barcode=>@document[:preferred_barcode], :before => 2, :after => 2})
respond_to do |format|
format.html {setup_next_and_previous_documents}
format.mobile {render :layout => false}
format.request {render :layout => false}
format.stackmap { render :layout => false }
# Add all dynamically added (such as by document extensions)
# export formats.
@document.export_formats.each_key do | format_name |
# It's important that the argument to send be a symbol;
# if it's a string, it makes Rails unhappy for unclear reasons.
format.send(format_name.to_sym) { render :text => @document.export_as(format_name) }
end
end
end
# updates the search counter (allows the show view to paginate)
# we need to override this because the redirect_to is putting catalog in the url.
def update
adjust_for_results_view
session[:search][:counter] = params[:counter]
redirect_to catalog_path(params[:id])
end
def ajax_hovers
response, @document = get_solr_response_for_doc_id
end
# # action for sending email. This is meant to post from the form and to do processing
# def send_email_record
# #@response, @document = get_solr_response_for_doc_id
# @response, @documents = get_solr_response_for_field_values("id",params[:id])
# if params[:to]
# from = request.host # host w/o port for From address (from address cannot have port#)
# host = request.host
# host << ":#{request.port}" unless request.port.nil? # host w/ port for linking
# case params[:style]
# when 'sms'
# if !params[:carrier].blank?
# if params[:to].length != 10
# flash[:error] = "You must enter a valid 10 digit phone number"
# else
# email = RecordMailer.create_sms_record(@documents, {:to => params[:to], :carrier => params[:carrier]}, from, host)
# end
# else
# flash[:error] = "You must select a carrier"
# end
# when 'email'
# if params[:message] =~ /.*href=.*|.*url=.*|.*http:\/\/.*|.*https:\/\/.*/i
# flash[:error] = "Your message appears to be spam, and has not been sent. Please try sending your message again without any links."
# else
# if params[:to].match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
# email = RecordMailer.create_email_record(@documents, {:to => params[:to], :subject => params[:subject], :message => params[:message]}, from, host)
# else
# flash[:error] = "You must enter a valid email address"
# end
# end
# end
# if params[:email_address] and params[:email_address] != ""
# flash[:error] = "You have filled in a field that makes you appear as a spammer. Please follow the directions for the individual form fields."
# end
# RecordMailer.deliver(email) unless flash[:error]
# redirect_to :back
# else
# flash[:error] = "You must enter a recipient in order to send this message"
# end
# end
# Email Action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
def email
if request.post?
@response, @documents = get_solr_response_for_field_values("id",params[:id])
if params[:to]
notice = []
from = request.host # host w/o port for From address (from address cannot have port#)
url_gen_params = {:host => request.host_with_port, :protocol => request.protocol}
if params[:message] =~ /.*href=.*|.*url=.*|.*http:\/\/.*|.*https:\/\/.*/i
flash[:error] = "Your message appears to be spam, and has not been sent. Please try sending your message again without any links."
else
to = []
i = 0
params[:to].split(",").uniq.each do |address|
if address.strip.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
to << address.strip
else
notice << "#{address} is not a valid email address."
end
if i == 4
notice << "Emails only sent to the first 5 addresses."
break
end
i += 1
end
unless to.blank?
email = RecordMailer.email_record(@documents, {:to => to.join(", "), :message => params[:message], :type => params[:type], :subject => params[:subject]}, from, url_gen_params)
else
flash[:error] = "You must enter a valid email address"
end
end
if params[:email_address] and params[:email_address] != ""
flash[:error] = "You have filled in a field that makes you appear as a spammer. Please follow the directions for the individual form fields."
end
unless flash[:error]
email.deliver
notice << "Your email(s) have been sent."
end
flash[:notice] = notice.join("<br/>") unless notice.blank?
redirect_to :back
else
flash[:error] = "You must enter a recipient in order to send this message"
end
else
@documents = []
params[:id].each do |id|
@documents << SolrDocument.new({:id=>id})
end
end
end
# SMS action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
def sms
@response, @documents = get_solr_response_for_field_values("id",params[:id])
if request.post?
from = request.host # host w/o port for From address (from address cannot have port#)
url_gen_params = {:host => request.host_with_port, :protocol => request.protocol}
if params[:to]
phone_num = params[:to].gsub(/[^\d]/, '')
unless params[:carrier].blank?
if phone_num.length != 10
flash[:error] = "You must enter a valid 10 digit phone number"
else
email = RecordMailer.sms_record(@documents, {:to => phone_num, :carrier => params[:carrier]}, from, url_gen_params)
end
if params[:email_address] and params[:email_address] != ""
flash[:error] = "You have filled in a field that makes you appear as a spammer. Please follow the directions for the individual form fields."
end
unless flash[:error]
email.deliver
flash[:notice] = "Your text message has been sent."
end
redirect_to :back
else
flash[:error] = "You must select a carrier"
end
else
flash[:error] = "You must enter a recipient's phone number in order to send this message"
end
end
end
def project_news
require 'rss/2.0'
feed_url = URI.parse('http://lib.stanford.edu/group/searchworks/blogfeed')
@news = []
xml = Net::HTTP.get(feed_url)
result = RSS::Parser.parse(xml, true)
i = 0
while i < 3
item = result.items[i]
@news << {:title=>item.title,:description=>item.description,:link=>item.link,:date=>item.pubDate}
i += 1
end
render :layout => false
end
def qrc
response, @document = get_solr_response_for_doc_id
end
def selected_databases
@databases = databases_hash
resp, @documents = get_solr_response_for_field_values("id",curated_database_ids, {:sort => "title_sort asc"})
end
protected
def append_advanced_search(solr_params,user_params)
if (user_params.has_key?(:search_field) or user_params.has_key?(:qt)) and (user_params[:search_field] == Blacklight.config[:advanced][:search_field] or user_params[:qt] == Blacklight.config[:advanced][:search_field])
advanced = Stanford::AdvancedQueryParser.new(user_params,Blacklight.config[:advanced])
advanced.to_solr.each do |key,val|
solr_params[key] = val if val and !val.empty?
end
user_params.delete("fq") if params[:action] == "facet" and user_params.has_key?("fq")
end
solr_params
end
def database_query_prefix(solr_params,user_params)
if user_params.has_key?(:f) and user_params[:f].has_key?(:format) and user_params[:f][:format].include?("Database") and user_params.has_key?(:prefix)
solr_params[:qt] = "standard"
if user_params[:prefix] == "0-9"
qa = []
("0".."9").each do |num|
qa << "title_sort:#{num}*"
end
query_string = qa.join(" OR ")
else
query_string = "title_sort:#{user_params[:prefix]}*"
end
query_string << " AND #{user_params[:q]}" if user_params[:q]
solr_params[:q] = query_string
end
end
def set_cache
unless request.xhr?
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
end
# remove all quotes if we're on a callnumber search
def check_callnum_search
if params[:search_field] == "call_number"
params[:q] = "\"#{params[:q].gsub('"',"")}\""
end
end
# when solr (RSolr) throws an error (RSolr::RequestError), this method is executed.
def rsolr_request_error(exception)
if Rails.env == 'development'
raise exception
else
if params[:search_field] == Blacklight.config[:advanced][:search_field]
flash[:error] = "Sorry, I don't understand your search. Please try again.<br/>If you used quotes in your search, try again without quotes."
else
flash[:error] = "Sorry, I don't understand your search. Please try again."
end
redirect_to root_path
end
end
# when a request for /catalog/BAD_SOLR_ID is made, this method is executed...
def invalid_solr_id_error
flash[:error] = "Sorry, you seem to have encountered an error."
redirect_to root_path
end
def save_current_search_params
return if search_session[:q].blank? and search_session[:f].blank? and search_session[:fq].blank? and search_session[:qt].blank? and search_session[:search_field].blank? and search_session[:action] != "browse"
params_copy = search_session.clone # don't think we need a deep copy for this
params_copy.delete(:page)
unless @searches.collect { |search| search.query_params }.include?(params_copy)
new_search = Search.create(:query_params => params_copy)
session[:history].unshift(new_search.id)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment