umlaut 3.0.0alpha1

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