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.
Files changed (170) hide show
  1. data/.gitignore +17 -0
  2. data/.gitmodules +6 -0
  3. data/.yardopts +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +14 -0
  6. data/README.rdoc +168 -0
  7. data/Rakefile +9 -0
  8. data/app/controllers/bookmarks_controller.rb +98 -0
  9. data/app/controllers/feedback_controller.rb +37 -0
  10. data/app/controllers/folder_controller.rb +49 -0
  11. data/app/controllers/saved_searches_controller.rb +45 -0
  12. data/app/controllers/search_history_controller.rb +25 -0
  13. data/app/helpers/blacklight_helper.rb +606 -0
  14. data/app/helpers/bookmarks_helper.rb +3 -0
  15. data/app/helpers/catalog_helper.rb +65 -0
  16. data/app/helpers/feedback_helper.rb +2 -0
  17. data/app/helpers/hash_as_hidden_fields.rb +57 -0
  18. data/app/helpers/render_constraints_helper.rb +120 -0
  19. data/app/helpers/saved_searches_helper.rb +2 -0
  20. data/app/helpers/search_history_helper.rb +2 -0
  21. data/app/models/bookmark.rb +6 -0
  22. data/app/models/record_mailer.rb +43 -0
  23. data/app/models/search.rb +19 -0
  24. data/app/views/_flash_msg.html.erb +6 -0
  25. data/app/views/_user_util_links.html.erb +13 -0
  26. data/app/views/bookmarks/index.html.erb +33 -0
  27. data/app/views/catalog/_bookmark_control.html.erb +25 -0
  28. data/app/views/catalog/_bookmark_form.html.erb +8 -0
  29. data/app/views/catalog/_citation.html.erb +15 -0
  30. data/app/views/catalog/_constraints.html.erb +7 -0
  31. data/app/views/catalog/_constraints_element.html.erb +33 -0
  32. data/app/views/catalog/_did_you_mean.html.erb +10 -0
  33. data/app/views/catalog/_document_list.html.erb +30 -0
  34. data/app/views/catalog/_email_form.html.erb +11 -0
  35. data/app/views/catalog/_facet_limit.html.erb +33 -0
  36. data/app/views/catalog/_facet_pagination.html.erb +28 -0
  37. data/app/views/catalog/_facets.html.erb +9 -0
  38. data/app/views/catalog/_folder_control.html.erb +12 -0
  39. data/app/views/catalog/_home.html.erb +6 -0
  40. data/app/views/catalog/_home_text.html.erb +6 -0
  41. data/app/views/catalog/_index_partials/_default.erb +11 -0
  42. data/app/views/catalog/_marc_view.html.erb +33 -0
  43. data/app/views/catalog/_opensearch_response_metadata.html.erb +3 -0
  44. data/app/views/catalog/_previous_next_doc.html.erb +6 -0
  45. data/app/views/catalog/_refworks_form.html.erb +7 -0
  46. data/app/views/catalog/_results_pagination.html.erb +11 -0
  47. data/app/views/catalog/_search_form.html.erb +14 -0
  48. data/app/views/catalog/_show_partials/_default.html.erb +9 -0
  49. data/app/views/catalog/_show_sidebar.html.erb +1 -0
  50. data/app/views/catalog/_show_tools.html.erb +46 -0
  51. data/app/views/catalog/_sms_form.html.erb +23 -0
  52. data/app/views/catalog/_solr_request.html.erb +5 -0
  53. data/app/views/catalog/_sort_and_per_page.html.erb +20 -0
  54. data/app/views/catalog/_unapi_microformat.html.erb +1 -0
  55. data/app/views/catalog/citation.html.erb +1 -0
  56. data/app/views/catalog/email.erb +1 -0
  57. data/app/views/catalog/endnote.endnote.erb +1 -0
  58. data/app/views/catalog/facet.html.erb +28 -0
  59. data/app/views/catalog/index.atom.builder +108 -0
  60. data/app/views/catalog/index.html.erb +37 -0
  61. data/app/views/catalog/index.rss.builder +19 -0
  62. data/app/views/catalog/librarian_view.html.erb +3 -0
  63. data/app/views/catalog/opensearch.json.erb +0 -0
  64. data/app/views/catalog/opensearch.xml.erb +11 -0
  65. data/app/views/catalog/send_email_record.erb +0 -0
  66. data/app/views/catalog/show.endnote.erb +1 -0
  67. data/app/views/catalog/show.html.erb +42 -0
  68. data/app/views/catalog/show.refworks.erb +1 -0
  69. data/app/views/catalog/sms.erb +1 -0
  70. data/app/views/catalog/unapi.xml.builder +6 -0
  71. data/app/views/feedback/complete.html.erb +3 -0
  72. data/app/views/feedback/show.html.erb +20 -0
  73. data/app/views/folder/_tools.html.erb +23 -0
  74. data/app/views/folder/index.html.erb +44 -0
  75. data/app/views/layouts/blacklight.html.erb +49 -0
  76. data/app/views/record_mailer/email_record.erb +6 -0
  77. data/app/views/record_mailer/sms_record.erb +4 -0
  78. data/app/views/saved_searches/index.html.erb +27 -0
  79. data/app/views/search_history/index.html.erb +23 -0
  80. data/blacklight.gemspec +50 -0
  81. data/config.ru +4 -0
  82. data/config/routes.rb +54 -0
  83. data/db/seeds.rb +7 -0
  84. data/features/generators.feature +77 -0
  85. data/features/support/aruba.rb +9 -0
  86. data/install.rb +0 -0
  87. data/install/solr.yml +8 -0
  88. data/lib/blacklight.rb +121 -0
  89. data/lib/blacklight/catalog.rb +311 -0
  90. data/lib/blacklight/comma_link_renderer.rb +27 -0
  91. data/lib/blacklight/configurable.rb +46 -0
  92. data/lib/blacklight/controller.rb +121 -0
  93. data/lib/blacklight/engine.rb +32 -0
  94. data/lib/blacklight/exceptions.rb +13 -0
  95. data/lib/blacklight/marc.rb +46 -0
  96. data/lib/blacklight/marc/citation.rb +251 -0
  97. data/lib/blacklight/search_fields.rb +107 -0
  98. data/lib/blacklight/solr.rb +7 -0
  99. data/lib/blacklight/solr/document.rb +239 -0
  100. data/lib/blacklight/solr/document/dublin_core.rb +40 -0
  101. data/lib/blacklight/solr/document/email.rb +15 -0
  102. data/lib/blacklight/solr/document/marc.rb +84 -0
  103. data/lib/blacklight/solr/document/marc_export.rb +430 -0
  104. data/lib/blacklight/solr/document/sms.rb +13 -0
  105. data/lib/blacklight/solr/facet_paginator.rb +93 -0
  106. data/lib/blacklight/solr_helper.rb +413 -0
  107. data/lib/blacklight/user.rb +55 -0
  108. data/lib/blacklight/version.rb +3 -0
  109. data/lib/colorize.rb +196 -0
  110. data/lib/generators/blacklight/blacklight_generator.rb +134 -0
  111. data/lib/generators/blacklight/templates/SolrMarc.jar +0 -0
  112. data/lib/generators/blacklight/templates/catalog_controller.rb +8 -0
  113. data/lib/generators/blacklight/templates/config/SolrMarc/config-test.properties +37 -0
  114. data/lib/generators/blacklight/templates/config/SolrMarc/config.properties +37 -0
  115. data/lib/generators/blacklight/templates/config/SolrMarc/index.properties +97 -0
  116. data/lib/generators/blacklight/templates/config/SolrMarc/index_scripts/dewey.bsh +47 -0
  117. data/lib/generators/blacklight/templates/config/SolrMarc/index_scripts/format.bsh +126 -0
  118. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/README_MAPS +1 -0
  119. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/callnumber_map.properties +407 -0
  120. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/composition_era_map.properties +56 -0
  121. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/country_map.properties +379 -0
  122. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/format_map.properties +50 -0
  123. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/instrument_map.properties +101 -0
  124. data/lib/generators/blacklight/templates/config/SolrMarc/translation_maps/language_map.properties +490 -0
  125. data/lib/generators/blacklight/templates/config/blacklight_config.rb +245 -0
  126. data/lib/generators/blacklight/templates/config/solr.yml +6 -0
  127. data/lib/generators/blacklight/templates/migrations/add_user_types_to_bookmarks_searches.rb +11 -0
  128. data/lib/generators/blacklight/templates/migrations/create_bookmarks.rb +17 -0
  129. data/lib/generators/blacklight/templates/migrations/create_searches.rb +15 -0
  130. data/lib/generators/blacklight/templates/migrations/remove_editable_fields_from_bookmarks.rb +11 -0
  131. data/lib/generators/blacklight/templates/public/images/blacklight/bg.png +0 -0
  132. data/lib/generators/blacklight/templates/public/images/blacklight/border.png +0 -0
  133. data/lib/generators/blacklight/templates/public/images/blacklight/bul_sq_gry.gif +0 -0
  134. data/lib/generators/blacklight/templates/public/images/blacklight/checkmark.gif +0 -0
  135. data/lib/generators/blacklight/templates/public/images/blacklight/logo.png +0 -0
  136. data/lib/generators/blacklight/templates/public/images/blacklight/magnifying_glass.gif +0 -0
  137. data/lib/generators/blacklight/templates/public/images/blacklight/remove.gif +0 -0
  138. data/lib/generators/blacklight/templates/public/images/blacklight/separator.gif +0 -0
  139. data/lib/generators/blacklight/templates/public/images/blacklight/start_over.gif +0 -0
  140. data/lib/generators/blacklight/templates/public/javascripts/blacklight.js +485 -0
  141. data/lib/generators/blacklight/templates/public/javascripts/jquery-1.4.2.min.js +154 -0
  142. data/lib/generators/blacklight/templates/public/javascripts/jquery-ui-1.8.1.custom.min.js +756 -0
  143. data/lib/generators/blacklight/templates/public/stylesheets/blacklight.css +487 -0
  144. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  145. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  146. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  147. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  148. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  149. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  150. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_gloss-wave_35_558fd0_500x100.png +0 -0
  151. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  152. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  153. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  154. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  155. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_2e4f81_256x240.png +0 -0
  156. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  157. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  158. data/lib/generators/blacklight/templates/public/stylesheets/jquery/ui-lightness/jquery-ui-1.8.1.custom.css +486 -0
  159. data/lib/generators/blacklight/templates/public/stylesheets/yui.css +31 -0
  160. data/lib/generators/blacklight/templates/solr_document.rb +30 -0
  161. data/lib/railties/blacklight.rake +66 -0
  162. data/lib/railties/cucumber.rake +53 -0
  163. data/lib/railties/rspec.rake +188 -0
  164. data/lib/railties/solr_marc.rake +148 -0
  165. data/lib/railties/test_solr_server.rb +130 -0
  166. data/spec/helpers/catalog_helper_spec.rb +111 -0
  167. data/spec/views/catalog/_sms_form.html.erb_spec.rb +19 -0
  168. data/tasks/blacklight_tasks.rake +4 -0
  169. data/uninstall.rb +1 -0
  170. metadata +431 -0
@@ -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
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run BlacklightApp::Application
@@ -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
+
@@ -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
+
@@ -0,0 +1,9 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 30
5
+ end
6
+
7
+ Before ('@really_slow_process') do
8
+ @aruba_timeout_seconds = 30
9
+ end
File without changes
@@ -0,0 +1,8 @@
1
+ production:
2
+ url: http://127.0.0.1:8983/solr
3
+ development:
4
+ url: http://127.0.0.1:8983/solr
5
+ test: &TEST
6
+ url: http://127.0.0.1:8983/solr
7
+ cucumber:
8
+ <<: *TEST
@@ -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