umlaut 3.0.0alpha1

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 (293) hide show
  1. data/LICENSE +7 -0
  2. data/README.md +49 -0
  3. data/Rakefile +37 -0
  4. data/app/assets/images/error.gif +0 -0
  5. data/app/assets/images/export_bg_bot.gif +0 -0
  6. data/app/assets/images/export_bg_mid.gif +0 -0
  7. data/app/assets/images/export_bg_top.gif +0 -0
  8. data/app/assets/images/famfamfam/book_open.png +0 -0
  9. data/app/assets/images/famfamfam/cross.png +0 -0
  10. data/app/assets/images/famfamfam/page_sound.gif +0 -0
  11. data/app/assets/images/famfamfam/page_text.gif +0 -0
  12. data/app/assets/images/famfamfam/page_up.gif +0 -0
  13. data/app/assets/images/famfamfam/page_white.png +0 -0
  14. data/app/assets/images/famfamfam/readme.html +1495 -0
  15. data/app/assets/images/famfamfam/tiny_cross.png +0 -0
  16. data/app/assets/images/frame_remove.gif +0 -0
  17. data/app/assets/images/ico_go.gif +0 -0
  18. data/app/assets/images/jhu_findit.gif +0 -0
  19. data/app/assets/images/list_closed.png +0 -0
  20. data/app/assets/images/list_open.png +0 -0
  21. data/app/assets/images/more_info.gif +0 -0
  22. data/app/assets/images/rails.png +0 -0
  23. data/app/assets/images/request.gif +0 -0
  24. data/app/assets/images/spinner.gif +0 -0
  25. data/app/assets/javascripts/umlaut/ajax_windows.js +35 -0
  26. data/app/assets/javascripts/umlaut/ensure_window_size.js.erb +34 -0
  27. data/app/assets/javascripts/umlaut/expand_contract_toggle.js +25 -0
  28. data/app/assets/javascripts/umlaut/search_autocomplete.js +46 -0
  29. data/app/assets/javascripts/umlaut/simple_visible_toggle.js +8 -0
  30. data/app/assets/javascripts/umlaut/update_html.js +152 -0
  31. data/app/assets/javascripts/umlaut.js +17 -0
  32. data/app/assets/stylesheets/umlaut.css +857 -0
  33. data/app/controllers/application_controller.rb +14 -0
  34. data/app/controllers/export_email_controller.rb +123 -0
  35. data/app/controllers/js_helper_controller.rb +10 -0
  36. data/app/controllers/link_router_controller.rb +87 -0
  37. data/app/controllers/open_search_controller.rb +9 -0
  38. data/app/controllers/resolve_controller.rb +288 -0
  39. data/app/controllers/resource_controller.rb +83 -0
  40. data/app/controllers/search_controller.rb +328 -0
  41. data/app/controllers/search_methods/sfx3.rb +148 -0
  42. data/app/controllers/search_methods/sfx4.rb +257 -0
  43. data/app/controllers/search_methods/sfx_api.rb +47 -0
  44. data/app/controllers/store_controller.rb +64 -0
  45. data/app/controllers/umlaut/controller_behavior.rb +20 -0
  46. data/app/controllers/umlaut/controller_logic.rb +96 -0
  47. data/app/controllers/umlaut/error_handling.rb +48 -0
  48. data/app/controllers/umlaut_controller.rb +112 -0
  49. data/app/helpers/application_helper.rb +4 -0
  50. data/app/helpers/emailer_helper.rb +43 -0
  51. data/app/helpers/export_email_helper.rb +34 -0
  52. data/app/helpers/open_search_helper.rb +7 -0
  53. data/app/helpers/resolve_helper.rb +225 -0
  54. data/app/helpers/search_helper.rb +50 -0
  55. data/app/helpers/umlaut/footer_helper.rb +64 -0
  56. data/app/helpers/umlaut/helper.rb +62 -0
  57. data/app/helpers/umlaut/html_head_helper.rb +37 -0
  58. data/app/helpers/umlaut/url_generation.rb +77 -0
  59. data/app/mailers/emailer.rb +48 -0
  60. data/app/models/clickthrough.rb +2 -0
  61. data/app/models/collection.rb +259 -0
  62. data/app/models/crossref_lookup.rb +2 -0
  63. data/app/models/dispatched_service.rb +58 -0
  64. data/app/models/permalink.rb +29 -0
  65. data/app/models/referent.rb +473 -0
  66. data/app/models/referent_value.rb +14 -0
  67. data/app/models/request.rb +449 -0
  68. data/app/models/service_response.rb +179 -0
  69. data/app/models/service_store.rb +59 -0
  70. data/app/models/service_type_value.rb +58 -0
  71. data/app/models/service_wave.rb +150 -0
  72. data/app/models/sfx_db/az_additional_title.rb +11 -0
  73. data/app/models/sfx_db/az_letter_group.rb +11 -0
  74. data/app/models/sfx_db/az_title.rb +38 -0
  75. data/app/models/sfx_db/az_title_v2.rb +34 -0
  76. data/app/models/sfx_db/isbn.rb +12 -0
  77. data/app/models/sfx_db/issn.rb +12 -0
  78. data/app/models/sfx_db/object.rb +35 -0
  79. data/app/models/sfx_db/object_portfolio.rb +6 -0
  80. data/app/models/sfx_db/publisher.rb +10 -0
  81. data/app/models/sfx_db/sfx_db_base.rb +54 -0
  82. data/app/models/sfx_db/target.rb +9 -0
  83. data/app/models/sfx_db/target_service.rb +10 -0
  84. data/app/models/sfx_db/title.rb +10 -0
  85. data/app/models/sfx_db.rb +10 -0
  86. data/app/models/sfx_url.rb +35 -0
  87. data/app/views/emailer/citation.text.erb +28 -0
  88. data/app/views/emailer/short_citation.text.erb +8 -0
  89. data/app/views/export_email/_email.html.erb +25 -0
  90. data/app/views/export_email/_send_email.html.erb +3 -0
  91. data/app/views/export_email/_send_txt.html.erb +3 -0
  92. data/app/views/export_email/_txt.html.erb +62 -0
  93. data/app/views/export_email/email.html.erb +3 -0
  94. data/app/views/export_email/send_email.html.erb +1 -0
  95. data/app/views/export_email/send_txt.html.erb +1 -0
  96. data/app/views/export_email/txt.html.erb +3 -0
  97. data/app/views/js_helper/loader.erb.js +13 -0
  98. data/app/views/layouts/umlaut.html.erb +52 -0
  99. data/app/views/open_search/index.html.erb +9 -0
  100. data/app/views/resolve/_api_in_progress.xml.erb +21 -0
  101. data/app/views/resolve/_background_progress.html.erb +51 -0
  102. data/app/views/resolve/_background_updater.html.erb +38 -0
  103. data/app/views/resolve/_citation.html.erb +87 -0
  104. data/app/views/resolve/_coins.html.erb +1 -0
  105. data/app/views/resolve/_compact_citation.html.erb +33 -0
  106. data/app/views/resolve/_cover_image.html.erb +35 -0
  107. data/app/views/resolve/_fulltext.html.erb +55 -0
  108. data/app/views/resolve/_help.html.erb +17 -0
  109. data/app/views/resolve/_holding.html.erb +91 -0
  110. data/app/views/resolve/_related_items.html.erb +35 -0
  111. data/app/views/resolve/_search_inside.html.erb +62 -0
  112. data/app/views/resolve/_section_display.html.erb +49 -0
  113. data/app/views/resolve/_service_errors.html.erb +29 -0
  114. data/app/views/resolve/_standard_response_item.html.erb +89 -0
  115. data/app/views/resolve/api.xml.builder +72 -0
  116. data/app/views/resolve/background_status.html.erb +26 -0
  117. data/app/views/resolve/index.html.erb +73 -0
  118. data/app/views/resolve/partial_html_sections.xml.erb +30 -0
  119. data/app/views/search/_a_to_z.html.erb +6 -0
  120. data/app/views/search/_citation.html.erb +94 -0
  121. data/app/views/search/_pager.html.erb +60 -0
  122. data/app/views/search/books.html.erb +103 -0
  123. data/app/views/search/journal_search.html.erb +90 -0
  124. data/app/views/search/journals.html.erb +167 -0
  125. data/app/views/search/opensearch_description.rxml +10 -0
  126. data/app/views/testing/index.html.erb +1 -0
  127. data/app/views/umlaut/README +5 -0
  128. data/app/views/umlaut/error.html.erb +45 -0
  129. data/db/migrate/01_umlaut_init.rb +113 -0
  130. data/db/orig_fixed_data/service_type_values.yml +120 -0
  131. data/db/seeds.rb +7 -0
  132. data/lib/CronTab.rb +192 -0
  133. data/lib/aws_product_sign.rb +146 -0
  134. data/lib/exlibris/aleph/patron.rb +64 -0
  135. data/lib/exlibris/aleph/record.rb +54 -0
  136. data/lib/exlibris/aleph/rest_api.rb +29 -0
  137. data/lib/exlibris/primo/holding.rb +192 -0
  138. data/lib/exlibris/primo/rsrc.rb +17 -0
  139. data/lib/exlibris/primo/searcher.rb +276 -0
  140. data/lib/exlibris/primo/source/aleph.rb +46 -0
  141. data/lib/exlibris/primo/source/distribution/nyu_aleph.rb +323 -0
  142. data/lib/exlibris/primo/toc.rb +17 -0
  143. data/lib/exlibris/primo_ws.rb +140 -0
  144. data/lib/generators/templates/umlaut_services.yml +237 -0
  145. data/lib/generators/umlaut/asset_hooks_generator.rb +44 -0
  146. data/lib/generators/umlaut/install_generator.rb +110 -0
  147. data/lib/hip3/bib.rb +291 -0
  148. data/lib/hip3/bib_searcher.rb +302 -0
  149. data/lib/hip3/custom_field_lookup.rb +44 -0
  150. data/lib/hip3/holding.rb +50 -0
  151. data/lib/hip3/item.rb +65 -0
  152. data/lib/hip3/receipt.rb +7 -0
  153. data/lib/hip3/serial_copy.rb +82 -0
  154. data/lib/holding.rb +32 -0
  155. data/lib/marc_helper.rb +254 -0
  156. data/lib/metadata_helper.rb +312 -0
  157. data/lib/opensearch_feed.rb +398 -0
  158. data/lib/opensearch_query.rb +98 -0
  159. data/lib/referent_filter.rb +16 -0
  160. data/lib/referent_filters/dissertation_catch.rb +45 -0
  161. data/lib/section_renderer.rb +503 -0
  162. data/lib/service.rb +336 -0
  163. data/lib/service_adaptors/ajax_export.rb +37 -0
  164. data/lib/service_adaptors/amazon.rb +412 -0
  165. data/lib/service_adaptors/blacklight.rb +327 -0
  166. data/lib/service_adaptors/book_finder.rb +40 -0
  167. data/lib/service_adaptors/bx.rb +51 -0
  168. data/lib/service_adaptors/cover_thing.rb +73 -0
  169. data/lib/service_adaptors/elsevier_cover.rb +57 -0
  170. data/lib/service_adaptors/email_export.rb +10 -0
  171. data/lib/service_adaptors/ezproxy.rb +171 -0
  172. data/lib/service_adaptors/google_book_search.rb +442 -0
  173. data/lib/service_adaptors/gpo.rb +124 -0
  174. data/lib/service_adaptors/hathi_trust.rb +308 -0
  175. data/lib/service_adaptors/hip3_service.rb +150 -0
  176. data/lib/service_adaptors/hip_holding_search.rb +237 -0
  177. data/lib/service_adaptors/internet_archive.rb +488 -0
  178. data/lib/service_adaptors/isbn_db.rb +86 -0
  179. data/lib/service_adaptors/isi.rb +258 -0
  180. data/lib/service_adaptors/jcr.rb +146 -0
  181. data/lib/service_adaptors/opac.rb +351 -0
  182. data/lib/service_adaptors/open_library.rb +316 -0
  183. data/lib/service_adaptors/open_library_cover.rb +73 -0
  184. data/lib/service_adaptors/primo_service.rb +392 -0
  185. data/lib/service_adaptors/primo_source.rb +78 -0
  186. data/lib/service_adaptors/pubmed.rb +133 -0
  187. data/lib/service_adaptors/request_to_fixture.rb +68 -0
  188. data/lib/service_adaptors/scopus.rb +295 -0
  189. data/lib/service_adaptors/sfx-new.rb +557 -0
  190. data/lib/service_adaptors/sfx.rb +566 -0
  191. data/lib/service_adaptors/sfx_backchannel_record.rb +69 -0
  192. data/lib/service_adaptors/txt_holding_export.rb +32 -0
  193. data/lib/service_adaptors/ulrichs_cover.rb +57 -0
  194. data/lib/service_adaptors/ulrichs_link.rb +47 -0
  195. data/lib/service_adaptors/worldcat.rb +116 -0
  196. data/lib/service_adaptors/worldcat_identities.rb +591 -0
  197. data/lib/tasks/umlaut.rake +134 -0
  198. data/lib/umlaut/default_configuration.rb +5 -0
  199. data/lib/umlaut/routes.rb +136 -0
  200. data/lib/umlaut/version.rb +3 -0
  201. data/lib/umlaut.rb +37 -0
  202. data/lib/umlaut_configurable.rb +343 -0
  203. data/lib/umlaut_http.rb +100 -0
  204. data/lib/xml_schema_helper.rb +109 -0
  205. data/test/dummy/Rakefile +7 -0
  206. data/test/dummy/app/assets/javascripts/application.js +13 -0
  207. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  208. data/test/dummy/app/controllers/application_controller.rb +3 -0
  209. data/test/dummy/app/controllers/umlaut_controller.rb +112 -0
  210. data/test/dummy/app/helpers/application_helper.rb +2 -0
  211. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  212. data/test/dummy/config/application.rb +45 -0
  213. data/test/dummy/config/boot.rb +10 -0
  214. data/test/dummy/config/database-jhu.yml +44 -0
  215. data/test/dummy/config/database.yml +25 -0
  216. data/test/dummy/config/environment.rb +5 -0
  217. data/test/dummy/config/environments/development.rb +34 -0
  218. data/test/dummy/config/environments/production.rb +60 -0
  219. data/test/dummy/config/environments/test.rb +39 -0
  220. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  221. data/test/dummy/config/initializers/inflections.rb +10 -0
  222. data/test/dummy/config/initializers/mime_types.rb +5 -0
  223. data/test/dummy/config/initializers/secret_token.rb +7 -0
  224. data/test/dummy/config/initializers/session_store.rb +8 -0
  225. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  226. data/test/dummy/config/locales/en.yml +5 -0
  227. data/test/dummy/config/routes.rb +61 -0
  228. data/test/dummy/config/umlaut_services.yml +237 -0
  229. data/test/dummy/config.ru +4 -0
  230. data/test/dummy/db/migrate/20111228211210_umlaut_init.rb +113 -0
  231. data/test/dummy/db/schema.rb +124 -0
  232. data/test/dummy/log/development.log +12981 -0
  233. data/test/dummy/log/production.log +0 -0
  234. data/test/dummy/public/404.html +26 -0
  235. data/test/dummy/public/422.html +26 -0
  236. data/test/dummy/public/500.html +26 -0
  237. data/test/dummy/public/favicon.ico +0 -0
  238. data/test/dummy/script/rails +6 -0
  239. data/test/dummy/tmp/cache/assets/C5F/340/sprockets%2F99692920160b7a279b86a80415b79db7 +0 -0
  240. data/test/dummy/tmp/cache/assets/C70/4D0/sprockets%2F034ad2036e623081bd352800786dfe80 +0 -0
  241. data/test/dummy/tmp/cache/assets/C73/920/sprockets%2Fd371318f22900492fd180f17c5e2a504 +9268 -0
  242. data/test/dummy/tmp/cache/assets/C80/980/sprockets%2Fc94807409c1523d43e18d25f35d93c41 +0 -0
  243. data/test/dummy/tmp/cache/assets/C8F/780/sprockets%2Fe47e28558116fb5f8038754e60d1961d +11769 -0
  244. data/test/dummy/tmp/cache/assets/CAA/EB0/sprockets%2F1d179210e8b76f1ea63c802688a015e4 +9271 -0
  245. data/test/dummy/tmp/cache/assets/CBB/9C0/sprockets%2F706f28923fb754cad04b9107c89986a1 +0 -0
  246. data/test/dummy/tmp/cache/assets/CBF/B60/sprockets%2F08ca89671549936265dcb673bf02e36f +0 -0
  247. data/test/dummy/tmp/cache/assets/CC9/9F0/sprockets%2F306166316e2cafd13c15e62b51a2339d +0 -0
  248. data/test/dummy/tmp/cache/assets/CF6/F20/sprockets%2F5b2ffa1103079dfd555197838f87a99f +0 -0
  249. data/test/dummy/tmp/cache/assets/CF7/2B0/sprockets%2F25a7c73655bd3598173b39d9f98bcd46 +862 -0
  250. data/test/dummy/tmp/cache/assets/CFE/080/sprockets%2F37fe9f4255baddbd549a659914929398 +0 -0
  251. data/test/dummy/tmp/cache/assets/D22/060/sprockets%2F9aec77b768e91a802d284271c58e2f7e +21357 -0
  252. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  253. data/test/dummy/tmp/cache/assets/D33/6D0/sprockets%2F500129c57f1146e556ec3aacd6cd38c1 +0 -0
  254. data/test/dummy/tmp/cache/assets/D33/FD0/sprockets%2F2ba0b4e6334a77b923e5f770381bb2bf +0 -0
  255. data/test/dummy/tmp/cache/assets/D42/C20/sprockets%2Fbcf14e437b1582bf93b77670acf8e090 +21353 -0
  256. data/test/dummy/tmp/cache/assets/D50/A30/sprockets%2F7d8b294ac433db5d056538f8cf7c66b9 +0 -0
  257. data/test/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +872 -0
  258. data/test/dummy/tmp/cache/assets/D65/590/sprockets%2Fc1bb92fc3406a126b7dd302edc96d629 +0 -0
  259. data/test/dummy/tmp/cache/assets/D71/6B0/sprockets%2Fde558b71b494cf09b1bf055c8dff0353 +0 -0
  260. data/test/dummy/tmp/cache/assets/D72/610/sprockets%2Fa8c708eeb30ef93de34d755d4f45d023 +859 -0
  261. data/test/dummy/tmp/cache/assets/D76/AD0/sprockets%2Fe2158cde93188cf5ab6457bc6d6602ec +0 -0
  262. data/test/dummy/tmp/cache/assets/D7A/E40/sprockets%2F9622ffcc499a57627cd1bb18fe31b8e4 +11772 -0
  263. data/test/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +0 -0
  264. data/test/dummy/tmp/cache/assets/D9B/770/sprockets%2F8aacf02eb7dbb0949704b28f27b87e0b +0 -0
  265. data/test/dummy/tmp/cache/assets/DA6/A80/sprockets%2F92e26d8e58d5bcc8b8f6c25d1b05b9c1 +0 -0
  266. data/test/dummy/tmp/cache/assets/DE8/790/sprockets%2Fd1333bde2b9aafcc712d11dd09ab35d8 +0 -0
  267. data/test/dummy/tmp/cache/assets/DF7/F30/sprockets%2F7bc16c4109b17fabe29f8ddbbf732d1c +374 -0
  268. data/test/dummy/tmp/cache/assets/E03/570/sprockets%2F493bdc0ac14cd4f57fdfe4253f992bde +0 -0
  269. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  270. data/test/dummy/tmp/cache/assets/E0B/4B0/sprockets%2F7988df51a61c81ce6ede4a2d4c8cce4f +377 -0
  271. data/test/dummy/tmp/cache/assets/E5F/960/sprockets%2Fdc007b6cad5c7ef08e33ec28cfff0ef6 +0 -0
  272. data/test/fixtures/dispatched_services.yml +5 -0
  273. data/test/fixtures/permalinks.yml +5 -0
  274. data/test/fixtures/referent_values.yml +1734 -0
  275. data/test/fixtures/referents.yml +156 -0
  276. data/test/fixtures/requests.yml +284 -0
  277. data/test/fixtures/service_responses.yml +5 -0
  278. data/test/fixtures/sfx_urls.yml +4 -0
  279. data/test/performance/browsing_test.rb +9 -0
  280. data/test/test_helper.rb +10 -0
  281. data/test/umlaut_test.rb +7 -0
  282. data/test/unit/aleph_patron_test.rb +39 -0
  283. data/test/unit/aleph_record_benchmarks.rb +28 -0
  284. data/test/unit/aleph_record_test.rb +30 -0
  285. data/test/unit/aws_product_sign_test.rb +93 -0
  286. data/test/unit/collection_test.rb +76 -0
  287. data/test/unit/google_book_search_test.rb +101 -0
  288. data/test/unit/primo_searcher_test.rb +403 -0
  289. data/test/unit/primo_service_test.rb +939 -0
  290. data/test/unit/primo_ws_test.rb +131 -0
  291. data/test/unit/service_response_test.rb +9 -0
  292. data/test/unit/service_test.rb +33 -0
  293. metadata +580 -0
