Permalink
Browse files

Initial Commit

  • Loading branch information...
0 parents commit cfc474389df64ffb61b69f8a2127b93ac19d07ab @g8tor g8tor committed Oct 30, 2009
Showing with 16,444 additions and 0 deletions.
  1. 0 CHANGES
  2. +14 −0 LICENSE
  3. +110 −0 PRE-REQUISITES.rdoc
  4. +188 −0 README.rdoc
  5. +21 −0 README_PRODUCTION.rdoc
  6. +28 −0 README_PROJECT.rdoc
  7. +226 −0 README_SOLR.rdoc
  8. +59 −0 Rakefile
  9. +59 −0 app/controllers/application_controller.rb
  10. +59 −0 app/controllers/bookmarks_controller.rb
  11. +205 −0 app/controllers/catalog_controller.rb
  12. +37 −0 app/controllers/feedback_controller.rb
  13. +44 −0 app/controllers/saved_searches_controller.rb
  14. +25 −0 app/controllers/search_history_controller.rb
  15. +43 −0 app/controllers/user_sessions_controller.rb
  16. +13 −0 app/controllers/users_controller.rb
  17. +362 −0 app/helpers/application_helper.rb
  18. +3 −0 app/helpers/bookmarks_helper.rb
  19. +44 −0 app/helpers/catalog_helper.rb
  20. +2 −0 app/helpers/feedback_helper.rb
  21. +2 −0 app/helpers/saved_searches_helper.rb
  22. +2 −0 app/helpers/search_history_helper.rb
  23. +2 −0 app/helpers/user_sessions_helper.rb
  24. +2 −0 app/helpers/users_helper.rb
  25. +7 −0 app/models/bookmark.rb
  26. +30 −0 app/models/record_mailer.rb
  27. +12 −0 app/models/search.rb
  28. +7 −0 app/models/solr_document.rb
  29. +46 −0 app/models/user.rb
  30. +4 −0 app/models/user_session.rb
  31. +6 −0 app/views/_flash_msg.html.erb
  32. +11 −0 app/views/_user_util_links.html.erb
  33. +33 −0 app/views/bookmarks/edit.html.erb
  34. +56 −0 app/views/bookmarks/index.html.erb
  35. +1 −0 app/views/bookmarks/new.html.erb
  36. +18 −0 app/views/bookmarks/show.html.erb
  37. +12 −0 app/views/catalog/_bookmark_control.html.erb
  38. +17 −0 app/views/catalog/_citation.html.erb
  39. +59 −0 app/views/catalog/_constraints.html.erb
  40. +10 −0 app/views/catalog/_did_you_mean.html.erb
  41. +32 −0 app/views/catalog/_document_list.html.erb
  42. +14 −0 app/views/catalog/_email_form.html.erb
  43. +6 −0 app/views/catalog/_facet_pagination.html.erb
  44. +26 −0 app/views/catalog/_facets.html.erb
  45. +7 −0 app/views/catalog/_hidden_filters.html.erb
  46. +6 −0 app/views/catalog/_home.html.erb
  47. +6 −0 app/views/catalog/_home_text.html.erb
  48. +11 −0 app/views/catalog/_index_partials/_default.html.erb
  49. +7 −0 app/views/catalog/_previous_next_doc.html.erb
  50. +23 −0 app/views/catalog/_search_constraints.html.erb
  51. +15 −0 app/views/catalog/_search_form.html.erb
  52. +18 −0 app/views/catalog/_show_partials/_default.html.erb
  53. +18 −0 app/views/catalog/_show_partials/_ead.html.erb
  54. +1,620 −0 app/views/catalog/_show_partials/_ead/_show.xsl
  55. +19 −0 app/views/catalog/_show_tools.html.erb
  56. +26 −0 app/views/catalog/_sms_form.html.erb
  57. +5 −0 app/views/catalog/_solr_request.html.erb
  58. +25 −0 app/views/catalog/_sort_and_per_page.html.erb
  59. +1 −0 app/views/catalog/citation.html.erb
  60. +1 −0 app/views/catalog/email.erb
  61. +11 −0 app/views/catalog/facet.html.erb
  62. +35 −0 app/views/catalog/index.html.erb
  63. +20 −0 app/views/catalog/index.rss.builder
  64. 0 app/views/catalog/opensearch.json.erb
  65. +10 −0 app/views/catalog/opensearch.xml.erb
  66. 0 app/views/catalog/send_email_record.erb
  67. +1 −0 app/views/catalog/show.endnote.erb
  68. +41 −0 app/views/catalog/show.html.erb
  69. +1 −0 app/views/catalog/show.refworks.erb
  70. +1 −0 app/views/catalog/sms.erb
  71. +3 −0 app/views/feedback/complete.html.erb
  72. +20 −0 app/views/feedback/show.html.erb
  73. +53 −0 app/views/layouts/application.html.erb
  74. +9 −0 app/views/record_mailer/email_record.erb
  75. +7 −0 app/views/record_mailer/sms_record.erb
  76. +27 −0 app/views/saved_searches/index.html.erb
  77. +23 −0 app/views/search_history/index.html.erb
  78. +5 −0 app/views/user_sessions/_login_form.html.erb
  79. +7 −0 app/views/user_sessions/index.html.erb
  80. +1 −0 app/views/user_sessions/new.html.erb
  81. +11 −0 app/views/users/new.html.erb
  82. +27 −0 app/views/users/show.html.erb
  83. BIN assets/images/bg.png
  84. BIN assets/images/border.png
  85. BIN assets/images/bul_sq_gry.gif
  86. BIN assets/images/checkmark.gif
  87. BIN assets/images/logo.png
  88. BIN assets/images/magnifying_glass.gif
  89. BIN assets/images/remove.gif
  90. BIN assets/images/separator.gif
  91. BIN assets/images/start_over.gif
  92. +15 −0 assets/javascripts/accordion.js
  93. +9 −0 assets/javascripts/application.js
  94. +3 −0 assets/javascripts/blacklight.js
  95. +19 −0 assets/javascripts/jquery-1.3.1.min.js
  96. +17 −0 assets/javascripts/lightbox.js
  97. +197 −0 assets/stylesheets/application.css
  98. +31 −0 assets/stylesheets/yui.css
  99. +15 −0 config/CONFIG_README
  100. +19 −0 config/SolrMarc/config.properties
  101. +19 −0 config/SolrMarc/demoserver.properties
  102. +97 −0 config/SolrMarc/index.properties
  103. +109 −0 config/boot.rb
  104. +20 −0 config/database.yml
  105. +13 −0 config/demo_config.properties
  106. +97 −0 config/demo_index.properties
  107. +95 −0 config/environment.rb
  108. +22 −0 config/environments/cucumber.rb
  109. +19 −0 config/environments/development.rb
  110. +30 −0 config/environments/test.rb
  111. +187 −0 config/initializers/blacklight_config.rb
  112. +10 −0 config/initializers/inflections.rb
  113. +5 −0 config/initializers/mime_types.rb
  114. +17 −0 config/initializers/new_rails_defaults.rb
  115. +5 −0 config/locales/en.yml
  116. +6 −0 config/routes.rb
  117. +4 −0 config/solr.yml
  118. +16 −0 db/migrate/20090127164730_create_users.rb
  119. +17 −0 db/migrate/20090127164740_create_bookmarks.rb
  120. +26 −0 db/migrate/20090127164750_acts_as_taggable_migration.rb
  121. +15 −0 db/migrate/20090428182620_create_searches.rb
  122. +15 −0 db/migrate/20090529161304_add_authlogic_fields_to_users.rb
  123. +60 −0 db/schema.rb
  124. +58 −0 features/bookmarks.feature
  125. +129 −0 features/did_you_mean.feature
  126. +16 −0 features/errors.feature
  127. +51 −0 features/saved_searches.feature
  128. +81 −0 features/search.feature
  129. +123 −0 features/search_filters.feature
  130. +98 −0 features/search_history.feature
  131. +17 −0 features/search_sort.feature
  132. +4 −0 features/step_definitions/bookmarks_steps.rb
  133. +4 −0 features/step_definitions/error_steps.rb
  134. +4 −0 features/step_definitions/general_steps.rb
  135. +14 −0 features/step_definitions/saved_searches_steps.rb
  136. +8 −0 features/step_definitions/search_history_steps.rb
  137. +86 −0 features/step_definitions/search_steps.rb
  138. +4 −0 features/step_definitions/user_steps.rb
  139. +115 −0 features/step_definitions/webrat_steps.rb
  140. +22 −0 features/support/env.rb
  141. +50 −0 features/support/paths.rb
  142. +58 −0 features/user_account.feature
  143. +30 −0 init.rb
  144. +83 −0 install.rb
  145. +6 −0 install/solr.yml
  146. +36 −0 jetty/README.txt
  147. +212 −0 jetty/etc/jetty.xml
  148. +379 −0 jetty/etc/webdefault.xml
  149. BIN jetty/lib/jetty-6.1.3.jar
  150. BIN jetty/lib/jetty-util-6.1.3.jar
  151. BIN jetty/lib/jsp-2.1/ant-1.6.5.jar
  152. BIN jetty/lib/jsp-2.1/core-3.1.1.jar
  153. BIN jetty/lib/jsp-2.1/jsp-2.1.jar
  154. BIN jetty/lib/jsp-2.1/jsp-api-2.1.jar
  155. BIN jetty/lib/servlet-api-2.5-6.1.3.jar
  156. 0 jetty/log
  157. 0 jetty/logs/.txt
  158. +52 −0 jetty/solr/README.txt
  159. +190 −0 jetty/solr/bin/abc
  160. +190 −0 jetty/solr/bin/abo
  161. +117 −0 jetty/solr/bin/backup
  162. +142 −0 jetty/solr/bin/backupcleaner
  163. +133 −0 jetty/solr/bin/commit
  164. +134 −0 jetty/solr/bin/optimize
  165. +129 −0 jetty/solr/bin/readercycle
  166. +77 −0 jetty/solr/bin/rsyncd-disable
  167. +76 −0 jetty/solr/bin/rsyncd-enable
  168. +145 −0 jetty/solr/bin/rsyncd-start
  169. +105 −0 jetty/solr/bin/rsyncd-stop
  170. +99 −0 jetty/solr/bin/scripts-util
  171. +154 −0 jetty/solr/bin/snapcleaner
  172. +179 −0 jetty/solr/bin/snapinstaller
  173. +269 −0 jetty/solr/bin/snappuller
  174. +77 −0 jetty/solr/bin/snappuller-disable
  175. +77 −0 jetty/solr/bin/snappuller-enable
  176. +136 −0 jetty/solr/bin/snapshooter
  177. +31 −0 jetty/solr/conf/admin-extra.html
  178. +36 −0 jetty/solr/conf/elevate.xml
  179. +246 −0 jetty/solr/conf/mapping-ISOLatin1Accent.txt
  180. +21 −0 jetty/solr/conf/protwords.txt
  181. +184 −0 jetty/solr/conf/schema.xml
  182. +24 −0 jetty/solr/conf/scripts.conf
  183. +564 −0 jetty/solr/conf/solrconfig.xml
  184. +2 −0 jetty/solr/conf/spellings.txt
  185. +58 −0 jetty/solr/conf/stopwords.txt
  186. +31 −0 jetty/solr/conf/synonyms.txt
  187. +132 −0 jetty/solr/conf/xslt/example.xsl
  188. +67 −0 jetty/solr/conf/xslt/example_atom.xsl
  189. +66 −0 jetty/solr/conf/xslt/example_rss.xsl
  190. +337 −0 jetty/solr/conf/xslt/luke.xsl
  191. BIN jetty/solr/data/index/_0.fdt
  192. BIN jetty/solr/data/index/_0.fdx
  193. BIN jetty/solr/data/index/_0.fnm
  194. BIN jetty/solr/data/index/_0.frq
  195. +1 −0 jetty/solr/data/index/_0.nrm
  196. BIN jetty/solr/data/index/_0.prx
  197. BIN jetty/solr/data/index/_0.tii
  198. BIN jetty/solr/data/index/_0.tis
  199. BIN jetty/solr/data/index/segments.gen
  200. BIN jetty/solr/data/index/segments_2
  201. BIN jetty/solr/data/spell/_0.cfs
  202. BIN jetty/solr/data/spell/segments.gen
  203. BIN jetty/solr/data/spell/segments_3
  204. BIN jetty/solr/data/spell_author/_0.cfs
  205. BIN jetty/solr/data/spell_author/segments.gen
  206. BIN jetty/solr/data/spell_author/segments_3
  207. BIN jetty/solr/data/spell_subject/_0.cfs
  208. BIN jetty/solr/data/spell_subject/segments.gen
  209. BIN jetty/solr/data/spell_subject/segments_3
  210. BIN jetty/solr/data/spell_title/_0.cfs
  211. BIN jetty/solr/data/spell_title/segments.gen
  212. BIN jetty/solr/data/spell_title/segments_3
  213. BIN jetty/solr/lib/UnicodeNormalizeFilter.jar
  214. BIN jetty/solr/lib/normalizer.jar
  215. BIN jetty/start.jar
  216. BIN jetty/webapps/solr.war
  217. BIN lib/.DS_Store
  218. +51 −0 lib/blacklight.rb
  219. +46 −0 lib/blacklight/configurable.rb
  220. +50 −0 lib/blacklight/core_ext.rb
  221. +41 −0 lib/blacklight/marc.rb
  222. +246 −0 lib/blacklight/marc/citation.rb
  223. +35 −0 lib/blacklight/routes.rb
  224. +5 −0 lib/blacklight/solr.rb
  225. +62 −0 lib/blacklight/solr/document.rb
  226. +5 −0 lib/blacklight/solr/document/README.txt
  227. +31 −0 lib/blacklight/solr/document/ead.rb
  228. +22 −0 lib/blacklight/solr/document/marc.rb
  229. +45 −0 lib/blacklight/solr/facets.rb
  230. +150 −0 lib/blacklight/solr_helper.rb
  231. +31 −0 lib/taggable_pagination.rb
  232. +46 −0 lib/tasks/blacklight.rake
  233. +18 −0 lib/tasks/cucumber.rake
  234. +186 −0 lib/tasks/rspec.rake
  235. +106 −0 lib/tasks/solr_marc.rake
  236. +20 −0 lib/will_paginate_link_renderer.rb
  237. +4 −0 script/about
  238. +6 −0 script/autospec
  239. +3 −0 script/console
  240. +8 −0 script/cucumber
  241. +3 −0 script/dbconsole
  242. +3 −0 script/destroy
  243. +3 −0 script/generate
  244. +3 −0 script/performance/benchmarker
  245. +3 −0 script/performance/profiler
  246. +3 −0 script/performance/request
  247. +3 −0 script/plugin
  248. +3 −0 script/process/inspector
  249. +3 −0 script/process/reaper
  250. +3 −0 script/process/spawner
  251. +3 −0 script/runner
  252. +3 −0 script/server
  253. +10 −0 script/spec
  254. +9 −0 script/spec_server
  255. BIN solr_marc/SolrMarc.jar
  256. +309 −0 spec/controllers/catalog_controller_spec.rb
  257. +26 −0 spec/controllers/saved_searches_controller_spec.rb
  258. +29 −0 spec/controllers/search_history_controller_spec.rb
  259. +1 −0 spec/data/test_data.utf8.mrc
  260. +133 −0 spec/helpers/application_helper_spec.rb
  261. +11 −0 spec/helpers/search_history_helper_spec.rb
  262. +397 −0 spec/helpers/solr_helper_spec.rb
  263. +82 −0 spec/lib/blacklight_marc_spec.rb
  264. +97 −0 spec/lib/configurable_spec.rb
  265. +37 −0 spec/lib/core_ext_deep_merge_unless_blank_spec.rb
  266. +261 −0 spec/lib/marc_citation_spec.rb
  267. +120 −0 spec/lib/test_solr_server.rb
  268. +37 −0 spec/models/bookmark_spec.rb
  269. +81 −0 spec/models/record_mailer_spec.rb
  270. +30 −0 spec/models/search_spec.rb
  271. +135 −0 spec/models/solr_document_spec.rb
  272. +124 −0 spec/models/user_spec.rb
  273. +3 −0 spec/rcov.opts
  274. +4 −0 spec/spec.opts
  275. +53 −0 spec/spec_helper.rb
  276. +44 −0 spec/views/catalog/_document_list.html.erb_spec.rb
  277. +182 −0 spec/views/catalog/_facets.html.erb_spec.rb
  278. +61 −0 spec/views/catalog/_index_partials/_default.html.erb_spec.rb
  279. +53 −0 spec/views/catalog/_show_partials/_default.html.erb_spec.rb
  280. +99 −0 spec/views/catalog/show.html.erb_spec.rb
  281. +4 −0 tasks/blacklight_tasks.rake
  282. +138 −0 template.rb
  283. +53 −0 todos_and_ideas.txt
  284. +1 −0 uninstall.rb
  285. +182 −0 vendor/plugins/acts_as_taggable_on_steroids/CHANGELOG
  286. +20 −0 vendor/plugins/acts_as_taggable_on_steroids/MIT-LICENSE
  287. +146 −0 vendor/plugins/acts_as_taggable_on_steroids/README
  288. +22 −0 vendor/plugins/acts_as_taggable_on_steroids/Rakefile
  289. +11 −0 ...aggable_on_steroids/generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb
  290. +26 −0 ...plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/templates/migration.rb
  291. +1 −0 vendor/plugins/acts_as_taggable_on_steroids/init.rb
  292. +205 −0 vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb
  293. +71 −0 vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb
  294. +3 −0 vendor/plugins/acts_as_taggable_on_steroids/lib/tag_counts_extension.rb
  295. +108 −0 vendor/plugins/acts_as_taggable_on_steroids/lib/tag_list.rb
  296. +12 −0 vendor/plugins/acts_as_taggable_on_steroids/lib/tagging.rb
  297. +13 −0 vendor/plugins/acts_as_taggable_on_steroids/lib/tags_helper.rb
  298. +97 −0 vendor/plugins/acts_as_taggable_on_steroids/test/abstract_unit.rb
  299. +364 −0 vendor/plugins/acts_as_taggable_on_steroids/test/acts_as_taggable_test.rb
  300. +10 −0 vendor/plugins/acts_as_taggable_on_steroids/test/database.yml
