blacklight 3.0pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/blacklight.gemspec
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require "lib/blacklight/version"
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = "blacklight"
|
|
6
|
+
s.version = Blacklight::VERSION
|
|
7
|
+
s.platform = Gem::Platform::RUBY
|
|
8
|
+
s.authors = ["jrochkind", "Matt Mitchell", "Chris Beer", "Jessie Keck", "Jason Ronallo", "Vernon Chapman", "Marck A. Matienzo"]
|
|
9
|
+
s.email = ["blacklight-development@googlegroups.com"]
|
|
10
|
+
s.homepage = "http://projectblacklight.org/"
|
|
11
|
+
s.summary = "A next-geration Library Catalag for Universities"
|
|
12
|
+
s.description = %q{Blacklight is a free and open source ruby-on-rails based discovery interface (a.k.a. “next-generation catalog”) especially optimized for heterogeneous collections. You can use it as a library catalog, as a front end for a digital repository, or as a single-search interface to aggregate digital content that would otherwise be siloed.}
|
|
13
|
+
|
|
14
|
+
s.rubyforge_project = "blacklight"
|
|
15
|
+
|
|
16
|
+
s.files = `git ls-files`.split("\n")
|
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
|
+
s.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
# PRODUCTION GEM REQUIREMENTS
|
|
22
|
+
# ---------------------------------------
|
|
23
|
+
# JRuby Specific Gems - and their counterparts
|
|
24
|
+
if defined?(JRUBY_VERSION)
|
|
25
|
+
# Jruby specific gems should go here.
|
|
26
|
+
else
|
|
27
|
+
s.add_dependency "unicode" # provides C-form normalization of unicode characters, as required by refworks.
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Required Gems
|
|
31
|
+
s.add_dependency "rails", "= 3.0.6"
|
|
32
|
+
s.add_dependency "nokogiri", "~>1.5.0.beta.3" # XML Parser
|
|
33
|
+
s.add_dependency "marc" # Marc record parser
|
|
34
|
+
s.add_dependency "rsolr", '1.0.0' # Library for interacting with rSolr.
|
|
35
|
+
s.add_dependency "rsolr-ext", '1.0.0' # extension to the above for some rails-ish behaviors - currently imbeded in our solr document ojbect.
|
|
36
|
+
s.add_dependency "will_paginate", "3.0.pre2" # the pagination (page 1,2,3, etc..) of our search results
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# TESTING GEM REQUIREMENTS
|
|
40
|
+
# -------------------------------------------
|
|
41
|
+
# For testing the generators
|
|
42
|
+
# s.add_dependency "cucumber-rails"
|
|
43
|
+
# s.add_dependency "capybara"
|
|
44
|
+
# s.add_dependency "aruba"
|
|
45
|
+
|
|
46
|
+
# s.add_dependency "rspec-rails", "~>2.3.0"
|
|
47
|
+
# s.add_dependency "webrat"
|
|
48
|
+
# s.add_dependency "database_cleaner"
|
|
49
|
+
|
|
50
|
+
end
|
data/config.ru
ADDED
data/config/routes.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Rails.application.routes.draw do
|
|
2
|
+
|
|
3
|
+
# Root context
|
|
4
|
+
root :to => "catalog#index"
|
|
5
|
+
|
|
6
|
+
# A Note on User Sessions:
|
|
7
|
+
# Blacklight expects the following named routes or at least the associated path helper methods to be defined.
|
|
8
|
+
# new_user_session (for logging in) - pages that require a log in will redirect users here.
|
|
9
|
+
# destroy_user_session (for logging out)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Bookmarks
|
|
13
|
+
match "bookmarks/clear", :to => "bookmarks#clear", :as => "clear_bookmarks"
|
|
14
|
+
resources :bookmarks
|
|
15
|
+
|
|
16
|
+
# Folder Paths
|
|
17
|
+
match "folder/clear", :to => "folder#clear", :as => "clear_folder"
|
|
18
|
+
match "folder/destroy", :to => "folder#destroy"
|
|
19
|
+
resources :folder, :only => [:index, :update, :destroy]
|
|
20
|
+
|
|
21
|
+
# Search History
|
|
22
|
+
match "search_history", :to => "search_history#index", :as => "search_history"
|
|
23
|
+
match "search_history/clear", :to => "search_history#clear", :as => "clear_search_history"
|
|
24
|
+
match "search_history/destroy/:id", :to => "search_history#destroy", :as => "delete_search"
|
|
25
|
+
|
|
26
|
+
# Saved Searches
|
|
27
|
+
match "saved_searches/clear", :to => "saved_searches#clear", :as => "clear_saved_searches"
|
|
28
|
+
match "saved_searches/index", :to => "saved_searches#index", :as => "saved_searches"
|
|
29
|
+
match "saved_searches/save/:id", :to => "saved_searches#save", :as => "save_search"
|
|
30
|
+
match "saved_searches/forget/:id", :to => "saved_searches#forget", :as => "forget_search"
|
|
31
|
+
|
|
32
|
+
# Catalog stuff.
|
|
33
|
+
match 'catalog/map', :as => "map_catalog"
|
|
34
|
+
match 'catalog/opensearch', :as => "opensearch_catalog"
|
|
35
|
+
match 'catalog/citation', :as => "citation_catalog"
|
|
36
|
+
match 'catalog/email', :as => "email_catalog"
|
|
37
|
+
match 'catalog/sms', :as => "sms_catalog"
|
|
38
|
+
match 'catalog/endnote', :as => "endnote_catalog"
|
|
39
|
+
match 'catalog/send_email_record', :as => "send_email_record_catalog"
|
|
40
|
+
match "catalog/facet/:id", :to => 'catalog#facet', :as => 'catalog_facet'
|
|
41
|
+
match 'catalog/unapi', :to => "catalog#unapi", :as => 'unapi'
|
|
42
|
+
resources :catalog, :only => [:index, :show, :update]
|
|
43
|
+
match 'catalog/:id/image', :to => "catalog#image"
|
|
44
|
+
match 'catalog/:id/status', :to => "catalog#status"
|
|
45
|
+
match 'catalog/:id/availability', :to => "catalog#availability"
|
|
46
|
+
match 'catalog/:id/librarian_view', :to => "catalog#librarian_view", :as => "librarian_view_catalog"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Feedback
|
|
50
|
+
match "feedback", :to => "feedback#show"
|
|
51
|
+
match "feedback/complete", :to => "feedback#complete"
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
data/db/seeds.rb
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# This file should contain all the record creation needed to seed the database with its default values.
|
|
2
|
+
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
|
|
3
|
+
#
|
|
4
|
+
# Examples:
|
|
5
|
+
#
|
|
6
|
+
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
|
|
7
|
+
# Mayor.create(:name => 'Daley', :city => cities.first)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Feature:
|
|
2
|
+
In order to easily add Blacklight fucntionality to a new rails app
|
|
3
|
+
As a user of Rails3 and Blacklight
|
|
4
|
+
I would like to use the blacklight generator.
|
|
5
|
+
|
|
6
|
+
Scenario: The Blacklight generators create all the correct files and file modifications when executed with defaults
|
|
7
|
+
When I run "rails new test_app"
|
|
8
|
+
And I cd to "test_app"
|
|
9
|
+
And a file named "Gemfile" with:
|
|
10
|
+
"""
|
|
11
|
+
source "http://rubygems.org"
|
|
12
|
+
gem 'rails', '>=3.0.4'
|
|
13
|
+
gem 'sqlite3-ruby', :require => 'sqlite3'
|
|
14
|
+
gem 'blacklight', :path => '../../../'
|
|
15
|
+
"""
|
|
16
|
+
And I run "bundle install --local"
|
|
17
|
+
|
|
18
|
+
When I write to "app/models/user.rb" with:
|
|
19
|
+
"""
|
|
20
|
+
class User < ActiveRecord::Base
|
|
21
|
+
end
|
|
22
|
+
"""
|
|
23
|
+
And I run "rails generate blacklight"
|
|
24
|
+
Then the following files should exist:
|
|
25
|
+
| config/initializers/blacklight_config.rb |
|
|
26
|
+
| config/solr.yml |
|
|
27
|
+
| public/images/blacklight/bg.png |
|
|
28
|
+
| public/javascripts/blacklight.js |
|
|
29
|
+
| public/javascripts/jquery-1.4.2.min.js |
|
|
30
|
+
| public/javascripts/jquery-ui-1.8.1.custom.min.js |
|
|
31
|
+
| public/stylesheets/blacklight.css |
|
|
32
|
+
| public/stylesheets/yui.css |
|
|
33
|
+
And a directory named "public/stylesheets/jquery" should exist
|
|
34
|
+
And the file "app/models/user.rb" should contain "is_blacklight_user"
|
|
35
|
+
|
|
36
|
+
# Devise should next exist in thie scenerio
|
|
37
|
+
And a directory named "app/views/devise" should not exist
|
|
38
|
+
And the file "app/models/user.rb" should not contain "devise"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@really_slow_process
|
|
42
|
+
Scenario: The Blacklight generator installs devise when given the -d option
|
|
43
|
+
When I run "rails new test_app"
|
|
44
|
+
And I cd to "test_app"
|
|
45
|
+
And a file named "Gemfile" with:
|
|
46
|
+
"""
|
|
47
|
+
source "http://rubygems.org"
|
|
48
|
+
gem 'rails', '>=3.0.4'
|
|
49
|
+
gem 'sqlite3-ruby', :require => 'sqlite3'
|
|
50
|
+
gem 'blacklight', :path => '../../../'
|
|
51
|
+
|
|
52
|
+
# For testing
|
|
53
|
+
gem 'rspec-rails'
|
|
54
|
+
gem 'cucumber-rails'
|
|
55
|
+
gem 'webrat' # still needed for rspec view tests
|
|
56
|
+
gem 'capybara' # used by latest cucumber
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
And I run "bundle install --local"
|
|
60
|
+
|
|
61
|
+
Then the file "app/models/user.rb" should not exist
|
|
62
|
+
And I run "rails generate blacklight -d"
|
|
63
|
+
|
|
64
|
+
# Devise should now be installed.
|
|
65
|
+
Then a file named "app/models/user.rb" should exist
|
|
66
|
+
Then a directory named "app/views/devise" should exist
|
|
67
|
+
Then the file "app/models/user.rb" should contain "devise"
|
|
68
|
+
|
|
69
|
+
# And the user model should be setup with Blacklight
|
|
70
|
+
And the file "app/models/user.rb" should contain "is_blacklight_user"
|
|
71
|
+
|
|
72
|
+
# And I copy over the rspec and feature tests, just in case I want to test them.
|
|
73
|
+
And I run "cp -r ../../../test_app/spec ."
|
|
74
|
+
And I run "cp -r ../../../test_app/features ."
|
|
75
|
+
And I run "cp ../../../test_app/Rakefile ."
|
|
76
|
+
And I run "cp -r ../../../test_app/jetty ."
|
|
77
|
+
|
data/install.rb
ADDED
|
File without changes
|
data/install/solr.yml
ADDED
data/lib/blacklight.rb
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require 'will_paginate'
|
|
2
|
+
require 'marc'
|
|
3
|
+
require 'rsolr'
|
|
4
|
+
require 'rsolr-ext'
|
|
5
|
+
|
|
6
|
+
module Blacklight
|
|
7
|
+
|
|
8
|
+
autoload :Configurable, 'blacklight/configurable'
|
|
9
|
+
autoload :SearchFields, 'blacklight/search_fields'
|
|
10
|
+
|
|
11
|
+
autoload :Solr, 'blacklight/solr'
|
|
12
|
+
autoload :Marc, 'blacklight/marc'
|
|
13
|
+
|
|
14
|
+
autoload :SolrHelper, 'blacklight/solr_helper'
|
|
15
|
+
|
|
16
|
+
autoload :Exceptions, 'blacklight/exceptions'
|
|
17
|
+
|
|
18
|
+
autoload :User, 'blacklight/user'
|
|
19
|
+
|
|
20
|
+
autoload :CommaLinkRenderer, 'blacklight/comma_link_renderer'
|
|
21
|
+
|
|
22
|
+
autoload :Controller, 'blacklight/controller'
|
|
23
|
+
autoload :Catalog, 'blacklight/catalog'
|
|
24
|
+
|
|
25
|
+
extend Configurable
|
|
26
|
+
extend SearchFields
|
|
27
|
+
|
|
28
|
+
require 'blacklight/engine' if defined?(Rails)
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
attr_accessor :solr, :solr_config
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Just returning a string for the Blacklight version number.
|
|
35
|
+
# I've just put master here now, should it say when it's running under master? (Master?)
|
|
36
|
+
# We need to find a better way of increasing this number automatically during releases, but this is a good way for now.
|
|
37
|
+
def self.version
|
|
38
|
+
"2.8.0"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Adding a little jruby support
|
|
42
|
+
def self.jruby?
|
|
43
|
+
defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.solr_file
|
|
47
|
+
"#{::Rails.root.to_s}/config/solr.yml"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.init
|
|
51
|
+
SolrDocument.connection = Blacklight.solr
|
|
52
|
+
logger.info("BLACKLIGHT: running version #{Blacklight.version}")
|
|
53
|
+
logger.info("BLACKLIGHT: initialized with Blacklight.solr_config: #{Blacklight.solr_config.inspect}")
|
|
54
|
+
logger.info("BLACKLIGHT: initialized with Blacklight.solr: #{Blacklight.solr.inspect}")
|
|
55
|
+
logger.info("BLACKLIGHT: initialized with Blacklight.config: #{Blacklight.config.inspect}")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.solr
|
|
59
|
+
@solr ||= RSolr::Ext.connect(Blacklight.solr_config)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.solr_config
|
|
63
|
+
@solr_config ||= begin
|
|
64
|
+
raise "You are missing a solr configuration file: #{solr_file}. Have you run \"rails generate blacklight\"?" unless File.exists?(solr_file)
|
|
65
|
+
solr_config = YAML::load(File.open(solr_file))
|
|
66
|
+
raise "The #{RAILS_ENV} environment settings were not found in the solr.yml config" unless solr_config[RAILS_ENV]
|
|
67
|
+
solr_config[RAILS_ENV].symbolize_keys
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.logger
|
|
72
|
+
::Rails.logger
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#############
|
|
76
|
+
# Methods for figuring out path to BL plugin, and then locate various files
|
|
77
|
+
# either in the app itself or defaults in the plugin -- whether you are running
|
|
78
|
+
# from the plugin itself or from an actual app using te plugin.
|
|
79
|
+
# In a seperate module so it can be used by both Blacklight class, and
|
|
80
|
+
# by rake tasks without loading the whole Rails environment.
|
|
81
|
+
#############
|
|
82
|
+
|
|
83
|
+
# returns the full path the the blacklight plugin installation
|
|
84
|
+
def self.root
|
|
85
|
+
@root ||= File.expand_path(File.dirname(File.dirname(__FILE__)))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# This is useful for modifying Blacklight models.
|
|
89
|
+
# In the main app you can then do this:
|
|
90
|
+
# require "#{MyEngine.models_dir}/bookmark"
|
|
91
|
+
# class Bookmark
|
|
92
|
+
# ...
|
|
93
|
+
# end
|
|
94
|
+
# BE AWARE - When you do this, you are monkey patching Blacklight
|
|
95
|
+
# we should eventually find a better way - such as the acts_as pattern
|
|
96
|
+
def self.models_dir
|
|
97
|
+
"#{root}/app/models"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.controllers_dir
|
|
101
|
+
"#{root}/app/controllers"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Searches Rails.root then Blacklight.root for a valid path
|
|
106
|
+
# returns a full path if a valid path is found
|
|
107
|
+
# returns nil if nothing is found.
|
|
108
|
+
# First looks in Rails.root, then Blacklight.root
|
|
109
|
+
#
|
|
110
|
+
# Example:
|
|
111
|
+
# full_path_to_solr_marc_jar = Blacklight.locate_path 'solr_marc', 'SolrMarc.jar'
|
|
112
|
+
|
|
113
|
+
def self.locate_path(*subpath_fragments)
|
|
114
|
+
subpath = subpath_fragments.join('/')
|
|
115
|
+
base_match = [Rails.root, self.root].find do |base|
|
|
116
|
+
File.exists? File.join(base, subpath)
|
|
117
|
+
end
|
|
118
|
+
File.join(base_match.to_s, subpath) if base_match
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
module Blacklight::Catalog
|
|
2
|
+
|
|
3
|
+
# The following code is executed when someone includes blacklight::catalog in their
|
|
4
|
+
# own controller.
|
|
5
|
+
def self.included(base)
|
|
6
|
+
# These two helper methods are provided by the blacklight solr::helper
|
|
7
|
+
base.send :helper_method, :facet_limit_hash
|
|
8
|
+
base.send :helper_method, :facet_limit_for
|
|
9
|
+
|
|
10
|
+
base.send :before_filter, :search_session, :history_session
|
|
11
|
+
base.send :before_filter, :delete_or_assign_search_session_params, :only => :index
|
|
12
|
+
base.send :after_filter, :set_additional_search_session_values, :only=>:index
|
|
13
|
+
|
|
14
|
+
# Whenever an action raises SolrHelper::InvalidSolrID, this block gets executed.
|
|
15
|
+
# Hint: the SolrHelper #get_solr_response_for_doc_id method raises this error,
|
|
16
|
+
# which is used in the #show action here.
|
|
17
|
+
base.send :rescue_from, Blacklight::Exceptions::InvalidSolrID, :with => :invalid_solr_id_error
|
|
18
|
+
# When RSolr::RequestError is raised, the rsolr_request_error method is executed.
|
|
19
|
+
# The index action will more than likely throw this one.
|
|
20
|
+
# Example, when the standard query parser is used, and a user submits a "bad" query.
|
|
21
|
+
base.send :rescue_from, RSolr::Error::Http, :with => :rsolr_request_error
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# get search results from the solr index
|
|
26
|
+
def index
|
|
27
|
+
|
|
28
|
+
delete_or_assign_search_session_params
|
|
29
|
+
|
|
30
|
+
extra_head_content << view_context.auto_discovery_link_tag(:rss, url_for(params.merge(:format => 'rss')), :title => "RSS for results")
|
|
31
|
+
extra_head_content << view_context.auto_discovery_link_tag(:atom, url_for(params.merge(:format => 'atom')), :title => "Atom for results")
|
|
32
|
+
extra_head_content << view_context.auto_discovery_link_tag(:unapi, unapi_url, {:type => 'application/xml', :rel => 'unapi-server', :title => 'unAPI' })
|
|
33
|
+
|
|
34
|
+
(@response, @document_list) = get_search_results
|
|
35
|
+
@filters = params[:f] || []
|
|
36
|
+
search_session[:total] = @response.total unless @response.nil?
|
|
37
|
+
|
|
38
|
+
respond_to do |format|
|
|
39
|
+
format.html { save_current_search_params }
|
|
40
|
+
format.rss { render :layout => false }
|
|
41
|
+
format.atom { render :layout => false }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# get single document from the solr index
|
|
46
|
+
def show
|
|
47
|
+
extra_head_content << view_context.auto_discovery_link_tag(:unapi, unapi_url, {:type => 'application/xml', :rel => 'unapi-server', :title => 'unAPI' })
|
|
48
|
+
@response, @document = get_solr_response_for_doc_id
|
|
49
|
+
|
|
50
|
+
respond_to do |format|
|
|
51
|
+
format.html {setup_next_and_previous_documents}
|
|
52
|
+
|
|
53
|
+
# Add all dynamically added (such as by document extensions)
|
|
54
|
+
# export formats.
|
|
55
|
+
@document.export_formats.each_key do | format_name |
|
|
56
|
+
# It's important that the argument to send be a symbol;
|
|
57
|
+
# if it's a string, it makes Rails unhappy for unclear reasons.
|
|
58
|
+
format.send(format_name.to_sym) { render :text => @document.export_as(format_name), :layout => false }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def unapi
|
|
65
|
+
@export_formats = Blacklight.config[:unapi] || {}
|
|
66
|
+
@format = params[:format]
|
|
67
|
+
if params[:id]
|
|
68
|
+
@response, @document = get_solr_response_for_doc_id
|
|
69
|
+
@export_formats = @document.export_formats
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
unless @format
|
|
73
|
+
render 'unapi.xml.builder', :layout => false and return
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
respond_to do |format|
|
|
77
|
+
format.all do
|
|
78
|
+
send_data @document.export_as(@format), :type => @document.export_formats[@format][:content_type], :disposition => 'inline' if @document.will_export_as @format
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# updates the search counter (allows the show view to paginate)
|
|
85
|
+
def update
|
|
86
|
+
adjust_for_results_view
|
|
87
|
+
session[:search][:counter] = params[:counter]
|
|
88
|
+
redirect_to :action => "show"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# displays values and pagination links for a single facet field
|
|
92
|
+
def facet
|
|
93
|
+
@pagination = get_facet_pagination(params[:id], params)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# single document image resource
|
|
97
|
+
def image
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# single document availability status (true/false)
|
|
101
|
+
def status
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# single document availability info
|
|
105
|
+
def availability
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# collection/search UI via Google maps
|
|
109
|
+
def map
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# method to serve up XML OpenSearch description and JSON autocomplete response
|
|
113
|
+
def opensearch
|
|
114
|
+
respond_to do |format|
|
|
115
|
+
format.xml do
|
|
116
|
+
render :layout => false
|
|
117
|
+
end
|
|
118
|
+
format.json do
|
|
119
|
+
render :json => get_opensearch_response
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# citation action
|
|
125
|
+
def citation
|
|
126
|
+
@response, @documents = get_solr_response_for_field_values("id",params[:id])
|
|
127
|
+
end
|
|
128
|
+
# grabs a bunch of documents to export to endnote
|
|
129
|
+
def endnote
|
|
130
|
+
@response, @documents = get_solr_response_for_field_values("id",params[:id])
|
|
131
|
+
respond_to do |format|
|
|
132
|
+
format.endnote
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Email Action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
|
|
137
|
+
def email
|
|
138
|
+
@response, @documents = get_solr_response_for_field_values("id",params[:id])
|
|
139
|
+
if request.post?
|
|
140
|
+
if params[:to]
|
|
141
|
+
from = request.host # host w/o port for From address (from address cannot have port#)
|
|
142
|
+
url_gen_params = {:host => request.host_with_port, :protocol => request.protocol}
|
|
143
|
+
|
|
144
|
+
if params[:to].match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
|
|
145
|
+
email = RecordMailer.create_email_record(@documents, {:to => params[:to], :message => params[:message]}, from, url_gen_params)
|
|
146
|
+
else
|
|
147
|
+
flash[:error] = "You must enter a valid email address"
|
|
148
|
+
end
|
|
149
|
+
email.deliver unless flash[:error]
|
|
150
|
+
redirect_to :back
|
|
151
|
+
else
|
|
152
|
+
flash[:error] = "You must enter a recipient in order to send this message"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# SMS action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
|
|
158
|
+
def sms
|
|
159
|
+
@response, @documents = get_solr_response_for_field_values("id",params[:id])
|
|
160
|
+
if request.post?
|
|
161
|
+
from = request.host # host w/o port for From address (from address cannot have port#)
|
|
162
|
+
url_gen_params = {:host => request.host_with_port, :protocol => request.protocol}
|
|
163
|
+
|
|
164
|
+
if params[:to]
|
|
165
|
+
phone_num = params[:to].gsub(/[^\d]/, '')
|
|
166
|
+
unless params[:carrier].blank?
|
|
167
|
+
if phone_num.length != 10
|
|
168
|
+
flash[:error] = "You must enter a valid 10 digit phone number"
|
|
169
|
+
else
|
|
170
|
+
email = RecordMailer.create_sms_record(@documents, {:to => phone_num, :carrier => params[:carrier]}, from, url_gen_params)
|
|
171
|
+
end
|
|
172
|
+
email.deliver unless flash[:error]
|
|
173
|
+
redirect_to :back
|
|
174
|
+
else
|
|
175
|
+
flash[:error] = "You must select a carrier"
|
|
176
|
+
end
|
|
177
|
+
else
|
|
178
|
+
flash[:error] = "You must enter a recipient's phone number in order to send this message"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# DEPRECATED backwards compatible method that will just redirect to the appropriate action. It will return a 404 if a bad action is supplied (just in case).
|
|
185
|
+
def send_email_record
|
|
186
|
+
warn "[DEPRECATION] CatalogController#send_email_record is deprecated. Please use the email or sms controller action instead."
|
|
187
|
+
if ["sms","email"].include?(params[:style])
|
|
188
|
+
redirect_to :action => params[:style]
|
|
189
|
+
else
|
|
190
|
+
render :file => "#{::Rails.root}/public/404.html", :layout => false, :status => 404
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def librarian_view
|
|
195
|
+
@response, @document = get_solr_response_for_doc_id
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
protected
|
|
200
|
+
#
|
|
201
|
+
# non-routable methods ->
|
|
202
|
+
#
|
|
203
|
+
|
|
204
|
+
# calls setup_previous_document then setup_next_document.
|
|
205
|
+
# used in the show action for single view pagination.
|
|
206
|
+
def setup_next_and_previous_documents
|
|
207
|
+
setup_previous_document
|
|
208
|
+
setup_next_document
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# gets a document based on its position within a resultset
|
|
212
|
+
def setup_document_by_counter(counter)
|
|
213
|
+
return if counter < 1 || session[:search].blank?
|
|
214
|
+
search = session[:search] || {}
|
|
215
|
+
get_single_doc_via_search(counter, search)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def setup_previous_document
|
|
219
|
+
@previous_document = session[:search][:counter] ? setup_document_by_counter(session[:search][:counter].to_i - 1) : nil
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def setup_next_document
|
|
223
|
+
@next_document = session[:search][:counter] ? setup_document_by_counter(session[:search][:counter].to_i + 1) : nil
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# sets up the session[:search] hash if it doesn't already exist
|
|
227
|
+
def search_session
|
|
228
|
+
session[:search] ||= {}
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# sets up the session[:history] hash if it doesn't already exist.
|
|
232
|
+
# assigns all Search objects (that match the searches in session[:history]) to a variable @searches.
|
|
233
|
+
def history_session
|
|
234
|
+
session[:history] ||= []
|
|
235
|
+
@searches = searches_from_history # <- in BlacklightController
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# This method copies request params to session[:search], omitting certain
|
|
239
|
+
# known blacklisted params not part of search, omitting keys with blank
|
|
240
|
+
# values. All keys in session[:search] are as symbols rather than strings.
|
|
241
|
+
def delete_or_assign_search_session_params
|
|
242
|
+
session[:search] = {}
|
|
243
|
+
params.each_pair do |key, value|
|
|
244
|
+
session[:search][key.to_sym] = value unless ["commit", "counter"].include?(key.to_s) ||
|
|
245
|
+
value.blank?
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Saves the current search (if it does not already exist) as a models/search object
|
|
250
|
+
# then adds the id of the serach object to session[:history]
|
|
251
|
+
def save_current_search_params
|
|
252
|
+
# If it's got anything other than controller, action, total, we
|
|
253
|
+
# consider it an actual search to be saved. Can't predict exactly
|
|
254
|
+
# what the keys for a search will be, due to possible extra plugins.
|
|
255
|
+
return if (search_session.keys - [:controller, :action, :total, :counter, :commit ]) == []
|
|
256
|
+
params_copy = search_session.clone # don't think we need a deep copy for this
|
|
257
|
+
params_copy.delete(:page)
|
|
258
|
+
unless @searches.collect { |search| search.query_params }.include?(params_copy)
|
|
259
|
+
new_search = Search.create(:query_params => params_copy)
|
|
260
|
+
session[:history].unshift(new_search.id)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# sets some additional search metadata so that the show view can display it.
|
|
265
|
+
def set_additional_search_session_values
|
|
266
|
+
unless @response.nil?
|
|
267
|
+
search_session[:total] = @response.total
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# we need to know if we are viewing the item as part of search results so we know whether to
|
|
272
|
+
# include certain partials or not
|
|
273
|
+
def adjust_for_results_view
|
|
274
|
+
if params[:results_view] == "false"
|
|
275
|
+
session[:search][:results_view] = false
|
|
276
|
+
else
|
|
277
|
+
session[:search][:results_view] = true
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
# when solr (RSolr) throws an error (RSolr::RequestError), this method is executed.
|
|
283
|
+
def rsolr_request_error(exception)
|
|
284
|
+
if RAILS_ENV == "development"
|
|
285
|
+
raise exception # Rails own code will catch and give usual Rails error page with stack trace
|
|
286
|
+
else
|
|
287
|
+
flash_notice = "Sorry, I don't understand your search."
|
|
288
|
+
# Set the notice flag if the flash[:notice] is already set to the error that we are setting.
|
|
289
|
+
# This is intended to stop the redirect loop error
|
|
290
|
+
notice = flash[:notice] if flash[:notice] == flash_notice
|
|
291
|
+
unless notice
|
|
292
|
+
flash[:notice] = flash_notice
|
|
293
|
+
redirect_to root_path, :status => 500
|
|
294
|
+
else
|
|
295
|
+
render :template => "public/500.html", :layout => false, :status => 500
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# when a request for /catalog/BAD_SOLR_ID is made, this method is executed...
|
|
301
|
+
def invalid_solr_id_error
|
|
302
|
+
if RAILS_ENV == "development"
|
|
303
|
+
render # will give us the stack trace
|
|
304
|
+
else
|
|
305
|
+
flash[:notice] = "Sorry, you have requested a record that doesn't exist."
|
|
306
|
+
redirect_to root_path, :status => 404
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
end
|