blacklight 3.0pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.gitmodules +6 -0
- data/.yardopts +4 -0
- data/Gemfile +4 -0
- data/LICENSE +14 -0
- data/README.rdoc +168 -0
- data/Rakefile +9 -0
- data/app/controllers/bookmarks_controller.rb +98 -0
- data/app/controllers/feedback_controller.rb +37 -0
- data/app/controllers/folder_controller.rb +49 -0
- data/app/controllers/saved_searches_controller.rb +45 -0
- data/app/controllers/search_history_controller.rb +25 -0
- data/app/helpers/blacklight_helper.rb +606 -0
- data/app/helpers/bookmarks_helper.rb +3 -0
- data/app/helpers/catalog_helper.rb +65 -0
- data/app/helpers/feedback_helper.rb +2 -0
- data/app/helpers/hash_as_hidden_fields.rb +57 -0
- data/app/helpers/render_constraints_helper.rb +120 -0
- data/app/helpers/saved_searches_helper.rb +2 -0
- data/app/helpers/search_history_helper.rb +2 -0
- data/app/models/bookmark.rb +6 -0
- data/app/models/record_mailer.rb +43 -0
- data/app/models/search.rb +19 -0
- data/app/views/_flash_msg.html.erb +6 -0
- data/app/views/_user_util_links.html.erb +13 -0
- data/app/views/bookmarks/index.html.erb +33 -0
- data/app/views/catalog/_bookmark_control.html.erb +25 -0
- data/app/views/catalog/_bookmark_form.html.erb +8 -0
- data/app/views/catalog/_citation.html.erb +15 -0
- data/app/views/catalog/_constraints.html.erb +7 -0
- data/app/views/catalog/_constraints_element.html.erb +33 -0
- data/app/views/catalog/_did_you_mean.html.erb +10 -0
- data/app/views/catalog/_document_list.html.erb +30 -0
- data/app/views/catalog/_email_form.html.erb +11 -0
- data/app/views/catalog/_facet_limit.html.erb +33 -0
- data/app/views/catalog/_facet_pagination.html.erb +28 -0
- data/app/views/catalog/_facets.html.erb +9 -0
- data/app/views/catalog/_folder_control.html.erb +12 -0
- data/app/views/catalog/_home.html.erb +6 -0
- data/app/views/catalog/_home_text.html.erb +6 -0
- data/app/views/catalog/_index_partials/_default.erb +11 -0
- data/app/views/catalog/_marc_view.html.erb +33 -0
- data/app/views/catalog/_opensearch_response_metadata.html.erb +3 -0
- data/app/views/catalog/_previous_next_doc.html.erb +6 -0
- data/app/views/catalog/_refworks_form.html.erb +7 -0
- data/app/views/catalog/_results_pagination.html.erb +11 -0
- data/app/views/catalog/_search_form.html.erb +14 -0
- data/app/views/catalog/_show_partials/_default.html.erb +9 -0
- data/app/views/catalog/_show_sidebar.html.erb +1 -0
- data/app/views/catalog/_show_tools.html.erb +46 -0
- data/app/views/catalog/_sms_form.html.erb +23 -0
- data/app/views/catalog/_solr_request.html.erb +5 -0
- data/app/views/catalog/_sort_and_per_page.html.erb +20 -0
- data/app/views/catalog/_unapi_microformat.html.erb +1 -0
- data/app/views/catalog/citation.html.erb +1 -0
- data/app/views/catalog/email.erb +1 -0
- data/app/views/catalog/endnote.endnote.erb +1 -0
- data/app/views/catalog/facet.html.erb +28 -0
- data/app/views/catalog/index.atom.builder +108 -0
- data/app/views/catalog/index.html.erb +37 -0
- data/app/views/catalog/index.rss.builder +19 -0
- data/app/views/catalog/librarian_view.html.erb +3 -0
- data/app/views/catalog/opensearch.json.erb +0 -0
- data/app/views/catalog/opensearch.xml.erb +11 -0
- data/app/views/catalog/send_email_record.erb +0 -0
- data/app/views/catalog/show.endnote.erb +1 -0
- data/app/views/catalog/show.html.erb +42 -0
- data/app/views/catalog/show.refworks.erb +1 -0
- data/app/views/catalog/sms.erb +1 -0
- data/app/views/catalog/unapi.xml.builder +6 -0
- data/app/views/feedback/complete.html.erb +3 -0
- data/app/views/feedback/show.html.erb +20 -0
- data/app/views/folder/_tools.html.erb +23 -0
- data/app/views/folder/index.html.erb +44 -0
- data/app/views/layouts/blacklight.html.erb +49 -0
- data/app/views/record_mailer/email_record.erb +6 -0
- data/app/views/record_mailer/sms_record.erb +4 -0
- data/app/views/saved_searches/index.html.erb +27 -0
- data/app/views/search_history/index.html.erb +23 -0
- data/blacklight.gemspec +50 -0
- data/config.ru +4 -0
- data/config/routes.rb +54 -0
- data/db/seeds.rb +7 -0
- data/features/generators.feature +77 -0
- data/features/support/aruba.rb +9 -0
- data/install.rb +0 -0
- data/install/solr.yml +8 -0
- data/lib/blacklight.rb +121 -0
- data/lib/blacklight/catalog.rb +311 -0
- data/lib/blacklight/comma_link_renderer.rb +27 -0
- data/lib/blacklight/configurable.rb +46 -0
- data/lib/blacklight/controller.rb +121 -0
- data/lib/blacklight/engine.rb +32 -0
- data/lib/blacklight/exceptions.rb +13 -0
- data/lib/blacklight/marc.rb +46 -0
- data/lib/blacklight/marc/citation.rb +251 -0
- data/lib/blacklight/search_fields.rb +107 -0
- data/lib/blacklight/solr.rb +7 -0
- data/lib/blacklight/solr/document.rb +239 -0
- data/lib/blacklight/solr/document/dublin_core.rb +40 -0
- data/lib/blacklight/solr/document/email.rb +15 -0
- data/lib/blacklight/solr/document/marc.rb +84 -0
- data/lib/blacklight/solr/document/marc_export.rb +430 -0
- data/lib/blacklight/solr/document/sms.rb +13 -0
- data/lib/blacklight/solr/facet_paginator.rb +93 -0
- data/lib/blacklight/solr_helper.rb +413 -0
- data/lib/blacklight/user.rb +55 -0
- data/lib/blacklight/version.rb +3 -0
- data/lib/colorize.rb +196 -0
- data/lib/generators/blacklight/blacklight_generator.rb +134 -0
- data/lib/generators/blacklight/templates/SolrMarc.jar +0 -0
- data/lib/generators/blacklight/templates/catalog_controller.rb +8 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/config-test.properties +37 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/config.properties +37 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/index.properties +97 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/index_scripts/dewey.bsh +47 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/index_scripts/format.bsh +126 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/README_MAPS +1 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/callnumber_map.properties +407 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/composition_era_map.properties +56 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/country_map.properties +379 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/format_map.properties +50 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/instrument_map.properties +101 -0
- data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/language_map.properties +490 -0
- data/lib/generators/blacklight/templates/config/blacklight_config.rb +245 -0
- data/lib/generators/blacklight/templates/config/solr.yml +6 -0
- data/lib/generators/blacklight/templates/migrations/add_user_types_to_bookmarks_searches.rb +11 -0
- data/lib/generators/blacklight/templates/migrations/create_bookmarks.rb +17 -0
- data/lib/generators/blacklight/templates/migrations/create_searches.rb +15 -0
- data/lib/generators/blacklight/templates/migrations/remove_editable_fields_from_bookmarks.rb +11 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/bg.png +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/border.png +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/bul_sq_gry.gif +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/checkmark.gif +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/logo.png +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/magnifying_glass.gif +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/remove.gif +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/separator.gif +0 -0
- data/lib/generators/blacklight/templates/public/images/blacklight/start_over.gif +0 -0
- data/lib/generators/blacklight/templates/public/javascripts/blacklight.js +485 -0
- data/lib/generators/blacklight/templates/public/javascripts/jquery-1.4.2.min.js +154 -0
- data/lib/generators/blacklight/templates/public/javascripts/jquery-ui-1.8.1.custom.min.js +756 -0
- data/lib/generators/blacklight/templates/public/stylesheets/blacklight.css +487 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_gloss-wave_35_558fd0_500x100.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_2e4f81_256x240.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
- data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/jquery-ui-1.8.1.custom.css +486 -0
- data/lib/generators/blacklight/templates/public/stylesheets/yui.css +31 -0
- data/lib/generators/blacklight/templates/solr_document.rb +30 -0
- data/lib/railties/blacklight.rake +66 -0
- data/lib/railties/cucumber.rake +53 -0
- data/lib/railties/rspec.rake +188 -0
- data/lib/railties/solr_marc.rake +148 -0
- data/lib/railties/test_solr_server.rb +130 -0
- data/spec/helpers/catalog_helper_spec.rb +111 -0
- data/spec/views/catalog/_sms_form.html.erb_spec.rb +19 -0
- data/tasks/blacklight_tasks.rake +4 -0
- data/uninstall.rb +1 -0
- metadata +431 -0
@@ -0,0 +1,413 @@
|
|
1
|
+
# SolrHelper is a controller layer mixin. It is in the controller scope: request params, session etc.
|
2
|
+
#
|
3
|
+
# NOTE: Be careful when creating variables here as they may be overriding something that already exists.
|
4
|
+
# The ActionController docs: http://api.rubyonrails.org/classes/ActionController/Base.html
|
5
|
+
#
|
6
|
+
# Override these methods in your own controller for customizations:
|
7
|
+
#
|
8
|
+
# class CatalogController < ActionController::Base
|
9
|
+
#
|
10
|
+
# include Blacklight::SolrHelper
|
11
|
+
#
|
12
|
+
# def solr_search_params
|
13
|
+
# super.merge :per_page=>10
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
|
19
|
+
module Blacklight::SolrHelper
|
20
|
+
MaxPerPage = 100
|
21
|
+
|
22
|
+
def self.included(klass)
|
23
|
+
if klass.respond_to?(:helper_method)
|
24
|
+
klass.helper_method(:facet_limit_hash)
|
25
|
+
klass.helper_method(:facet_limit_for)
|
26
|
+
end
|
27
|
+
|
28
|
+
# We want to install a class-level place to keep
|
29
|
+
# solr_search_params_logic method names. Compare to before_filter,
|
30
|
+
# similar design. Since we're a module, we have to add it in here.
|
31
|
+
# There are too many different semantic choices in ruby 'class variables',
|
32
|
+
# we choose this one for now, supplied by Rails.
|
33
|
+
klass.class_inheritable_accessor :solr_search_params_logic
|
34
|
+
# Set defaults. Each symbol identifies a _method_ that must be in
|
35
|
+
# this class, taking two parameters (solr_parameters, user_parameters)
|
36
|
+
# Can be changed in local apps or by plugins, eg:
|
37
|
+
# CatalogController.include ModuleDefiningNewMethod
|
38
|
+
# CatalogController.solr_search_params_logic << :new_method
|
39
|
+
# CatalogController.solr_search_params_logic.delete(:we_dont_want)
|
40
|
+
klass.solr_search_params_logic = [:default_solr_parameters , :add_query_to_solr, :add_facet_fq_to_solr, :add_facetting_to_solr, :add_sorting_paging_to_solr ]
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# A helper method used for generating solr LocalParams, put quotes
|
45
|
+
# around the term unless it's a bare-word. Escape internal quotes
|
46
|
+
# if needed.
|
47
|
+
def solr_param_quote(val, options = {})
|
48
|
+
options[:quote] ||= '"'
|
49
|
+
unless val =~ /^[a-zA-Z$_\-\^]+$/
|
50
|
+
val = options[:quote] +
|
51
|
+
# Yes, we need crazy escaping here, to deal with regexp esc too!
|
52
|
+
val.gsub("'", "\\\\\'").gsub('"', "\\\\\"") +
|
53
|
+
options[:quote]
|
54
|
+
end
|
55
|
+
return val
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# returns a params hash for searching solr.
|
60
|
+
# The CatalogController #index action uses this.
|
61
|
+
# Solr parameters can come from a number of places. From lowest
|
62
|
+
# precedence to highest:
|
63
|
+
# 1. General defaults in blacklight config (are trumped by)
|
64
|
+
# 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
|
65
|
+
# 3. certain parameters directly on input HTTP query params
|
66
|
+
# * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
|
67
|
+
# * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
|
68
|
+
# 4. extra parameters passed in as argument.
|
69
|
+
#
|
70
|
+
# spellcheck.q will be supplied with the [:q] value unless specifically
|
71
|
+
# specified otherwise.
|
72
|
+
#
|
73
|
+
# Incoming parameter :f is mapped to :fq solr parameter.
|
74
|
+
def solr_search_params(user_params = params || {})
|
75
|
+
solr_parameters = {}
|
76
|
+
solr_search_params_logic.each do |method_name|
|
77
|
+
send(method_name, solr_parameters, user_params)
|
78
|
+
end
|
79
|
+
|
80
|
+
return solr_parameters
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
####
|
85
|
+
# Start with general defaults from BL config. Need to use custom
|
86
|
+
# merge to dup values, to avoid later mutating the original by mistake.
|
87
|
+
def default_solr_parameters(solr_parameters, user_params)
|
88
|
+
if Blacklight.config[:default_solr_params]
|
89
|
+
Blacklight.config[:default_solr_params].each_pair do |key, value|
|
90
|
+
solr_parameters[key] = value.dup rescue value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
###
|
96
|
+
# copy paging and sorting params from BL app over to solr, with
|
97
|
+
# fairly little transformation.
|
98
|
+
def add_sorting_paging_to_solr(solr_parameters, user_params)
|
99
|
+
# Omit empty strings and nil values.
|
100
|
+
# Apparently RSolr takes :per_page and converts it to Solr :rows,
|
101
|
+
# so we let it.
|
102
|
+
[:page, :sort, :per_page].each do |key|
|
103
|
+
solr_parameters[key] = user_params[key] unless user_params[key].blank?
|
104
|
+
end
|
105
|
+
|
106
|
+
# limit to MaxPerPage (100). Tests want this to be a string not an integer,
|
107
|
+
# not sure why.
|
108
|
+
solr_parameters[:per_page] = solr_parameters[:per_page].to_i > self.max_per_page ? self.max_per_page.to_s : solr_parameters[:per_page]
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# Take the user-entered query, and put it in the solr params,
|
113
|
+
# including config's "search field" params for current search field.
|
114
|
+
# also include setting spellcheck.q.
|
115
|
+
def add_query_to_solr(solr_parameters, user_parameters)
|
116
|
+
###
|
117
|
+
# Merge in search field configured values, if present, over-writing general
|
118
|
+
# defaults
|
119
|
+
###
|
120
|
+
# legacy behavior of user param :qt is passed through, but over-ridden
|
121
|
+
# by actual search field config if present. We might want to remove
|
122
|
+
# this legacy behavior at some point. It does not seem to be currently
|
123
|
+
# rspec'd.
|
124
|
+
solr_parameters[:qt] = user_parameters[:qt] if user_parameters[:qt]
|
125
|
+
|
126
|
+
search_field_def = Blacklight.search_field_def_for_key(user_parameters[:search_field])
|
127
|
+
if (search_field_def)
|
128
|
+
solr_parameters[:qt] = search_field_def[:qt] if search_field_def[:qt]
|
129
|
+
solr_parameters.merge!( search_field_def[:solr_parameters]) if search_field_def[:solr_parameters]
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Create Solr 'q' including the user-entered q, prefixed by any
|
134
|
+
# solr LocalParams in config, using solr LocalParams syntax.
|
135
|
+
# http://wiki.apache.org/solr/LocalParams
|
136
|
+
##
|
137
|
+
if (search_field_def && hash = search_field_def[:solr_local_parameters])
|
138
|
+
local_params = hash.collect do |key, val|
|
139
|
+
key.to_s + "=" + solr_param_quote(val, :quote => "'")
|
140
|
+
end.join(" ")
|
141
|
+
solr_parameters[:q] = "{!#{local_params}}#{user_parameters[:q]}"
|
142
|
+
else
|
143
|
+
solr_parameters[:q] = user_parameters[:q] if user_parameters[:q]
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
##
|
148
|
+
# Set Solr spellcheck.q to be original user-entered query, without
|
149
|
+
# our local params, otherwise it'll try and spellcheck the local
|
150
|
+
# params! Unless spellcheck.q has already been set by someone,
|
151
|
+
# respect that.
|
152
|
+
#
|
153
|
+
# TODO: Change calling code to expect this as a symbol instead of
|
154
|
+
# a string, for consistency? :'spellcheck.q' is a symbol. Right now
|
155
|
+
# rspec tests for a string, and can't tell if other code may
|
156
|
+
# insist on a string.
|
157
|
+
solr_parameters["spellcheck.q"] = user_parameters[:q] unless solr_parameters["spellcheck.q"]
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Add any existing facet limits, stored in app-level HTTP query
|
162
|
+
# as :f, to solr as appropriate :fq query.
|
163
|
+
def add_facet_fq_to_solr(solr_parameters, user_params)
|
164
|
+
# :fq, map from :f.
|
165
|
+
if ( user_params[:f])
|
166
|
+
f_request_params = user_params[:f]
|
167
|
+
|
168
|
+
solr_parameters[:fq] ||= []
|
169
|
+
f_request_params.each_pair do |facet_field, value_list|
|
170
|
+
value_list.each do |value|
|
171
|
+
solr_parameters[:fq] << "{!raw f=#{facet_field}}#{value}"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Add appropriate Solr facetting directives in, including
|
179
|
+
# taking account of our facet paging/'more'. This is not
|
180
|
+
# about solr 'fq', this is about solr facet.* params.
|
181
|
+
def add_facetting_to_solr(solr_parameters, user_params)
|
182
|
+
# While not used by BL core behavior, legacy behavior seemed to be
|
183
|
+
# to accept incoming params as "facet.field" or "facets", and add them
|
184
|
+
# on to any existing facet.field sent to Solr. Legacy behavior seemed
|
185
|
+
# to be accepting these incoming params as arrays (in Rails URL with []
|
186
|
+
# on end), or single values. At least one of these is used by
|
187
|
+
# Stanford for "faux hieararchial facets".
|
188
|
+
if user_params.has_key?("facet.field") || user_params.has_key?("facets")
|
189
|
+
solr_parameters[:"facet.field"] ||= []
|
190
|
+
solr_parameters[:"facet.field"].concat( [user_params["facet.field"], user_params["facets"]].flatten.compact ).uniq!
|
191
|
+
end
|
192
|
+
|
193
|
+
# Support facet paging and 'more'
|
194
|
+
# links, by sending a facet.limit one more than what we
|
195
|
+
# want to page at, according to configured facet limits.
|
196
|
+
facet_limit_hash.each_key do |field_name|
|
197
|
+
next if field_name.nil? # skip the 'default' key
|
198
|
+
next unless (limit = facet_limit_for(field_name))
|
199
|
+
|
200
|
+
solr_parameters[:"f.#{field_name}.facet.limit"] = (limit + 1)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
# a solr query method
|
207
|
+
# given a user query, return a solr response containing both result docs and facets
|
208
|
+
# - mixes in the Blacklight::Solr::SpellingSuggestions module
|
209
|
+
# - the response will have a spelling_suggestions method
|
210
|
+
# Returns a two-element array (aka duple) with first the solr response object,
|
211
|
+
# and second an array of SolrDocuments representing the response.docs
|
212
|
+
def get_search_results(user_params = params || {}, extra_controller_params = {})
|
213
|
+
|
214
|
+
# In later versions of Rails, the #benchmark method can do timing
|
215
|
+
# better for us.
|
216
|
+
bench_start = Time.now
|
217
|
+
|
218
|
+
solr_response = Blacklight.solr.find( self.solr_search_params(user_params).merge(extra_controller_params))
|
219
|
+
|
220
|
+
document_list = solr_response.docs.collect {|doc| SolrDocument.new(doc, solr_response)}
|
221
|
+
|
222
|
+
Rails.logger.debug("Solr fetch: #{self.class}#get_search_results (#{'%.1f' % ((Time.now.to_f - bench_start.to_f)*1000)}ms)")
|
223
|
+
|
224
|
+
return [solr_response, document_list]
|
225
|
+
end
|
226
|
+
|
227
|
+
# returns a params hash for finding a single solr document (CatalogController #show action)
|
228
|
+
# If the id arg is nil, then the value is fetched from params[:id]
|
229
|
+
# This method is primary called by the get_solr_response_for_doc_id method.
|
230
|
+
def solr_doc_params(id=nil)
|
231
|
+
id ||= params[:id]
|
232
|
+
# just to be consistent with the other solr param methods:
|
233
|
+
{
|
234
|
+
:qt => :document,
|
235
|
+
:id => id
|
236
|
+
}
|
237
|
+
end
|
238
|
+
|
239
|
+
# a solr query method
|
240
|
+
# retrieve a solr document, given the doc id
|
241
|
+
# TODO: shouldn't hardcode id field; should be setable to unique_key field in schema.xml
|
242
|
+
def get_solr_response_for_doc_id(id=nil, extra_controller_params={})
|
243
|
+
solr_response = Blacklight.solr.find solr_doc_params(id).merge(extra_controller_params)
|
244
|
+
raise Blacklight::Exceptions::InvalidSolrID.new if solr_response.docs.empty?
|
245
|
+
document = SolrDocument.new(solr_response.docs.first, solr_response)
|
246
|
+
[solr_response, document]
|
247
|
+
end
|
248
|
+
|
249
|
+
# given a field name and array of values, get the matching SOLR documents
|
250
|
+
def get_solr_response_for_field_values(field, values, extra_solr_params = {})
|
251
|
+
value_str = "(\"" + values.to_a.join("\" OR \"") + "\")"
|
252
|
+
solr_params = {
|
253
|
+
:defType => "lucene", # need boolean for OR
|
254
|
+
:q => "#{field}:#{value_str}",
|
255
|
+
# not sure why fl * is neccesary, why isn't default solr_search_params
|
256
|
+
# sufficient, like it is for any other search results solr request?
|
257
|
+
# But tests fail without this. I think because some functionality requires
|
258
|
+
# this to actually get solr_doc_params, not solr_search_params. Confused
|
259
|
+
# semantics again.
|
260
|
+
:fl => "*",
|
261
|
+
:facet => 'false',
|
262
|
+
:spellcheck => 'false'
|
263
|
+
}.merge(extra_solr_params)
|
264
|
+
|
265
|
+
solr_response = Blacklight.solr.find( self.solr_search_params().merge(solr_params) )
|
266
|
+
document_list = solr_response.docs.collect{|doc| SolrDocument.new(doc, solr_response) }
|
267
|
+
[solr_response,document_list]
|
268
|
+
end
|
269
|
+
|
270
|
+
# returns a params hash for a single facet field solr query.
|
271
|
+
# used primary by the get_facet_pagination method.
|
272
|
+
# Looks up Facet Paginator request params from current request
|
273
|
+
# params to figure out sort and offset.
|
274
|
+
# Default limit for facet list can be specified by defining a controller
|
275
|
+
# method facet_list_limit, otherwise 20.
|
276
|
+
def solr_facet_params(facet_field, user_params=params || {}, extra_controller_params={})
|
277
|
+
input = user_params.deep_merge(extra_controller_params)
|
278
|
+
|
279
|
+
# First start with a standard solr search params calculations,
|
280
|
+
# for any search context in our request params.
|
281
|
+
solr_params = solr_search_params(user_params).merge(extra_controller_params)
|
282
|
+
|
283
|
+
# Now override with our specific things for fetching facet values
|
284
|
+
solr_params[:"facet.field"] = facet_field
|
285
|
+
|
286
|
+
# Need to set as f.facet_field.facet.limit to make sure we
|
287
|
+
# override any field-specific default in the solr request handler.
|
288
|
+
solr_params[:"f.#{facet_field}.facet.limit"] =
|
289
|
+
if solr_params["facet.limit"]
|
290
|
+
solr_params["facet.limit"] + 1
|
291
|
+
elsif respond_to?(:facet_list_limit)
|
292
|
+
facet_list_limit.to_s.to_i + 1
|
293
|
+
else
|
294
|
+
20 + 1
|
295
|
+
end
|
296
|
+
solr_params['facet.offset'] = input[ Blacklight::Solr::FacetPaginator.request_keys[:offset] ].to_i # will default to 0 if nil
|
297
|
+
solr_params['facet.sort'] = input[ Blacklight::Solr::FacetPaginator.request_keys[:sort] ]
|
298
|
+
solr_params[:rows] = 0
|
299
|
+
|
300
|
+
return solr_params
|
301
|
+
end
|
302
|
+
|
303
|
+
# a solr query method
|
304
|
+
# used to paginate through a single facet field's values
|
305
|
+
# /catalog/facet/language_facet
|
306
|
+
def get_facet_pagination(facet_field, extra_controller_params={})
|
307
|
+
|
308
|
+
solr_params = solr_facet_params(facet_field, params, extra_controller_params)
|
309
|
+
|
310
|
+
# Make the solr call
|
311
|
+
response = Blacklight.solr.find(solr_params)
|
312
|
+
|
313
|
+
limit =
|
314
|
+
if respond_to?(:facet_list_limit)
|
315
|
+
facet_list_limit.to_s.to_i
|
316
|
+
elsif solr_params[:"f.#{facet_field}.facet.limit"]
|
317
|
+
solr_params[:"f.#{facet_field}.facet.limit"] - 1
|
318
|
+
else
|
319
|
+
nil
|
320
|
+
end
|
321
|
+
|
322
|
+
|
323
|
+
# Actually create the paginator!
|
324
|
+
# NOTE: The sniffing of the proper sort from the solr response is not
|
325
|
+
# currently tested for, tricky to figure out how to test, since the
|
326
|
+
# default setup we test against doesn't use this feature.
|
327
|
+
return Blacklight::Solr::FacetPaginator.new(response.facets.first.items,
|
328
|
+
:offset => solr_params['facet.offset'],
|
329
|
+
:limit => limit,
|
330
|
+
:sort => response["responseHeader"]["params"]["f.#{facet_field}.facet.sort"] || response["responseHeader"]["params"]["facet.sort"]
|
331
|
+
)
|
332
|
+
end
|
333
|
+
|
334
|
+
# a solr query method
|
335
|
+
# this is used when selecting a search result: we have a query and a
|
336
|
+
# position in the search results and possibly some facets
|
337
|
+
# Pass in an index where 1 is the first document in the list, and
|
338
|
+
# the Blacklight app-level request params that define the search.
|
339
|
+
def get_single_doc_via_search(index, request_params)
|
340
|
+
solr_params = solr_search_params(request_params)
|
341
|
+
solr_params[:start] = index - 1 # start at 0 to get 1st doc, 1 to get 2nd.
|
342
|
+
solr_params[:per_page] = 1
|
343
|
+
solr_params[:rows] = 1
|
344
|
+
solr_params[:fl] = '*'
|
345
|
+
Blacklight.solr.find(solr_params).docs.first
|
346
|
+
end
|
347
|
+
|
348
|
+
# returns a solr params hash
|
349
|
+
# if field is nil, the value is fetched from Blacklight.config[:index][:show_link]
|
350
|
+
# the :fl (solr param) is set to the "field" value.
|
351
|
+
# per_page is set to 10
|
352
|
+
def solr_opensearch_params(field=nil)
|
353
|
+
solr_params = solr_search_params
|
354
|
+
solr_params[:per_page] = 10
|
355
|
+
solr_params[:fl] = Blacklight.config[:index][:show_link]
|
356
|
+
solr_params
|
357
|
+
end
|
358
|
+
|
359
|
+
# a solr query method
|
360
|
+
# does a standard search but returns a simplified object.
|
361
|
+
# an array is returned, the first item is the query string,
|
362
|
+
# the second item is an other array. This second array contains
|
363
|
+
# all of the field values for each of the documents...
|
364
|
+
# where the field is the "field" argument passed in.
|
365
|
+
def get_opensearch_response(field=nil, extra_controller_params={})
|
366
|
+
solr_params = solr_opensearch_params().merge(extra_controller_params)
|
367
|
+
response = Blacklight.solr.find(solr_params)
|
368
|
+
a = [solr_params[:q]]
|
369
|
+
a << response.docs.map {|doc| doc[solr_params[:fl]].to_s }
|
370
|
+
end
|
371
|
+
|
372
|
+
|
373
|
+
|
374
|
+
# Look up facet limit for given facet_field. Will look at config, and
|
375
|
+
# if config is 'true' will look up from Solr @response if available. If
|
376
|
+
# no limit is avaialble, returns nil. Used from #solr_search_params
|
377
|
+
# to supply f.fieldname.facet.limit values in solr request (no @response
|
378
|
+
# available), and used in display (with @response available) to create
|
379
|
+
# a facet paginator with the right limit.
|
380
|
+
def facet_limit_for(facet_field)
|
381
|
+
limits_hash = facet_limit_hash
|
382
|
+
return nil if limits_hash.blank?
|
383
|
+
|
384
|
+
limit = limits_hash[facet_field]
|
385
|
+
|
386
|
+
if ( limit == true && @response &&
|
387
|
+
@response["responseHeader"] &&
|
388
|
+
@response["responseHeader"]["params"])
|
389
|
+
limit =
|
390
|
+
@response["responseHeader"]["params"]["f.#{facet_field}.facet.limit"] ||
|
391
|
+
@response["responseHeader"]["params"]["facet.limit"]
|
392
|
+
limit = (limit.to_i() -1) if limit
|
393
|
+
limit = nil if limit == -2 # -1-1==-2, unlimited.
|
394
|
+
elsif limit == true
|
395
|
+
limit = nil
|
396
|
+
end
|
397
|
+
|
398
|
+
return limit
|
399
|
+
end
|
400
|
+
|
401
|
+
# Returns complete hash of key=facet_field, value=limit.
|
402
|
+
# Used by SolrHelper#solr_search_params to add limits to solr
|
403
|
+
# request for all configured facet limits.
|
404
|
+
def facet_limit_hash
|
405
|
+
Blacklight.config[:facet][:limits] || {}
|
406
|
+
end
|
407
|
+
|
408
|
+
def max_per_page
|
409
|
+
MaxPerPage
|
410
|
+
end
|
411
|
+
|
412
|
+
|
413
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Blacklight::User
|
2
|
+
|
3
|
+
# This gives us an is_blacklight_user method that can be included in
|
4
|
+
# the containing applications models.
|
5
|
+
# SEE ALSO: The /lib/blacklight/engine.rb class for how when this
|
6
|
+
# is injected into the hosting application through ActiveRecord::Base extend
|
7
|
+
def self.included(base)
|
8
|
+
base.send :has_many, :bookmarks, :dependent => :destroy, :as => :user
|
9
|
+
base.send :has_many, :searches, :dependent => :destroy, :as => :user
|
10
|
+
base.send :include, InstanceMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
# The following methods will be included in any active model object
|
14
|
+
# that calls "is_blacklight_user"
|
15
|
+
module InstanceMethods
|
16
|
+
|
17
|
+
# fixme: This needs to be re-implemented
|
18
|
+
def last_search_url
|
19
|
+
return self.searches.last
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_bookmarks?
|
23
|
+
bookmarks.count > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_searches?
|
27
|
+
searches.count > 0
|
28
|
+
end
|
29
|
+
|
30
|
+
def bookmarked_document_ids
|
31
|
+
self.bookmarks.map{|bm|bm.document_id}
|
32
|
+
end
|
33
|
+
|
34
|
+
# see #current_bookmark_for, is easier
|
35
|
+
def document_is_bookmarked?(document_id)
|
36
|
+
bookmarked_document_ids.include? document_id
|
37
|
+
end
|
38
|
+
|
39
|
+
# returns a Bookmark object if there is one for document_id, else
|
40
|
+
# nil.
|
41
|
+
def existing_bookmark_for(document_id)
|
42
|
+
# to_a, we don't want to go to the database, we want to use cached
|
43
|
+
# copy.
|
44
|
+
self.bookmarks.to_a.find {|b| b.document_id == document_id}
|
45
|
+
end
|
46
|
+
|
47
|
+
def documents_to_bookmark=(docs)
|
48
|
+
docs.each do |doc|
|
49
|
+
self.bookmarks.create(doc) unless bookmarked_document_ids.include?(doc[:document_id])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end # /InstanceMethods
|
54
|
+
|
55
|
+
end
|