blacklight 3.0pre1

Sign up to get free protection for your applications and to get access to all the features.
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