@@ -0,0 +1,257 @@
1
+ require 'nokogiri'
2
+
3
+ module SearchMethods
4
+ module Sfx4
5
+ include MetadataHelper # for normalize_lccn
6
+
7
+ protected
8
+
9
+ # used by umlaut:load_sfx_urls task. Kind of hacky way of trying to extract
10
+ # target URLs from SFX4.
11
+ def self.fetch_sfx_urls(sfx_global_db = "sfxglb41")
12
+ connection = SfxDb::Object.connection
13
+
14
+ # Crazy crazy URLs to try to find PARSE_PARAMS in Sfx4 db that have a period in
15
+ # them, so they look like they might be URLs. Parse params could be at target service
16
+ # level, or at portfolio level; and could be in local overrides or in global kb.
17
+ # This is crazy crazy SQL to get this, sorry. Talking directly to SFX db isn't
18
+ # a great idea, but best way we've found to get this for now. Might make more
19
+ # sense to try to use the (very very slow) SFX export in the future instead.
20
+ sql = %{
21
+ SELECT
22
+ COALESCE(LCL_SERVICE_LINKING_INFO.PARSE_PARAM,KB_TARGET_SERVICES.PARSE_PARAM) PARSE_PARAM
23
+ FROM
24
+ LCL_TARGET_INVENTORY
25
+ JOIN #{sfx_global_db}.KB_TARGET_SERVICES
26
+ ON KB_TARGET_SERVICES.TARGET_ID = LCL_TARGET_INVENTORY.TARGET_ID
27
+ JOIN LCL_SERVICE_INVENTORY
28
+ ON LCL_TARGET_INVENTORY.TARGET_ID = LCL_SERVICE_INVENTORY.TARGET_ID
29
+ LEFT OUTER JOIN LCL_SERVICE_LINKING_INFO
30
+ ON LCL_SERVICE_INVENTORY.TARGET_SERVICE_ID = LCL_SERVICE_LINKING_INFO.TARGET_SERVICE_ID
31
+ WHERE
32
+ ( LCL_SERVICE_LINKING_INFO.PARSE_PARAM like '%.%' OR
33
+ KB_TARGET_SERVICES.PARSE_PARAM like '%.%' )
34
+ AND
35
+ LCL_SERVICE_INVENTORY.ACTIVATION_STATUS='ACTIVE'
36
+ AND
37
+ LCL_TARGET_INVENTORY.ACTIVATION_STATUS = 'ACTIVE'
38
+
39
+ UNION
40
+ -- object portfolio parse param version
41
+ SELECT
42
+ COALESCE(LCL_OBJECT_PORTFOLIO_LINKING_INFO.PARSE_PARAM, KB_OBJECT_PORTFOLIOS.PARSE_PARAM) PARSE_PARAM
43
+ FROM
44
+ #{sfx_global_db}.KB_OBJECT_PORTFOLIOS
45
+ JOIN LCL_SERVICE_INVENTORY
46
+ ON KB_OBJECT_PORTFOLIOS.TARGET_SERVICE_ID = LCL_SERVICE_INVENTORY.TARGET_SERVICE_ID
47
+ JOIN LCL_OBJECT_PORTFOLIO_INVENTORY
48
+ ON KB_OBJECT_PORTFOLIOS.OP_ID = LCL_OBJECT_PORTFOLIO_INVENTORY.OP_ID
49
+ left outer join LCL_OBJECT_PORTFOLIO_LINKING_INFO
50
+ ON KB_OBJECT_PORTFOLIOS.OP_ID = LCL_OBJECT_PORTFOLIO_LINKING_INFO.OP_ID
51
+ WHERE
52
+ ( KB_OBJECT_PORTFOLIOS.PARSE_PARAM like '%.%' OR
53
+ LCL_OBJECT_PORTFOLIO_LINKING_INFO.PARSE_PARAM like '%.%' )
54
+ AND LCL_OBJECT_PORTFOLIO_INVENTORY.ACTIVATION_STATUS = 'ACTIVE'
55
+ AND LCL_SERVICE_INVENTORY.ACTIVATION_STATUS='ACTIVE'
56
+ }
57
+
58
+ results = connection.select_all(sql)
59
+
60
+ urls = []
61
+ results.each do |line|
62
+ param_string = line["PARSE_PARAM"]
63
+
64
+ # Try to get things that look sort of like URLs out. Brutal force,
65
+ # sorry.
66
+ url_re = Regexp.new('(https?://\S+\.\S+)(\s|$)')
67
+ urls.concat( param_string.scan( url_re ).collect {|matches| matches[0]} )
68
+ end
69
+ urls.uniq!
70
+ return urls
71
+ end
72
+
73
+
74
+ # Needs to return ContextObjects
75
+ def find_by_title
76
+ connection = sfx4_db_connection
77
+
78
+
79
+ query_match_clause = case search_type_param
80
+ when "contains"
81
+ terms = title_query_param.split(" ")
82
+ #SFX4 seems to ignore 'the' or 'a' on the front, so we will too.
83
+ if (["the", "a"].include? terms[0])
84
+ terms = terms.slice(1..-1)
85
+ end
86
+ # Then make each term required, but stemmed. Seems to match SFX4,
87
+ # and more importantly give us decent results.
88
+ query = terms.collect do |term|
89
+ "+" + connection.quote_string(term) + "*"
90
+ end.join(" ")
91
+
92
+ "MATCH (TS.TITLE_SEARCH) AGAINST ('#{query}' IN BOOLEAN MODE)"
93
+ when "begins"
94
+ # For 'begins', searching against TITLE itself rather than TITLE_SEARCH gives us
95
+ # results more like SFX4 native, without so many 'also known as' titles confusing
96
+ # things.
97
+ "(T.TITLE_DISPLAY LIKE '#{connection.quote_string(title_query_param)}%' OR T.TITLE_SORT LIKE '#{connection.quote_string(title_query_param)}%')"
98
+ #"TS.TITLE_SEARCH LIKE '#{connection.quote_string(title_query_param)}%'"
99
+ else # exact
100
+ "( TS.TITLE_SEARCH = '#{connection.quote_string(title_query_param)}' OR
101
+ T.TITLE_DISPLAY = '#{connection.quote_string(title_query_param)}' OR
102
+ T.TITLE_SORT = '#{connection.quote_string(title_query_param)}'
103
+ )"
104
+ end.upcase
105
+
106
+ from_where_clause = %{
107
+ FROM
108
+ AZ_TITLE T, AZ_TITLE_SEARCH TS
109
+ WHERE
110
+ TS.AZ_TITLE_ID = T.AZ_TITLE_ID AND
111
+ #{query_match_clause} AND
112
+ T.AZ_PROFILE = '#{connection.quote_string(sfx_az_profile)}'
113
+ }
114
+
115
+ statement = %{
116
+ SELECT
117
+ DISTINCT T.OBJECT_ID
118
+ #{from_where_clause}
119
+ ORDER BY
120
+ T.SCRIPT DESC, T.TITLE_SORT
121
+ LIMIT #{batch_size.to_i}
122
+ OFFSET #{(batch_size * (page - 1)).to_i}
123
+ }
124
+
125
+ # do the count
126
+ total_hits = SfxDb::Object.count_by_sql(
127
+ "SELECT COUNT(DISTINCT(T.OBJECT_ID)) #{from_where_clause}"
128
+ )
129
+
130
+ object_ids = connection.select_all(statement).collect {|i| i.values.first}
131
+
132
+ sql = SfxDb::Object.send(:sanitize_sql_array,
133
+ [%{
134
+ SELECT
135
+ EI.OBJECT_ID, T.TITLE_DISPLAY, EI.EXTRA_INFO_XML
136
+ FROM
137
+ AZ_TITLE T
138
+ JOIN AZ_EXTRA_INFO EI
139
+ ON (EI.OBJECT_ID = T.OBJECT_ID AND EI.AZ_PROFILE = T.AZ_PROFILE)
140
+ WHERE
141
+ T.AZ_PROFILE=?
142
+ AND EI.OBJECT_ID IN (?)
143
+ ORDER BY
144
+ T.SCRIPT DESC, T.TITLE_SORT
145
+ },
146
+ sfx_az_profile,
147
+ object_ids])
148
+
149
+ title_objects = connection.select_all(sql)
150
+
151
+ # Make em into context objects
152
+ context_objects = title_objects.collect do |sfx_obj|
153
+ ctx = OpenURL::ContextObject.new
154
+ # Start out wtih everything in search, to preserve date/vol/etc
155
+ ctx.import_context_object( context_object_from_params )
156
+
157
+ extra_info_xml = Nokogiri::XML( sfx_obj["EXTRA_INFO_XML"] )
158
+
159
+ # Put SFX object id in rft.object_id, that's what SFX does.
160
+ ctx.referent.set_metadata('object_id', sfx_obj["OBJECT_ID"])
161
+ ctx.referent.set_metadata("jtitle", sfx_obj["TITLE_DISPLAY"] || "Unknown Title")
162
+
163
+ issn = extra_info_xml.search("item[key=issn]").text
164
+ isbn = extra_info_xml.search("item[key=isbn]").text
165
+ lccn = extra_info_xml.search("item[key=lccn]").text
166
+
167
+ ctx.referent.set_metadata("issn", issn ) unless issn.blank?
168
+ ctx.referent.set_metadata("isbn", isbn) unless isbn.blank?
169
+ ctx.referent.add_identifier("info:lccn/#{normalize_lccn(lccn)}") unless lccn.blank?
170
+
171
+ ctx
172
+ end
173
+ return [context_objects, total_hits]
174
+ end
175
+
176
+ # Used for clicks on A, B, C, 0-9, etc.
177
+ def find_by_group
178
+ connection = sfx4_db_connection
179
+ from_where_clause = %{
180
+ FROM
181
+ AZ_TITLE T
182
+ JOIN AZ_EXTRA_INFO EI
183
+ ON (EI.OBJECT_ID = T.OBJECT_ID AND EI.AZ_PROFILE = T.AZ_PROFILE)
184
+ JOIN AZ_LETTER_GROUP
185
+ ON (T.AZ_TITLE_ID = AZ_LETTER_GROUP.AZ_TITLE_ID)
186
+ WHERE
187
+ T.AZ_PROFILE= '#{connection.quote_string(sfx_az_profile)}'
188
+ AND #{sfx4_quoted_letter_group_condition}
189
+ }
190
+ count_sql = %{
191
+ SELECT count(*)
192
+
193
+ #{from_where_clause}
194
+ }
195
+
196
+ fetch_sql = %{
197
+ SELECT
198
+ EI.OBJECT_ID, T.TITLE_DISPLAY, EI.EXTRA_INFO_XML
199
+
200
+ #{from_where_clause}
201
+
202
+ ORDER BY
203
+ T.SCRIPT DESC, T.TITLE_SORT
204
+ LIMIT #{batch_size.to_i}
205
+ OFFSET #{(batch_size * (page - 1)).to_i}
206
+ }
207
+
208
+ total_count = SfxDb::Object.count_by_sql( count_sql )
209
+ context_objects = sfx4_db_to_ctxobj( connection.select_all(fetch_sql) )
210
+
211
+ return [context_objects, total_count]
212
+ end
213
+
214
+ def sfx4_db_connection
215
+ SfxDb::Object.connection
216
+ end
217
+
218
+ def sfx4_quoted_letter_group_condition
219
+ " AZ_LETTER_GROUP.AZ_LETTER_GROUP_NAME " +
220
+ case params[:id]
221
+ when "0-9"
222
+ " IN ('0','1','2','3','4','5','6','7','8','9')"
223
+ when /^Other/i
224
+ "= 'Others'"
225
+ else
226
+ "= '#{sfx4_db_connection.quote_string(params[:id].upcase)}'"
227
+ end
228
+ end
229
+
230
+ def sfx4_db_to_ctxobj(title_rows)
231
+ title_rows.collect do |sfx_obj|
232
+ ctx = OpenURL::ContextObject.new
233
+ # Start out wtih everything in search, to preserve date/vol/etc
234
+ ctx.import_context_object( context_object_from_params )
235
+
236
+ extra_info_xml = Nokogiri::XML( sfx_obj["EXTRA_INFO_XML"] )
237
+
238
+ # Put SFX object id in rft.object_id, that's what SFX does.
239
+ ctx.referent.set_metadata('object_id', sfx_obj["OBJECT_ID"])
240
+ ctx.referent.set_metadata("jtitle", sfx_obj["TITLE_DISPLAY"] || "Unknown Title")
241
+
242
+ issn = extra_info_xml.search("item[key=issn]").text
243
+ isbn = extra_info_xml.search("item[key=isbn]").text
244
+ lccn = extra_info_xml.search("item[key=lccn]").text
245
+
246
+ ctx.referent.set_metadata("issn", issn ) unless issn.blank?
247
+ ctx.referent.set_metadata("isbn", isbn) unless isbn.blank?
248
+ ctx.referent.add_identifier("info:lccn/#{normalize_lccn(lccn)}") unless lccn.blank?
249
+
250
+ ctx
251
+ end
252
+
253
+ end
254
+
255
+ end
256
+ end
257
+
@@ -0,0 +1,47 @@
1
+ module SearchMethods
2
+
3
+ # NON-WORKING sketch of a search method that contacts SFX api directly.
4
+ # Problem with this was that SFX is way too slow; SFX api didn't take
5
+ # account of year/volume/issue when displaying multiple results anwyay,
6
+ # so there wasn't that functionality benefit. It just wasn't worth it.
7
+ #
8
+ # This code is basically copied and pasted from before the refactor,
9
+ # it's not close to working yet, but is left for archival purposes
10
+ # in case anyone wants to take a stab at it.
11
+ module SfxApi
12
+
13
+ def find_by_title
14
+ ctx = context_object_from_params
15
+ search_results = []
16
+
17
+ sfx_url = umlaut_config.sfx_base_url
18
+ unless (sfx_url)
19
+ # try to guess it from our institutions
20
+ instutitions = Institution.find_all_by_default_institution(true)
21
+ instutitions.each { |i| i.services.each { |s|
22
+ sfx_url = s.base_url if s.kind_of?(Sfx) }}
23
+ end
24
+
25
+ transport = OpenURL::Transport.new(sfx_url, ctx)
26
+ transport.extra_args["sfx.title_search"] = params["sfx.title_search"]
27
+ transport.extra_args["sfx.response_type"] = 'multi_obj_xml'
28
+
29
+
30
+ transport.transport_inline
31
+
32
+ doc = REXML::Document.new transport.response
33
+
34
+ #client = SfxClient.new(ctx, resolver)
35
+
36
+ doc.elements.each('ctx_obj_set/ctx_obj') { | ctx_obj |
37
+ ctx_attr = ctx_obj.elements['ctx_obj_attributes']
38
+ next unless ctx_attr and ctx_attr.has_text?
39
+
40
+ perl_data = ctx_attr.get_text.value
41
+ search_results << Sfx.parse_perl_data( perl_data )
42
+ }
43
+ return [search_results, doc.elements.length]
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,64 @@
1
+ class StoreController < UmlautController
2
+ #require 'open_url'
3
+ require 'openurl'
4
+ def index
5
+
6
+ perm = Permalink.find(:first, :conditions => { :id => params[:id]})
7
+ co = OpenURL::ContextObject.new
8
+
9
+ # We might have a link to a Referent in our db, or we might
10
+ # instead have to rely on an XML serialized ContextObject in
11
+ # the permalink, if the Referent has been purged. Either way
12
+ # we're good.
13
+ referent = nil
14
+ if ( perm && perm.referent)
15
+ referent = perm.referent
16
+ elsif (perm && perm.context_obj_serialized)
17
+ stored_co = perm.restore_context_object
18
+
19
+ # And a referrent, no referrer for now, we'll restore it later.
20
+ referent = Referent.create_by_context_object( stored_co, nil, :permalink => false )
21
+ perm.referent = referent
22
+ perm.save!
23
+ end
24
+
25
+
26
+ unless ( referent )
27
+ # We can't find a referent or succesfully restore an xml context
28
+ # object to send the user to the request. We can not resolve
29
+ # this permalink!
30
+
31
+ raise NotFound.new("Permalink request could not be resolved. Returning 404. Permalink id: #{params[:id]}")
32
+ end
33
+
34
+ # Whether it was an already existing one, or a newly created one
35
+ # turn it back to a co so we can add a few more things.
36
+ co.import_context_object(referent.to_context_object)
37
+
38
+ # We preserve original referrer. Even though this isn't entirely accurate
39
+ # this is neccesary to get SFX to handle it properly when we call to SFX,
40
+ # including handling source-specific private data, etc.
41
+ co.referrer.add_identifier( perm.orig_rfr_id ) if perm.orig_rfr_id
42
+
43
+ # Let's add any supplementary umlaut params passed to us
44
+ # Everything except the 'id' which we used for the Rails action.
45
+ new_params = params.clone
46
+ new_params.delete(:id)
47
+ # and add in our new action
48
+ new_params[:controller] = 'resolve'
49
+ new_params[:action] = 'index'
50
+ # Plus let's tell it about the referent, to make sure we get a referent
51
+ # match even though we've changed the rfr_id etc.
52
+ new_params[:'umlaut.referent_id'] = referent.id
53
+
54
+ # Generate a Rails URL, then add on the KEV for our CO on the end
55
+ # You might think you can just merge these into a hash and use url_for,
56
+ # but Rails redirect_to/url_for isn't happy with multiple query params
57
+ # with same name.
58
+
59
+ redirect_to( url_for_with_co( new_params, co) )
60
+ end
61
+
62
+ class NotFound < Exception ; end
63
+
64
+ end
@@ -0,0 +1,20 @@
1
+ # All behavior from UmlautController is extracted into this module,
2
+ # so that we can generate a local UmlautController that includes
3
+ # this module, and local app can configure or over-ride default behavior.
4
+ #
5
+ module Umlaut::ControllerBehavior
6
+ extend ActiveSupport::Concern
7
+
8
+ include UmlautConfigurable
9
+ include Umlaut::ErrorHandling
10
+ include Umlaut::ControllerLogic
11
+
12
+ included do |controller|
13
+ controller.helper Umlaut::Helper # global umlaut view helpers
14
+
15
+ # init default configuration values
16
+ UmlautConfigurable.set_default_configuration!(controller.umlaut_config)
17
+ end
18
+
19
+
20
+ end
@@ -0,0 +1,96 @@
1
+ # Some standard logic needed accross Umlaut controllers,
2
+ # module included in UmlautController superclass so it'll be avail
3
+ # to all controllers. Also exposes most of these methods as helpers so
4
+ # they'll be avail in views as well as controllers.
5
+ module Umlaut::ControllerLogic
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ helper_method :escape_xml, :url_for_with_co, :permalink_url, :with_format
10
+ end
11
+
12
+ protected
13
+
14
+ # Just replaces <, >, &, ', and " so you can include arbitrary text
15
+ # as an xml payload. I think those three chars are all you need for
16
+ # an xml escape. Weird this isn't built into Rails, huh?
17
+ def escape_xml(string)
18
+ string.gsub(/[&<>\'\"]/) do | match |
19
+ case match
20
+ when '&' then '&amp;'
21
+ when '<' then '&lt;'
22
+ when '>' then '&gt;'
23
+ when '"' then '&quot;'
24
+ when "'" then '&apos;'
25
+ end
26
+ end
27
+ end
28
+
29
+ # Pass in a hash of Rails params, plus a context object.
30
+ # Get back a url suitable for calling those params in your
31
+ # rails app, with the kev OpenURL context object tacked on
32
+ # the end. This is neccesary instead of the naive hash
33
+ # merge approach we were previously using, because
34
+ # of possibility of multiple openurl kev query params
35
+ # with same name.
36
+ def url_for_with_co(params, context_object)
37
+ url = url_for(params)
38
+ if (url.include?('?'))
39
+ url += '&'
40
+ else
41
+ url += '?'
42
+ end
43
+
44
+ url += context_object.kev
45
+
46
+ return url
47
+ end
48
+
49
+ # if it's an xml-http-request, and we're redirecting to ourselves...
50
+ # afraid we're going to lost the X-Requested-With header on redirect,
51
+ # messing up our Rails code. Add it as a query param, sorry weird
52
+ # workaround.
53
+ def params_preserve_xhr(my_params = params)
54
+ if request.xml_http_request?
55
+ my_params = my_params.clone
56
+ my_params["X-Requested-With"] = "XmlHttpRequest"
57
+ end
58
+ my_params
59
+ end
60
+
61
+
62
+ # helper method we need available in controllers too
63
+ # Absolute URL for permalink for given request.
64
+ # Have to supply rails request and umlaut request.
65
+ def permalink_url(rails_request, umlaut_request, options = {})
66
+ # if we don't have everything, we can't make a permalink.
67
+ unless (umlaut_request && umlaut_request.referent &&
68
+ umlaut_request.referent.permalinks &&
69
+ umlaut_request.referent.permalinks[0] )
70
+
71
+ return nil
72
+ end
73
+
74
+ return url_for(options.merge({:controller=>"store",
75
+ :id=>umlaut_request.referent.permalinks[0].id,
76
+ :only_path => false}) )
77
+
78
+ end
79
+
80
+ # Let you render templates or partials in a different format
81
+ # than current request format.
82
+ # with_format("xml") do
83
+ # render
84
+ # end
85
+ def with_format(format, &block)
86
+ old_formats = formats
87
+ begin
88
+ self.formats = [format]
89
+ return block.call
90
+ ensure
91
+ self.formats = old_formats
92
+ end
93
+ end
94
+
95
+
96
+ end