Sorry, we could not display the entire diff because too many files (494) changed.
0 CHANGES
No changes.
14 LICENSE
@@ -0,0 +1,14 @@
+##########################################################################
+# Copyright 2008 Rector and Visitors of the University of Virginia
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
110 PRE-REQUISITES.rdoc
@@ -0,0 +1,110 @@
+== Pre-requisites
+
+===Ruby
+
+Ruby version 1.8.7 (or 1.8.6 enterprise) is required. You can find out which version you are running by executing:
+ ruby -v
+Information on installing Ruby can be found here:
+http://www.ruby-lang.org/en/downloads
+
+For installing Ruby and related goodies on Ubuntu, this may be helpful:
+ http://www.rubyinside.com/how-to-install-a-ruby-18-stack-on-ubuntu-810-from-scratch-1566.html
+
+===Ruby Gems
+
+You'll need Ruby Gems version 1.3.1 or later. You can check which version of “gem” you have by running:
+ gem -v
+Information on installing Ruby Gems can be found here:
+ http://www.rubygems.org/read/chapter/3
+
+To update your Ruby Gems, run (YMMV for various operating systems):
+ sudo gem install rubygems-update
+ sudo update_rubygems
+
+You can also manually install Ruby Gems:
+ wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
+ tar xzf rubygems-1.3.1.tgz
+ cd rubygems-1.3.1
+ sudo ruby setup.rb
+ gem -v
+
+These commands should work for Linux and OSX, but we haven't yet written any instructions for Windows installation. If anyone is able to volunteer for this task, please let us know!
+
+===Ruby Gems Sources
+
+Make sure you have the standard ruby gem sources available:
+ gem sources -l
+should show
+ http://gems.rubyforge.org
+ http://gems.rubyonrails.org
+ http://gems.github.com
+ http://gemcutter.org
+
+If you're missing those gem sources, add them like this:
+ gem sources -a http://gems.rubyforge.org
+ gem sources -a http://gems.rubyonrails.org
+ gem sources -a http://gems.github.com
+ gem sources -a http://gemcutter.org
+
+===Git Client
+
+Some of the rubygems required by blacklight are hosted in git repositories.
+Information on getting the git client installed can be found here:
+
+ http://git-scm.com/
+ http://book.git-scm.com/2_installing_git.html
+
+ If you are behind a firewall, you may need to open port 9418 for Git.
+
+
+===Install Blacklight's Ruby Gem dependencies:
+You will need Rails gem version 2.3.2. You can check if you have it installed:
+ gem list
+
+If you need to install rails 2.3.4:
+ sudo gem install -v=2.3.4 rails
+
+You will need libxml and libxslt installed for the ruby-xslt and nokogiri gems.
+
+ On Red Hat Fedora the command is:
+ sudo yum install libxml2-devel libxslt-devel
+
+Note: the curb gem can be used for Blacklight SOLR requests, instead of net::http,
+which can be used by the rsolr gem. If you'd rather use curb than net::http, you need to make sure curl is installed.
+
+ On Red Hat Fedora the command is:
+ sudo yum install curl curl-devel
+
+and then install the curb gem:
+ sudo gem install curb
+
+===Database dependencies
+You can choose to use any database that has ruby on rails bindings, but sqlite and MySQL are used most commonly and are documented here.
+
+* if you are using sqlite3:
+ sudo gem install sqlite3-ruby
+
+If you want to use sqlite, you will need to install sqlite3 and its ruby bindings
+
+ On Red Hat Fedora the command is:
+ sudo yum install sqlite sqlite-devel ruby-sqlite3
+
+ On OSX macports the command is:
+ sudo port install sqlite3 rb-sqlite3
+
+ On FreeBSD the commands are:
+ cd /usr/ports/databases/rubygem-sqlite3
+ make install clean
+
+
+* if you are using MySQL, make sure MySQL is installed, and run:
+ sudo gem install mysql
+
+===Dependencies included with Blacklight
+
+* ActsAsTaggableOnSteroids plugin docs: http://agilewebdevelopment.com/plugins/acts_as_taggable_on_steroids
+
+* Resource Controller: http://github.com/giraffesoft/resource_controller/tree/master There is a very good
+video tutorial on the resource_controller plugin: http://www.vimeo.com/637894
+
+* Additional gems are vendorized with blacklight and will be built locally by the ''rake gems:build'' command. See the README in this same directory for more information (provided in the post installation instructions.
188 README.rdoc
@@ -0,0 +1,188 @@
+=Blacklight
+
+Please see {README_PROJECT.rdoc}[link:files/vendor/plugins/blacklight/README_PROJECT_rdoc.html] for main information about this project and plugin.
+
+Please see {PRE-REQUISITES.rdoc}[link:files/vendor/plugins/blacklight/PRE-REQUISITES_rdoc.html] for pre-requisites Blacklight needs.
+
+Please see {README_SOLR.rdoc}[link:files/vendor/plugins/blacklight/README_SOLR_rdoc.html] for information about setting up and configuring SOLR (http://lucene.apache.org/solr).
+
+Note: these instructions apply to releases 2.2.0 and above.
+
+NOTE: issue commands from your Rails application's root directory.
+
+==How to Install the Blacklight Plugin into Your Rails Project
+
+1. Create your rails app: http://guides.rubyonrails.org/getting_started.html#creating-a-new-rails-project
+2. Install Blacklight:
+From a release: (2.2.0_RC2 in this example)
+ script/plugin -v install http://blacklight.rubyforge.org/svn/releases/plugins/blacklight-plugin-2.2.0_RC2/
+Or from trunk:
+ script/plugin -v install http://blacklight.rubyforge.org/svn/trunk/rails/vendor/plugins/blacklight/
+
+Using <tt>script/plugin install</tt> calls the plugin's install.rb script, which does the following:
+
+1. Automatically installs the Engines plugin ( http://rails-engines.org )
+2. Updates config/environment.rb with the necessary lines for Engines and Blacklight
+3. Copies the vendorized Authlogic gem from vendor/plugins/blacklight/vendor/gems to vendor/gems
+4. Adds default solr.yml to config dir
+5. Copies the migration files from vendor/plugins/blacklight/db/migrate to db/migrate
+6. Copies the default blacklight_config.rb file to config/initializers/blacklight_config.rb
+
+If you need to manually install Blacklight, see Installing Blacklight Manually below, then return to Post Installation.
+
+==Post Installation
+
+===Remove Rails Application Files Conflicting with Blacklight Plugin
+From the your rails application's root directory:
+
+ rm public/index.html
+ rm app/controllers/application_controller.rb
+ rm app/helpers/application_helper.rb
+
+===Run the Database Migrations
+By default, Rails uses a SQLite3 database. Configure others in config/databases.yml. For more information, see {PRE-REQUISITES.rdoc}[link:files/vendor/plugins/blacklight/PRE-REQUISITES_rdoc.html]
+
+ rake db:migrate
+
+===Build Gems
+Now you need to build the "vendorized" gems for your local system:
+ from (rails app)/vendor/plugins/blacklight:
+
+ sudo rake gems:build
+
+ Note: you can run the above command from your rails app directory, but you may get error messages saying you need to install additional gems, e.g.
+
+ sudo gem install mislav-hanna
+ and/or messages that you need to create a database.yml file (see {DEMO_README}[link:files/DEMO_README] re: database.yml file).
+
+After you successfully run gems:build, see if you have all of the required gems
+installed, or whether you're still missing some:
+
+ rake gems
+
+The ''rake gems'' command will give you a list of the required gems and their version numbers, and will tell you which ones are installed already.
+You can also see vendor/plugins/blacklight/init.rb for the Blacklight plugin dependencies' versions.
+An example of a versioned install: sudo gem install rails --version '2.3.2')
+
+The gems vendorized with blacklight are in (rails_app)/vendor/plugins/blacklight/vendor/gems; all of the gems found there should be built locally by the ''rake gems:build'' command.
+
+You can confirm your gem installations and their release numbers with
+
+ gem list
+
+If you manually install (or uninstall?) gems, be sure to run ''sudo rake gems:build'' afterwards.
+
+====Possible Issues with Gems
+
+curb gem: since curb is currently not required for the RSolr gem (it will default to net::http, which should already be available via your ruby installation), you can do the following to get rid of the curb dependency:
+ in bl-demo/vendor/plugins/blacklight/init.rb
+ comment out the line
+ config.gem curb
+ by inserting "#" at the beginning of the line.
+
+ruby-xslt gem: installations on Windows machines may have difficulties with ruby-xslt. This gem is only used for indexing EAD files. To remove this dependency:
+ in bl-demo/vendor/plugins/blacklight/init.rb
+ comment out the line
+ config.gem 'ruby-xslt', :lib=>'xml/xslt' # you may need to install libxml and libxslt
+ by inserting "#" at the beginning of the line.
+
+Note: as of 2009-08-10, there have been some reports of problems with gems. If you are seeing errors relating to gems, you may need to uninstall other versions of gems if they are already installed, for example:
+ sudo gem uninstall curb
+ sudo gem uninstall nokogiri
+ sudo gem uninstall ruby-xslt
+
+Be aware of gems that may have been inadvertently installed in your (home)/.gems directory, rather than in your system location for ruby gems. At least one site encountered difficulties when gems were installed in the account's directory, rather than in the system location. (This can happen if you don't use "sudo gem install" but instead use "gem install"). In this case, you may need to remove the account's version of the gems.
+ gem uninstall (gem name) - note absence of ''sudo''
+If that doesn't work, you can try the brute force method to remove them:
+ cd ~/.gem/ruby/1.8/gems
+ then remove everything in that directory.
+
+You may also see messages to run refresh_spec when you run the ''rake gems'' command; go ahead and follow those instructions. (In at least one case, the refresh_spec command needed to be run many times before the error messages ceased.)
+
+
+===Start Solr
+You need a running instance of Solr. Just to get going you can use the test instance in the Blacklight plugin:
+
+ cd vendor/plugins/blacklight/jetty
+ java -jar start.jar
+
+This starts an instance of jetty with Solr running on port 8983. If you want to start on another port, use Java's -D argument:
+
+ java -Djetty.port=8888 -jar start.jar
+
+This Solr instance already has data in the index. Once you start it you can run your Rails app and it will use this SOLR index (expected on port 8983).
+
+ ./script/server
+
+Now navigate to http://localhost:3000 and you should have a working demo blacklight application with the test data set!
+
+
+==Installing Blacklight Manually
+
+This assumes that for some reason you can't install the plugin via <tt>script/plugin install</tt> or
+there was a problem and you need to finish manually. Otherwise, see the instructions above.
+
+1. Create your Rails app: http://guides.rubyonrails.org/getting_started.html#creating-a-new-rails-project
+2. Get the Blacklight plugin and put it in your plugins directory:
+
+ Edge: svn export http://blacklight.rubyforge.org/svn/trunk/rails/vendor/plugins/blacklight vendor/plugins/blacklight
+
+ Specific Release:
+
+ 1. Find the release you want here: http://blacklight.rubyforge.org/svn/releases/plugins/
+ 2. Then navigate to the plugin, for example: http://blacklight.rubyforge.org/svn/releases/plugins/blacklight-plugin-2.2.0
+ 3. Use SVN to export it: svn export http://blacklight.rubyforge.org/svn/releases/plugins/blacklight-plugin-2.2.0
+
+ Finally, you can also downlowd the archive and unpack it in vendor/plugins/blacklight:
+
+ 1. Find the release you want here: http://rubyforge.org/frs/?group_id=5235
+ 2. Download it into vendor/plugins
+ 3. Move to the directory: cd vendor/plugins
+ 4. Unarchive: tar xvzf blacklight-plugin-2.2.0
+ 5. Rename the directory: mv blacklight-plugin-2.2.0 blacklight
+
+3. Install the Engines plugin:
+
+ script/plugin install git://github.com/lazyatom/engines.git
+
+ If you aren't using or can't use script/plugin, then install it manually:
+
+ 1. git clone git://github.com/lazyatom/engines.git vendor/plugins/engines
+ 2. rm -rf vendor/plugins/engines/.git
+
+4. Update _config/environment.rb_ with necessary lines:
+
+ 1. Below require File.join(File.dirname(__FILE__), 'boot'):
+
+ require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')
+
+ 2. Inside Rails::Initializer.run do |config| block:
+
+ config.gem 'authlogic'
+ config.plugin_paths += ["#{RAILS_ROOT}/vendor/plugins/blacklight/vendor/plugins"]
+ config.plugins = %W(engines blacklight acts_as_taggable_on_steroids resource_controller)
+
+5. Install the Authlogic gem. You can install this as a system gem or copy it from the Blacklight plugin:
+
+ * As a system gem:
+
+ sudo gem install authlogic
+
+ * As a vendorized gem (this is what the Blacklight installer does--see above):
+
+ mkdir vendor/gems
+ cp -rp vendor/plugins/blacklight/vendor/gems/authlogic-<version> vendor/gems/authlogic-<version>
+
+6. Copy solr.yml to config dir:
+
+ cp vendor/plugins/blacklight/install/solr.yml config/
+
+7. Copy the migration files to your app:
+
+ cp -pR vendor/plugins/blacklight/db/migrate db/migrate
+
+8. Copy the default blacklight_config.rb file to config/initializers:
+
+ cp vendor/plugins/blacklight/config/initializers/blacklight_config.rb config/initializers/
+
+9. Go to "Post Installation", above.
21 README_PRODUCTION.rdoc
@@ -0,0 +1,21 @@
+== Running Blacklight in Production Mode
+
+Rails projects are generally designed so that "development" mode will reload files as you modify them, "test" mode is for testing only, and "production" mode caches files for faster performance.
+
+To run Blacklight in Production Mode:
+
+1. Create the prod database
+
+You will need to ensure that the database for your production instance exists. See
+ (your app)/config/database.yml
+
+2. Do the database migration for production
+ rake db:migrate RAILS_ENV=”production”
+
+3. Start up your web server in production mode.
+
+Many sites prefer mod_passenger as their web server, especially for production. See http://www.modrails.com/install.html
+
+For mongrel, the command is
+
+ script/server -e production
28 README_PROJECT.rdoc
@@ -0,0 +1,28 @@
+Please note: The main Blacklight website is http://projectblacklight.org
+
+=Installing Blacklight
+
+== Some background information
+
+Blacklight is open source discovery software. Libraries (or anyone else) can use Blacklight to enable searching and browsing of their collections online. Blacklight uses the Apache SOLR ( http://lucene.apache.org/solr ) search engine to index and search full text and/or metadata, and Blacklight has a highly configurable Ruby on Rails front-end. Currently, Blacklight can index, search, and provide faceted browsing for MaRC records and EAD XML files, and support is planned for Dublin Core and MODS as well. Blacklight was originally developed at the University of Virginia Library and is made public under an Apache 2.0 license. As of version 2.3.0 (released July 31, 2009), Blacklight is distributed as a rails engines plugin and also as a demo rails application that uses an engines Blacklight plugin.
+
+== Which one should I install?
+There are two ways of installing Blacklight. You can either install a pre-configured demo app, which already has the Blacklight plugin installed and integrated, or you can install the plugin into an existing rails application.
+
+If you're just getting started with Blacklight and want to get something up and running
+relatively quickly, start by installing the demo app. This will give you a good introduction
+to the pieces of the Blacklight system before you start customizing your own installation.
+
+If you want to integrate Blacklight search and discovery into another rails app, or if you already have a customized copy of Blacklight and you only want to upgrade the plugin, you'll want the plugin installation instructions.
+
+==Pre-requisites
+Whichever method you choose for installation, be sure you have all the pre-requisites in place. You can find these detailed in {PRE-REQUISITES.rdoc}[link:files/vendor/plugins/blacklight/PRE-REQUISITES_rdoc.html]
+
+==Installing the demo app
+Instructions for installing the demo app are contained in the file DEMO_README
+
+==Installing the plugin into an existing rails app
+Instructions for installing the demo app are contained in the plugin's {README.rdoc}[link:files/vendor/plugins/blacklight/README_rdoc.html]
+
+==Running solr
+You'll also want some information about how Blacklight expects Apache SOLR ( http://lucene.apache.org/solr ) to run, which you can find in {README_SOLR.rdoc}[link:files/vendor/plugins/blacklight/README_SOLR_rdoc.html]
226 README_SOLR.rdoc
@@ -0,0 +1,226 @@
+=Solr in Blacklight
+
+==Setting up Solr
+
+Blacklight uses Solr as its "search engine".
+More information about Solr is available at the Solr web site ( http://lucene.apache.org/solr/)
+
+There are three sections to this document:
+* Getting Solr
+* Configuring Solr
+** schema.xml
+** solrconfig.xml
+* SolrMARC
+
+=== Getting Solr
+ Create a directory for a solr distribution and download the latest Solr nightly build:
+ cd <my-new-solr-dir>
+ wget http://people.apache.org/builds/lucene/solr/nightly/solr-2009-01-27.tgz
+
+ Uncompress the file:
+ tar -xzvf solr-2009-01-27.tgz
+
+You now have a usable copy of Solr.
+
+=== Configuring Solr
+====Solr Schema.xml
+
+Solr uses a schema.xml file to define document fields (among other things). These fields store data for searching and for result display.
+You can find the example/solr/conf/schema.xml file in the Solr distribution you just downloaded and uncompressed.
+
+Documentation about the Solr schema.xml file is available at (http://wiki.apache.org/solr/SchemaXml).
+
+ The default schema.xml file comes with some preset fields made to work with
+ the example data. If you don't already have a schema.xml setup, we
+ recommend using a simplified "fields" section like this:
+ <fields>
+ <field name="id" type="string" indexed="true" stored="true" required="true" />
+ <field name="text" type="text" indexed="true" stored="false" multiValued="true"/>
+ <field name="timestamp" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
+ <field name="spell" type="textSpell" indexed="true" stored="true" multiValued="true"/>
+ <dynamicField name="*_i" type="sint" indexed="true" stored="true"/>
+ <dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true"/>
+ <dynamicField name="*_l" type="slong" indexed="true" stored="true"/>
+ <dynamicField name="*_t" type="text" indexed="true" stored="true" multiValued="true"/>
+ <dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
+ <dynamicField name="*_f" type="sfloat" indexed="true" stored="true"/>
+ <dynamicField name="*_d" type="sdouble" indexed="true" stored="true"/>
+ <dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
+ <dynamicField name="random*" type="random" />
+ <dynamicField name="*_facet" type="string" indexed="true" stored="true" multiValued="true" />
+ <dynamicField name="*_display" type="string" indexed="false" stored="true" />
+ </fields>
+
+ Simply replace the "fields" section in the schema.xml with the block above.
+
+ Additionally, replace all of the tags after the "fields" section, and before
+ the </schema> tag with this:
+ <uniqueKey>id</uniqueKey>
+ <defaultSearchField>text</defaultSearchField>
+ <solrQueryParser defaultOperator="OR"/>
+ <copyField source="*_facet" dest="text"/>
+
+ Now you have a basic schema.xml file ready. The required fields used by the
+ built in Blacklight rails views are:
+ id
+
+ Other fields are used, but specified in a configuration file: app/config/initializers/blacklight_config.rb
+
+ Fields that are "indexed" are searchable.
+
+ Fields that are "stored" are can be viewed/displayed from the Solr search
+ results.
+
+ The fields with asterisks ('*') in their names are "dynamic" fields. These
+ allow you to create arbitrary tags at index time.
+
+ The *_facet field can be used for creating your facets. When you index,
+ simply define a field with _facet on the end:
+ category_facet
+
+ The *_display field can be used for storing text that doesn't need to be
+ indexed. An example would be the raw MARC for a record's detail view:
+ raw_marc_display
+
+ For text that will be queried (and possibly displayed), use the *_t type
+ field for tokenized text (text broken into pieces/words) or the *_s type
+ for queries that should exactly match the field contents:
+ description_t
+ url_s
+
+ The Blacklight application is generic enough to work with any Solr schema, but to
+ manipulate the search results and single record displays, you'll need to know the
+ stored fields in your indexed documents.
+
+ For more information, refer to the Solr documentation:
+ http://wiki.apache.org/solr/SchemaXml
+
+
+====Solr Config.xml
+
+Solr uses the solrconfig.xml file to define searching configurations, set cache options, etc.
+You can find the examples/solr/conf/solrconfig.xml in the distribution directory you just uncompressed.
+
+Documentation about the solrconfig.xml file is available at (http://wiki.apache.org/solr/SolrConfigXml).
+
+ Blacklight expects a few things to be setup in the solrconfig.xml file,
+ namely two special request handler definitions.
+
+ You MUST set up these two request handlers.
+
+
+=====Solr Search Request Handlers
+
+ When Blacklight does a collection search, it sends a request to a Solr
+ request handler named "search". The most important settings in this handler
+ definition are the "fl" param (field list) and the facet params.
+
+ The "fl" param specifies which fields are returned in a Solr response.
+ The facet related params set up the faceting mechanism.
+
+ Find out more about the basic params:
+ http://wiki.apache.org/solr/DisMaxRequestHandler
+
+ Find out more about the faceting params:
+ http://wiki.apache.org/solr/SimpleFacetParameters
+
+
+======How the "fl" param works in Blacklight's request handlers
+
+ Blacklight comes with a set of "default" views for rendering each document
+ in a search results page. This view simply loops through all of the fields
+ returned in each document in the Solr response. The "fl" (field list) param
+ tells Solr which fields to include in the documents in the response ...
+ and these are the fields rendered in the Blacklight default views.
+ Thus, the fields you want rendered must be specified in "fl". Note that
+ only "stored" fields will be available; if you want a field to be rendered
+ in the result, it must be "stored" per the field definition in schema.xml.
+
+ The "fl" parameter definition in the "search" handler looks like this:
+ <str name="fl">*,score</str>
+
+ The asterisk could be replaced by a list of specific field names:
+ <str name="fl">id,title_display,score</str>
+
+
+======How the facet params work in Blacklight's request handlers
+
+ In the search results view, Blacklight will look into the Solr response for
+ facets. If you specify any facet.field params in your "search" handler,
+ they will automatically get displayed in the facets list:
+ <str name="facet.field">format</str>
+ <str name="facet.field">language_facet</str>
+
+
+=====Blacklight's "search" request handler: for search results
+
+ When Blacklight displays a list of search results, it uses a Solr request
+ handler named "search." Thus, the field list (fl param) for the "search"
+ request handler should be tailored to what will be displayed in a search
+ results page. Generally, this will not include fields containing a large
+ quantity of text. The facet param should contain the facets to be
+ displayed with the search results.
+
+ <requestHandler name="search" class="solr.SearchHandler" >
+ <lst name="defaults">
+ <str name="defType">dismax</str>
+ <str name="echoParams">explicit</str>
+ <!-- list fields to be returned in the "fl" param -->
+ <str name="fl">*,score</str>
+
+ <str name="facet">on</str>
+ <str name="facet.mincount">1</str>
+ <str name="facet.limit">10</str>
+
+ <!-- list fields to be displayed as facets here. -->
+ <str name="facet.field">format</str>
+ <str name="facet.field">language_facet</str>
+
+ <str name="q.alt">*:*</str>
+ </lst>
+ </requestHandler>
+
+
+=====Blacklight's "document" request handler: for a single record
+
+ When Blacklight displays a single record it uses a Solr request handler
+ named "document". The "document" handler doesn't necessarily need to be
+ different than the "search" handler, but it can be used to control which
+ fields are available to display a single document. In the example below,
+ there is no faceting set (facets are not displayed with a single record)
+ and the "rows" param is set to 1 (since there will only be a single record).
+ Also, the field list ("fl" param) could include fields containing large
+ text values if they are desired for record display. Is is acceptable to
+ include large amounts of data, because this handler should only be used
+ to query for one document:
+
+ <requestHandler name="document" class="solr.SearchHandler">
+ <lst name="defaults">
+ <str name="echoParams">explicit</str>
+ <str name="fl">*</str>
+ <str name="rows">1</str>
+ <str name="q">{!raw f=id v=$id}</str>
+ <!-- use id=blah instead of q=id:blah -->
+ </lst>
+ </requestHandler>
+
+ A Solr query for a single record might look like this:
+ http://(yourSolrBaseUrl)/solr/select?id=my_doc_id&qt=document
+
+
+====Blacklight Solr Schema and Solrconfig File Templates
+
+Blacklight provides schema.xml and solrconfig.xml files as starting points:
+
+ http://blacklight.rubyforge.org/svn/trunk/solr-templates/
+
+
+=SolrMARC: from Marc data to Solr documents
+
+The SolrMARC project is designed to create a Solr index from raw MARC data.
+It can be configured easily and used with the basic parsing and indexing
+supplied. It is also readily customized for a site's unique requirements.
+
+The project software and documentation is available at (http://code.google.com/p/solrmarc)
+
+The indexing code provided with the demo index is the GenericBlacklight example in the SolrMarc project.
59 Rakefile
@@ -0,0 +1,59 @@
+# require 'rake'
+# require 'rake/testtask'
+# require 'rake/rdoctask'
+
+require(File.join(File.dirname(__FILE__), 'config', 'boot'))
+
+require 'rake'
+#require 'rake/clean'
+require 'rake/testtask'
+require 'rake/rdoctask'
+require 'tasks/rails'
+
+# the default rake task
+desc "run migrations and call solr:spec and solr:features"
+task :default => "test"
+
+# run migrations and call solr:spec and solr:features
+desc 'run migrations and call solr:spec and solr:features'
+ task "test" => ["db:migrate", "solr:spec", "solr:features"] do
+end
+
+# Set constants used for publishing releases and rdocs
+
+# The name of your project
+PROJECT = "Blacklight"
+# Short summary of your project, used in packaging.
+PROJECT_SUMMARY = "Blacklight is open source discovery software. Libraries (or anyone else) may use blacklight to enable searching and browsing of their collections online. Blacklight uses Solr to index and search text and/or metadata, and it has a highly configurable Ruby on Rails front-end. Currently, Blacklight can index, search, and provide faceted browsing for MaRC records and several kinds of XML documents, including TEI, EAD, and GDMS. Blacklight was developed at the University of Virginia Library and is made public under an Apache 2.0 license."
+# The project's package name (as opposed to its display name). Used for
+# RubyForge connectivity and packaging.
+UNIX_NAME = "blacklight"
+# Your RubyForge user name.
+RUBYFORGE_USER = ENV["RUBYFORGE_USER"] || "eos8d"
+# Directory on RubyForge where your website's files should be uploaded.
+RUBYFORGE_PATH = "/var/www/gforge-projects/blacklight/"
+# Output directory for the rdoc html files.
+# If you don't have a custom homepage, and want to use the RDoc
+# index.html as homepage, just set it to WEBSITE_DIR.
+RDOC_HTML_DIR = "html"
+# Additional RDoc formatted files, besides the Ruby source files.
+RDOC_FILES = FileList["README.rdoc", "Changes.rdoc"]
+CURRENT_SVN_BRANCH = "http://blacklight.rubyforge.org/svn/trunk/"
+
+
+desc 'Generate documentation for the blacklight plugin.'
+Rake::RDocTask.new('rdoc') do |t|
+ t.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
+ t.main = 'README.rdoc'
+ t.title = "Blacklight API documentation"
+ t.options << '--line-numbers' << '--inline-source'
+end
+
+desc "Upload website to RubyForge. scp will prompt for your RubyForge password."
+task "publish-rdoc" => ["rdoc"] do
+ rubyforge_path = "/var/www/gforge-projects/#{UNIX_NAME}/"
+ sh "scp -r #{RDOC_HTML_DIR}/* " +
+ "#{RUBYFORGE_USER}@rubyforge.org:#{RUBYFORGE_PATH}",
+ :verbose => true
+end
+
59 app/controllers/application_controller.rb
@@ -0,0 +1,59 @@
+#
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+#
+class ApplicationController < ActionController::Base
+
+ filter_parameter_logging :password, :password_confirmation
+ helper_method :current_user_session, :current_user
+
+ def user_class; User; end
+
+ helper_method [:request_is_for_user_resource?]#, :user_logged_in?]
+ #before_filter [:set_current_user, :restrict_user_access]
+
+ # See ActionController::RequestForgeryProtection for details
+ # Uncomment the :secret if you're not using the cookie session store
+ protect_from_forgery # :secret => '200c1e5f25e610288439b479ef176bbd'
+
+ layout :choose_layout
+
+ # test for exception notifier plugin
+ def error
+ raise RuntimeError, "Generating a test error..."
+ end
+
+ protected
+
+ # Returns a list of Searches from the ids in the user's history.
+ def searches_from_history
+ session[:history].blank? ? [] : Search.find(session[:history]) rescue []
+ end
+
+ #
+ # Controller and view helper for determining if the current url is a request for a user resource
+ #
+ def request_is_for_user_resource?
+ request.env['PATH_INFO'] =~ /\/?users\/?/
+ end
+
+ #
+ # If a param[:no_layout] is set OR
+ # request.env['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest'
+ # don't use a layout, otherwise use the "application.html.erb" layout
+ #
+ def choose_layout
+ 'application' unless request.xml_http_request? || ! params[:no_layout].blank?
+ end
+
+ def current_user_session
+ return @current_user_session if defined?(@current_user_session)
+ @current_user_session = UserSession.find
+ end
+
+ def current_user
+ return @current_user if defined?(@current_user)
+ @current_user = current_user_session && current_user_session.user
+ end
+
+end
59 app/controllers/bookmarks_controller.rb
@@ -0,0 +1,59 @@
+class BookmarksController < ApplicationController
+
+ # see vendor/plugins/resource_controller/
+ resource_controller
+
+ # acts_as_taggable_on_steroids plugin
+ helper TagsHelper
+
+ before_filter :verify_user, :except => :index
+
+ # overrides the ResourceController collection method
+ # see vendor/plugins/resource_controller/
+ def collection
+ user_id = current_user ? current_user.id : nil
+ assocations = nil
+ conditions = ['user_id = ?', user_id]
+ if params[:a] == 'find' && ! params[:q].blank?
+ q = "%#{params[:q]}%"
+ conditions.first << ' AND (tags.name LIKE ? OR title LIKE ? OR notes LIKE ?)'
+ conditions += [q, q, q]
+ assocations = [:tags]
+ end
+ Bookmark.paginate_by_tag(params[:tag], :per_page => 8, :page => params[:page], :order => 'bookmarks.id ASC', :conditions => conditions, :include => assocations)
+ end
+
+ update.wants.html { redirect_to :back }
+
+ def create
+ if current_user.bookmarks.create(params[:bookmark])
+ flash[:notice] = "Successfully added bookmark."
+ else
+ flash[:error] = "There was a problem adding that bookmark."
+ end
+ redirect_to :back
+ end
+
+ def destroy
+ if current_user.bookmarks.delete(Bookmark.find(params[:id]))
+ flash[:notice] = "Successfully removed that bookmark."
+ else
+ flash[:error] = "Couldn't remove that bookmark."
+ end
+ redirect_to :back
+ end
+
+ def clear
+ if current_user.bookmarks.clear
+ flash[:notice] = "Cleared your bookmarks."
+ else
+ flash[:error] = "There was a problem clearing your bookmarks."
+ end
+ redirect_to :action => "index"
+ end
+
+ protected
+ def verify_user
+ flash[:error] = "Please log in to manage and view your bookmarks." and redirect_to :back unless current_user
+ end
+end
205 app/controllers/catalog_controller.rb
@@ -0,0 +1,205 @@
+class CatalogController < ApplicationController
+
+ include Blacklight::SolrHelper
+
+ before_filter :search_session, :history_session
+ before_filter :delete_or_assign_search_session_params, :only=>:index
+ after_filter :set_additional_search_session_values, :only=>:index
+
+ # Whenever an action raises SolrHelper::InvalidSolrID, this block gets executed.
+ # Hint: the SolrHelper #get_solr_response_for_doc_id method raises this error,
+ # which is used in the #show action here.
+ rescue_from InvalidSolrID, :with => lambda {
+ # when a request for /catalog/BAD_SOLR_ID is made, this method is executed...
+ flash[:notice] = "Sorry, you seem to have encountered an error."
+ redirect_to catalog_index_path
+ }
+
+ # When RSolr::RequestError is raised, this block is executed.
+ # The index action will more than likely throw this one.
+ # Example, when the standard query parser is used, and a user submits a "bad" query.
+ rescue_from RSolr::RequestError, :with => lambda {
+ # when solr (RSolr) throws an error (RSolr::RequestError), this method is executed.
+ flash[:notice] = "Sorry, I don't understand your search."
+ redirect_to catalog_index_path
+ }
+
+ # get search results from the solr index
+ def index
+ @response = get_search_results
+ @filters = params[:f] || []
+ respond_to do |format|
+ format.html { save_current_search_params }
+ format.rss { render :layout => false }
+ end
+ end
+
+ # get single document from the solr index
+ def show
+ @response = get_solr_response_for_doc_id
+ @document = SolrDocument.new(@response.docs.first)
+ respond_to do |format|
+ format.html {setup_next_and_previous_documents}
+ format.xml {render :xml => @document.marc.to_xml}
+ format.refworks
+ format.endnote
+ end
+ end
+
+ # updates the search counter (allows the show view to paginate)
+ def update
+ session[:search][:counter] = params[:counter]
+ redirect_to :action => "show"
+ end
+
+ # displays values and pagination links for a single facet field
+ def facet
+ @pagination = get_facet_pagination(params[:id], params)
+ end
+
+ # single document image resource
+ def image
+ end
+
+ # single document availability status (true/false)
+ def status
+ end
+
+ # single document availability info
+ def availability
+ end
+
+ # collection/search UI via Google maps
+ def map
+ end
+
+ # method to serve up XML OpenSearch description and JSON autocomplete response
+ def opensearch
+ respond_to do |format|
+ format.xml do
+ render :layout => false
+ end
+ format.json do
+ render :json => get_opensearch_response
+ end
+ end
+ end
+
+ # citation action
+ def citation
+ @response = get_solr_response_for_doc_id
+ @document = SolrDocument.new(@response.docs.first)
+ end
+ # Email Action (this will only be accessed when the Email link is clicked by a non javascript browser)
+ def email
+ @response = get_solr_response_for_doc_id
+ @document = SolrDocument.new(@response.docs.first)
+ end
+ # SMS action (this will only be accessed when the SMS link is clicked by a non javascript browser)
+ def sms
+ @response = get_solr_response_for_doc_id
+ @document = SolrDocument.new(@response.docs.first)
+ end
+
+ # action for sending email. This is meant to post from the form and to do processing
+ def send_email_record
+ @response = get_solr_response_for_doc_id
+ @document = SolrDocument.new(@response.docs.first)
+ if params[:to]
+ from = request.host # host w/o port for From address (from address cannot have port#)
+ host = request.host
+ host << ":#{request.port}" unless request.port.nil? # host w/ port for linking
+ case params[:style]
+ when 'sms'
+ if !params[:carrier].blank?
+ if params[:to].length != 10
+ flash[:error] = "You must enter a valid 10 digit phone number"
+ else
+ email = RecordMailer.create_sms_record(@document, {:to => params[:to], :carrier => params[:carrier]}, from, host)
+ end
+ else
+ flash[:error] = "You must select a carrier"
+ end
+ when 'email'
+ if params[:to].match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
+ email = RecordMailer.create_email_record(@document, {:to => params[:to], :message => params[:message]}, from, host)
+ else
+ flash[:error] = "You must enter a valid email address"
+ end
+ end
+ RecordMailer.deliver(email) unless flash[:error]
+ redirect_to catalog_path(@document.id)
+ else
+ flash[:error] = "You must enter a recipient in order to send this message"
+ end
+ end
+
+ protected
+
+ #
+ # non-routable methods ->
+ #
+
+ # calls setup_previous_document then setup_next_document.
+ # used in the show action for single view pagination.
+ def setup_next_and_previous_documents
+ setup_previous_document
+ setup_next_document
+ end
+
+ # gets a document based on its position within a resultset
+ def setup_document_by_counter(counter)
+ return if counter < 1 || session[:search].blank?
+ search = session[:search] || {}
+ get_single_doc_via_search(search.merge({:page => counter}))
+ end
+
+ def setup_previous_document
+ @previous_document = session[:search][:counter] ? setup_document_by_counter(session[:search][:counter].to_i - 1) : nil
+ end
+
+ def setup_next_document
+ @next_document = session[:search][:counter] ? setup_document_by_counter(session[:search][:counter].to_i + 1) : nil
+ end
+
+ # sets up the session[:search] hash if it doesn't already exist
+ def search_session
+ session[:search] ||= {}
+ end
+
+ # sets up the session[:history] hash if it doesn't already exist.
+ # assigns all Search objects (that match the searches in session[:history]) to a variable @searches.
+ def history_session
+ session[:history] ||= []
+ @searches = searches_from_history # <- in ApplicationController
+ end
+
+ # This method will remove certain params from the session[:search] hash
+ # if the values are blank? (nil or empty string)
+ # if the values aren't blank, they are saved to the session in the :search hash.
+ def delete_or_assign_search_session_params
+ [:q, :qt, :f, :per_page, :page, :sort].each do |pname|
+ params[pname].blank? ? session[:search].delete(pname) : session[:search][pname] = params[pname]
+ end
+ end
+
+ # Saves the current search (if it does not already exist) as a models/search object
+ # then adds the id of the serach object to session[:history]
+ def save_current_search_params
+ return if search_session[:q].blank? && search_session[:f].blank?
+ params_copy = search_session.clone # don't think we need a deep copy for this
+ params_copy.delete(:page)
+ unless @searches.collect { |search| search.query_params }.include?(params_copy)
+ new_search = Search.create(:query_params => params_copy)
+ session[:history].unshift(new_search.id)
+ end
+ end
+
+ # sets some additional search metadata so that the show view can display it.
+ def set_additional_search_session_values
+ unless @response.nil?
+ search_session[:total] = @response.total
+ end
+ end
+
+end
37 app/controllers/feedback_controller.rb
@@ -0,0 +1,37 @@
+class FeedbackController < ApplicationController
+
+ # http://expressica.com/simple_captcha/
+ # include SimpleCaptcha::ControllerHelpers
+
+ # show the feedback form
+ def show
+ @errors=[]
+ if request.method==:post
+ if validate
+ Notifier.deliver_feedback(params)
+ redirect_to feedback_complete_path
+ end
+ end
+ end
+
+ protected
+
+ # validates the incoming params
+ # returns either an empty array or an array with error messages
+ def validate
+ unless params[:name] =~ /\w+/
+ @errors << 'A valid name is required'
+ end
+ unless params[:email] =~ /\w+@\w+\.\w+/
+ @errors << 'A valid email address is required'
+ end
+ unless params[:message] =~ /\w+/
+ @errors << 'A message is required'
+ end
+ #unless simple_captcha_valid?
+ # @errors << 'Captcha did not match'
+ #end
+ @errors.empty?
+ end
+
+end
44 app/controllers/saved_searches_controller.rb
@@ -0,0 +1,44 @@
+class SavedSearchesController < ApplicationController
+ before_filter :verify_user, :except => :index
+
+ def index
+ @searches = current_user ? Search.find_all_by_user_id(current_user.id) : []
+ end
+
+ def save
+ if Search.update(params[:id], :user_id => current_user.id)
+ flash[:notice] = "Successfully saved your search."
+ else
+ flash[:error] = "The was a problem saving your search."
+ end
+ redirect_to :back
+ end
+
+ # Only dereferences the user rather than removing the item in case it
+ # is in the session[:history]
+ def destroy
+ if current_user.search_ids.include?(params[:id].to_i) && Search.update(params[:id].to_i, :user_id => nil)
+ flash[:notice] = "Successfully removed that saved search."
+ else
+ flash[:error] = "Couldn't remove that saved search."
+ end
+ redirect_to :back
+ end
+
+ # Only dereferences the user rather than removing the items in case they
+ # are in the session[:history]
+ def clear
+ if Search.update_all("user_id = NULL", "user_id = #{current_user.id}")
+ flash[:notice] = "Cleared your saved searches."
+ else
+ flash[:error] = "There was a problem clearing your saved searches."
+ end
+ redirect_to :action => "index"
+ end
+
+
+ protected
+ def verify_user
+ flash[:error] = "Please log in to manage and view your saved searches." and redirect_to :back unless current_user
+ end
+end
25 app/controllers/search_history_controller.rb
@@ -0,0 +1,25 @@
+class SearchHistoryController < ApplicationController
+ def index
+ @searches = searches_from_history
+ end
+
+ #TODO we may want to remove unsaved (those without user_id) items from the database when removed from history
+ def destroy
+ if session[:history].delete_at(params[:id].to_i)
+ flash[:notice] = "Successfully removed that search history item."
+ else
+ flash[:error] = "Couldn't remove that search history item."
+ end
+ redirect_to :back
+ end
+
+ #TODO we may want to remove unsaved (those without user_id) items from the database when removed from history
+ def clear
+ if session[:history].clear
+ flash[:notice] = "Cleared your search history."
+ else
+ flash[:error] = "There was a problem clearing your search history."
+ end
+ redirect_to :back
+ end
+end
43 app/controllers/user_sessions_controller.rb
@@ -0,0 +1,43 @@
+class UserSessionsController < ApplicationController
+# before_filter :require_no_user, :only => [:new, :create]
+# before_filter :require_user, :only => :destroy
+
+# def create
+# if user = User.authenticate(params[:email], params[:password])
+# self.current_user = user
+# user.update_attribute(:last_login, Time.now)
+# flash[:notice] = "Welcome #{user.login}!"
+# redirect_to root_path
+# else
+# flash.now[:error] = "Couldn't locate a user with those credentials"
+# render :action => :new
+# end
+# end
+#
+# def destroy
+# session[:user_id] = nil
+# flash[:notice] = "You have successfully logged out."
+# redirect_to root_path
+# end
+
+ def new
+ @user_session = UserSession.new
+ end
+
+ def create
+ @user_session = UserSession.new(params[:user_session])
+ if @user_session.save
+ flash[:notice] = "Welcome #{@user_session.login}!"
+ redirect_to root_path
+ else
+ flash.now[:error] = "Couldn't locate a user with those credentials"
+ render :action => :new
+ end
+ end
+
+ def destroy
+ current_user_session.destroy
+ flash[:notice] = "You have successfully logged out."
+ redirect_to root_path
+ end
+end
13 app/controllers/users_controller.rb
@@ -0,0 +1,13 @@
+class UsersController < ApplicationController
+
+ # see vendor/plugins/resource_controller
+ resource_controller :singleton
+
+ create.flash { "Welcome #{@user.login}!"}
+
+ protected
+ def object
+ @object ||= current_user
+ end
+
+end
362 app/helpers/application_helper.rb
@@ -0,0 +1,362 @@
+#
+# Methods added to this helper will be available to all templates in the application.
+#
+module ApplicationHelper
+
+ def application_name
+ 'Blacklight'
+ end
+
+ # collection of items to be rendered in the @sidebar
+ def sidebar_items
+ @sidebar_items ||= []
+ end
+
+ #
+ # Blacklight.config based helpers ->
+ #
+
+ # used in the catalog/_facets partial
+ def facet_field_labels
+ Blacklight.config[:facet][:labels]
+ end
+
+ # used in the catalog/_facets partial
+ def facet_field_names
+ Blacklight.config[:facet][:field_names]
+ end
+
+ # used in the catalog/_index_partials/_default view
+ def index_field_names
+ Blacklight.config[:index_fields][:field_names]
+ end
+
+ # used in the _index_partials/_default view
+ def index_field_labels
+ Blacklight.config[:index_fields][:labels]
+ end
+
+ # Used in the show view for displaying the main solr document heading
+ def document_heading
+ @document[Blacklight.config[:show][:heading]]
+ end
+
+ # Used in the show view for setting the main html document title
+ def document_show_html_title
+ @document[Blacklight.config[:show][:html_title]]
+ end
+
+ # Used in the document_list partial (search view) for building a select element
+ def sort_fields
+ Blacklight.config[:sort_fields]
+ end
+
+ # Used in the document list partial (search view) for creating a link to the document show action
+ def document_show_link_field
+ Blacklight.config[:index][:show_link].to_sym
+ end
+
+ # Used in the search form partial for building a select tag
+ def search_fields
+ Blacklight.config[:search_fields]
+ end
+
+ # used in the catalog/_show/_default partial
+ def document_show_fields
+ Blacklight.config[:show_fields][:field_names]
+ end
+
+ # used in the catalog/_show/_default partial
+ def document_show_field_labels
+ Blacklight.config[:show_fields][:labels]
+ end
+
+ # currently only used by the render_document_partial helper method (below)
+ def document_partial_name(document)
+ document[Blacklight.config[:show][:display_type]]
+ end
+
+ # given a doc and action_name, this method attempts to render a partial template
+ # based on the value of doc[:format]
+ # if this value is blank (nil/empty) the "default" is used
+ # if the partial is not found, the "default" partial is rendered instead
+ def render_document_partial(doc, action_name)
+ format = document_partial_name(doc)
+ begin
+ render :partial=>"catalog/_#{action_name}_partials/#{format}", :locals=>{:document=>doc}
+ rescue ActionView::MissingTemplate
+ render :partial=>"catalog/_#{action_name}_partials/default", :locals=>{:document=>doc}
+ end
+ end
+
+ # Search History and Saved Searches display
+ def link_to_previous_search(params)
+ query_part = params[:qt] == Blacklight.config[:default_qt] ? params[:q] : "#{params[:qt]}:(#{params[:q]})"
+ facet_part =
+ if params[:f]
+ tmp =
+ params[:f].collect do |pair|
+ "#{Blacklight.config[:facet][:labels][pair.first]}:#{pair.last}"
+ end.join(" AND ")
+ "{#{tmp}}"
+ else
+ ""
+ end
+ link_to("#{query_part} #{facet_part}", catalog_index_path(params))
+ end
+
+ #
+ # Export Helpers
+ #
+ def render_refworks_text(record)
+ if record.marc.marc
+ fields = record.marc.marc.find_all { |f| ('000'..'999') === f.tag }
+ text = "LEADER #{record.marc.marc.leader}"
+ fields.each do |field|
+ unless ["940","999"].include?(field.tag)
+ if field.is_a?(MARC::ControlField)
+ text << "#{field.tag} #{field.value}\n"
+ else
+ text << "#{field.tag} "
+ text << (field.indicator1 ? field.indicator1 : " ")
+ text << (field.indicator2 ? field.indicator2 : " ")
+ text << " "
+ field.each {|s| s.code == 'a' ? text << "#{s.value}" : text << " |#{s.code}#{s.value}"}
+ text << "\n"
+ end
+ end
+ end
+ text
+ end
+ end
+ def render_endnote_text(record)
+ end_note_format = {
+ "%A" => "100.a",
+ "%C" => "260.a",
+ "%D" => "260.c",
+ "%E" => "700.a",
+ "%I" => "260.b",
+ "%J" => "440.a",
+ "%@" => "020.a",
+ "%_@" => "022.a",
+ "%T" => "245.a,245.b",
+ "%U" => "856.u",
+ "%7" => "250.a"
+ }
+ marc = record.marc.marc
+ text = ''
+ text << "%0 #{document_partial_name(record)}\n"
+ # If there is some reliable way of getting the language of a record we can add it here
+ #text << "%G #{record['language'].first}\n"
+ end_note_format.each do |key,value|
+ values = value.split(",")
+ first_value = values[0].split('.')
+ if values.length > 1
+ second_value = values[1].split('.')
+ else
+ second_value = []
+ end
+
+ if marc[first_value[0].to_s]
+ marc.find_all{|f| (first_value[0].to_s) === f.tag}.each do |field|
+ if field[first_value[1]].to_s or field[second_value[1]].to_s
+ text << "#{key.gsub('_','')}"
+ if field[first_value[1]].to_s
+ text << " #{field[first_value[1]].to_s}"
+ end
+ if field[second_value[1]].to_s
+ text << " #{field[second_value[1]].to_s}"
+ end
+ text << "\n"
+ end
+ end
+ end
+ end
+ text
+ end
+
+ #
+ # facet param helpers ->
+ #
+
+ # adds the value and/or field to params[:f]
+ def add_facet_params(field, value)
+ p = params.dup
+ p.delete :page
+ p[:f]||={}
+ p[:f][field] ||= []
+ p[:f][field].push(value)
+ p
+ end
+
+ # copies the current params (or whatever is passed in as the 3rd arg)
+ # removes the field value from params[:f]
+ # removes the field if there are no more values in params[:f][field]
+ # removes additional params (page, id, etc..)
+ def remove_facet_params(field, value, source_params=params)
+ p = source_params.dup.symbolize_keys!
+ # need to dup the facet values too,
+ # if the values aren't dup'd, then the values
+ # from the session will get remove in the show view...
+ p[:f] = p[:f].dup.symbolize_keys!
+ p.delete :page
+ p.delete :id
+ p.delete :counter
+ p.delete :commit
+ #return p unless p[field]
+ p[:f][field] = p[:f][field] - [value]
+ p[:f].delete(field) if p[:f][field].size == 0
+ p
+ end
+
+ # true or false, depending on whether the field and value is in params[:f]
+ def facet_in_params?(field, value)
+ params[:f] and params[:f][field] and params[:f][field].include?(value)
+ end
+
+ # NOTE: as of 2009-04-20, this is only used for facet.html.erb, which
+ # is facet pagination ... and it probably shouldn't be used there.
+ # creates a formatted label for a field (removes _facet and _display etc.)
+ def field_label(field)
+ @__field_label_cache ||= {}
+ @__field_label_cache[field] ||= field.to_s.sub(/_facet$|_display$|_[a-z]$/,'').gsub(/_/,' ')
+ @__field_label_cache[field]
+ end
+
+ #
+ # shortcut for built-in Rails helper, "number_with_delimiter"
+ #
+ def format_num(num); number_with_delimiter(num) end
+
+ #
+ # link based helpers ->
+ #
+
+ # create link to query (e.g. spelling suggestion)
+ def link_to_query(query)
+ p = params.dup
+ p.delete :page
+ p.delete :action
+ p[:q]=query
+ link_url = catalog_index_path(p)
+ link_to(query, link_url)
+ end
+
+ # link_to_document(doc, :label=>'VIEW', :counter => 3)
+ # Use the catalog_path RESTful route to create a link to the show page for a specific item.
+ # catalog_path accepts a HashWithIndifferentAccess object. The solr query params are stored in the session,
+ # so we only need the +counter+ param here.
+ def link_to_document(doc, opts={:label=>Blacklight.config[:index][:show_link].to_sym, :counter => nil})
+ label = case opts[:label]
+ when Symbol
+ doc.get(opts[:label])
+ when String
+ opts[:label]
+ else
+ raise 'Invalid label argument'
+ end
+ link_to_with_data(label, catalog_path(doc[:id]), {:method => :put, :data => {:counter => opts[:counter]}})
+ end
+
+ # link_back_to_catalog(:label=>'Back to Search')
+ # Create a link back to the index screen, keeping the user's facet, query and paging choices intact by using session.
+ def link_back_to_catalog(opts={:label=>'Back to Search'})
+ query_params = session[:search].dup || {}
+ query_params.delete :counter
+ query_params.delete :total
+ link_url = catalog_index_path(query_params)
+ link_to opts[:label], link_url
+ end
+
+ def link_to_previous_document(previous_document)
+ return if previous_document == nil
+ link_to_document previous_document, :label=>'< Previous', :counter => session[:search][:counter].to_i - 1
+ end
+
+ def link_to_next_document(next_document)
+ return if next_document == nil
+ link_to_document next_document, :label=>'Next >', :counter => session[:search][:counter].to_i + 1
+ end
+
+
+ # This is an updated +link_to+ that allows you to pass a +data+ hash along with the +html_options+
+ # which are then written to the generated form for non-GET requests. The key is the form element name
+ # and the value is the value:
+ #
+ # link_to_with_data('Name', some_path(some_id), :method => :post, :html)
+ def link_to_with_data(*args, &block)
+ if block_given?
+ options = args.first || {}
+ html_options = args.second
+ concat(link_to(capture(&block), options, html_options))
+ else
+ name = args.first
+ options = args.second || {}
+ html_options = args.third
+
+ url = url_for(options)
+
+ if html_options
+ html_options = html_options.stringify_keys
+ href = html_options['href']
+ convert_options_to_javascript_with_data!(html_options, url)
+ tag_options = tag_options(html_options)
+ else
+ tag_options = nil
+ end
+
+ href_attr = "href=\"#{url}\"" unless href
+ "<a #{href_attr}#{tag_options}>#{h(name) || h(url)}</a>"
+ end
+ end
+
+ # This is derived from +convert_options_to_javascript+ from module +UrlHelper+ in +url_helper.rb+
+ def convert_options_to_javascript_with_data!(html_options, url = '')
+ confirm, popup = html_options.delete("confirm"), html_options.delete("popup")
+
+ method, href = html_options.delete("method"), html_options['href']
+ data = html_options.delete("data")
+ data = data.stringify_keys if data
+
+ html_options["onclick"] = case
+ when method
+ "#{method_javascript_function_with_data(method, url, href, data)}return false;"
+ else
+ html_options["onclick"]
+ end
+ end
+
+ # This is derived from +method_javascript_function+ from module +UrlHelper+ in +url_helper.rb+
+ def method_javascript_function_with_data(method, url = '', href = nil, data=nil)
+ action = (href && url.size > 0) ? "'#{url}'" : 'this.href'
+ submit_function =
+ "var f = document.createElement('form'); f.style.display = 'none'; " +
+ "this.parentNode.appendChild(f); f.method = 'POST'; f.action = #{action};"
+
+ if data
+ data.each_pair do |key, value|
+ submit_function << "var d = document.createElement('input'); d.setAttribute('type', 'hidden'); "
+ submit_function << "d.setAttribute('name', '#{key}'); d.setAttribute('value', '#{value}'); f.appendChild(d);"
+ end
+ end
+ unless method == :post
+ submit_function << "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); "
+ submit_function << "m.setAttribute('name', '_method'); m.setAttribute('value', '#{method}'); f.appendChild(m);"
+ end
+
+ if protect_against_forgery?
+ submit_function << "var s = document.createElement('input'); s.setAttribute('type', 'hidden'); "
+ submit_function << "s.setAttribute('name', '#{request_forgery_protection_token}'); s.setAttribute('value', '#{escape_javascript form_authenticity_token}'); f.appendChild(s);"
+ end
+ submit_function << "f.submit();"
+ end
+
+ # performs an XSLT transform
+ def xslt(stylesheet_file_path, document, params={})
+ require 'nokogiri'
+ document = Nokogiri::XML(document) if document.is_a?(String)
+ stylesheet = Nokogiri::XSLT.parse(render(stylesheet_file_path))
+ stylesheet.apply_to(Nokogiri::XML(document.to_xml), params)
+ end
+
+end
3 app/helpers/bookmarks_helper.rb
@@ -0,0 +1,3 @@
+module BookmarksHelper
+
+end
44 app/helpers/catalog_helper.rb
@@ -0,0 +1,44 @@
+module CatalogHelper
+
+ #
+ # shortcut for built-in Rails helper, "number_with_delimiter"
+ #
+ def format_num(num); number_with_delimiter(num) end
+
+ #
+ #
+ #
+ def page_entries_info(collection, options = {})
+ start = collection.next_page == 2 ? 1 : collection.previous_page * collection.per_page + 1
+ total_hits = @response.total
+ start_num = format_num(start)
+ end_num = format_num(start + collection.per_page - 1)
+ total_num = format_num(total_hits)
+
+ entry_name = options[:entry_name] ||
+ (collection.empty?? 'entry' : collection.first.class.name.underscore.sub('_', ' '))
+
+ if collection.total_pages < 2
+ case collection.size
+ when 0; "No #{entry_name.pluralize} found"
+ when 1; "Displaying <b>1</b> #{entry_name}"
+ else; "Displaying <b>all #{total_num}</b> #{entry_name.pluralize}"
+ end
+ else
+ "Displaying #{entry_name.pluralize} <b>#{start_num} - #{end_num}</b> of <b>#{total_num}</b>"
+ end
+ end
+
+ # Look up search field user-displayable label
+ # based on params[:qt] and configuration.
+ # Return "Keyword" if not found.
+ def search_field_label(params)
+ if ( (! params[:qt].blank?) &&
+ pair = search_fields.find {|pair| pair[1] == params[:qt] })
+ h(pair[0])
+ else
+ "Keyword"
+ end
+ end
+
+end
2 app/helpers/feedback_helper.rb
@@ -0,0 +1,2 @@
+module FeedbackHelper
+end
2 app/helpers/saved_searches_helper.rb
@@ -0,0 +1,2 @@
+module SavedSearchesHelper
+end
2 app/helpers/search_history_helper.rb
@@ -0,0 +1,2 @@
+module SearchHistoryHelper
+end
2 app/helpers/user_sessions_helper.rb
@@ -0,0 +1,2 @@
+module UserSessionsHelper
+end
2 app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
+module UsersHelper
+end
7 app/models/bookmark.rb
@@ -0,0 +1,7 @@
+class Bookmark < ActiveRecord::Base
+
+ acts_as_taggable
+ belongs_to :user
+ validates_presence_of :user_id, :scope=>:document_id
+
+end
30 app/models/record_mailer.rb
@@ -0,0 +1,30 @@
+class RecordMailer < ActionMailer::Base
+ def email_record(document, details, from_host, host)
+ recipients details[:to]
+ subject "Item Record: #{document.marc.marc['245']['a'] rescue 'N/A'}"
+ from "no-reply@" << from_host
+ body :document => document, :host => host, :message => details[:message]
+ end
+
+ def sms_record(document, details, from_host, host)
+ if sms_mapping[details[:carrier]]
+ to = "#{details[:to]}@#{sms_mapping[details[:carrier]]}"
+ end
+ recipients to
+ from "no-reply@" << from_host
+ body :document => document, :host => host
+ end
+
+ protected
+
+ def sms_mapping
+ {'virgin' => 'vmobl.com',
+ 'att' => 'txt.att.net',
+ 'verizon' => 'vtext.com',
+ 'nextel' => 'messaging.nextel.com',
+ 'sprint' => 'messaging.sprintpcs.com',
+ 'tmobile' => 'tmomail.net',
+ 'alltel' => 'message.alltel.com',
+ 'cricket' => 'mms.mycricket.com'}
+ end
+end
12 app/models/search.rb
@@ -0,0 +1,12 @@
+class Search < ActiveRecord::Base
+
+ belongs_to :user
+
+ serialize :query_params
+
+ # A Search instance is considered a saved search if it has a user_id.
+ def saved?
+ self.user_id?
+ end
+
+end
7 app/models/solr_document.rb
@@ -0,0 +1,7 @@
+class SolrDocument
+
+ include Blacklight::Solr::Document
+ include Blacklight::Solr::Document::Marc
+ include Blacklight::Solr::Document::EAD
+
+end
46 app/models/user.rb
@@ -0,0 +1,46 @@
+class User < ActiveRecord::Base
+
+ acts_as_authentic do |config|
+ #config.my_config_option = my_value
+ #config.transition_from_crypto_providers = Authlogic::CryptoProviders::BCrypt
+ end
+
+ has_many :searches, :dependent => :destroy
+
+ validates_presence_of :email
+ validates_uniqueness_of :email
+
+ validates_presence_of :password, :on => :create
+ validates_confirmation_of :password
+
+ validates_presence_of :login
+ validates_uniqueness_of :login
+
+ has_many :bookmarks, :dependent => :destroy
+
+ def to_s; login; end
+
+ def has_bookmarks?; bookmarks.count > 0; end
+
+ #
+ # Does this user actually exist in the db?
+ #
+ def is_real?
+ self.class.count(:conditions=>['id = ?',self.id]) == 1
+ end
+
+ def bookmarked_document_ids
+ self.bookmarks.map{|bm|bm.document_id}
+ end
+
+ def document_is_bookmarked?(document_id)
+ bookmarked_document_ids.include? document_id
+ end
+
+ def documents_to_bookmark=(docs)
+ docs.each do |doc|
+ self.bookmarks.create(doc) unless bookmarked_document_ids.include?(doc[:document_id])
+ end
+ end
+
+end
4 app/models/user_session.rb
@@ -0,0 +1,4 @@
+class UserSession < Authlogic::Session::Base
+
+
+end
6 app/views/_flash_msg.html.erb
@@ -0,0 +1,6 @@
+<% if flash_notice = flash[:notice] %>
+ <div class="notice"><%= flash_notice %></div>
+<% end %>
+<% if flash_error = flash[:error] %>
+ <div class="error"><%= flash_error %></div>
+<% end %>
11 app/views/_user_util_links.html.erb
@@ -0,0 +1,11 @@
+<% if current_user %>
+ <%= link_to "Log Out", logout_path %> [<%= link_to current_user.login, user_path(current_user) %>]
+ <% if current_user.last_search_url %>
+ | <%= link_to('View your last search', catalog_index_path(current_user.last_search_url)) %><% end %> |
+ <%= link_to 'Your Bookmarks', bookmarks_path %> |
+ <%= link_to "Saved Searches", saved_searches_path %>
+<% else %>
+ <%= link_to 'Login', login_path %>
+<% end %>
+|
+<%= link_to "Search History", search_history_index_path %>
33 app/views/bookmarks/edit.html.erb
@@ -0,0 +1,33 @@
+<h2>Editing Bookmark for "<%= link_to @bookmark.title, catalog_path(@bookmark.document_id) %>"</h2>
+
+<% sidebar_items << capture do %>
+ <%= link_to '<< back to my bookmarks', bookmarks_path %>
+<% end %>
+
+<% form_for @bookmark, :url => bookmark_path do |f| %>
+
+ <fieldset>
+
+ <div