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
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
|