hydra-head 3.0.0pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. data/.gitignore +71 -0
  2. data/.gitmodules +6 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +257 -0
  5. data/README.textile +150 -0
  6. data/README_RAILS3_CHANGES.textile +42 -0
  7. data/Rakefile +5 -0
  8. data/TESTING.textile +85 -0
  9. data/app/controllers/assets_controller.rb +117 -0
  10. data/app/controllers/contributors_controller.rb +54 -0
  11. data/app/controllers/file_assets_controller.rb +152 -0
  12. data/app/controllers/permissions_controller.rb +137 -0
  13. data/app/controllers/user_sessions_controller.rb +14 -0
  14. data/app/helpers/article_metadata_helper.rb +80 -0
  15. data/app/helpers/blacklight_helper.rb +192 -0
  16. data/app/helpers/downloads_helper.rb +19 -0
  17. data/app/helpers/generic_content_objects_helper.rb +16 -0
  18. data/app/helpers/hydra_assets_helper.rb +75 -0
  19. data/app/helpers/hydra_djatoka_helper.rb +23 -0
  20. data/app/helpers/hydra_fedora_metadata_helper.rb +365 -0
  21. data/app/helpers/hydra_helper.rb +155 -0
  22. data/app/helpers/hydra_uploader_helper.rb +18 -0
  23. data/app/helpers/inline_editable_metadata_helper.rb +15 -0
  24. data/app/helpers/javascript_includes_helper.rb +93 -0
  25. data/app/helpers/release_process_helper.rb +32 -0
  26. data/app/models/audio_asset.rb +8 -0
  27. data/app/models/file_asset.rb +111 -0
  28. data/app/models/generic_content.rb +21 -0
  29. data/app/models/generic_image.rb +62 -0
  30. data/app/models/image_asset.rb +8 -0
  31. data/app/models/mods_asset.rb +6 -0
  32. data/app/models/role_mapper.rb +22 -0
  33. data/app/models/superuser.rb +6 -0
  34. data/app/models/video_asset.rb +8 -0
  35. data/app/views/_add_assets_links.html.erb +13 -0
  36. data/app/views/_brown_sidebar.html +15 -0
  37. data/app/views/_user_util_links.html.erb +31 -0
  38. data/app/views/catalog/_citation.html.erb +11 -0
  39. data/app/views/catalog/_constraints_element.html.erb +34 -0
  40. data/app/views/catalog/_delete_partials/_default.html.erb +29 -0
  41. data/app/views/catalog/_document_list.html.erb +11 -0
  42. data/app/views/catalog/_edit_partials/_default.html.erb +64 -0
  43. data/app/views/catalog/_edit_partials/_default_details.html.erb +15 -0
  44. data/app/views/catalog/_email_form.html.erb +9 -0
  45. data/app/views/catalog/_facets.html.erb +37 -0
  46. data/app/views/catalog/_flash_msg.html.erb +17 -0
  47. data/app/views/catalog/_home.html.erb +6 -0
  48. data/app/views/catalog/_home_text.html.erb +10 -0
  49. data/app/views/catalog/_index_partials/_default.html.erb +20 -0
  50. data/app/views/catalog/_index_partials/_default_details.html.erb +11 -0
  51. data/app/views/catalog/_index_partials/_default_group.html.erb +15 -0
  52. data/app/views/catalog/_search_form.html.erb +12 -0
  53. data/app/views/catalog/_show_partials/_default.html.erb +23 -0
  54. data/app/views/catalog/_show_partials/_default_details.html.erb +12 -0
  55. data/app/views/catalog/_show_partials/_facets.html.erb +52 -0
  56. data/app/views/catalog/_sms_form.html.erb +21 -0
  57. data/app/views/catalog/_sort_and_per_page.html.erb +22 -0
  58. data/app/views/catalog/_uva_tabs.html.erb +10 -0
  59. data/app/views/catalog/about.html.erb +0 -0
  60. data/app/views/catalog/show.html.erb +48 -0
  61. data/app/views/contributors/_add_contributor_split_button.html.erb +10 -0
  62. data/app/views/contributors/_edit_conference.html.erb +29 -0
  63. data/app/views/contributors/_edit_organization.html.erb +29 -0
  64. data/app/views/contributors/_edit_person.html.erb +42 -0
  65. data/app/views/contributors/_index.html.erb +12 -0
  66. data/app/views/contributors/_new.html.erb +10 -0
  67. data/app/views/contributors/_show_conference.html.erb +22 -0
  68. data/app/views/contributors/_show_organization.html.erb +29 -0
  69. data/app/views/contributors/_show_person.html.erb +17 -0
  70. data/app/views/contributors/new.html.erb +13 -0
  71. data/app/views/downloads/index.html.erb +1 -0
  72. data/app/views/file_assets/_deletable_result.html.erb +5 -0
  73. data/app/views/file_assets/_index.html.erb +15 -0
  74. data/app/views/file_assets/_new.html.erb +2 -0
  75. data/app/views/file_assets/_result.html.erb +16 -0
  76. data/app/views/file_assets/index.html.erb +5 -0
  77. data/app/views/fluid_infusion/_uploader.html.erb +81 -0
  78. data/app/views/fluid_infusion/_uploader_generic_content_objects.js.erb +38 -0
  79. data/app/views/fluid_infusion/_uploader_js.erb +45 -0
  80. data/app/views/generic_content_objects/_edit_description.html.erb +50 -0
  81. data/app/views/generic_content_objects/_new.html.erb +0 -0
  82. data/app/views/generic_content_objects/_show_description.html.erb +68 -0
  83. data/app/views/generic_content_objects/contributors/_edit_conference.html.erb +29 -0
  84. data/app/views/generic_content_objects/contributors/_edit_organization.html.erb +29 -0
  85. data/app/views/generic_content_objects/contributors/_edit_person.html.erb +37 -0
  86. data/app/views/generic_content_objects/contributors/_new.html.erb +10 -0
  87. data/app/views/generic_content_objects/contributors/_show_conference.html.erb +22 -0
  88. data/app/views/generic_content_objects/contributors/_show_organization.html.erb +22 -0
  89. data/app/views/generic_content_objects/contributors/_show_person.html.erb +38 -0
  90. data/app/views/generic_contents/_edit.html.erb +59 -0
  91. data/app/views/generic_contents/_index.html.erb +23 -0
  92. data/app/views/generic_contents/_show.html.erb +18 -0
  93. data/app/views/generic_contents/_show_content.html.erb +4 -0
  94. data/app/views/generic_images/_edit.html.erb +59 -0
  95. data/app/views/generic_images/_index.html.erb +24 -0
  96. data/app/views/generic_images/_show.html.erb +18 -0
  97. data/app/views/generic_images/_show_all.html.erb +14 -0
  98. data/app/views/generic_images/_show_content.html.erb +7 -0
  99. data/app/views/layouts/application.html.erb +57 -0
  100. data/app/views/layouts/hydra-head.html.erb +12 -0
  101. data/app/views/mods_assets/_edit.html.erb +49 -0
  102. data/app/views/mods_assets/_edit_description.html.erb +82 -0
  103. data/app/views/mods_assets/_edit_journal.html.erb +72 -0
  104. data/app/views/mods_assets/_index.html.erb +1 -0
  105. data/app/views/mods_assets/_index_list.html.erb +37 -0
  106. data/app/views/mods_assets/_index_table.html.erb +7 -0
  107. data/app/views/mods_assets/_progress_box.html.erb +82 -0
  108. data/app/views/mods_assets/_show.html.erb +44 -0
  109. data/app/views/mods_assets/_show_description.html.erb +44 -0
  110. data/app/views/mods_assets/_show_journal.html.erb +42 -0
  111. data/app/views/mods_assets/_show_permissions.html.erb +14 -0
  112. data/app/views/permissions/_edit_person_permissions.html.erb +35 -0
  113. data/app/views/permissions/_index.html.erb +55 -0
  114. data/app/views/permissions/_new.html.erb +18 -0
  115. data/app/views/permissions/index.html.erb +1 -0
  116. data/app/views/permissions/new.html.erb +1 -0
  117. data/app/views/shared/_delete_asset_confirmation.html.erb +17 -0
  118. data/app/views/user_sessions/_login_form.html.erb +10 -0
  119. data/app/views/user_sessions/logged_out.html.erb +1 -0
  120. data/config/routes.rb +12 -0
  121. data/fedora_conf/conf/fedora.fcfg +1021 -0
  122. data/hydra-head.gemspec +70 -0
  123. data/lib/application_controller.rb +25 -0
  124. data/lib/application_helper.rb +2 -0
  125. data/lib/engine.rb +30 -0
  126. data/lib/generators/hydra/head_generator.rb +152 -0
  127. data/lib/generators/hydra/templates/config/fedora.yml +17 -0
  128. data/lib/generators/hydra/templates/config/initializers/blacklight_config.rb +246 -0
  129. data/lib/generators/hydra/templates/config/initializers/fedora_config.rb +23 -0
  130. data/lib/generators/hydra/templates/config/initializers/hydra_config.rb +29 -0
  131. data/lib/generators/hydra/templates/config/role_map_cucumber.yml +10 -0
  132. data/lib/generators/hydra/templates/config/role_map_development.yml +12 -0
  133. data/lib/generators/hydra/templates/config/role_map_production.yml +2 -0
  134. data/lib/generators/hydra/templates/config/role_map_test.yml +15 -0
  135. data/lib/generators/hydra/templates/config/solr.yml +10 -0
  136. data/lib/generators/hydra/templates/config/solr_mappings.yml +22 -0
  137. data/lib/generators/hydra/templates/fedora_conf/conf/fedora.fcfg +1021 -0
  138. data/lib/generators/hydra/templates/migrations/add_user_attributes_table.rb +15 -0
  139. data/lib/generators/hydra/templates/migrations/create_superusers.rb +12 -0
  140. data/lib/generators/hydra/templates/solr_conf/conf/schema.xml +118 -0
  141. data/lib/generators/hydra/templates/solr_conf/conf/solrconfig.xml +332 -0
  142. data/lib/generators/hydra/templates/solr_conf/solr.xml +35 -0
  143. data/lib/hydra-head.rb +29 -0
  144. data/lib/hydra-head/engine.rb +9 -0
  145. data/lib/hydra-head/routes.rb +87 -0
  146. data/lib/hydra-head/version.rb +4 -0
  147. data/lib/hydra.rb +22 -0
  148. data/lib/hydra/access_controls_enforcement.rb +236 -0
  149. data/lib/hydra/access_controls_evaluation.rb +97 -0
  150. data/lib/hydra/assets_controller_helper.rb +144 -0
  151. data/lib/hydra/catalog.rb +64 -0
  152. data/lib/hydra/common_mods_index_methods.rb +42 -0
  153. data/lib/hydra/controller.rb +7 -0
  154. data/lib/hydra/file_assets_helper.rb +144 -0
  155. data/lib/hydra/fixtures.rb +43 -0
  156. data/lib/hydra/generic_content.rb +113 -0
  157. data/lib/hydra/generic_image.rb +100 -0
  158. data/lib/hydra/image.rb +177 -0
  159. data/lib/hydra/model_methods.rb +95 -0
  160. data/lib/hydra/model_mixins.rb +2 -0
  161. data/lib/hydra/model_mixins/common_metadata.rb +24 -0
  162. data/lib/hydra/model_mixins/mods_object.rb +16 -0
  163. data/lib/hydra/mods_article.rb +505 -0
  164. data/lib/hydra/mods_dataset.rb +165 -0
  165. data/lib/hydra/mods_generic_content.rb +494 -0
  166. data/lib/hydra/mods_image.rb +494 -0
  167. data/lib/hydra/repository_controller.rb +102 -0
  168. data/lib/hydra/rights_metadata.rb +189 -0
  169. data/lib/hydra/superuser_attributes.rb +12 -0
  170. data/lib/hydra/testing_server.rb +183 -0
  171. data/lib/hydra/user.rb +22 -0
  172. data/lib/mediashelf/active_fedora_helper.rb +72 -0
  173. data/lib/railties/all_tests.rake +23 -0
  174. data/lib/railties/hydra-fixtures.rake +184 -0
  175. data/lib/railties/hydra_jetty.rake +79 -0
  176. data/lib/railties/hyhead_cucumber.rake +127 -0
  177. data/lib/railties/hyhead_rspec.rake +137 -0
  178. data/lib/stanford/searchworks_helper.rb +1338 -0
  179. data/lib/stanford/solr_helper.rb +108 -0
  180. data/lib/uva/mods_index_methods.rb +24 -0
  181. data/solr_conf/conf/schema.xml +122 -0
  182. data/solr_conf/conf/solrconfig.xml +332 -0
  183. data/solr_conf/solr.xml +35 -0
  184. data/tasks/hydra-head-fixtures.rake +54 -0
  185. data/tasks/hydra-head.rake +247 -0
  186. data/tasks/hydra_jetty.rake +79 -0
  187. data/tasks/replicator.rake +27 -0
  188. data/tasks/solrizer-fedora.rake +53 -0
  189. data/tasks/solrizer.rake +13 -0
  190. data/test_support/etc/Gemfile +29 -0
  191. data/test_support/etc/rvmrc +32 -0
  192. data/test_support/features/button_add_assets.feature +22 -0
  193. data/test_support/features/button_add_generic_content.feature +11 -0
  194. data/test_support/features/button_add_image.feature +11 -0
  195. data/test_support/features/button_add_mods_asset.feature +11 -0
  196. data/test_support/features/contributor_add.feature +39 -0
  197. data/test_support/features/file_assets_list.feature +32 -0
  198. data/test_support/features/file_upload.feature +40 -0
  199. data/test_support/features/home_page.feature +9 -0
  200. data/test_support/features/html_validity.feature +47 -0
  201. data/test_support/features/mods_asset_contributors_edit.feature +80 -0
  202. data/test_support/features/mods_asset_create.feature +12 -0
  203. data/test_support/features/mods_asset_edit.feature +33 -0
  204. data/test_support/features/mods_asset_edit_without_permission.feature +10 -0
  205. data/test_support/features/mods_asset_search_result.feature +13 -0
  206. data/test_support/features/mods_asset_show.feature +39 -0
  207. data/test_support/features/permissions_add.feature +15 -0
  208. data/test_support/features/permissions_edit.feature +63 -0
  209. data/test_support/features/step_definitions/catalog_index_steps.rb +14 -0
  210. data/test_support/features/step_definitions/create_asset_steps.rb +7 -0
  211. data/test_support/features/step_definitions/edit_metadata_steps.rb +73 -0
  212. data/test_support/features/step_definitions/file_list_steps.rb +28 -0
  213. data/test_support/features/step_definitions/hydra_metadata_steps.rb +3 -0
  214. data/test_support/features/step_definitions/hydra_steps.rb +8 -0
  215. data/test_support/features/step_definitions/inline_editable_edit_steps.rb +77 -0
  216. data/test_support/features/step_definitions/search_steps.rb +88 -0
  217. data/test_support/features/step_definitions/searching_steps.rb +22 -0
  218. data/test_support/features/step_definitions/show_document_steps.rb +85 -0
  219. data/test_support/features/step_definitions/user_steps.rb +36 -0
  220. data/test_support/features/step_definitions/web_steps.rb +219 -0
  221. data/test_support/features/support/env.rb +55 -0
  222. data/test_support/features/support/paths.rb +80 -0
  223. data/test_support/features/switch_users.feature +14 -0
  224. data/test_support/features/view_catalog_index.feature +18 -0
  225. data/test_support/fixtures/empty_file.txt +0 -0
  226. data/test_support/fixtures/hydrangea_fixture_archivist_only_mods_article.foxml.xml +1212 -0
  227. data/test_support/fixtures/hydrangea_fixture_file_asset1.foxml.xml +4946 -0
  228. data/test_support/fixtures/hydrangea_fixture_mods_article1.foxml.xml +234 -0
  229. data/test_support/fixtures/hydrangea_fixture_mods_article2.foxml.xml +177 -0
  230. data/test_support/fixtures/hydrangea_fixture_mods_article3.foxml.xml +170 -0
  231. data/test_support/fixtures/hydrangea_fixture_mods_dataset1.foxml.xml +187 -0
  232. data/test_support/fixtures/hydrangea_fixture_uploaded_svg1.foxml.xml +676 -0
  233. data/test_support/fixtures/image.jp2 +0 -0
  234. data/test_support/fixtures/libra-oa_1.foxml.xml +2324 -0
  235. data/test_support/fixtures/libra-oa_2.foxml.xml +2422 -0
  236. data/test_support/spec/controllers/assets_controller_spec.rb +113 -0
  237. data/test_support/spec/controllers/catalog_controller_spec.rb +148 -0
  238. data/test_support/spec/controllers/catalog_controller_viewing_context_spec.rb +62 -0
  239. data/test_support/spec/controllers/contributors_controller_spec.rb +47 -0
  240. data/test_support/spec/controllers/file_assets_controller_spec.rb +189 -0
  241. data/test_support/spec/controllers/hydra_controller_spec.rb +15 -0
  242. data/test_support/spec/controllers/permissions_controller_spec.rb +80 -0
  243. data/test_support/spec/controllers/user_sessions_controller_spec.rb +35 -0
  244. data/test_support/spec/generators/hydra-head_generator_spec.rb +14 -0
  245. data/test_support/spec/helpers/access_controls_enforcement_spec.rb +212 -0
  246. data/test_support/spec/helpers/access_controls_evaluation_spec.rb +35 -0
  247. data/test_support/spec/helpers/assets_controller_helper_spec.rb +71 -0
  248. data/test_support/spec/helpers/blacklight_helper_spec.rb +64 -0
  249. data/test_support/spec/helpers/file_assets_helper_spec.rb +107 -0
  250. data/test_support/spec/helpers/hydra-repository_controller_spec.rb +32 -0
  251. data/test_support/spec/helpers/hydra_assets_helper_spec.rb +195 -0
  252. data/test_support/spec/helpers/hydra_djatoka_helper_spec.rb +32 -0
  253. data/test_support/spec/helpers/hydra_fedora_metadata_helper_spec.rb +215 -0
  254. data/test_support/spec/helpers/hydra_helper_spec.rb +73 -0
  255. data/test_support/spec/helpers/hydra_model_methods_spec.rb +95 -0
  256. data/test_support/spec/helpers/hydra_uploader_helper_spec.rb +18 -0
  257. data/test_support/spec/helpers/javascript_includes_helper_spec.rb +43 -0
  258. data/test_support/spec/integration/file_asset_spec.rb +150 -0
  259. data/test_support/spec/lib/active_fedora_helper_spec.rb +56 -0
  260. data/test_support/spec/lib/catalog_spec.rb +16 -0
  261. data/test_support/spec/lib/common_mods_index_methods_spec.rb +28 -0
  262. data/test_support/spec/models/audio_asset_spec.rb +23 -0
  263. data/test_support/spec/models/file_asset_spec.rb +42 -0
  264. data/test_support/spec/models/generic_content_spec.rb +29 -0
  265. data/test_support/spec/models/generic_image_spec.rb +58 -0
  266. data/test_support/spec/models/hydra_rights_metadata_spec.rb +162 -0
  267. data/test_support/spec/models/image_asset_spec.rb +23 -0
  268. data/test_support/spec/models/mods_asset_spec.rb +29 -0
  269. data/test_support/spec/models/role_mapper_spec.rb +22 -0
  270. data/test_support/spec/models/user_spec.rb +52 -0
  271. data/test_support/spec/models/video_asset_spec.rb +23 -0
  272. data/test_support/spec/rcov.opts +3 -0
  273. data/test_support/spec/spec.opts +4 -0
  274. data/test_support/spec/spec_helper.rb +44 -0
  275. data/test_support/spec/support/matchers/helper_matcher.rb +14 -0
  276. data/test_support/spec/support/matchers/solr_matchers.rb +60 -0
  277. data/test_support/spec/unit/hydra-head-engine_spec.rb +8 -0
  278. data/test_support/spec/unit/hydra-head_spec.rb +8 -0
  279. data/test_support/spec/utilities/hydra_testing_server_spec.rb +49 -0
  280. data/test_support/spec/views/uploader.html.erb_spec.rb +30 -0
  281. data/vendor/cache/RedCloth-4.2.3.gem +0 -0
  282. data/vendor/cache/abstract-1.0.0.gem +0 -0
  283. data/vendor/cache/actionmailer-3.0.9.gem +0 -0
  284. data/vendor/cache/actionpack-3.0.9.gem +0 -0
  285. data/vendor/cache/active-fedora-2.3.3.gem +0 -0
  286. data/vendor/cache/activemodel-3.0.9.gem +0 -0
  287. data/vendor/cache/activerecord-3.0.9.gem +0 -0
  288. data/vendor/cache/activeresource-3.0.9.gem +0 -0
  289. data/vendor/cache/activesupport-3.0.9.gem +0 -0
  290. data/vendor/cache/arel-2.0.10.gem +0 -0
  291. data/vendor/cache/blacklight-3.0.0.gem +0 -0
  292. data/vendor/cache/block_helpers-0.3.3.gem +0 -0
  293. data/vendor/cache/builder-2.1.2.gem +0 -0
  294. data/vendor/cache/capybara-1.0.0.gem +0 -0
  295. data/vendor/cache/childprocess-0.2.0.gem +0 -0
  296. data/vendor/cache/columnize-0.3.4.gem +0 -0
  297. data/vendor/cache/crack-0.1.8.gem +0 -0
  298. data/vendor/cache/cucumber-1.0.2.gem +0 -0
  299. data/vendor/cache/cucumber-rails-1.0.2.gem +0 -0
  300. data/vendor/cache/curb-0.7.15.gem +0 -0
  301. data/vendor/cache/daemons-1.1.4.gem +0 -0
  302. data/vendor/cache/database_cleaner-0.6.7.gem +0 -0
  303. data/vendor/cache/diff-lcs-1.1.2.gem +0 -0
  304. data/vendor/cache/equivalent-xml-0.2.7.gem +0 -0
  305. data/vendor/cache/erubis-2.6.6.gem +0 -0
  306. data/vendor/cache/facets-2.8.4.gem +0 -0
  307. data/vendor/cache/factory_girl-1.3.3.gem +0 -0
  308. data/vendor/cache/fastercsv-1.5.4.gem +0 -0
  309. data/vendor/cache/ffi-1.0.9.gem +0 -0
  310. data/vendor/cache/gherkin-2.4.5.gem +0 -0
  311. data/vendor/cache/haml-3.1.2.gem +0 -0
  312. data/vendor/cache/httparty-0.7.8.gem +0 -0
  313. data/vendor/cache/i18n-0.5.0.gem +0 -0
  314. data/vendor/cache/jettywrapper-0.0.10.gem +0 -0
  315. data/vendor/cache/json-1.5.3.gem +0 -0
  316. data/vendor/cache/json_pure-1.5.3.gem +0 -0
  317. data/vendor/cache/kaminari-0.12.4.gem +0 -0
  318. data/vendor/cache/launchy-2.0.3.gem +0 -0
  319. data/vendor/cache/linecache-0.46.gem +0 -0
  320. data/vendor/cache/logger-1.2.8.gem +0 -0
  321. data/vendor/cache/mail-2.2.19.gem +0 -0
  322. data/vendor/cache/marc-0.4.3.gem +0 -0
  323. data/vendor/cache/mediashelf-loggable-0.4.2.gem +0 -0
  324. data/vendor/cache/mime-types-1.16.gem +0 -0
  325. data/vendor/cache/mocha-0.9.12.gem +0 -0
  326. data/vendor/cache/multipart-post-1.1.2.gem +0 -0
  327. data/vendor/cache/nokogiri-1.5.0.gem +0 -0
  328. data/vendor/cache/om-1.2.5.gem +0 -0
  329. data/vendor/cache/polyglot-0.3.1.gem +0 -0
  330. data/vendor/cache/rack-1.2.3.gem +0 -0
  331. data/vendor/cache/rack-mount-0.6.14.gem +0 -0
  332. data/vendor/cache/rack-test-0.5.7.gem +0 -0
  333. data/vendor/cache/rails-3.0.9.gem +0 -0
  334. data/vendor/cache/railties-3.0.9.gem +0 -0
  335. data/vendor/cache/rake-0.9.2.gem +0 -0
  336. data/vendor/cache/rbx-require-relative-0.0.5.gem +0 -0
  337. data/vendor/cache/rcov-0.9.9.gem +0 -0
  338. data/vendor/cache/rdoc-3.8.gem +0 -0
  339. data/vendor/cache/rsolr-1.0.2.gem +0 -0
  340. data/vendor/cache/rsolr-ext-1.0.3.gem +0 -0
  341. data/vendor/cache/rspec-2.6.0.gem +0 -0
  342. data/vendor/cache/rspec-core-2.6.4.gem +0 -0
  343. data/vendor/cache/rspec-expectations-2.6.0.gem +0 -0
  344. data/vendor/cache/rspec-mocks-2.6.0.gem +0 -0
  345. data/vendor/cache/rspec-rails-2.6.1.gem +0 -0
  346. data/vendor/cache/ruby-debug-0.10.4.gem +0 -0
  347. data/vendor/cache/ruby-debug-base-0.10.4.gem +0 -0
  348. data/vendor/cache/rubyzip-0.9.4.gem +0 -0
  349. data/vendor/cache/sanitize-2.0.3.gem +0 -0
  350. data/vendor/cache/selenium-webdriver-0.2.2.gem +0 -0
  351. data/vendor/cache/solr-ruby-0.0.8.gem +0 -0
  352. data/vendor/cache/solrizer-1.1.0.gem +0 -0
  353. data/vendor/cache/solrizer-fedora-1.1.0.gem +0 -0
  354. data/vendor/cache/sqlite3-ruby-1.2.5.gem +0 -0
  355. data/vendor/cache/stomp-1.1.9.gem +0 -0
  356. data/vendor/cache/term-ansicolor-1.0.5.gem +0 -0
  357. data/vendor/cache/thor-0.14.6.gem +0 -0
  358. data/vendor/cache/treetop-1.4.9.gem +0 -0
  359. data/vendor/cache/trollop-1.16.2.gem +0 -0
  360. data/vendor/cache/tzinfo-0.3.29.gem +0 -0
  361. data/vendor/cache/unicode-0.4.0.gem +0 -0
  362. data/vendor/cache/will_paginate-2.3.15.gem +0 -0
  363. data/vendor/cache/xml-simple-1.1.0.gem +0 -0
  364. data/vendor/cache/xpath-0.1.4.gem +0 -0
  365. data/vendor/cache/yard-0.7.2.gem +0 -0
  366. metadata +1110 -0
