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,134 @@
1
+
2
+ namespace :umlaut do
3
+ desc "Perform nightly maintenance. Set up in cron."
4
+ task :nightly_maintenance => [:load_sfx_urls, :expire_sessions, :expire_old_data]
5
+
6
+
7
+
8
+ desc "Loads sfx_urls from SFX installation. SFX mysql login needs to be set in config."
9
+ task :load_sfx_urls => :environment do
10
+
11
+ if SfxDb.connection_configured?
12
+
13
+ puts "Loading SFXUrls via direct access to SFX db."
14
+ #sfxlcl41.TARGET_SERVICE
15
+ # Check if we have an SFX3 schema, or if not use SFX4
16
+ sfx3 = true
17
+ begin
18
+ SfxDb::Object.connection.select_all("SHOW FIELDS FROM TARGET_SERVICE")
19
+ rescue ActiveRecord::StatementInvalid
20
+ sfx3 = false
21
+ end
22
+
23
+ if sfx3
24
+ urls = SfxDb::SfxDbBase.fetch_sfx_urls
25
+ else
26
+ urls = SearchMethods::Sfx4.fetch_sfx_urls
27
+ end
28
+
29
+ ignore_urls = UmlautController.umlaut_config.lookup!("sfx.sfx_load_ignore_hosts", [])
30
+
31
+ # We only want the hostnames
32
+ hosts = urls.collect do |u|
33
+ begin
34
+ uri = URI.parse(u)
35
+ uri.host
36
+ rescue Exception
37
+ end
38
+ end
39
+ hosts.uniq!
40
+
41
+ SfxUrl.transaction do
42
+ SfxUrl.delete_all
43
+
44
+ hosts.each {|h| SfxUrl.new({:url => h}).save! unless ignore_urls.find {|ignore| ignore === h }}
45
+ end
46
+ else
47
+ puts "Skipping load of SFXURLs via direct access to SFX db. No direct access is configured. Configure in config/umlaut_config/database.yml"
48
+ end
49
+ end
50
+
51
+ desc "Expire sessions older than config.app_config.session_expire_seconds"
52
+ task :expire_sessions => :environment do
53
+ # Assume sessions are in db.
54
+ # Don't know good way to get the connection associated with sessions,
55
+ # since there is no model. Assume Request is in the same db.
56
+ expire_seconds = UmlautController.umlaut_config.lookup!("session_expire_seconds", 1.day)
57
+ puts "Expiring sessions older than #{expire_seconds} seconds (set with config session_expire_seconds)."
58
+ Request.connection.execute("delete from sessions where now() - updated_at > #{expire_seconds}")
59
+ end
60
+
61
+
62
+ desc "Cleanup of database for old data associated with expired sessions etc."
63
+ task :expire_old_data => :environment do
64
+ # There are requests, responses, and dispatched_service entries
65
+ # hanging around for things that may be way old and no longer
66
+ # need to hang around. How do we know if they're too old?
67
+ # If they are no longer associated with any session, mainly.
68
+
69
+ # Deleting things as aggressively as we're doing here doesn't leave
70
+ # us much for statistics, but we aren't currently gathering any
71
+ # statistics anyway. If statistics are needed, more exploration
72
+ # is needed of performance vs. leaving things around for statistics.
73
+
74
+ # For efficiency, we delete with direct DB calls, so don't count
75
+ # on Rails business logic being triggered! Was just WAY too slow
76
+ # otherwise. Also, sorry, doing all this in a db efficient way (one db
77
+ # query) requires some tricky SQL, which be MySQL specific.
78
+
79
+ # Current Umlaut never re-uses a request different between sessions, so
80
+ # if the session is dead, we can purge the Requests too. Permalink
81
+ # architecture has been fixed to not rely on requests or referents,
82
+ # permalinks (post new architecture) store their own context object.
83
+
84
+ puts "Deleting Requests no longer associated with a session."
85
+ begin_time = Time.now
86
+ work_clause = " FROM requests LEFT OUTER JOIN sessions ON requests.session_id = sessions.session_id WHERE sessions.id is null "
87
+ count = Request.count_by_sql("SELECT count(*) " + work_clause)
88
+ Request.connection.execute("DELETE requests " + work_clause)
89
+ puts " Deleted #{count} Requests in #{Time.now - begin_time}"
90
+
91
+
92
+
93
+
94
+
95
+ # Now, let's get rid of any ServiceResponses that no longer have
96
+ # Requests
97
+
98
+ puts "Deleting orphaned ServiceResponses...."
99
+ begin_time = Time.now
100
+ work_clause = " FROM service_responses WHERE NOT EXISTS (SELECT * FROM requests WHERE service_responses.request_id = requests.id)"
101
+ count = ServiceResponse.count_by_sql("SELECT count(*) " + work_clause)
102
+ ServiceResponse.connection.execute("DELETE " + work_clause)
103
+ puts " Deleted #{count} ServiceResponses in #{Time.now - begin_time}"
104
+
105
+
106
+ # And get rid of DispatchedServices for 'dead' requests too. Don't
107
+ # need em.
108
+ puts "Deleting DispatchedServices for dead Requests..."
109
+ begin_time = Time.now
110
+ # Sorry, may be MySQL only.
111
+ work_clause = " FROM (dispatched_services LEFT OUTER JOIN requests ON dispatched_services.request_id = requests.id) WHERE requests.id IS NULL "
112
+ count = DispatchedService.count_by_sql("SELECT count(*) " + work_clause)
113
+ DispatchedService.connection.execute("DELETE dispatched_services " + work_clause)
114
+ puts " Deleted #{count} DispatchedServices in #{Time.now - begin_time}"
115
+
116
+
117
+ # Turns out we need to get rid of old referents and referentvalues
118
+ # too. There are just too many. Permalinks have been updated to
119
+ # store their own info and not depend on Referent existing.
120
+ referent_expire = Time.now - UmlautController.umlaut_config.lookup!("referent_expire_seconds", 20.days)
121
+ puts "Deleting Referents/ReferentValues older than #{referent_expire.inspect}"
122
+ begin_time = Time.now
123
+ # May be MySQL dependent.
124
+ Referent.connection.execute("DELETE referents, referent_values FROM referents, referent_values where referents.id = referent_values.referent_id AND referents.created_at < '#{referent_expire.to_formatted_s(:db)}'" )
125
+ puts " Deleted Referents in #{Time.now - begin_time}"
126
+
127
+ # And turns out we have all Clickthroughs being stored for no apparent
128
+ # reason, let's just delete any older than 3 months ago.
129
+ Clickthrough.destroy_all(['created_at < ?', 3.months.ago])
130
+ puts "Deleted Clickthroughs older than 3 months"
131
+
132
+ end
133
+
134
+ end
@@ -0,0 +1,5 @@
1
+ module Umlaut::DefaultConfiguration
2
+
3
+
4
+
5
+ end
@@ -0,0 +1,136 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Umlaut
3
+ # Class to inject Umlaut routes, design copied from Blacklight project.
4
+ # you would do a:
5
+ # Umlaut::Routes.new(self, optional_args).draw
6
+ # in local
7
+ # app routes.rb, that line is generated into local app by Umlaut generator.
8
+ # options include :only and :except to limit what route groups are generated.
9
+ class Routes
10
+
11
+ def initialize(router, options ={})
12
+ @router = router
13
+ @options = options
14
+ end
15
+
16
+ def draw
17
+ route_sets.each do |r|
18
+ self.send(r)
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def add_routes &blk
25
+ @router.instance_exec(@options, &blk)
26
+ end
27
+
28
+ def route_sets
29
+ (@options[:only] || default_route_sets) - (@options[:except] || [])
30
+ end
31
+
32
+ def default_route_sets
33
+ [:root, :permalinks, :a_z, :resolve, :open_search, :link_router, :export_email, :resources, :search]
34
+ end
35
+
36
+ module RouteSets
37
+ # for now include root generation in Umlaut auto-generation
38
+ def root
39
+ add_routes do |options|
40
+ root :to => "resolve#index"
41
+ end
42
+ end
43
+
44
+ def permalinks
45
+ add_routes do |options|
46
+ match 'go/:id' => 'store#index'
47
+ end
48
+ end
49
+
50
+ # some special direct links to A-Z type searches, including
51
+ # legacy redirects for SFX-style urls, to catch any bookmarks.
52
+ def a_z
53
+ add_routes do |options|
54
+ # Special one for alpha list
55
+ match 'journal_list/:id/:page' => 'search#journal_list', :defaults => { :page => 1, :id => 'A' }
56
+
57
+
58
+ # Catch redirected from SFX A-Z and citation linker urls
59
+ # v2 A-Z links redirected to umlaut, point to journal_list
60
+ # code in journal_list filter picks out SFX URL vars for
61
+ # letter.
62
+ match '/resolve/azlist/default' => 'search#journal_list', :page => 1, :id => 'A'
63
+
64
+ # SFX v3 A-Z list url format
65
+ match 'resolve/az' => 'search#journal_list', :page => 1, :id => 'A'
66
+ end
67
+ end
68
+
69
+ # This is a legacy wild controller route that's not recommended for RESTful applications.
70
+ # Note: This route will make all actions in every controller accessible via GET requests.
71
+ # match ':controller(/:action(/:id(.:format)))'
72
+
73
+ def resolve
74
+ add_routes do |options|
75
+ # ResolveController still uses rails 2.0 style 'wildcard' routes,
76
+ # TODO tighten this up to only match what oughta be matched.
77
+ # Note: This route will make all actions in this controller accessible via GET requests.
78
+
79
+ match 'resolve(/:action(/:id(.:format)))' => "resolve"
80
+ end
81
+ end
82
+
83
+ def open_search
84
+ add_routes do |options|
85
+ # OpenSearchController still uses rails 2.0 style 'wildcard' routes,
86
+ # TODO tighten this up to only match what oughta be matched.
87
+ # Note: This route will make all actions in this controller accessible via GET requests.
88
+
89
+ match 'open_search(/:action(/:id(.:format)))' => "open_search"
90
+ end
91
+ end
92
+
93
+ def link_router
94
+ add_routes do |options|
95
+ # LinkRouterController still uses rails 2.0 style 'wildcard' routes,
96
+ # TODO tighten this up to only match what oughta be matched.
97
+ # Note: This route will make all actions in this controller accessible via GET requests.
98
+
99
+ match 'link_router(/:action(/:id(.:format)))' => "link_router"
100
+ end
101
+ end
102
+
103
+ def export_email
104
+ add_routes do |options|
105
+ # ExportEmailController still uses rails 2.0 style 'wildcard' routes,
106
+ # TODO tighten this up to only match what oughta be matched.
107
+ # Note: This route will make all actions in this controller accessible via GET requests.
108
+
109
+ match 'export_email(/:action(/:id(.:format)))' => "export_email"
110
+ end
111
+ end
112
+
113
+ def resources
114
+ add_routes do |options|
115
+ # ResourceController still uses rails 2.0 style 'wildcard' routes,
116
+ # TODO tighten this up to only match what oughta be matched.
117
+ # Note: This route will make all actions in this controller accessible via GET requests.
118
+
119
+ match 'resource(/:action(/:id(.:format)))' => "resource"
120
+ end
121
+ end
122
+
123
+ def search
124
+ add_routes do |options|
125
+ # SearchController still uses rails 2.0 style 'wildcard' routes,
126
+ # TODO tighten this up to only match what oughta be matched.
127
+ # Note: This route will make all actions in this controller accessible via GET requests.
128
+
129
+ match 'search(/:action(/:id(.:format)))' => "search"
130
+ end
131
+ end
132
+
133
+ end
134
+ include RouteSets
135
+ end
136
+ end
@@ -0,0 +1,3 @@
1
+ module Umlaut
2
+ VERSION = "3.0.0alpha1"
3
+ end
data/lib/umlaut.rb ADDED
@@ -0,0 +1,37 @@
1
+ require 'umlaut/routes'
2
+
3
+ # not sure why including openurl gem doesn't do the require, but it
4
+ # seems to need this.
5
+ require 'openurl'
6
+
7
+ module Umlaut
8
+ class Engine < Rails::Engine
9
+ engine_name "umlaut"
10
+
11
+ # we store some things in non-standard subdirs, add em to path.
12
+ #
13
+ # We EAGER load em all to try and handle threading issues.
14
+
15
+ config.autoload_paths << File.join(self.root, "lib", "referent_filters")
16
+ config.eager_load_paths << File.join(self.root, "lib", "referent_filters")
17
+
18
+ config.autoload_paths << File.join(self.root, "lib", "service_adaptors")
19
+ config.eager_load_paths << File.join(self.root, "lib", "service_adaptors")
20
+
21
+ # Ane make 'lib' dir auto-loaded, because we have legacy Rails2 code
22
+ # that assumes it.
23
+ config.autoload_paths << File.join(self.root, "lib")
24
+ # Sadly including eager_load_paths here makes weird things happen, apparently
25
+ # I don't entirely understand what's going on.
26
+ #config.eager_load_paths << File.join(self.root, "lib")
27
+
28
+ # This makes our rake tasks visible.
29
+ rake_tasks do
30
+ Dir.chdir(File.expand_path(File.join(File.dirname(__FILE__), '..'))) do
31
+ Dir.glob(File.join('lib', 'tasks', '*.rake')).each do |railtie|
32
+ load railtie
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,343 @@
1
+ # meant to be included in _controllers_, to get an
2
+ # umlaut_config method as a class_attribute (avail on class, overrideable
3
+ # on instance), exposed as helper method too,
4
+ # that has a Confstruct configuration object that starts out
5
+ # holding global config. (right now via a direct refernce to the global
6
+ # one).
7
+
8
+ require 'confstruct'
9
+
10
+ module UmlautConfigurable
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ class_attribute :umlaut_config
15
+ helper_method :umlaut_config
16
+ self.umlaut_config = Confstruct::Configuration.new
17
+ end
18
+
19
+
20
+
21
+ # Call as UmlautConfigurable.set_default_configuration!(confstruct_obj)
22
+ # to initialize
23
+ def self.set_default_configuration!(configuration)
24
+ configuration.configure do
25
+ app_name 'Find It'
26
+ # URL to image to use for link resolver, OR name of image asset in local app.
27
+ #link_img_url "http//something"
28
+
29
+ # Sometimes Umlaut sends out email, what email addr should it be from?
30
+ from_email_addr 'no_reply@umlaut.example.com'
31
+
32
+ layout "umlaut"
33
+ resolve_layout deferred! {|c| c.layout}
34
+ search_layout deferred! {|c| c.layout}
35
+
36
+ # help url used on error page and a few other places.
37
+ # help_url "http://www.library.jhu.edu/services/askalib/index.html"
38
+
39
+ # Minimum height and width of browser window. We have little control over
40
+ # what size a content provider generates a window for a link resolver. Often
41
+ # it's too small for umlaut. So we resize in js, if these config params
42
+ # are given. Set to 0 to disable.
43
+ # Sadly, only some browsers let us resize the browser window, so this
44
+ # feature only works in some browsers.
45
+ minimum_window_width 820
46
+ minimum_window_height 400
47
+
48
+
49
+ # rfr_ids used for umlaut generated pages.
50
+ rfr_ids do
51
+ opensearch "info:sid/umlaut.code4lib.org:opensearch"
52
+ citation "info:sid/umlaut.code4lib.org:citation"
53
+ azlist 'info:sid/umlaut.code4lib.org:azlist'
54
+ end
55
+
56
+ # If you have a test umlaut set up at another location to stage/test
57
+ # new features, link to it here, and a helper method in default
58
+ # layout will provide a subtle debugging link to it in footer,
59
+ # for current OpenURL.
60
+ # test_resolve_base "http://app01.mse.jhu.edu/umlaut_dev"
61
+
62
+ opensearch_short_name deferred! {|c| "Find Journals with #{c.app_name}" }
63
+ opensearch_description deferred! {|c| "Search #{c.app_name} for journal names containing your term"}
64
+
65
+
66
+
67
+ # Referent filters. Sort of like SFX source parsers.
68
+ # hash, key is regexp to match a sid, value is filter object
69
+ # (see lib/referent_filters )
70
+ add_referent_filters!( :match => /.*/, :filter => DissertationCatch.new )
71
+
72
+
73
+ # skip_resolve_menu can be used to control 'direct' linking, skipping
74
+ # the resolve menu to deliver a full text link or other resource
75
+ # directly to the user.
76
+ # Possible values:
77
+ # false : [default] Never skip menu
78
+ # A hash with one or more keys....
79
+ # {:service_types => ['fulltext']} : list of service type values, if
80
+ # they're present skip the menu with the first response available.
81
+ # {:excluded_services => ['JH_HIP'] : list of service IDs, exclude responses
82
+ # from these services for direct linking. (Not yet implemented)
83
+ # {:excluded_urls => [/regexp/, 'string'] : list of regexps or strings,
84
+ # exclude URLs that match this string from being skipped to. (Not yet implemented)
85
+ # {:excluded_rfr_ids => ["info:sid/sfxit.com:citation", '"info:sid/umlaut.code4lib.org:citation"'] }
86
+ # {:lambda => lambda {|p, l| return something}} : Not yet implemented.
87
+
88
+ # lambda expression: A lambda expression can be provided that
89
+ # should expect one argument, a hash with key :request
90
+ # and value the Umlaut Request object. Return nil to
91
+ # not skip menu, or a ServiceType join obj to skip
92
+ # menu to that response.
93
+
94
+ # A pretty typical direct-linking setup, excludes queries that come
95
+ # from citation linker/azlist/opensearch from direct linking.
96
+ # AppConfig::Base.skip_resolve_menu = {:service_types => ['fulltext'],
97
+ #:services=>['JH_SFX'], :excluded_rfr_ids => ["info:sid/sfxit.com:citation",
98
+ #'info:sid/umlaut.code4lib.org:citation',
99
+ #'info:sid/umlaut.code4lib.org:azlist',
100
+ #'info:sid/umlaut.code4lib.org:opensearch']}
101
+ #
102
+ # "umlaut.skip_resolve_menu" paramter can also be passed in per-request, with
103
+ # 'true' or shortname of a service type.
104
+ skip_resolve_menu false
105
+
106
+ # How many seconds between updates of the background updater for background
107
+ # services?
108
+ poll_wait_seconds 4
109
+
110
+ # if a background service hasn't returned in this many seconds, consider
111
+ # it failed. (May actually be slow, more likely raised an exception and
112
+ # our exception handling failed to note it as failed.)
113
+ background_service_timeout 30
114
+ # If a service has status FailedTemporary, and it's older than a
115
+ # certain value, it will be re-queued in #serviceDispatch.
116
+ # This value defaults to 10 times background_service_timeout,
117
+ # but can be set in app config variable requeue_failedtemporary_services
118
+ # If you set it too low, you can wind up with a request that never completes,
119
+ # as it constantly re-queues a service which constantly fails.
120
+ requeue_failedtemporary_services_in deferred! {|c| c.background_service_timeout * 10}
121
+
122
+ # custom view template for resolve#index
123
+ resolve_view nil
124
+
125
+ # If OpenURL came from manual entry of title/ISSN, and no match is found in
126
+ # link resolver knowledge base, display a warning to the user of potential
127
+ # typo?
128
+ entry_not_in_kb_warning true
129
+
130
+ nightly_maintenance do
131
+ # When nightly_maintenance will expire sessions. Default to
132
+ # 1 day. Over-ride locally if desired, but
133
+ # probably no reason to.
134
+ session_expire_seconds 1.day
135
+ referent_expire_seconds deferred! {|c| c.session_expire_seconds }
136
+
137
+
138
+ # Expire service responses. Service responses are only re-used by the same
139
+ # session that generated them. But sometimes even that's too much, we
140
+ # want to expire them eventually, say every 24 hours.
141
+ # You can do this in two ways.
142
+ #
143
+ # A Number of seconds in an interval, eg:
144
+ response_expire_interval 1.day
145
+ #
146
+ # Or, sometimes it's convenient to synchronize this with some other
147
+ # process that runs on crontab. Say, expire at midnight every night:
148
+ # response_expire_crontab_format "00 00 * * *"
149
+
150
+ end
151
+
152
+ # Configuration for the 'search' functions -- A-Z lookup
153
+ # and citation entry.
154
+ search do
155
+ # Is your SFX database connection, defined in database.yml under
156
+ # sfx_db and used for A-Z searches, Sfx3 or Sfx4? Other SearchMethods
157
+ # in addition to SFX direct db may be provided later.
158
+ az_search_method SearchMethods::Sfx4
159
+ #az_search_method SearchMethods::Sfx3
160
+
161
+ # When talking directly to the SFX A-Z list database, you may
162
+ # need to set this, if you have multiple A-Z profiles configured
163
+ # and don't want to use the 'default.
164
+ sfx_az_profile "default"
165
+
166
+ # Use your own custom search view? mention it here.
167
+ #search_view = "my_search"
168
+
169
+ # can set to "_blank" etc.
170
+ result_link_target nil
171
+
172
+ end
173
+
174
+ # config only relevant to SFX use
175
+ sfx do
176
+ # was: 'main_sfx_base_url'
177
+ # base sfx url to use for search actions, error condition backup,
178
+ # and some other purposes. For search actions (A-Z), direct database
179
+ # connection to your SFX db also needs to be defined in database.yml
180
+ # sfx_base_url 'http://sfx.library.jhu.edu:8000/jhu_sfx?'
181
+ #
182
+
183
+
184
+
185
+ # Umlaut tries to figure out from the SFX knowledge base
186
+ # which hosts are "SFX controlled", to avoid duplicating SFX
187
+ # urls with urls from catalog. But sometimes it misses some, or
188
+ # alternate hostnames for some. Regexps matching against
189
+ # urls can be included here. Eg,
190
+ # AppConfig::Base.additional_sfx_controlled_urls = [
191
+ # %r{^http://([^\.]\.)*pubmedcentral\.com}
192
+ # ]
193
+ additional_sfx_controlled_urls = []
194
+
195
+ # "web.archive.org" is listed in SFX, but that causes suppression
196
+ # of MARC 856 tags from our catalog pointing to archive.org, which are
197
+ # being used for some digitized books. We'd like to ignore that archive.org
198
+ # is in SFX. Same for netlibrary.
199
+ #sfx_load_ignore_hosts = [/.*\.archive\.org/, /www\.netlibrary\.com/, 'www.loc.gov']
200
+ sfx_load_ignore_hosts = []
201
+ end
202
+
203
+ # Output timing of service execution to logs
204
+ log_service_timing = true if Rails.env == "development"
205
+
206
+
207
+ #####
208
+ # Pieces of content on a Resolve page can be declaritively configured.
209
+ # Here are the defaults. You can add new elements to the resolve_sections
210
+ # array in config and modify or delete existing resolve_sections elements.
211
+ #
212
+ # Look in comments at top of SectionRenderer class for what the keys
213
+ # in each entry mean.
214
+ add_resolve_sections! do
215
+ div_id "cover_image"
216
+ partial "cover_image"
217
+ visibility :responses_exist
218
+ show_heading false
219
+ show_spinner false
220
+ end
221
+
222
+ add_resolve_sections! do
223
+ div_id "search_inside"
224
+ html_area :resource_info
225
+ partial "search_inside"
226
+ show_partial_only true
227
+ end
228
+
229
+ add_resolve_sections! do
230
+ div_id "fulltext"
231
+ section_title "#{ServiceTypeValue[:fulltext].display_name} via:"
232
+ html_area :main
233
+ partial :fulltext
234
+ show_partial_only true
235
+ end
236
+
237
+ add_resolve_sections! do
238
+ div_id "excerpts"
239
+ section_prompt "A limited preview which may include table of contents, index, and other selected pages."
240
+ html_area :main
241
+ list_visible_limit 5
242
+ visibility :responses_exist
243
+ end
244
+
245
+ add_resolve_sections! do
246
+ div_id "audio"
247
+ section_title "#{ServiceTypeValue[:audio].display_name} via"
248
+ html_area :main
249
+ visibility :responses_exist
250
+ end
251
+
252
+ add_resolve_sections! do
253
+ div_id :holding
254
+ section_title ServiceTypeValue[:holding].display_name_pluralize
255
+ html_area :main
256
+ partial 'holding'
257
+ service_type_values ["holding","holding_search"]
258
+ end
259
+
260
+ add_resolve_sections! do
261
+ div_id "document_delivery"
262
+ section_title "Request a copy from Inter-Library Loan"
263
+ html_area :main
264
+ visibility :responses_exist
265
+ bg_update false
266
+ end
267
+
268
+ add_resolve_sections! do
269
+ div_id "table_of_contents"
270
+ html_area :main
271
+ visibility :responses_exist
272
+ end
273
+
274
+ add_resolve_sections! do
275
+ div_id "abstract"
276
+ html_area :main
277
+ visibility :responses_exist
278
+ end
279
+
280
+ add_resolve_sections! do
281
+ div_id "help"
282
+ html_area :sidebar
283
+ bg_update false
284
+ partial "help"
285
+ show_heading false
286
+ show_spinner false
287
+ visibility :responses_exist
288
+ end
289
+
290
+ add_resolve_sections! do
291
+ div_id "coins"
292
+ html_area :sidebar
293
+ partial "coins"
294
+ service_type_values []
295
+ show_heading false
296
+ show_spinner false
297
+ bg_update false
298
+ partial_html_api false
299
+ end
300
+
301
+ add_resolve_sections! do
302
+ div_id "export_citation"
303
+ html_area :sidebar
304
+ visibility :in_progress
305
+ item_name_plural "Export tools"
306
+ end
307
+
308
+ add_resolve_sections! do
309
+ div_id "related_items"
310
+ html_area :sidebar
311
+ partial "related_items"
312
+ section_title "More like this"
313
+ item_name_plural "Related Items"
314
+ # custom visibility, show it for item-level cites,
315
+ # or if we actually have some
316
+ visibility( lambda do |renderer|
317
+ (! renderer.request.title_level_citation?) ||
318
+ (! renderer.responses_empty?)
319
+ end )
320
+ service_type_values ['cited_by', 'similar']
321
+ end
322
+
323
+ add_resolve_sections! do
324
+ div_id "highlighted_link"
325
+ section_title "See also"
326
+ html_area :sidebar
327
+ visibility :in_progress
328
+ partial_locals( :show_source => true )
329
+ end
330
+
331
+ add_resolve_sections! do
332
+ div_id "service_errors"
333
+ partial "service_errors"
334
+ html_area :service_errors
335
+ service_type_values []
336
+ end
337
+
338
+ end
339
+ end
340
+
341
+
342
+
343
+ end