hydra-head 3.0.0pre1

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