@@ -0,0 +1,137 @@
1
+ # Blacklight customization of the Rake tasks that come with rspec-2, to run
2
+ # specs located in alternate location (inside BL plugin), and to provide
3
+ # rake tasks for jetty/solr wrapping.
4
+ #
5
+ # Same tasks as in ordinary rspec, but prefixed with blacklight:.
6
+ #
7
+ # rspec2 keeps it's rake tasks inside it's own code, it doesn't generate them.
8
+ # We had to copy them from there and modify, may have to be done again
9
+ # if rspec2 changes a lot, but this code looks relatively cleanish.
10
+ begin
11
+ require 'rspec/core'
12
+ require 'rspec/core/rake_task'
13
+ Rake.application.instance_variable_get('@tasks')['default'].prerequisites.delete('test')
14
+
15
+ spec_prereq = Rails.configuration.generators.options[:rails][:orm] == :active_record ? "db:test:prepare" : :noop
16
+ task :noop do; end
17
+ #task :default => :spec
18
+
19
+ hyhead_spec = File.expand_path("./test_support/spec", HydraHead.root)
20
+
21
+ # Set env variable to tell our spec/spec_helper.rb where we really are,
22
+ # so it doesn't have to guess with relative path, which will be wrong
23
+ # since we allow spec_dir to be in a remote location. spec_helper.rb
24
+ # needs it before Rails.root is defined there, even though we can
25
+ # oddly get it here, i dunno.
26
+ ENV['RAILS_ROOT'] = Rails.root.to_s
27
+
28
+ namespace :hyhead do
29
+
30
+ desc "Run all specs in spec directory (excluding plugin specs)"
31
+ RSpec::Core::RakeTask.new(:spec => spec_prereq) do |t|
32
+ # the user might not have run rspec generator because they don't
33
+ # actually need it, but without an ./.rspec they won't get color,
34
+ # let's insist.
35
+ t.rspec_opts = "--colour"
36
+
37
+ # pattern directory name defaults to ./**/*_spec.rb, but has a more concise command line echo
38
+ t.pattern = "#{hyhead_spec}"
39
+ end
40
+
41
+ # Don't understand what this does or how to make it use our remote stats_directory
42
+ #task :stats => "spec:statsetup"
43
+
44
+ namespace :spec do
45
+ [:requests, :models, :controllers, :views, :helpers, :mailers, :lib, :routing, :generators, :utilities].each do |sub|
46
+ desc "Run the code examples in spec/#{sub}"
47
+ RSpec::Core::RakeTask.new(sub => spec_prereq) do |t|
48
+ # the user might not have run rspec generator because they don't
49
+ # actually need it, but without an ./.rspec they won't get color,
50
+ # let's insist.
51
+ t.rspec_opts = "--colour"
52
+
53
+ # pattern directory name defaults to ./**/*_spec.rb, but has a more concise command line echo
54
+ t.pattern = "#{hyhead_spec}/#{sub}"
55
+ end
56
+ end
57
+
58
+ desc "Run all specs"
59
+ task :run => spec_prereq do
60
+ [:models, :controllers, :helpers, :lib, :generators, :utilities].each do |sub|
61
+ puts "invoking: hyhead:spec:#{sub}"
62
+ Rake::Task["hyhead:spec:#{sub}"].invoke
63
+ end
64
+ end
65
+
66
+ desc "Run all specs with rcov"
67
+ RSpec::Core::RakeTask.new(:rcov => spec_prereq) do |t|
68
+ t.rcov = true
69
+ # pattern directory name defaults to ./**/*_spec.rb, but has a more concise command line echo
70
+ t.pattern = File.join(hyhead_spec, "/**/*_spec.rb")
71
+ t.rspec_opts = "--colour"
72
+ t.rcov_opts = '-o "' + HydraHead.root + '/coverage" --exclude /gems/,/Library/,/usr/,test_support,lib/tasks,.bundle,config,/lib/rspec/,/lib/rspec-'
73
+ end
74
+
75
+ # Blacklight. Solr wrapper. for now just for blacklight:spec, plan to
76
+ # provide it for all variants eventually.
77
+ # if you would like to see solr startup messages on STDERR
78
+ # when starting solr test server during functional tests use:
79
+ #
80
+ # rake SOLR_CONSOLE=true
81
+ require File.expand_path('../jetty_solr_server.rb', __FILE__)
82
+ desc "hyhead:solr with jetty/solr launch"
83
+ task :with_solr do
84
+ # wrap tests with a test-specific Solr server
85
+ # Need to look up where the test jetty is located
86
+ # from solr.yml, we don't hardcode it anymore.
87
+
88
+ solr_yml_path = locate_path("config", "solr.yml")
89
+ jetty_path = if ( File.exists?( solr_yml_path ))
90
+ solr_config = YAML::load(File.open(solr_yml_path))
91
+ solr_config["test"]["jetty_path"] if solr_config["test"]
92
+ end
93
+ raise Exception.new("Can't find jetty path to start test jetty. Expect a jetty_path key in config/solr.yml for test environment.") unless jetty_path
94
+
95
+
96
+ # wrap tests with a test-specific Solr server
97
+ JettySolrServer.new(
98
+ :jetty_home => File.expand_path(jetty_path, Rails.root),
99
+ :sleep_after_start => 2).wrap do
100
+ Rake::Task["hyhead:spec"].invoke
101
+ end
102
+ end
103
+
104
+
105
+ # Don't understand what this does or how to make it use our remote stats_directory.
106
+ # task :statsetup do
107
+ # require 'rails/code_statistics'
108
+ # ::STATS_DIRECTORIES << %w(Model\ specs spec/models) if File.exist?('spec/models')
109
+ # ::STATS_DIRECTORIES << %w(View\ specs spec/views) if File.exist?('spec/views')
110
+ # ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers')
111
+ # ::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) if File.exist?('spec/helpers')
112
+ # ::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib')
113
+ # ::STATS_DIRECTORIES << %w(Mailer\ specs spec/mailers) if File.exist?('spec/mailers')
114
+ # ::STATS_DIRECTORIES << %w(Routing\ specs spec/routing) if File.exist?('spec/routing')
115
+ # ::STATS_DIRECTORIES << %w(Request\ specs spec/requests) if File.exist?('spec/requests')
116
+ # ::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models')
117
+ # ::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views')
118
+ # ::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers')
119
+ # ::CodeStatistics::TEST_TYPES << "Helper specs" if File.exist?('spec/helpers')
120
+ # ::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib')
121
+ # ::CodeStatistics::TEST_TYPES << "Mailer specs" if File.exist?('spec/mailers')
122
+ # ::CodeStatistics::TEST_TYPES << "Routing specs" if File.exist?('spec/routing')
123
+ # ::CodeStatistics::TEST_TYPES << "Request specs" if File.exist?('spec/requests')
124
+ # end
125
+ end
126
+ end
127
+ rescue LoadError
128
+ # This rescue pattern stolen from cucumber; rspec didn't need it before since
129
+ # tasks only lived in rspec gem itself, but for Blacklight since we're copying
130
+ # these tasks into BL, we use the rescue so you can still run BL (without
131
+ # these tasks) even if you don't have rspec installed.
132
+ desc 'rspec rake tasks not available (rspec not installed)'
133
+ task :spec do
134
+ abort 'Rspec rake tasks not available. Be sure to install rspec gems. '
135
+ end
136
+ end
137
+
@@ -0,0 +1,1338 @@
1
+ module Stanford::SearchworksHelper
2
+
3
+ require_plugin_dependency 'vendor/plugins/blacklight/app/helpers/application_helper.rb'
4
+
5
+ include Stanford::SolrHelper # for nearby on shelf lookups
6
+
7
+ # def application_name
8
+ # 'SearchWorks (SULAIR)'
9
+ # end
10
+ def vern_document_heading
11
+ @document[Blacklight.config[:show][:vern_heading]]
12
+ end
13
+ def home_facet_field_names
14
+ Blacklight.config[:home_facet][:solr]
15
+ end
16
+ def home_facet_field_labels
17
+ Blacklight.config[:home_facet][:labels]
18
+ end
19
+ # overriding because we need to escape the '< Previous' at the linking level
20
+ def link_to_previous_document(previous_document)
21
+ return if previous_document == nil
22
+ link_to_document previous_document, :label=>'&laquo; Previous', :counter => session[:search][:counter].to_i - 1
23
+ end
24
+ # overriding because we need to escape the 'Next >' at the linking level
25
+ def link_to_next_document(next_document)
26
+ return if next_document == nil
27
+ link_to_document next_document, :label=>'Next &raquo;', :counter => session[:search][:counter].to_i + 1
28
+ end
29
+
30
+ # copies the current params (or whatever is passed in as the 3rd arg)
31
+ # removes the field value from params[:f]
32
+ # removes the field if there are no more values in params[:f][field]
33
+ # removes additional params (page, id, etc..)
34
+ def remove_query_params(value, source_params=params)
35
+ p = source_params.dup.symbolize_keys!
36
+ # need to dup the facet values too,
37
+ # if the values aren't dup'd, then the values
38
+ # from the session will get remove in the show view...
39
+ p[:q] = p[:q].dup
40
+ p.delete :page
41
+ p.delete :id
42
+ p.delete :total
43
+ p.delete :counter
44
+ p.delete :commit
45
+ #return p unless p[field]
46
+ p[:q] = p[:q].gsub(value,"").strip
47
+ p.delete(:q) if p[:q].size == 0
48
+ p
49
+ end
50
+
51
+ # link_back_to_catalog(:label=>'Back to Search')
52
+ # Create a link back to the index screen, keeping the user's facet, query and paging choices intact by using session.
53
+ def link_back_to_catalog(opts={:label=>'Back to Search'})
54
+ query_params = session[:search].dup || {}
55
+ query_params.delete :counter
56
+ query_params.delete :total
57
+ link_url = root_path(query_params)
58
+ link_to opts[:label], link_url
59
+ end
60
+
61
+ # This is an updated +link_to+ that allows you to pass a +data+ hash along with the +html_options+
62
+ # which are then written to the generated form for non-GET requests. The key is the form element name
63
+ # and the value is the value:
64
+ #
65
+ # link_to_with_data('Name', some_path(some_id), :method => :post, :html)
66
+ def link_to_with_data(*args, &block)
67
+ if block_given?
68
+ options = args.first || {}
69
+ html_options = args.second
70
+ concat(link_to(capture(&block), options, html_options))
71
+ else
72
+ name = args.first
73
+ options = args.second || {}
74
+ html_options = args.third
75
+
76
+ url = url_for(options)
77
+
78
+ if html_options
79
+ html_options = html_options.stringify_keys
80
+ href = html_options['href']
81
+ convert_options_to_javascript_with_data!(html_options, url)
82
+ tag_options = tag_options(html_options)
83
+ else
84
+ tag_options = nil
85
+ end
86
+
87
+ href_attr = "href=\"#{url}\"" unless href
88
+ "<a #{href_attr}#{tag_options}>#{name || url}</a>"
89
+ end
90
+ end
91
+ # Generate the # - # of # results text
92
+ def results_text(pp, p, result_num)
93
+ if pp.nil?
94
+ per_page = Blacklight.config[:index][:num_per_page].to_i
95
+ else
96
+ per_page = pp.to_i
97
+ end
98
+
99
+ if p.nil?
100
+ start_num = 1
101
+ p = 1
102
+ else
103
+ start_num = (p.to_i * per_page) - (per_page - 1)
104
+ end
105
+
106
+ if p == 1 and per_page < result_num
107
+ end_num = per_page
108
+ elsif ((per_page * p.to_i) > result_num)
109
+ end_num = result_num
110
+ else
111
+ end_num = per_page * p.to_i
112
+ end
113
+ "#{start_num} - #{end_num} of "
114
+ end
115
+ # Genrate dt/dd with a relevance
116
+ def get_relevance_bar(score,label)
117
+ score_mod = (score * 9).round(2)
118
+ if score_mod > 100
119
+ score_mod = 100
120
+ elsif score_mod == 0.0
121
+ score_mod = (score * 9).round(4)
122
+ end
123
+ text = "<dt>#{label}</dt>"
124
+ text += "<dd>"
125
+ text += "<div class='relevance_container'>"
126
+ text += "<span>#{score_mod}%</span>"
127
+ text += "<div class='relevance_bar' style='width:#{score_mod}%'>"
128
+ text += "</div>"
129
+ text += "</div>"
130
+ text += "</dd>"
131
+ end
132
+
133
+ # Generate a dt/dd pair given a Solr field
134
+ # If you provide a :default value in the opts hash,
135
+ # then when the solr field is empty, the default value will be used.
136
+ # If you don't provide a default value, this method will not generate html when the field is empty.
137
+ def get_data_with_label(doc, label, field_string, opts={})
138
+ if opts[:default] && !doc[field_string]
139
+ doc[field_string] = opts[:default]
140
+ end
141
+
142
+ if doc[field_string]
143
+ field = doc[field_string]
144
+ text = "<dt>#{label}</dt><dd>"
145
+ if field.is_a?(Array)
146
+ field.each do |l|
147
+ text += "#{h(l)}"
148
+ if l != h(field.last)
149
+ text += "<br/>"
150
+ end
151
+ end
152
+ else
153
+ text += h(field)
154
+ end
155
+ #Does the field have a vernacular equivalent?
156
+ if doc["vern_#{field_string}"]
157
+ vern_field = doc["vern_#{field_string}"]
158
+ text += "<br/>"
159
+ if vern_field.is_a?(Array)
160
+ vern_field.each do |l|
161
+ text += "#{h(l)}"
162
+ if l != h(vern_field.last)
163
+ text += "<br/>"
164
+ end
165
+ end
166
+ else
167
+ text += h(vern_field)
168
+ end
169
+ end
170
+ text += "</dd>"
171
+ text
172
+ end
173
+ end
174
+ # generate an dt/dd pair given a marc field
175
+ def get_data_with_label_from_marc(doc,label,field,sFields=[])
176
+ if doc.marc[field]
177
+ text = "<dt>#{label}</dt><dd>"
178
+ doc.marc.find_all{|f| (field) === f.tag}.each do |l|
179
+ if sFields.length > 0
180
+ l.each{|sl| sFields.include?(sl.code) ? text << "#{h(sl.value)} " : ""}
181
+ else
182
+ temp_text = ""
183
+ # get_vern method should be here? In each loop below? After?
184
+ l.each {|sl| ['w','0', '5', '6', '8'].include?(sl.code) ? nil : temp_text += "#{sl.value} "}
185
+ vernacular = get_vernacular(doc,l)
186
+ text += h(temp_text)
187
+ end
188
+ vernacular = get_vernacular(doc,l)
189
+ text += "<br/>#{vernacular}" unless vernacular.nil?
190
+ text += "<br/>" unless l == doc.marc.find_all{|f| (field) === f.tag}.last
191
+ end
192
+ text += "</dd>"
193
+ text
194
+ else
195
+
196
+ # The below if statement is attempting to find unmatched vernacular fields that match the supplied field string
197
+ if doc.marc['880']
198
+ doc.marc.find_all{|f| ('880') === f.tag}.each do |l|
199
+ if l['6'].split("-")[1].gsub("//r","") == "00" and l['6'].split("-")[0] == field
200
+ text = "<dt>#{label}</dt><dd>"
201
+ l.each {|sl| ['w','0', '5', '6', '8'].include?(sl.code) ? nil : text += "#{sl.value} "}
202
+ text += "</dd>"
203
+ end
204
+ end
205
+ text
206
+ end
207
+
208
+ end
209
+ end
210
+ # Generate a dt/dd pair with a comma separated list of formats given an array of format strings
211
+ def show_formats(field)
212
+ if field
213
+ text = "<dt>Format:</dt><dd>"
214
+ field.each do |l|
215
+ text += "<span class='iconSpan #{l.downcase.gsub(" ","").gsub("/","_")}'>"
216
+ text += h(l)
217
+ text += ", " unless l == field.last
218
+ text += "</span>"
219
+ end
220
+ text += "</dd>"
221
+ text
222
+ end
223
+
224
+
225
+ end
226
+ # Generate a dt/dd pair with a link with a label given a field in the SolrDocument
227
+ def link_to_data_with_label(doc,label,field_string,url)
228
+ if doc[field_string]
229
+ field = doc[field_string]
230
+ text = "<dt>#{label}</dt><dd>"
231
+ if field.is_a?(Array)
232
+ field.each do |l|
233
+ text += link_to l, url.merge!(:q => "\"#{l}\"")
234
+ if l != field.last
235
+ text += "<br/>"
236
+ end
237
+ end
238
+ else
239
+ text += link_to field, url.merge!(:q => "\"#{field}\"")
240
+ end
241
+ if doc["vern_#{field_string}"]
242
+ vern_field = doc["vern_#{field_string}"]
243
+ text += "<br/>"
244
+ if vern_field.is_a?(Array)
245
+ vern_field.each do |l|
246
+ text += link_to l, url.merge!(:q => "\"#{l}\"")
247
+ if l != vern_field.last
248
+ text += "<br/>"
249
+ end
250
+ end
251
+ else
252
+ text += link_to vern_field, url.merge!(:q => "\"#{vern_field}\"")
253
+ end
254
+ end
255
+
256
+ text += "</dd>"
257
+ text
258
+ end
259
+ end
260
+ # Generate dt/dd pair with an unordered list from the table of contents (IE marc 505s)
261
+ def get_toc(doc)
262
+ if doc.marc['505']
263
+ text = "<dt>Contents:</dt><dd>"
264
+ doc.marc.find_all{|f| ('505') === f.tag}.each do |l|
265
+ text << "<ul class='toc'><li>"
266
+ l.each{|sl| ['w','0', '5', '6', '8'].include?(sl.code) ? nil : text << "#{sl.value.gsub(' -- ','</li><li>')} " }
267
+ text << "</li></ul>"
268
+ text << "<ul class='toc'><li>#{get_vernacular(doc,l).gsub('--','</li><li>')}</li></ul>" unless get_vernacular(doc,l).nil?
269
+ end
270
+ text << "</dd>"
271
+ else
272
+ if doc.marc['880']
273
+ doc.marc.find_all{|f| ('880') === f.tag}.each do |l|
274
+ if l['6'].split("-")[1].gsub("//r","") == "00" and l['6'].split("-")[0] == "505"
275
+ text = "<dt>Contents:</dt><dd><ul class='toc'><li>"
276
+ l.each {|sl| ['w','0', '5', '6', '8'].include?(sl.code) ? nil : text << "#{sl.value.gsub('--','</li><li>')} "}
277
+ text << "</li></dd>"
278
+ end
279
+ end
280
+ text
281
+ end
282
+ end
283
+ end
284
+ # Generate dt/dd pair with a link with a label given a marc field
285
+ def link_to_data_with_label_from_marc(doc,label,field,url,sFields=[])
286
+ if doc.marc[field]
287
+ text = "<dt>#{label}</dt><dd>"
288
+ doc.marc.find_all{|f| (field) === f.tag}.each do |l|
289
+ if sFields.length > 0
290
+ link_text = ""
291
+ sFields.each do |sf|
292
+ if l.find{|s| s.code == sf.to_s}
293
+ link_text << "#{l.find{|s| s.code == sf.to_s}.value} "
294
+ end
295
+ end
296
+ text += link_to link_text, url.merge!(:q => "\"#{link_text}\"")
297
+ else
298
+ link_text = ''
299
+ l.each {|sl| ['w','0', '5', '6', '8'].include?(sl.code) ? nil : link_text += "#{sl.value} " unless (sl.code == 'a' and sl.value[0,1] == "%") }
300
+ text += link_to link_text, url.merge!(:q => "\"#{link_text}\"")
301
+ end
302
+ vernacular = get_vernacular(doc,l)
303
+ temp_vern = "\"#{vernacular}\""
304
+ text += "<br/>#{link_to vernacular, url.merge!(:q => temp_vern)}" unless vernacular.nil?
305
+ text += "<br/>" unless l == doc.marc.find_all{|f| (field) === f.tag}.last
306
+ end
307
+ text += "</dd>"
308
+ else
309
+ if doc.marc['880']
310
+ doc.marc.find_all{|f| ('880') === f.tag}.each do |l|
311
+ if l['6'].split("-")[1].gsub("//r","") == "00" and l['6'].split("-")[0] == field
312
+ text = "<dt>#{label}</dt><dd>"
313
+ link_text = ''
314
+ l.each {|sl| ['w','0', '5', '6', '8'].include?(sl.code) ? nil : link_text += "#{sl.value} "}
315
+ text += link_to link_text, url.merge!(:q => "\"#{link_text}\"")
316
+ text += "</dd>"
317
+ end
318
+ end
319
+ text
320
+ end
321
+ end
322
+ end
323
+ # Generate dt/dd pair of contributors with translations
324
+ def link_to_contributor_from_marc(doc)
325
+ text = "<dt>Contributor:</dt><dd>"
326
+ ['700', '710', '711', '720'].each do |field|
327
+ if doc.marc[field]
328
+ doc.marc.find_all{|f| (field) === f.tag}.each do |l|
329
+ link_text = ''
330
+ relator_text = []
331
+ l.each {|sl| sl.code == '4' ? relator_text << " #{relator_terms[sl.value]}" : sl.code == '6' ? nil : link_text << "#{sl.value} "}
332
+ text << link_to(link_text.strip, :q => "\"#{link_text}\"", :controller => 'catalog', :action => 'index', :qt => 'search_author' )
333
+ text << relator_text.join(", ") unless relator_text.empty?
334
+ vernacular = get_vernacular(doc,l)
335
+ temp_vern = "\"#{vernacular}\""
336
+ text << "<br/>#{link_to vernacular, :q => temp_vern, :controller => 'catalog', :action => 'index', :qt => 'search_author'}" unless vernacular.nil?
337
+ text << "<br/>"
338
+ end
339
+ else
340
+ if doc.marc['880']
341
+ doc.marc.find_all{|f| ('880') === f.tag}.each do |l|
342
+ if l['6'].split("-")[1].gsub("//r","") == "00" and l['6'].split("-")[0] == field
343
+ text = "<dt>Contributor:</dt><dd>"
344
+ link_text = ''
345
+ relator_text = []
346
+ l.each {|sl| sl.code == '4' ? relator_text << " #{relator_terms[sl.value]}" : link_text << "#{sl.value} "}
347
+ text << link_to(link_text.strip,:q => "\"#{link_text}\"", :action => 'index', :qt => 'author_search')
348
+ text << relator_text.join(", ") unless relator_text.empty?
349
+ end
350
+ end
351
+ end
352
+ end
353
+ end
354
+ text << "</dd>"
355
+ text unless text == "<dt>Contributor:</dt><dd></dd>"
356
+ end
357
+
358
+ def title_change_data_from_marc(doc)
359
+ if doc.marc['780'] or doc.marc['785']
360
+ text = ""
361
+
362
+ if doc.marc['780']
363
+ doc.marc.find_all{|f| ('780') === f.tag}.each do |field|
364
+ text << "<dt>#{name_change_780_translations[field.indicator2]}:</dt>"
365
+ temp_text = ""
366
+ field.each{|subfield|
367
+ if subfield.code == "w"
368
+ nil
369
+ elsif subfield.code == "t"
370
+ query = "\"#{subfield.value}\""
371
+ temp_text << "#{link_to(subfield.value, params.dup.merge!(:action=>'index', :qt=>'search_title', :q=>query))} "
372
+ elsif subfield.code == "x"
373
+ temp_text << "(#{link_to(subfield.value, params.dup.merge!(:action=>'index', :qt=>'search', :q=>subfield.value))}) "
374
+ else
375
+ temp_text << "#{subfield.value} "
376
+ end
377
+ }
378
+ text << "<dd>#{temp_text}</dd>"
379
+ end
380
+ end
381
+
382
+ if doc.marc['785']
383
+ special_handler = []
384
+ doc.marc.find_all{|f| ('785') === f.tag}.each do |field|
385
+ if field.indicator2 == "7"
386
+ special_handler << field
387
+ end
388
+ end
389
+
390
+ doc.marc.find_all{|f| ('785') === f.tag}.each do |field|
391
+ text << "<dt>"
392
+ if field.indicator2 == "7" and field == special_handler.first
393
+ text << "Merged with:"
394
+ elsif field.indicator2 == "7" and field == special_handler.last
395
+ text << "to form:"
396
+ elsif field.indicator2 == "7" and field != special_handler.first and field != special_handler.last
397
+ text << "and with:"
398
+ else
399
+ text << "#{name_change_785_translations[field.indicator2]}:"
400
+ end
401
+ text << "</dt>"
402
+ temp_text = ""
403
+ field.each{|subfield|
404
+ if subfield.code == "w"
405
+ nil
406
+ elsif subfield.code == "t"
407
+ query = "\"#{subfield.value}\""
408
+ temp_text << "#{link_to(subfield.value, params.dup.merge!(:action=>'index', :qt=>'search_title', :q=>query))} "
409
+ elsif subfield.code == "x"
410
+ temp_text << "(#{link_to(subfield.value, params.dup.merge!(:action=>'index', :qt=>'search', :q=>subfield.value))}) "
411
+ else
412
+ temp_text << "#{subfield.value} "
413
+ end
414
+ }
415
+ text << "<dd>#{temp_text}</dd>"
416
+ end
417
+ end
418
+ text
419
+ end
420
+ end
421
+
422
+
423
+ # Generate hierarchical structure of subject headings from marc
424
+ def get_subjects(doc)
425
+ text = "<ul id='related_subjects'>"
426
+ subs = ['600','610','611','630','650','651','653','654','655','656','657','658','690','691','693','696', '697','698','699']
427
+ data = []
428
+ subs.each do |s|
429
+ if doc.marc[s]
430
+ doc.marc.find_all{|f| (s) === f.tag }.each do |l|
431
+ multi_a = []
432
+ temp_data_array = []
433
+ temp_subs_text = ""
434
+ temp_xyv_array = []
435
+ unless (s == "690" and l['a'].downcase.include?("collection"))
436
+ l.each{|sf|
437
+ unless ['w','0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].include?(sf.code)
438
+ if sf.code == "a"
439
+ multi_a << sf.value unless sf.code == "a" and sf.value[0,1] == "%"
440
+ end
441
+ if ["v","x","y","z"].include?(sf.code)
442
+ temp_xyv_array << sf.value
443
+ else
444
+ temp_subs_text << "#{sf.value} " unless (sf.code == "a" or (sf.code == "a" and sf.value[0,1] == "%"))
445
+ end
446
+ end
447
+ }
448
+ if multi_a.length > 1
449
+ multi_a.each do |a|
450
+ data << [a]
451
+ end
452
+ elsif multi_a.length == 1
453
+ str = multi_a.to_s << " " << temp_subs_text unless (temp_subs_text.blank? and multi_a.empty?)
454
+ temp_data_array << str
455
+ else
456
+ temp_data_array << temp_subs_text unless temp_subs_text.blank?
457
+ end
458
+ temp_data_array.concat(temp_xyv_array) unless temp_xyv_array.empty?
459
+ data << temp_data_array unless temp_data_array.empty?
460
+ end
461
+ end
462
+ end
463
+ end
464
+ i = 0
465
+
466
+ data.each do |fields|
467
+ text << "<li>"
468
+ link_text = ""
469
+ title_text = "Search: "
470
+ fields.each do |field|
471
+ link_text << " " unless field == data[i].first
472
+ link_text << "\"#{field.strip}\""
473
+ title_text << " - " unless field == data[i].first
474
+ title_text << "#{field.strip}"
475
+ text << link_to(field.strip, {:controller => 'catalog', :action => 'index', :q => link_text, :qt => 'search_subject'}, :title => title_text)
476
+ text << " &gt; " unless field == data[i].last
477
+ end
478
+ text << "</li>"
479
+ i += 1
480
+ end
481
+ text << "</ul>"
482
+ return text unless text == "<ul id='related_subjects'></ul>"
483
+ end
484
+ # Generate unordered list of Online Access Links (IE marc 856s)
485
+ def get_856(doc)
486
+ if doc.marc['856']
487
+ text = ''
488
+ int = 1
489
+ text += "<ul class='online'>"
490
+ text += "<li>"
491
+ text += "<ol>"
492
+ doc.marc.find_all{|f| ('856') === f.tag }.each do |field|
493
+ if !field['u'].nil?
494
+ # Not sure why I need this, but it fails on certain URLs w/o it. The link printed still has character in it
495
+ fixed_url = field['u'].gsub("^","").strip
496
+ url = URI.parse(fixed_url)
497
+ sub3 = ""
498
+ subz = []
499
+ suby = ""
500
+ field.each{|subfield|
501
+ if subfield.code == "3"
502
+ sub3 = subfield.value
503
+ elsif subfield.code == "z"
504
+ subz << subfield.value
505
+ elsif subfield.code == "y"
506
+ suby = subfield.value
507
+ end
508
+ }
509
+ if int > 3
510
+ text += "<li class='more' style='display:none;'>#{!sub3.blank? ? sub3 << ' ' : ''}#{!subz[0].blank? ? subz[0] << ' ' : ''}<a href='#{field['u']}'>#{(subz[1] and field['x'] == "eLoaderURL") ? subz[1] : !suby.blank? ? suby : url.host}</a></li>"
511
+ else
512
+ text += "<li>#{!sub3.blank? ? sub3 << ' ' : ''}#{!subz[0].blank? ? subz[0] << ' ' : ''}<a href='#{field['u']}'>#{(subz[1] and field['x'] == "eLoaderURL") ? subz[1] : !suby.blank? ? suby : url.host}</a></li>"
513
+ end
514
+ if int == 3 and field != doc.marc.find_all{|f| ('856') === f.tag }.last
515
+ text += "<li class='more_link' id='more_link'><a href=''>more<span class='off_screen'> links</span></a></li>"
516
+ end
517
+ int += 1
518
+ end
519
+ end
520
+ if int > 3
521
+ text += "<li id='less_link' class='less_link' style='display:none;'><a href=''>less<span class='off_screen'> links</span></a></li>"
522
+ end
523
+ text += "</ol>"
524
+ text += "</li>"
525
+ text += "</ul>"
526
+ text
527
+ end
528
+ end
529
+
530
+ def get_suppl_urls(doc)
531
+ text = ""
532
+ if doc['url_fulltext']
533
+ urls = doc['url_fulltext']
534
+ text << "<dt>Online:</dt><dd>"
535
+ #urls.each do |url|
536
+ fixed_url = urls[0].gsub("^","").strip
537
+ url_host = URI.parse(fixed_url).host
538
+ text << "<a href='#{urls[0].strip}'>#{url_host}</a>"
539
+ if urls.length > 1
540
+ text << " + #{pluralize(urls.length - 1, 'more source')}"
541
+ end
542
+ #end
543
+ text << "</dd>"
544
+ end
545
+ text
546
+
547
+ rescue URI::InvalidURIError
548
+ return ""
549
+ end
550
+
551
+ def get_vernacular(doc,field)
552
+ return_text = ""
553
+ if field['6']
554
+ field_original = field.tag
555
+ match_original = field['6'].split("-")[1]
556
+ doc.marc.find_all{|f| ('880') === f.tag}.each do |l|
557
+ if l['6']
558
+ field_880 = l['6'].split("-")[0]
559
+ match_880 = l['6'].split("-")[1].gsub("//r","")
560
+ if match_original == match_880 and field_original == field_880
561
+ return_text = ""
562
+ l.each{
563
+ |sl|
564
+ if !['w','0', '5', '6', '8'].include?(sl.code)
565
+ return_text += "#{sl.value} "
566
+ end
567
+ }
568
+ end
569
+ end
570
+ end
571
+ end
572
+ return nil if return_text.blank?
573
+ return_text
574
+ end
575
+
576
+ def get_callnum(doc)
577
+ test_hash = {}
578
+ if doc['item_display']
579
+ doc['item_display'].each do |item|
580
+ item_array = item.split(' -|- ')
581
+ if test_hash.has_key?(item_array[1])
582
+ if test_hash[item_array[1]].has_key?(item_array[2])
583
+ if params[:action] == 'index'
584
+ test_hash[item_array[1]][item_array[2]] << [item_array[3],item_array[0],item_array[6],item_array[4],item_array[7]] unless test_hash[item_array[1]][item_array[2]].flatten.include?(item_array[3])
585
+ else
586
+ test_hash[item_array[1]][item_array[2]] << [item_array[3],item_array[0],item_array[6],item_array[4],item_array[7]] #|Commenting out so that multiple copies show up on record view| unless test_hash[item_array[1]][item_array[2]].flatten.include?(item_array[6])
587
+ end
588
+ else
589
+ test_hash[item_array[1]][item_array[2]] = [[item_array[3],item_array[0],item_array[6],item_array[4],item_array[7]]]
590
+ end
591
+ else
592
+ test_hash[item_array[1]] = {item_array[2] => [[item_array[3],item_array[0],item_array[6],item_array[4],item_array[7]]]}
593
+ end
594
+ end
595
+ end
596
+ test_hash
597
+ end
598
+
599
+ def get_facet_tag_cloud(facet,response)
600
+ text = ""
601
+ display_facet = response.facets.detect {|f| f.name == facet }
602
+ facet_arr = []
603
+ display_facet.items.each do |item|
604
+ facet_arr << [item.hits,item.value]
605
+ end
606
+ facet_arr = facet_arr.sort_by {rand}
607
+ text += "<div class='cloud_div' id='cloud_#{facet}'>"
608
+ facet_arr.each do |l|
609
+ if l[0] > 500000
610
+ #font_size = "3"
611
+ font_size = "jumbo"
612
+ elsif l[0] > 100000
613
+ #font_size = "2.2"
614
+ font_size = "large"
615
+ elsif l[0] > 75000
616
+ #font_size = "1.8"
617
+ font_size = "medium"
618
+ elsif l[0] > 50000
619
+ #font_size = "1.4"
620
+ font_size = "small"
621
+ else
622
+ #font_size = "1"
623
+ font_size = "tiny"
624
+ end
625
+ if facet == 'building_facet' and translate_lib.has_key?(l[1])
626
+ value = translate_lib[l[1]]
627
+ else
628
+ value = l[1]
629
+ end
630
+ text += " <span class='tag_cloud #{font_size}'>#{link_to h(value), add_facet_params(facet, l[1])}</span> "
631
+ end
632
+ text += "</div>"
633
+ end
634
+
635
+ # given the solr field name of a *refinement* facet (e.g. lc_alpha_facet),
636
+ # return a string containing appropriate html to display the given facet
637
+ # heading and its values
638
+ def get_refine_facet(solr_fname, response)
639
+ text = ""
640
+ display_facet = response.facets.detect {|f| f.name == solr_fname}
641
+ if !display_facet.nil? && !display_facet.items.nil? && display_facet.items.length > 0
642
+ text = "<li>"
643
+ text << " <h3 class='facet_selected'>" + facet_field_labels[solr_fname] + "</h3>"
644
+ text << " <ul>"
645
+ item_count = 0
646
+ display_facet.items.each do |item|
647
+ if facet_in_params? solr_fname, item.value
648
+ text << "<li>"
649
+ text << "<span class='selected'>" + h(item.value) + " (" + item.hits.to_s + ")</span>"
650
+ text << "[#{link_to 'remove', remove_facet_params(solr_fname, item.value), :class=>'remove'}]"
651
+ text << "</li>"
652
+ # accommodate further call number levels
653
+ case solr_fname
654
+ when "lc_alpha_facet"
655
+ text << get_refine_facet("lc_b4cutter_facet", response)
656
+ when "dewey_2digit_facet"
657
+ text << get_refine_facet("dewey_b4cutter_facet", response)
658
+ when "dewey_1digit_facet"
659
+ text << get_refine_facet("dewey_2digit_facet", response)
660
+ end
661
+ else
662
+ # display the value as a link unless it is at the peer level of a selected call number facet -%>
663
+ if !( display_facet.name.match(/^(lc_|dewey_|gov_)/i) && params_facet_has_value?(display_facet.name) )
664
+ if item_count > 4
665
+ text << " <li class=\"more\">"
666
+ else
667
+ text << " <li>"
668
+ end
669
+ if params[:qt] == 'standard'
670
+ text << " #{h(item.value)} (" + item.hits.to_s + ")"
671
+ else
672
+ text << " #{link_to h(item.value), add_facet_params(solr_fname, item.value)} (" + item.hits.to_s + ")"
673
+ end
674
+ text << " </li>"
675
+ item_count += 1
676
+ end
677
+ end
678
+ end
679
+ if display_facet.items.length > 5
680
+ if !( display_facet.name.match(/^(lc_|dewey_|gov_)/i) && params_facet_has_value?(display_facet.name) )
681
+ text << "<li class='more_li'><a href='' class='more_link' alt='more' #{home_facet_field_labels[solr_fname]}>more...</a></li>"
682
+ text << "<li class='less_li' style='display:none;'><a href='' class='more_link' alt='less' #{home_facet_field_labels[solr_fname]}>less...</a></li>"
683
+ end
684
+ end
685
+ text << " </ul>"
686
+ text << "</li>"
687
+ end # have facet to display
688
+ text
689
+ end
690
+
691
+ # true or false, depending on whether the field and a value is in params[:f]
692
+ def params_facet_has_value?(field)
693
+ if params[:f] and params[:f][field]
694
+ !params[:f][field].compact.empty?
695
+ else
696
+ false
697
+ end
698
+ end
699
+
700
+
701
+ def get_search_breadcrumb_terms(q_param)
702
+ if q_param.scan(/"([^"\r\n]*)"/)
703
+ q_arr = []
704
+ old_q = q_param.dup
705
+ q_param.scan(/"([^"\r\n]*)"/).each{|t| q_arr << "\"#{h(t)}\""}
706
+ q_arr.each do |l|
707
+ old_q.gsub!(l,'')
708
+ end
709
+ unless old_q.blank?
710
+ old_q.split(' ').each {|q| q_arr << h(q) }
711
+ end
712
+ q_arr
713
+ else
714
+ q_arr = q_param.split(' ')
715
+ end
716
+ end
717
+
718
+ def get_advanced_search_query_terms(params)
719
+ # if using the standard query parser and have an actual query we need to modify the q param after the search results are requested to something more visually friendly
720
+ if params[:qt] == "standard" and params[:q] != "collection:sirsi"
721
+ str = []
722
+ fields = []
723
+ new_query = params[:q][1,params[:q].length-2]
724
+ new_query.gsub!(") AND (", " -|- ")
725
+ new_query.gsub!(") OR (", " -|- ")
726
+ new_query.gsub!(/\^\d+ OR /, " -|- ")
727
+ new_query.split(" -|- ").each do |query_string|
728
+ fields << query_string.split(":")[0]
729
+ query = query_string.split(":")[1][/\(.*\)/]
730
+ Blacklight.config[:advanced].each do |key,value|
731
+ if value.keys.collect{|x| x.to_s}.sort == fields.sort
732
+ str << "#{key.to_s == "description_checked" ? "Description-TOC" : key.to_s.capitalize} = #{query[1,query.length][0,query.length-2]}" unless str.include?("#{key.to_s == "description_checked" ? "Description-TOC" : key.to_s.capitalize} = #{query[1,query.length][0,query.length-2]}")
733
+ fields = []
734
+ end
735
+ end
736
+ end
737
+ h str.join(" #{params[:op]} ")
738
+ end
739
+ end
740
+
741
+ def get_advanced_search_filter_terms(params)
742
+ # Modifying the fq param to be what the UI is expecting from the f param, then setting the f param to this modified hash
743
+ # Note that the query to Solr has already been made, anything beyond this will just be modifying how the UI interperets the query
744
+ unless params[:fq].to_s.empty?
745
+ a_hash = {}
746
+ fq_params = params[:fq].split("), ")
747
+ fq_params.each do |fq_param|
748
+ fq_fields = fq_param.split(":")
749
+ fq_field = fq_fields[0]
750
+ fq_values = fq_fields[1][1,fq_fields[1].length][0,fq_fields[1].length-2].split('" OR "')
751
+ fq_values.each do |value|
752
+ if a_hash.has_key?("#{fq_field}")
753
+ a_hash["#{fq_field}"] << value.gsub('"',"")
754
+ else
755
+ a_hash["#{fq_field}"] = [value.gsub('"',"")]
756
+ end
757
+ end
758
+ end
759
+ a_hash
760
+ end
761
+ end
762
+
763
+ def previous_search_is_referrer?
764
+ # If the referrer params are empty and there is no search history return false (User went directly to the record w/o a search session)
765
+ if referrer_params.empty? and url_back_to_catalog.empty?
766
+ false
767
+ # If the search history == the referrer params return true.
768
+ elsif url_back_to_catalog == referrer_params
769
+ true
770
+ # If the referrer includes the base URL (ie, <Prev | Next> links on record view) then return true
771
+ elsif request.referrer.include?(url_for({:controller => 'catalog', :only_path => false}))
772
+ true
773
+ else
774
+ false
775
+ end
776
+ end
777
+
778
+ def referrer_params
779
+ request_params = {}
780
+ if request.referrer.to_s.include?("&") or request.referrer.to_s.include?("?")
781
+ request.referrer.to_s[/\/\?.*/].split("&").each do |paramater|
782
+ unless paramater == "/?"
783
+ key = CGI::unescape(paramater.split("=")[0].gsub(/\/\?/,"")).to_sym
784
+ key.to_s[0,2] == "/?" ? key.to_s.gsub!("/?","").to_sym : ""
785
+ value = paramater.split("=").length > 1 ? h(paramater.split("=")[1].gsub("+"," ")) : ""
786
+ if request_params.has_key?(key)
787
+ request_params[key] << CGI::unescape(value)
788
+ else
789
+ request_params[key] = CGI::unescape(value)
790
+ end
791
+ end
792
+ end
793
+ end
794
+ request_params
795
+ end
796
+
797
+ # url back to catalog
798
+ # show the url back to the search result, keeping the user's facet, query and paging choices intact by using session.
799
+ # this is to match against the http.referrer
800
+ def url_back_to_catalog
801
+ query_params = session[:search].dup || {}
802
+ query_params.delete :counter
803
+ query_params.delete :total
804
+ if query_params.has_key?(:f)
805
+ query_params[:f].each do |key,val|
806
+ query_params["f[#{key}][]".to_sym] = val.to_s
807
+ end
808
+ query_params.delete(:f)
809
+ end
810
+ query_params
811
+ end
812
+
813
+
814
+ # Generate display text for "nearby" selections according to call number
815
+ def get_nearby_items(document, response, how_many)
816
+ text = "<ul id='nearby_objects'>"
817
+
818
+ # TODO: how choose if there are multiple call numbers for this document?
819
+ # 1. VALID call numbers only
820
+ # 2. if only one, use it
821
+ # 3. if only one LC, use it
822
+ # 4. if multiple LC, do someting
823
+ # 5. if no LC, do something
824
+
825
+ if !document[:callnum_sort].nil?
826
+ =begin
827
+ num = document[:callnum_sort].length
828
+ if num == 1
829
+ this_item_shelfkey = document[:callnum_sort][0].downcase
830
+ elsif
831
+ # only one LC, use it
832
+ elsif
833
+ # mult LC, use ... one of them?
834
+ else
835
+ # no LC ... do something
836
+
837
+ end
838
+ =end
839
+
840
+ #puts('DEBUG: document has callnum_sort ' + document[:callnum_sort].to_s)
841
+ this_item_shelfkey = document[:callnum_sort][0].downcase
842
+ # this_item_reverse_shelfkey = reverse_alphanum(this_item_shelfkey)
843
+ # FIXME: don't have the right conversion yet ..
844
+ this_item_reverse_shelfkey = document[:callnum_reverse_sort][0].downcase
845
+
846
+ # TODO: need to take all the returned <li> and sort them by shelfkey, then by title, then by author
847
+
848
+ # get preceding bookspines
849
+
850
+ # terms is array of one element hashes with key=term and value=count
851
+ terms_array = get_next_terms(this_item_reverse_shelfkey, "callnum_reverse_sort", how_many+1)
852
+ reverse_shelfkeys_b4 = []
853
+ num_docs = 0
854
+ puts "num rev terms is " + terms_array.length.to_s
855
+ terms_array.each { |term_hash|
856
+ reverse_shelfkeys_b4 << term_hash.keys[0] unless term_hash.keys[0] == this_item_reverse_shelfkey
857
+ num_docs = num_docs + term_hash.values[0]
858
+ }
859
+ text << get_spines_from_field(reverse_shelfkeys_b4, "callnum_reverse_sort").join
860
+
861
+ =begin
862
+ # preceding shelfkeys are in the reverse order of what we need to display -
863
+ # they are returned as closest, next closest, ... , furthest
864
+ # but b/c they are displayed BEFORE the current result, they
865
+ # need to be ordered furthest to closest
866
+ # also, don't display THIS document's stuff yet.
867
+ # reverse_shelfkeys_b4.reverse_each do |r_shelfkey|
868
+ reverse_shelfkeys_b4.each do |r_shelfkey|
869
+ if r_shelfkey != reverse_shelfkeys_b4.first
870
+ # text << get_spines_from_field(reverse_shelfkeys_b4, "callnum_reverse_sort").join
871
+ text << get_spines_from_field([r_shelfkey], "callnum_reverse_sort").join
872
+ end
873
+ end
874
+ =end
875
+
876
+ # display spine for THIS doc's shelfkey
877
+ text << "<br/>"
878
+ if terms_array[0].values[0] == 1
879
+ # orig document is only instance of its shelfkey
880
+ spines = get_spines_from_doc(document, [this_item_shelfkey])
881
+ unless spines.nil?
882
+ spines.each { |spine|
883
+ text << spine unless text.include?(spine)
884
+ }
885
+ end
886
+ else
887
+ text << get_spines_from_field([this_item_shelfkey], "callnum_sort").join
888
+ end
889
+ text << "<br/>"
890
+
891
+ # get following bookspines
892
+ terms_array = get_next_terms(this_item_shelfkey, "callnum_sort", how_many+1)
893
+ shelfkeys_after = []
894
+ num_docs = 0
895
+ puts "num terms is " + terms_array.length.to_s
896
+ terms_array.each { |term_hash|
897
+ shelfkeys_after << term_hash.keys[0] unless term_hash.keys[0] == this_item_shelfkey
898
+ num_docs = num_docs + term_hash.values[0]
899
+ }
900
+
901
+ text << get_spines_from_field(shelfkeys_after, "callnum_sort").join
902
+
903
+ =begin
904
+ shelfkeys_after.each do |shelfkey|
905
+ if shelfkey != shelfkeys_after.first
906
+ # text << get_spines_from_field(shelfkeys_after, "callnum_sort").join
907
+ text << get_spines_from_field(shelfkey[0], "callnum_sort").join
908
+ end
909
+ end
910
+ =end
911
+ end
912
+
913
+ text << "</ul>"
914
+ return text unless text == "<ul id='nearby_objects'><br/><br/></ul>"
915
+ end
916
+
917
+
918
+ protected
919
+ # create an array of sorted html list items containing the appropriate display text
920
+ # (analogous to what would be visible if you were looking at the spine of
921
+ # a book on a shelf) from relevant solr docs, given a particular solr
922
+ # field and value for which to retrieve spine info.
923
+ # The shelf key in each html list item must match a desired shelf key in the
924
+ # desired_shelfkeys array
925
+ def get_spines_from_field(values, field)
926
+
927
+ # FIXME: I think we want to deal with reversing and the like in the calling
928
+ # method. This should get spines given a particular list of shelf keys
929
+ # in each doc, we look for item display matches for shelfkeys, not reverse shelfkeys
930
+ desired_shelfkeys = []
931
+ if (field == "callnum_reverse_sort")
932
+ values.each { |rev_shelfkey|
933
+ # turn it back into a shelfkey
934
+ desired_shelfkeys << reverse_alphanum(rev_shelfkey)
935
+ }
936
+ else
937
+ desired_shelfkeys = values
938
+ end
939
+
940
+ unsorted_result = []
941
+ docs = get_docs_for_field_values(values, field)
942
+ docs.each do |doc|
943
+ # FIXME!!! "desired_shelfkeys" is call numbers, but we have shelfkeys ...
944
+ unsorted_result = unsorted_result | get_spines_from_doc(doc, desired_shelfkeys)
945
+ end
946
+ unsorted_result.uniq!
947
+ # result is: title [(pub year)] [<br/> author] <br/> callnum
948
+
949
+ # need to sort results by callnum asc, then by title asc, then by pub date desc
950
+ sort_hash = {}
951
+ unsorted_result.each_index { |i|
952
+ line_array = unsorted_result[i].split("<br/>")
953
+ callnum = line_array.last
954
+ # need to get rid of <li> and link stuff
955
+ title_year = line_array.first.sub(/<li>.*<a.*">/, '')
956
+ title = title_year.sub(/\(\d.*\)/, '')
957
+ year = title_year.sub(/.*\(/, '')
958
+ sort_hash[i]= callnum + ' ' + title + ' ' + reverse_alphanum(year)
959
+ }
960
+ # sort by values, then order result (then lift and separate?)
961
+ sorted_array = sort_hash.sort { |a,b| a[1] <=> b[1]}
962
+ sorted_result = []
963
+ sorted_array.each_index { |i|
964
+ # sort_array is array of [unsorted_result_ix, sort_val]
965
+ sort_ix = sorted_array[i][0]
966
+ sorted_result[i]= unsorted_result[sorted_array[i][0]]
967
+ }
968
+
969
+ sorted_result
970
+ end
971
+
972
+ # create an array of html list items containing the appropriate display text
973
+ # (analogous to what would be visible if you were looking at the spine of
974
+ # a book on a shelf) from a solr doc.
975
+ # The shelf key in each html list item must match a desired shelf key in the
976
+ # desired_shelfkeys array
977
+ def get_spines_from_doc(doc, desired_shelfkeys, max_len=30)
978
+ result = []
979
+ return if doc[:item_display].nil?
980
+ doc[:item_display].each { |item_disp|
981
+ callnum = item_disp.split(" -|- ")[3]
982
+ # if desired_shelfkeys.include?(callnum)
983
+ if true
984
+ id = doc[:id]
985
+ title = doc[:title_245a_display]
986
+ author = case
987
+ when doc[:author_person_display] : doc[:author_person_display]
988
+ when doc[:author_corp_display] : doc[:author_corp_display]
989
+ when doc[:author_meeting_display] : doc[:author_meeting_display]
990
+ else nil
991
+ end
992
+ pub_year = doc[:pub_date]
993
+
994
+ spine_text = "<li>"
995
+ spine_text << link_to_document(doc, :label=>title[0,max_len])
996
+ spine_text << " (" + pub_year + ")" unless pub_year.nil? || pub_year.length == 0
997
+ spine_text << "<br/>" + author[0,max_len] unless author.nil?
998
+ spine_text << "<br/>" + callnum
999
+ spine_text << "</li>"
1000
+ result << spine_text unless result.include?(spine_text)
1001
+ end
1002
+ }
1003
+ return result
1004
+ end
1005
+
1006
+ def reverse_alphanum(str)
1007
+ rev_str = String.new(str)
1008
+ last = str.length-1
1009
+ for i in 0..last
1010
+ case rev_str[i,1]
1011
+ when '~': rev_str[i]= ' '
1012
+ when '0': rev_str[i]= 'z'
1013
+ when '1': rev_str[i]= 'y'
1014
+ when '2': rev_str[i]= 'x'
1015
+ when '3': rev_str[i]= 'w'
1016
+ when '4': rev_str[i]= 'v'
1017
+ when '5': rev_str[i]= 'u'
1018
+ when '6': rev_str[i]= 't'
1019
+ when '7': rev_str[i]= 's'
1020
+ when '8': rev_str[i]= 'r'
1021
+ when '9': rev_str[i]= 'q'
1022
+ when 'a': rev_str[i]= 'p'
1023
+ when 'b': rev_str[i]= 'o'
1024
+ when 'c': rev_str[i]= 'n'
1025
+ when 'd': rev_str[i]= 'm'
1026
+ when 'e': rev_str[i]= 'l'
1027
+ when 'f': rev_str[i]= 'k'
1028
+ when 'g': rev_str[i]= 'j'
1029
+ when 'h': rev_str[i]= 'i'
1030
+ when 'i': rev_str[i]= 'h'
1031
+ when 'j': rev_str[i]= 'g'
1032
+ when 'k': rev_str[i]= 'f'
1033
+ when 'l': rev_str[i]= 'e'
1034
+ when 'm': rev_str[i]= 'd'
1035
+ when 'n': rev_str[i]= 'c'
1036
+ when 'o': rev_str[i]= 'b'
1037
+ when 'p': rev_str[i]= 'a'
1038
+ when 'q','Q': rev_str[i]= '9'
1039
+ when 'r','R': rev_str[i]= '8'
1040
+ when 's','S': rev_str[i]= '7'
1041
+ when 't','T': rev_str[i]= '6'
1042
+ when 'u','U': rev_str[i]= '5'
1043
+ when 'v','V': rev_str[i]= '4'
1044
+ when 'w','W': rev_str[i]= '3'
1045
+ when 'x','X': rev_str[i]= '2'
1046
+ when 'y','Y': rev_str[i]= '1'
1047
+ when 'z','Z': rev_str[i]= '0'
1048
+ when 'A': rev_str[i]= 'P'
1049
+ when 'B': rev_str[i]= 'O'
1050
+ when 'C': rev_str[i]= 'N'
1051
+ when 'D': rev_str[i]= 'M'
1052
+ when 'E': rev_str[i]= 'L'
1053
+ when 'F': rev_str[i]= 'K'
1054
+ when 'G': rev_str[i]= 'J'
1055
+ when 'H': rev_str[i]= 'I'
1056
+ when 'I': rev_str[i]= 'H'
1057
+ when 'J': rev_str[i]= 'G'
1058
+ when 'K': rev_str[i]= 'F'
1059
+ when 'L': rev_str[i]= 'E'
1060
+ when 'M': rev_str[i]= 'D'
1061
+ when 'N': rev_str[i]= 'C'
1062
+ when 'O': rev_str[i]= 'B'
1063
+ when 'P': rev_str[i]= 'A'
1064
+ end
1065
+ end
1066
+ rev_str
1067
+ end
1068
+
1069
+ def translate_lib
1070
+ {"Archive of Recorded Sound" => "Archive of Recorded Sound",
1071
+ "Art & Architecture" => "Art",
1072
+ "Branner (Earth Sciences & Maps)" => "Earth Sciences",
1073
+ "Classics" => "Classics",
1074
+ "Cubberley (Education)" => "Education",
1075
+ "Crown (Law)" => "Law",
1076
+ "East Asia" => "East Asia",
1077
+ "Engineering" => "Engineering",
1078
+ "Falconer (Biology)" => "Biology",
1079
+ "Green (Humanities & Social Sciences)" => "Green Library",
1080
+ "Hoover Library" => "Hoover Library",
1081
+ "Hoover Archives" => "Hoover Archives",
1082
+ "Jackson (Business)" => "Business",
1083
+ "Jonsson (Government Documents)" => "GovDocs",
1084
+ "Lane (Medical)" => "Medicine",
1085
+ "Miller (Hopkins Marine Station)" => "Hopkins Marine",
1086
+ "Math & Computer Science" => "Math & CompSci",
1087
+ "Meyer" => "",
1088
+ "Music" => "Music",
1089
+ "SAL3 (Off-campus)" => "",
1090
+ "SAL Newark (Off-campus)" => "",
1091
+ "Physics" => "Physics",
1092
+ "Stanford Auxiliary Library (On-campus)" => "",
1093
+ "Special Collections & Archives" => "Special Collections",
1094
+ "Stanford University Libraries" => "",
1095
+ "Swain (Chemistry & Chem. Engineering)" => "Chemistry",
1096
+ "Tanner (Philosophy Dept.)" => "Philosophy",
1097
+ "Applied Physics Department" => ""}
1098
+ end
1099
+
1100
+ def relator_terms
1101
+ {"acp" => "Art copyist",
1102
+ "act" => "Actor",
1103
+ "adp" => "Adapter",
1104
+ "aft" => "Author of afterword, colophon, etc.",
1105
+ "anl" => "Analyst",
1106
+ "anm" => "Animator",
1107
+ "ann" => "Annotator",
1108
+ "ant" => "Bibliographic antecedent",
1109
+ "app" => "Applicant",
1110
+ "aqt" => "Author in quotations or text abstracts",
1111
+ "arc" => "Architect",
1112
+ "ard" => "Artistic director ",
1113
+ "arr" => "Arranger",
1114
+ "art" => "Artist",
1115
+ "asg" => "Assignee",
1116
+ "asn" => "Associated name",
1117
+ "att" => "Attributed name",
1118
+ "auc" => "Auctioneer",
1119
+ "aud" => "Author of dialog",
1120
+ "aui" => "Author of introduction",
1121
+ "aus" => "Author of screenplay",
1122
+ "aut" => "Author",
1123
+ "bdd" => "Binding designer",
1124
+ "bjd" => "Bookjacket designer",
1125
+ "bkd" => "Book designer",
1126
+ "bkp" => "Book producer",
1127
+ "bnd" => "Binder",
1128
+ "bpd" => "Bookplate designer",
1129
+ "bsl" => "Bookseller",
1130
+ "ccp" => "Conceptor",
1131
+ "chr" => "Choreographer",
1132
+ "clb" => "Collaborator",
1133
+ "cli" => "Client",
1134
+ "cll" => "Calligrapher",
1135
+ "clt" => "Collotyper",
1136
+ "cmm" => "Commentator",
1137
+ "cmp" => "Composer",
1138
+ "cmt" => "Compositor",
1139
+ "cng" => "Cinematographer",
1140
+ "cnd" => "Conductor",
1141
+ "cns" => "Censor",
1142
+ "coe" => "Contestant -appellee",
1143
+ "col" => "Collector",
1144
+ "com" => "Compiler",
1145
+ "cos" => "Contestant",
1146
+ "cot" => "Contestant -appellant",
1147
+ "cov" => "Cover designer",
1148
+ "cpc" => "Copyright claimant",
1149
+ "cpe" => "Complainant-appellee",
1150
+ "cph" => "Copyright holder",
1151
+ "cpl" => "Complainant",
1152
+ "cpt" => "Complainant-appellant",
1153
+ "cre" => "Creator",
1154
+ "crp" => "Correspondent",
1155
+ "crr" => "Corrector",
1156
+ "csl" => "Consultant",
1157
+ "csp" => "Consultant to a project",
1158
+ "cst" => "Costume designer",
1159
+ "ctb" => "Contributor",
1160
+ "cte" => "Contestee-appellee",
1161
+ "ctg" => "Cartographer",
1162
+ "ctr" => "Contractor",
1163
+ "cts" => "Contestee",
1164
+ "ctt" => "Contestee-appellant",
1165
+ "cur" => "Curator",
1166
+ "cwt" => "Commentator for written text",
1167
+ "dfd" => "Defendant",
1168
+ "dfe" => "Defendant-appellee",
1169
+ "dft" => "Defendant-appellant",
1170
+ "dgg" => "Degree grantor",
1171
+ "dis" => "Dissertant",
1172
+ "dln" => "Delineator",
1173
+ "dnc" => "Dancer",
1174
+ "dnr" => "Donor",
1175
+ "dpc" => "Depicted",
1176
+ "dpt" => "Depositor",
1177
+ "drm" => "Draftsman",
1178
+ "drt" => "Director",
1179
+ "dsr" => "Designer",
1180
+ "dst" => "Distributor",
1181
+ "dtc" => "Data contributor ",
1182
+ "dte" => "Dedicatee",
1183
+ "dtm" => "Data manager ",
1184
+ "dto" => "Dedicator",
1185
+ "dub" => "Dubious author",
1186
+ "edt" => "Editor",
1187
+ "egr" => "Engraver",
1188
+ "elg" => "Electrician ",
1189
+ "elt" => "Electrotyper",
1190
+ "eng" => "Engineer",
1191
+ "etr" => "Etcher",
1192
+ "exp" => "Expert",
1193
+ "fac" => "Facsimilist",
1194
+ "fld" => "Field director ",
1195
+ "flm" => "Film editor",
1196
+ "fmo" => "Former owner",
1197
+ "fpy" => "First party",
1198
+ "fnd" => "Funder",
1199
+ "frg" => "Forger",
1200
+ "gis" => "Geographic information specialist ",
1201
+ "grt" => "Graphic technician",
1202
+ "hnr" => "Honoree",
1203
+ "hst" => "Host",
1204
+ "ill" => "Illustrator",
1205
+ "ilu" => "Illuminator",
1206
+ "ins" => "Inscriber",
1207
+ "inv" => "Inventor",
1208
+ "itr" => "Instrumentalist",
1209
+ "ive" => "Interviewee",
1210
+ "ivr" => "Interviewer",
1211
+ "lbr" => "Laboratory ",
1212
+ "lbt" => "Librettist",
1213
+ "ldr" => "Laboratory director ",
1214
+ "led" => "Lead",
1215
+ "lee" => "Libelee-appellee",
1216
+ "lel" => "Libelee",
1217
+ "len" => "Lender",
1218
+ "let" => "Libelee-appellant",
1219
+ "lgd" => "Lighting designer",
1220
+ "lie" => "Libelant-appellee",
1221
+ "lil" => "Libelant",
1222
+ "lit" => "Libelant-appellant",
1223
+ "lsa" => "Landscape architect",
1224
+ "lse" => "Licensee",
1225
+ "lso" => "Licensor",
1226
+ "ltg" => "Lithographer",
1227
+ "lyr" => "Lyricist",
1228
+ "mcp" => "Music copyist",
1229
+ "mfr" => "Manufacturer",
1230
+ "mdc" => "Metadata contact",
1231
+ "mod" => "Moderator",
1232
+ "mon" => "Monitor",
1233
+ "mrk" => "Markup editor",
1234
+ "msd" => "Musical director",
1235
+ "mte" => "Metal-engraver",
1236
+ "mus" => "Musician",
1237
+ "nrt" => "Narrator",
1238
+ "opn" => "Opponent",
1239
+ "org" => "Originator",
1240
+ "orm" => "Organizer of meeting",
1241
+ "oth" => "Other",
1242
+ "own" => "Owner",
1243
+ "pat" => "Patron",
1244
+ "pbd" => "Publishing director",
1245
+ "pbl" => "Publisher",
1246
+ "pdr" => "Project director",
1247
+ "pfr" => "Proofreader",
1248
+ "pht" => "Photographer",
1249
+ "plt" => "Platemaker",
1250
+ "pma" => "Permitting agency",
1251
+ "pmn" => "Production manager",
1252
+ "pop" => "Printer of plates",
1253
+ "ppm" => "Papermaker",
1254
+ "ppt" => "Puppeteer",
1255
+ "prc" => "Process contact",
1256
+ "prd" => "Production personnel",
1257
+ "prf" => "Performer",
1258
+ "prg" => "Programmer",
1259
+ "prm" => "Printmaker",
1260
+ "pro" => "Producer",
1261
+ "prt" => "Printer",
1262
+ "pta" => "Patent applicant",
1263
+ "pte" => "Plaintiff -appellee",
1264
+ "ptf" => "Plaintiff",
1265
+ "pth" => "Patent holder",
1266
+ "ptt" => "Plaintiff-appellant",
1267
+ "rbr" => "Rubricator",
1268
+ "rce" => "Recording engineer",
1269
+ "rcp" => "Recipient",
1270
+ "red" => "Redactor",
1271
+ "ren" => "Renderer",
1272
+ "res" => "Researcher",
1273
+ "rev" => "Reviewer",
1274
+ "rps" => "Repository",
1275
+ "rpt" => "Reporter",
1276
+ "rpy" => "Responsible party",
1277
+ "rse" => "Respondent-appellee",
1278
+ "rsg" => "Restager",
1279
+ "rsp" => "Respondent",
1280
+ "rst" => "Respondent-appellant",
1281
+ "rth" => "Research team head",
1282
+ "rtm" => "Research team member",
1283
+ "sad" => "Scientific advisor",
1284
+ "sce" => "Scenarist",
1285
+ "scl" => "Sculptor",
1286
+ "scr" => "Scribe",
1287
+ "sds" => "Sound designer",
1288
+ "sec" => "Secretary",
1289
+ "sgn" => "Signer",
1290
+ "sht" => "Supporting host",
1291
+ "sng" => "Singer",
1292
+ "spk" => "Speaker",
1293
+ "spn" => "Sponsor",
1294
+ "spy" => "Second party",
1295
+ "srv" => "Surveyor",
1296
+ "std" => "Set designer",
1297
+ "stl" => "Storyteller",
1298
+ "stm" => "Stage manager",
1299
+ "stn" => "Standards body",
1300
+ "str" => "Stereotyper",
1301
+ "tcd" => "Technical director",
1302
+ "tch" => "Teacher",
1303
+ "ths" => "Thesis advisor",
1304
+ "trc" => "Transcriber",
1305
+ "trl" => "Translator",
1306
+ "tyd" => "Type designer",
1307
+ "tyg" => "Typographer",
1308
+ "vdg" => "Videographer",
1309
+ "voc" => "Vocalist",
1310
+ "wam" => "Writer of accompanying material",
1311
+ "wdc" => "Woodcutter",
1312
+ "wde" => "Wood -engraver",
1313
+ "wit" => "Witness"}
1314
+ end
1315
+
1316
+ def name_change_780_translations
1317
+ {"0" => "Continues",
1318
+ "1" => "Continues in part",
1319
+ "2" => "Supersedes",
1320
+ "3" => "Supersedes in part",
1321
+ "4" => "Merged from",
1322
+ "5" => "Absorbed",
1323
+ "6" => "Absorbed in part",
1324
+ "7" => "Separated from"}
1325
+ end
1326
+
1327
+ def name_change_785_translations
1328
+ {"0" => "Continued by",
1329
+ "1" => "Continued in part by",
1330
+ "2" => "Superseded by",
1331
+ "3" => "Superseded in part by",
1332
+ "4" => "Absorbed by",
1333
+ "5" => "Absorbed in part by",
1334
+ "6" => "Split into",
1335
+ "7" => "Merged with ... to form ...",
1336
+ "8" => "Changed back to"}
1337
+ end
1338
+ end