umlaut 3.0.5 → 3.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +48 -5
- data/app/assets/images/umlaut_icons.png +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-book-go.png +0 -0
- data/app/assets/images/{famfamfam/book_open.png → umlaut_icons/famfamfam-book-open.png} +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-book.png +0 -0
- data/app/assets/images/{famfamfam/cross.png → umlaut_icons/famfamfam-cross.png} +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-error.png +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-help.png +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-information.png +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-link.png +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-page-sound.png +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-page-text.png +0 -0
- data/app/assets/images/umlaut_icons/famfamfam-page-up.png +0 -0
- data/app/assets/images/{famfamfam/page_white.png → umlaut_icons/famfamfam-page-white.png} +0 -0
- data/app/assets/images/{famfamfam/readme.html → umlaut_icons/famfamfam-readme.html} +0 -0
- data/app/assets/images/{famfamfam/tiny_cross.png → umlaut_icons/famfamfam-tiny-cross.png} +0 -0
- data/app/assets/images/{list_closed.png → umlaut_icons/list-closed.png} +0 -0
- data/app/assets/images/{list_open.png → umlaut_icons/list-open.png} +0 -0
- data/app/assets/javascripts/umlaut.js +5 -4
- data/app/assets/javascripts/umlaut/ajax_windows.js +41 -23
- data/app/assets/javascripts/umlaut/expand_contract_toggle.js +21 -29
- data/app/assets/javascripts/umlaut/load_permalink.js +26 -0
- data/app/assets/javascripts/umlaut/search_autocomplete.js +103 -44
- data/app/assets/stylesheets/umlaut.css.scss +19 -0
- data/app/assets/stylesheets/umlaut/_admin.scss +14 -0
- data/app/assets/stylesheets/umlaut/_az.scss +29 -0
- data/app/assets/stylesheets/umlaut/_forms.scss +31 -0
- data/app/assets/stylesheets/umlaut/_icons.scss +64 -0
- data/app/assets/stylesheets/umlaut/_layout.scss +52 -0
- data/app/assets/stylesheets/umlaut/_misc.scss +59 -0
- data/app/assets/stylesheets/umlaut/_mixins.scss +65 -0
- data/app/assets/stylesheets/umlaut/_modal.scss +4 -0
- data/app/assets/stylesheets/umlaut/_resolve.scss +308 -0
- data/app/assets/stylesheets/umlaut/_results.scss +34 -0
- data/app/assets/stylesheets/umlaut/_search.scss +14 -0
- data/app/assets/stylesheets/umlaut/_spinner.scss +12 -0
- data/app/assets/stylesheets/umlaut/_variables.scss +72 -0
- data/app/controllers/export_email_controller.rb +22 -39
- data/app/controllers/journal_tocs_controller +90 -0
- data/app/controllers/js_helper_controller.rb +2 -3
- data/app/controllers/link_router_controller.rb +32 -43
- data/app/controllers/open_search_controller.rb +3 -4
- data/app/controllers/resolve_controller.rb +68 -107
- data/app/controllers/resource_controller.rb +14 -20
- data/app/controllers/search_controller.rb +75 -94
- data/app/controllers/search_methods/README.md +28 -0
- data/app/controllers/search_methods/sfx4.rb +50 -119
- data/app/controllers/search_methods/sfx4_solr/README.md +57 -0
- data/app/controllers/search_methods/sfx4_solr/local.rb +40 -0
- data/app/controllers/search_methods/sfx4_solr/searcher.rb +90 -0
- data/app/controllers/store_controller.rb +24 -30
- data/app/controllers/umlaut/controller_behavior.rb +45 -17
- data/app/controllers/umlaut/error_handling.rb +20 -25
- data/{lib → app/controllers}/umlaut_configurable.rb +35 -21
- data/app/controllers/umlaut_controller.rb +43 -46
- data/app/helpers/emailer_helper.rb +9 -16
- data/app/helpers/export_email_helper.rb +8 -8
- data/app/helpers/open_search_helper.rb +2 -3
- data/app/helpers/resolve_helper.rb +130 -100
- data/app/helpers/search_helper.rb +17 -5
- data/app/helpers/umlaut/footer_helper.rb +1 -1
- data/app/helpers/umlaut/helper.rb +34 -0
- data/app/helpers/umlaut/html_head_helper.rb +12 -21
- data/{lib → app/mixin_logic}/marc_helper.rb +1 -1
- data/{lib → app/mixin_logic}/metadata_helper.rb +6 -5
- data/{lib → app/mixin_logic}/umlaut_http.rb +0 -0
- data/{lib → app/mixin_logic}/xml_schema_helper.rb +0 -0
- data/app/models/collection.rb +97 -95
- data/{lib → app/models}/hip3/bib.rb +0 -0
- data/{lib → app/models}/hip3/bib_searcher.rb +0 -0
- data/{lib → app/models}/hip3/custom_field_lookup.rb +0 -0
- data/{lib → app/models}/hip3/holding.rb +0 -0
- data/{lib → app/models}/hip3/item.rb +0 -0
- data/{lib → app/models}/hip3/receipt.rb +0 -0
- data/{lib → app/models}/hip3/serial_copy.rb +0 -0
- data/app/models/permalink.rb +3 -8
- data/app/models/referent.rb +29 -21
- data/app/models/request.rb +19 -8
- data/app/models/service_response.rb +24 -3
- data/app/models/service_store.rb +108 -39
- data/app/models/service_store.rb-NEW +73 -0
- data/app/models/service_wave.rb +2 -0
- data/app/models/sfx4/abstract/README.md +68 -0
- data/app/models/sfx4/abstract/az_extra_info.rb +44 -0
- data/app/models/sfx4/abstract/az_letter_group.rb +24 -0
- data/app/models/sfx4/abstract/az_title.rb +96 -0
- data/app/models/sfx4/abstract/az_title_search.rb +24 -0
- data/app/models/sfx4/abstract/base.rb +77 -0
- data/app/models/sfx4/global/base.rb +24 -0
- data/app/models/sfx4/global/kb_objects.rb +34 -0
- data/app/models/sfx4/local/az_extra_info.rb +7 -0
- data/app/models/sfx4/local/az_letter_group.rb +7 -0
- data/app/models/sfx4/local/az_title.rb +7 -0
- data/app/models/sfx4/local/az_title_search.rb +7 -0
- data/app/models/sfx4/local/base.rb +26 -0
- data/{lib → app/presentation}/section_renderer.rb +0 -12
- data/app/referent_filters/dissertation_catch.rb +67 -0
- data/{lib → app/referent_filters}/referent_filter.rb +0 -0
- data/{lib → app}/service_adaptors/ajax_export.rb +0 -0
- data/{lib → app}/service_adaptors/amazon.rb +2 -0
- data/{lib → app}/service_adaptors/blacklight.rb +22 -10
- data/{lib → app}/service_adaptors/book_finder.rb +0 -0
- data/{lib → app}/service_adaptors/bx.rb +0 -0
- data/{lib → app}/service_adaptors/cover_thing.rb +0 -0
- data/{lib → app}/service_adaptors/dummy_service.rb +0 -0
- data/{lib → app}/service_adaptors/elsevier_cover.rb +0 -0
- data/{lib → app}/service_adaptors/email_export.rb +0 -0
- data/{lib → app}/service_adaptors/ezproxy.rb +0 -0
- data/{lib → app}/service_adaptors/google_book_search.rb +0 -0
- data/app/service_adaptors/google_scholar_link.rb +71 -0
- data/{lib → app}/service_adaptors/gpo.rb +0 -0
- data/{lib → app}/service_adaptors/hathi_trust.rb +0 -0
- data/{lib → app}/service_adaptors/hip3_service.rb +0 -0
- data/{lib → app}/service_adaptors/hip_holding_search.rb +0 -0
- data/{lib → app}/service_adaptors/internet_archive.rb +0 -0
- data/{lib → app}/service_adaptors/isbn_db.rb +0 -0
- data/{lib → app}/service_adaptors/isi.rb +22 -13
- data/{lib → app}/service_adaptors/jcr.rb +0 -0
- data/{lib → app}/service_adaptors/opac.rb +0 -0
- data/{lib → app}/service_adaptors/open_library.rb +0 -0
- data/{lib → app}/service_adaptors/open_library_cover.rb +0 -0
- data/{lib → app}/service_adaptors/pubmed.rb +0 -0
- data/{lib → app}/service_adaptors/request_to_fixture.rb +0 -0
- data/{lib → app}/service_adaptors/scopus.rb +0 -0
- data/{lib → app/service_adaptors}/service.rb +3 -3
- data/{lib → app}/service_adaptors/sfx.rb +154 -11
- data/{lib → app}/service_adaptors/sfx_backchannel_record.rb +0 -0
- data/app/service_adaptors/tr_link.rb +267 -0
- data/app/service_adaptors/tr_links.rb +278 -0
- data/{lib → app}/service_adaptors/txt_holding_export.rb +0 -0
- data/{lib → app}/service_adaptors/ulrichs_cover.rb +0 -0
- data/{lib → app}/service_adaptors/ulrichs_link.rb +0 -0
- data/{lib → app}/service_adaptors/worldcat.rb +0 -0
- data/{lib → app}/service_adaptors/worldcat_identities.rb +0 -0
- data/app/views/admin/service_errors/_dispatched_service.html.erb +13 -13
- data/app/views/admin/service_errors/index.html.erb +11 -21
- data/app/views/export_email/email.html.erb +17 -2
- data/app/views/export_email/send_email.html.erb +2 -1
- data/app/views/export_email/send_txt.html.erb +2 -1
- data/app/views/export_email/txt.html.erb +30 -2
- data/app/views/layouts/umlaut.html.erb +29 -49
- data/app/views/resolve/_background_progress.html.erb +43 -50
- data/app/views/resolve/_background_updater.html.erb +23 -36
- data/app/views/resolve/_citation.html.erb +63 -87
- data/app/views/resolve/_compact_citation.html.erb +15 -33
- data/app/views/resolve/_cover_image.html.erb +34 -43
- data/app/views/resolve/_fulltext.html.erb +29 -50
- data/app/views/resolve/_help.html.erb +17 -14
- data/app/views/resolve/_holding.html.erb +65 -82
- data/app/views/resolve/_manually_entered_warning.html.erb +7 -0
- data/app/views/resolve/_modal.html.erb +19 -0
- data/app/views/resolve/_related_items.html.erb +20 -35
- data/app/views/resolve/_search_inside.html.erb +34 -57
- data/app/views/resolve/_section_display.html.erb +34 -46
- data/app/views/resolve/_section_heading.html.erb +17 -0
- data/app/views/resolve/_service_errors.html.erb +27 -28
- data/app/views/resolve/_standard_response_item.html.erb +42 -72
- data/app/views/resolve/background_status.html.erb +19 -23
- data/app/views/resolve/get_permalink.html.erb +6 -0
- data/app/views/resolve/index.html.erb +47 -73
- data/app/views/search/_a_to_z.html.erb +9 -6
- data/app/views/search/_citation.html.erb +73 -94
- data/app/views/search/_pager.html.erb +6 -6
- data/app/views/search/books.html.erb +34 -102
- data/app/views/search/journal_search.html.erb +53 -90
- data/app/views/search/journals.html.erb +73 -167
- data/app/views/umlaut/_header.html.erb +9 -0
- data/app/views/umlaut/error.html.erb +44 -44
- data/config/locales/en.yml +5 -0
- data/lib/{CronTab.rb → cron_tab.rb} +0 -0
- data/lib/generators/templates/umlaut_services.yml +57 -43
- data/lib/generators/umlaut/install_generator.rb +12 -0
- data/lib/service_adaptors/README.md +0 -0
- data/lib/tasks/umlaut.rake +8 -24
- data/lib/umlaut.rb +1 -21
- data/lib/umlaut/version.rb +1 -1
- data/test/README.md +75 -0
- data/test/dummy/app/controllers/umlaut_controller.rb +3 -3
- data/test/dummy/config/application.rb +3 -0
- data/test/dummy/config/sunspot.yml +20 -0
- data/test/dummy/config/travis_database.yml +96 -0
- data/test/dummy/config/umlaut_services.yml +16 -23
- data/test/dummy/db/migrate/20120927163304_sfx4_global.rb +26 -0
- data/test/dummy/db/migrate/20120927164040_sfx4_local.rb +54 -0
- data/test/dummy/tmp/cache/assets/BBA/6A0/sprockets%2F2a335471966f33256b321f8324041981 +0 -0
- data/test/dummy/tmp/cache/assets/C2A/410/sprockets%2Fd654b74912b4773a2534616863fb6565 +0 -0
- data/test/dummy/tmp/cache/assets/C45/A30/sprockets%2F39494895e462697b478d3d0c79298a26 +0 -0
- data/test/dummy/tmp/cache/assets/C49/730/sprockets%2F212d35831188417b5131e3e693aa69a6 +0 -0
- data/test/dummy/tmp/cache/assets/C55/1D0/sprockets%2F5af2f2a3403040f736981863fd278529 +0 -0
- data/test/dummy/tmp/cache/assets/C5A/A80/sprockets%2F2328c7370b56b4151776981a5f6d394e +0 -0
- data/test/dummy/tmp/cache/assets/C5F/340/sprockets%2F99692920160b7a279b86a80415b79db7 +0 -0
- data/test/dummy/tmp/cache/assets/C70/4D0/sprockets%2F034ad2036e623081bd352800786dfe80 +0 -0
- data/test/dummy/tmp/cache/assets/C80/980/sprockets%2Fc94807409c1523d43e18d25f35d93c41 +0 -0
- data/test/dummy/tmp/cache/assets/C94/E20/sprockets%2F19579abc248373f419b1c3e287d74598 +0 -0
- data/test/dummy/tmp/cache/assets/C98/330/sprockets%2F0c81574ba94abc10657315d4190c201f +0 -0
- data/test/dummy/tmp/cache/assets/CA4/440/sprockets%2F0feb4425db6319d7d0582192a503671b +0 -0
- data/test/dummy/tmp/cache/assets/CA7/E80/sprockets%2F33310f455a870eaedd6d938e30620714 +0 -0
- data/test/dummy/tmp/cache/assets/CB8/3C0/sprockets%2F697cd846490fda9f0e20c558320610f8 +0 -0
- data/test/dummy/tmp/cache/assets/CBF/B60/sprockets%2F08ca89671549936265dcb673bf02e36f +0 -0
- data/test/dummy/tmp/cache/assets/CC7/F10/sprockets%2F939637f806eef3f0f21584659458ab2e +0 -0
- data/test/dummy/tmp/cache/assets/CC9/9F0/sprockets%2F306166316e2cafd13c15e62b51a2339d +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CF7/2B0/sprockets%2F25a7c73655bd3598173b39d9f98bcd46 +0 -0
- data/test/dummy/tmp/cache/assets/CF8/DA0/sprockets%2Ff5b8c8499d3da954d392fa57739503c5 +0 -0
- data/test/dummy/tmp/cache/assets/CF9/590/sprockets%2F096bcc45cd31b3796fa2121cd203215f +0 -0
- data/test/dummy/tmp/cache/assets/CFE/080/sprockets%2F37fe9f4255baddbd549a659914929398 +0 -0
- data/test/dummy/tmp/cache/assets/D04/CC0/sprockets%2Fe9c1b92f2e437e1bbbe020d718739220 +0 -0
- data/test/dummy/tmp/cache/assets/D0B/090/sprockets%2F58009091c95e3ac328c91c68fca30e0e +0 -0
- data/test/dummy/tmp/cache/assets/D1A/B50/sprockets%2F2db5892438129fe94da8429b8be114ec +0 -0
- data/test/dummy/tmp/cache/assets/D2D/1A0/sprockets%2F376426b4896a3cff7969ce6c7b387e0e +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D37/2B0/sprockets%2F40834fb07d7318c1fddd5003bd9e04f6 +0 -0
- data/test/dummy/tmp/cache/assets/D43/0D0/sprockets%2F682843a8d0795a5fbcfeb2f0c81727d0 +0 -0
- data/test/dummy/tmp/cache/assets/D46/F80/sprockets%2Fb15c08e749067d7aad9baf5e9388221c +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D6C/7D0/sprockets%2F8a05d6981ec0d38c51739bef0b3a9c2b +0 -0
- data/test/dummy/tmp/cache/assets/D6E/CF0/sprockets%2F5661c6e4f0cea86fe4523f27261aade5 +0 -0
- data/test/dummy/tmp/cache/assets/D94/FF0/sprockets%2F3b56a1aa77de0d570c38a4a9d5f4b1d6 +0 -0
- data/test/dummy/tmp/cache/assets/D97/6B0/sprockets%2Fb070e8c799d1a4ad5e62e0a1ae3b83e6 +0 -0
- data/test/dummy/tmp/cache/assets/D9A/2F0/sprockets%2Fbba0f4b972dc53c15ce6c8c1993b82a4 +0 -0
- data/test/dummy/tmp/cache/assets/D9C/860/sprockets%2Fec2d9f20b270d70e698ff33e53c21fca +0 -0
- data/test/dummy/tmp/cache/assets/DA6/A80/sprockets%2F92e26d8e58d5bcc8b8f6c25d1b05b9c1 +0 -0
- data/test/dummy/tmp/cache/assets/DA8/BB0/sprockets%2F0cf1c7e9f966dce425517c0e2a844efe +0 -0
- data/test/dummy/tmp/cache/assets/DA9/BC0/sprockets%2Fcb9062b73291befe5e5bf2a70978dec8 +0 -0
- data/test/dummy/tmp/cache/assets/DB6/ED0/sprockets%2Ff4482d9b9f76fb65eef16430bde2f8e6 +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/DE8/790/sprockets%2Fd1333bde2b9aafcc712d11dd09ab35d8 +0 -0
- data/test/dummy/tmp/cache/assets/DF7/960/sprockets%2F99ac6db10b44a64fbba4ee847b35ba8b +0 -0
- data/test/dummy/tmp/cache/assets/DFD/300/sprockets%2Fabac9489cf7f1db8ef00d72a1571ee1e +0 -0
- data/test/dummy/tmp/cache/assets/E02/C10/sprockets%2F1463cadfce3fc70e61d482f9fcb75ac7 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E38/FE0/sprockets%2Fe1fc875efa817cbb94a5d8de25ea4e6b +0 -0
- data/test/dummy/tmp/cache/assets/E50/F00/sprockets%2Fec61afdbb1cc4df075e3dad46f0af571 +0 -0
- data/test/dummy/tmp/cache/assets/E5E/5F0/sprockets%2Feffaeb4d7f9bf4c0cc840ff320fde046 +0 -0
- data/test/dummy/tmp/cache/assets/E5F/960/sprockets%2Fdc007b6cad5c7ef08e33ec28cfff0ef6 +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_accordion.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_alerts.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_breadcrumbs.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_button-groups.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_buttons.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_carousel.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_close.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_code.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_component-animations.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_dropdowns.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_forms.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_grid.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_hero-unit.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_labels-badges.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_layouts.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_media.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_mixins.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_modals.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_navbar.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_navs.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_pager.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_pagination.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_popovers.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_progress-bars.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_reset.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_responsive-1200px-min.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_responsive-767px-max.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_responsive-768px-979px.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_responsive-navbar.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_responsive-utilities.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_scaffolding.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_sprites.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_tables.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_thumbnails.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_tooltip.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_type.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_utilities.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_variables.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/_wells.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/bootstrap.scssc +0 -0
- data/test/dummy/tmp/cache/sass/310d901c169042855feb8cf3903e1e2821d27f13/responsive.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_admin.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_az.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_base.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_forms.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_icons.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_misc.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_mixins.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_modal.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_resolve.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_results.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_search.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_spinner.scssc +0 -0
- data/test/dummy/tmp/cache/sass/3af72421a0fbed39d3047687ca0ad6e6e5545041/_variables.scssc +0 -0
- data/test/dummy/tmp/cache/sass/93d65682d6bddb0b2e6788c1232f4849af20a35e/bootstrap-responsive.scssc +0 -0
- data/test/dummy/tmp/cache/sass/93d65682d6bddb0b2e6788c1232f4849af20a35e/bootstrap.scssc +0 -0
- data/test/dummy/tmp/cache/sass/fb58c04fd15fcc38a8c4d91b7070bcfeaf1c3799/umlaut.css.scssc +0 -0
- data/test/fixtures/dispatched_services.yml +0 -4
- data/test/fixtures/permalinks.yml +23 -4
- data/test/fixtures/referent_values.yml +226 -1493
- data/test/fixtures/referents.yml +14 -137
- data/test/fixtures/requests.yml +22 -260
- data/test/fixtures/service_responses.yml +169 -5
- data/test/fixtures/sfx4/global/KB_OBJECTS.yml +46 -0
- data/test/fixtures/sfx4/local/AZ_EXTRA_INFO.yml +4802 -0
- data/test/fixtures/sfx4/local/AZ_LETTER_GROUP.yml +105 -0
- data/test/fixtures/sfx4/local/AZ_TITLE.yml +165 -0
- data/test/fixtures/sfx4/local/AZ_TITLE_SEARCH.yml +341 -0
- data/test/fixtures/sfx_urls.yml +3 -0
- data/test/functional/export_email_controller_test.rb +43 -0
- data/test/functional/link_router_controller_test.rb +16 -0
- data/test/functional/resolve_controller_test.rb +102 -0
- data/test/functional/search_controller_test.rb +40 -0
- data/test/functional/store_controller_test.rb +29 -0
- data/test/helper/list_with_limit_test.rb +90 -0
- data/test/integration/permalinks_test.rb +14 -0
- data/test/support/search_methods/test_case.rb +0 -0
- data/test/support/service_adaptors/test_case.rb +0 -0
- data/test/support/test_with_cassette.rb +37 -0
- data/test/test_helper.rb +76 -30
- data/test/unit/aws_product_sign_test.rb +2 -0
- data/test/unit/determine_services_test.rb +163 -0
- data/test/unit/google_book_search_test.rb +8 -25
- data/test/unit/google_scholar_link_test.rb +81 -0
- data/test/unit/internet_archive_test.rb +33 -0
- data/test/unit/permalink_test.rb +15 -0
- data/test/unit/service_store_test.rb +47 -0
- data/test/unit/service_test.rb +28 -13
- data/test/unit/sfx/sfx_target_roll_up_test.rb +369 -0
- data/test/unit/sfx4_search_test.rb +102 -0
- data/test/unit/sfx4_solr_search_test.rb +77 -0
- data/test/unit/sfx_test.rb +38 -0
- data/test/unit/worldcat_test.rb +7 -0
- data/test/vcr_cassettes/google_book_search/frankenstein_by_OCLC_number.yml +107 -0
- data/test/vcr_cassettes/internet_archive/momo_by_title_author.yml +116 -0
- data/test/vcr_cassettes/resolve/fulltext_with_edition_warning.yml +44 -0
- data/test/vcr_cassettes/resolve/no_holdings.yml +649 -0
- data/test/vcr_cassettes/resolve/nytimes_by_issn.yml +224 -0
- data/test/vcr_cassettes/sfx/nytimes_by_issn.yml +1395 -0
- data/test/vcr_cassettes/sfx4_solr/find_by_group.yml +109 -0
- data/test/vcr_cassettes/sfx4_solr/find_by_title_begins_with.yml +33 -0
- data/test/vcr_cassettes/sfx4_solr/find_by_title_contains.yml +34 -0
- data/test/vcr_cassettes/sfx4_solr/find_by_title_exact.yml +32 -0
- data/test/view/holding_test.rb +30 -0
- metadata +435 -179
- data/app/assets/images/export_bg_bot.gif +0 -0
- data/app/assets/images/export_bg_mid.gif +0 -0
- data/app/assets/images/export_bg_top.gif +0 -0
- data/app/assets/images/famfamfam/page_sound.gif +0 -0
- data/app/assets/images/famfamfam/page_text.gif +0 -0
- data/app/assets/images/famfamfam/page_up.gif +0 -0
- data/app/assets/images/ico_go.gif +0 -0
- data/app/assets/images/more_info.gif +0 -0
- data/app/assets/images/rails.png +0 -0
- data/app/assets/images/request.gif +0 -0
- data/app/assets/javascripts/umlaut/simple_visible_toggle.js +0 -8
- data/app/assets/stylesheets/umlaut.css +0 -900
- data/app/assets/stylesheets/umlaut/_background_progress_spinner.scss +0 -21
- data/app/assets/stylesheets/umlaut/_expand_contract.scss +0 -28
- data/app/controllers/search_methods/sfx3.rb +0 -148
- data/app/models/sfx_db.rb +0 -10
- data/app/models/sfx_db/az_additional_title.rb +0 -11
- data/app/models/sfx_db/az_letter_group.rb +0 -11
- data/app/models/sfx_db/az_title.rb +0 -40
- data/app/models/sfx_db/az_title_v2.rb +0 -34
- data/app/models/sfx_db/isbn.rb +0 -12
- data/app/models/sfx_db/issn.rb +0 -12
- data/app/models/sfx_db/object.rb +0 -35
- data/app/models/sfx_db/object_portfolio.rb +0 -6
- data/app/models/sfx_db/publisher.rb +0 -10
- data/app/models/sfx_db/sfx_db_base.rb +0 -58
- data/app/models/sfx_db/target.rb +0 -10
- data/app/models/sfx_db/target_service.rb +0 -10
- data/app/models/sfx_db/title.rb +0 -10
- data/app/views/export_email/_email.html.erb +0 -25
- data/app/views/export_email/_send_email.html.erb +0 -3
- data/app/views/export_email/_send_txt.html.erb +0 -3
- data/app/views/export_email/_txt.html.erb +0 -62
- data/lib/holding.rb +0 -32
- data/lib/opensearch_feed.rb +0 -398
- data/lib/opensearch_query.rb +0 -98
- data/lib/referent_filters/dissertation_catch.rb +0 -45
- data/lib/service_adaptors/journal_tocs.progress +0 -68
- data/lib/service_adaptors/primo_service.rb +0 -452
- data/lib/service_adaptors/primo_source.rb +0 -82
- data/lib/umlaut/default_configuration.rb +0 -5
- data/test/dummy/config/primo.yml +0 -271
- data/test/unit/primo_service_test.rb +0 -947
data/lib/opensearch_query.rb
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
module FeedTools
|
2
|
-
class OpensearchQuery
|
3
|
-
def initialize(role='request', attributes={})
|
4
|
-
@role = self.role=role
|
5
|
-
@title = nil
|
6
|
-
@search_terms = nil
|
7
|
-
@total_results = nil
|
8
|
-
@count = nil
|
9
|
-
@start_index = nil
|
10
|
-
@start_page = nil
|
11
|
-
@language = nil
|
12
|
-
@input_encoding = nil
|
13
|
-
@output_encoding = nil
|
14
|
-
attributes.each { | key, val |
|
15
|
-
next unless val
|
16
|
-
iv = "@"+key.to_s
|
17
|
-
self.instance_variable_set(iv.to_sym, val) if self.instance_variables.index(iv)
|
18
|
-
}
|
19
|
-
end
|
20
|
-
def role
|
21
|
-
return @role
|
22
|
-
end
|
23
|
-
def role=(role)
|
24
|
-
roles = ["request","example","related","correction","subset","superset"]
|
25
|
-
raise(ArgumentError, "Must be a valid role") unless roles.index(role)
|
26
|
-
@role=role
|
27
|
-
end
|
28
|
-
def title
|
29
|
-
return @title
|
30
|
-
end
|
31
|
-
def title=(title)
|
32
|
-
@title=title
|
33
|
-
end
|
34
|
-
def search_terms
|
35
|
-
return @search_terms
|
36
|
-
end
|
37
|
-
def search_terms=(search_terms)
|
38
|
-
@search_terms=search_terms
|
39
|
-
end
|
40
|
-
def total_results
|
41
|
-
return @total_results
|
42
|
-
end
|
43
|
-
def total_results=(total_results)
|
44
|
-
@total_results=total_results
|
45
|
-
end
|
46
|
-
def count
|
47
|
-
return @count
|
48
|
-
end
|
49
|
-
def count=(count)
|
50
|
-
@count=count
|
51
|
-
end
|
52
|
-
def start_index
|
53
|
-
return @start_index
|
54
|
-
end
|
55
|
-
def start_index=(start_index)
|
56
|
-
@start_index=start_index
|
57
|
-
end
|
58
|
-
def start_page
|
59
|
-
return @start_page
|
60
|
-
end
|
61
|
-
def start_page=(start_page)
|
62
|
-
@start_page=start_page
|
63
|
-
end
|
64
|
-
def language
|
65
|
-
return @language
|
66
|
-
end
|
67
|
-
def language=(lang)
|
68
|
-
@language=lang
|
69
|
-
end
|
70
|
-
def input_encoding
|
71
|
-
return @input_encoding
|
72
|
-
end
|
73
|
-
def input_encoding=(ip)
|
74
|
-
@input_encoding=ip
|
75
|
-
end
|
76
|
-
def output_encoding
|
77
|
-
return @output_encoding
|
78
|
-
end
|
79
|
-
def output_encoding=(op)
|
80
|
-
@output_encoding=op
|
81
|
-
end
|
82
|
-
def build_xml(xml)
|
83
|
-
attrs = {}
|
84
|
-
attrs[:role]=@role if @role
|
85
|
-
attrs[:title]=@title if @title
|
86
|
-
attrs[:count]=@count if @count
|
87
|
-
attrs[:language]=@language if @language
|
88
|
-
attrs[:searchTerms]=@search_terms if @search_terms
|
89
|
-
attrs[:startIndex]=@start_index if @start_index
|
90
|
-
attrs[:startPage]=@start_page if @start_page
|
91
|
-
attrs[:inputEncoding]=@input_encoding if @input_encoding
|
92
|
-
attrs[:outputEncoding]=@output_encoding if @output_encoding
|
93
|
-
attrs[:totalResults]=@total_results if @total_results
|
94
|
-
xml.tag!("opensearch:Query", attrs)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
class DissertationCatch < ReferentFilter
|
2
|
-
include MetadataHelper
|
3
|
-
|
4
|
-
@@da_issns = ['00959154', '00993123', '04194209', '04194217', '0420073X', '00993123', '10427279', '03076075']
|
5
|
-
|
6
|
-
# input: ropenurl ContextObject
|
7
|
-
# Is this a citation to a Dissertation Abstracts
|
8
|
-
# issn, or do we otherwise think it's a dissertation citation? Then change
|
9
|
-
# it to a dissertation citation.
|
10
|
-
def filter(referent)
|
11
|
-
issn = get_identifier(:urn, "issn", referent)
|
12
|
-
|
13
|
-
return unless issn
|
14
|
-
|
15
|
-
# normalize removing hyphen
|
16
|
-
issn.gsub!('-', '')
|
17
|
-
|
18
|
-
if ( @@da_issns.find { |i| i == issn } )
|
19
|
-
# || lc($jtitle) =~ /dissertation/i || lc($jtitle2) =~ /dissertation/i)
|
20
|
-
|
21
|
-
referent.enhance_referent("genre", "dissertation")
|
22
|
-
|
23
|
-
metadata = referent.metadata
|
24
|
-
# Reset it's title to the dissertation title
|
25
|
-
title = metadata['atitle'] || metadata['title']
|
26
|
-
referent.enhance_referent("btitle", title)
|
27
|
-
referent.enhance_referent("title", title, true, false, :overwrite => true)
|
28
|
-
# Now erase titles that do not apply
|
29
|
-
referent.remove_value("atitle")
|
30
|
-
referent.remove_value("jtitle")
|
31
|
-
referent.remove_value("stitle")
|
32
|
-
# issn or isbn are wrong, probably point to Dissertation Abstracts
|
33
|
-
referent.remove_value("issn")
|
34
|
-
referent.remove_value("isbn")
|
35
|
-
# Same with all article level metadata
|
36
|
-
referent.remove_value("volume")
|
37
|
-
referent.remove_value("issue")
|
38
|
-
referent.remove_value("issue_start")
|
39
|
-
referent.remove_value("spage")
|
40
|
-
referent.remove_value("epage")
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
require 'open-uri'
|
3
|
-
|
4
|
-
|
5
|
-
class JournalTocs < Service
|
6
|
-
include MetadataHelper
|
7
|
-
|
8
|
-
def service_types_generated
|
9
|
-
return [ServiceTypeValue['table_of_contents']]
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@base_url = 'http://www.journaltocs.ac.uk/api'
|
14
|
-
super
|
15
|
-
end
|
16
|
-
|
17
|
-
def handle(request)
|
18
|
-
issn = get_issn(request.referent)
|
19
|
-
|
20
|
-
# Can only work with an ISSN
|
21
|
-
unless issn
|
22
|
-
return request.dispatched(self, true)
|
23
|
-
end
|
24
|
-
|
25
|
-
xml = Nokogiri::XML( open(request_url(url)) )
|
26
|
-
|
27
|
-
items = xml.search("//rss:item")
|
28
|
-
|
29
|
-
unless items.length > 0
|
30
|
-
# found nothing, no match, or no contents.
|
31
|
-
return request.dispatched(self, true)
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
def request_url(issn)
|
40
|
-
return "#{@base_url.chomp('/')}/#{issn}?output=articles"
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
def xml_ns
|
45
|
-
{ "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
46
|
-
"rss" => "http://purl.org/rss/1.0/",
|
47
|
-
"prism"="http://prismstandard.org/namespaces/1.2/basic/",
|
48
|
-
"dc"="http://purl.org/dc/elements/1.1/",
|
49
|
-
"mn"="http://usefulinc.com/rss/manifest/",
|
50
|
-
"content"="http://purl.org/rss/1.0/modules/content/"
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
# Given a Nokogiri list of rss:items, returns a list of OpenURL::ContextObjects
|
55
|
-
def extract_items(items)
|
56
|
-
items.collect do |item|
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
class Item
|
63
|
-
attr_accessor :title,
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
|
@@ -1,452 +0,0 @@
|
|
1
|
-
# == Overview
|
2
|
-
# PrimoService is a Service that makes a call to the Primo web services based on the OpenURL key value pairs.
|
3
|
-
#--
|
4
|
-
# NOT YET:
|
5
|
-
# It first looks for rft.primo *DEPRECATED*, failing that, it parses the identifier for an id.
|
6
|
-
#++
|
7
|
-
# It first looks for rft.primo, the Primo id.
|
8
|
-
# If the Primo id is present, the service gets the PNX record from the Primo web
|
9
|
-
# services.
|
10
|
-
# If no Primo id is found, the service searches Primo by (in order of precedence):
|
11
|
-
# * ISBN
|
12
|
-
# * ISSN
|
13
|
-
# * Title, Author, Genre
|
14
|
-
#
|
15
|
-
# == Available Services
|
16
|
-
# Several service types are available in the Primo service. The default service types are:
|
17
|
-
# fulltext, holding, holding_search, table_of_contents, referent_enhance, cover_image
|
18
|
-
# Available service types are listed below and can be configured using the service_types parameter
|
19
|
-
# in service.yml:
|
20
|
-
# * fulltext - parsed from links/linktorsrc elements in the PNX record
|
21
|
-
# * holding - parsed from display/availlibrary elements in the PNX record
|
22
|
-
# * holding_search - link to an exact title search in Primo if no holdings found AND the OpenURL did not come from Primo
|
23
|
-
# * primo_source - similar to holdings but used in conjuction with the PrimoSource service to map Primo records to their original sources; a PrimoSource service must be defined in service.yml for this to work
|
24
|
-
# * table_of_contents - parsed from links/linktotoc elements in the PNX record
|
25
|
-
# * referent_enhance - metadata parsed from the addata section of the PNX record when the record was found by Primo id
|
26
|
-
# * cover_image - parsed from first addata/lad02 element in the PNX record
|
27
|
-
# * highlighted_link - parsed from links/addlink elements in the PNX record
|
28
|
-
#
|
29
|
-
# ==Available Parameters
|
30
|
-
# Several configurations parameters are available to be set in services.yml, e.g.
|
31
|
-
# Primo:
|
32
|
-
# type: PrimoService
|
33
|
-
# priority: 2 # After SFX, to get SFX metadata enhancement
|
34
|
-
# status: active
|
35
|
-
# base_url: http://bobcat.library.nyu.edu
|
36
|
-
# vid: NYU
|
37
|
-
# holding_search_institution: NYU
|
38
|
-
# holding_search_text: Search for this title in BobCat.
|
39
|
-
# suppress_holdings: [ !ruby/regexp '/\$\$LWEB/', !ruby/regexp '/\$\$1Restricted Internet Resources/' ]
|
40
|
-
# ez_proxy: !ruby/regexp '/https\:\/\/ezproxy\.library\.nyu\.edu\/login\?url=/'
|
41
|
-
# service_types:
|
42
|
-
# - holding
|
43
|
-
# - holding_search
|
44
|
-
# - fulltext
|
45
|
-
# - table_of_contents
|
46
|
-
# - referent_enhance
|
47
|
-
# - cover_image
|
48
|
-
# - highlighted_link
|
49
|
-
# base_url:: _required_ host and port of Primo server; used for Primo web services, deep links and holding_search
|
50
|
-
# base_path:: *DEPRECATED* previous name of base_url
|
51
|
-
# vid:: _required_ view id for Primo deep links and holding_search.
|
52
|
-
# institution:: _required_ institution id for Primo institution; used for Primo web services
|
53
|
-
# base_view_id:: *DEPRECATED* previous name of vid
|
54
|
-
# holding_search_institution:: _required if service types include holding_search_ institution to be used for the holding_search
|
55
|
-
# holding_search_text:: _optional_ text to display for the holding_search
|
56
|
-
# default holding search text:: "Search for this title."
|
57
|
-
# link_to_search_text:: *DEPRECATED* previous name of holding_search_text
|
58
|
-
# service_types:: _optional_ array of strings that represent the service types desired.
|
59
|
-
# options are: fulltext, holding, holding_search, table_of_contents,
|
60
|
-
# referent_enhance, cover_image, primo_source
|
61
|
-
# defaults are: fulltext, holding, holding_search, table_of_contents,
|
62
|
-
# referent_enhance, cover_image
|
63
|
-
# if no options are specified, default service types will be added.
|
64
|
-
# suppress_urls:: _optional_ array of strings or regexps to NOT use from the catalog.
|
65
|
-
# Used for linktorsrc elements that may duplicate resources from in other services.
|
66
|
-
# Regexps can be put in the services.yml like this:
|
67
|
-
# [!ruby/regexp '/sagepub.com$/']
|
68
|
-
# suppress_holdings:: _optional_ array of strings or regexps to NOT use from the catalog.
|
69
|
-
# Used for availlibrary elements that may duplicate resources from in other services.
|
70
|
-
# Regexps can be put in the services.yml like this:
|
71
|
-
# [!ruby/regexp '/\$\$LWEB$/']
|
72
|
-
# suppress_tocs:: _optional_ array of strings or regexps to NOT link to for Tables of Contents.
|
73
|
-
# Used for linktotoc elements that may duplicate resources from in other services.
|
74
|
-
# Regexps can be put in the services.yml like this:
|
75
|
-
# [!ruby/regexp '/\$\$LWEB$/']
|
76
|
-
# service_types:: _optional_ array of strings that represent the service types desired.
|
77
|
-
# options are: fulltext, holding, holding_search, table_of_contents,
|
78
|
-
# referent_enhance, cover_image, primo_source
|
79
|
-
# defaults are: fulltext, holding, holding_search, table_of_contents,
|
80
|
-
# referent_enhance, cover_image
|
81
|
-
# if no options are specified, default service types will be added.
|
82
|
-
# ez_proxy:: _optional_ string or regexp of an ezproxy prefix.
|
83
|
-
# used in the case where an ezproxy prefix (on any other regexp) is hardcoded in the URL,
|
84
|
-
# and needs to be removed in order to match against SFXUrls.
|
85
|
-
# Example:
|
86
|
-
# !ruby/regexp '/https\:\/\/ezproxy\.library\.nyu\.edu\/login\?url=/'
|
87
|
-
# primo_config:: _optional_ string representing the primo yaml config file in config/umlaut_config
|
88
|
-
# default file name: primo.yml
|
89
|
-
# hash mappings from yaml config
|
90
|
-
# institutions:
|
91
|
-
# "primo_institution_code": "Primo Institution String"
|
92
|
-
# libraries:
|
93
|
-
# "primo_library_code": "Primo Library String"
|
94
|
-
# statuses:
|
95
|
-
# "status1_code": "Status One"
|
96
|
-
# sources:
|
97
|
-
# data_source1:
|
98
|
-
# base_url: "http://source1.base.url
|
99
|
-
# type: source_type
|
100
|
-
# class_name: Source1Implementation (in exlibris/primo/sources or exlibris/primo/sources/local)
|
101
|
-
# source1_config_option1: source1_config_option1
|
102
|
-
# source1_config_option2: source1_config_option2
|
103
|
-
# data_source2:
|
104
|
-
# base_url: "http://source2.base.url
|
105
|
-
# type: source_type
|
106
|
-
# class_name: Source2Implementation (in exlibris/primo/sources or exlibris/primo/sources/local)
|
107
|
-
# source2_config_option1: source2_config_option1
|
108
|
-
# source2_config_option2: source2_config_option2
|
109
|
-
# holding_attributes:: _optional_ array of Holding attribute readers to save to
|
110
|
-
# holding/primo_source service_data; can be used to save
|
111
|
-
# custom source implementation attributes for display by a custom holding partial
|
112
|
-
# ==Benchmarks
|
113
|
-
# The following benchmarks were run on SunOS 5.10 Generic_141414-08 sun4u sparc SUNW,Sun-Fire-V240.
|
114
|
-
# Rehearsal ----------------------------------------------------------------
|
115
|
-
# PrimoService Minimum Config: 3.850000 0.060000 3.910000 ( 4.163065)
|
116
|
-
# PrimoService Default Config: 3.410000 0.060000 3.470000 ( 3.958777)
|
117
|
-
# ------------------------------------------------------- total: 7.380000sec
|
118
|
-
#
|
119
|
-
# user system total real
|
120
|
-
# PrimoService Minimum Config: 3.470000 0.050000 3.520000 ( 4.567797)
|
121
|
-
# PrimoService Default Config: 3.420000 0.050000 3.470000 ( 3.990271)
|
122
|
-
class PrimoService < Service
|
123
|
-
require 'exlibris-primo'
|
124
|
-
|
125
|
-
required_config_params :base_url, :vid, :institution
|
126
|
-
# For matching purposes.
|
127
|
-
attr_reader :title, :author
|
128
|
-
|
129
|
-
# Overwrites Service#new.
|
130
|
-
def initialize(config)
|
131
|
-
# defaults
|
132
|
-
@holding_attributes = Exlibris::Primo::Holding.base_attributes
|
133
|
-
@rsrc_attributes = Exlibris::Primo::Rsrc.base_attributes
|
134
|
-
@toc_attributes = Exlibris::Primo::Toc.base_attributes
|
135
|
-
@related_link_attributes = Exlibris::Primo::RelatedLink.base_attributes
|
136
|
-
# TODO: Run these decisions by Bill M. to see if they make sense.
|
137
|
-
@referent_enhancements = {
|
138
|
-
# Prefer SFX journal titles to Primo journal titles
|
139
|
-
:jtitle => { :overwrite => false },
|
140
|
-
:btitle => { :overwrite => true }, :aulast => { :overwrite => true },
|
141
|
-
:aufirst => { :overwrite => true }, :aucorp => { :overwrite => true },
|
142
|
-
:au => { :overwrite => true }, :pub => { :overwrite => true },
|
143
|
-
:place => { :value => :cop, :overwrite => false },
|
144
|
-
# Prefer SFX journal titles to Primo journal titles
|
145
|
-
:title => { :value => :jtitle, :overwrite => false},
|
146
|
-
:title => { :value => :btitle, :overwrite => true},
|
147
|
-
# Primo lccn and oclcid are spotty in Primo, so don't overwrite
|
148
|
-
:lccn => { :overwrite => false }, :oclcnum => { :value => :oclcid, :overwrite => false}
|
149
|
-
}
|
150
|
-
@suppress_urls = []
|
151
|
-
@suppress_tocs = []
|
152
|
-
@suppress_related_links = []
|
153
|
-
@suppress_holdings = []
|
154
|
-
@service_types = [ "fulltext", "holding", "holding_search",
|
155
|
-
"table_of_contents", "referent_enhance", "cover_image" ] if @service_types.nil?
|
156
|
-
# For backward compatibility, re-map "old" config values to new more
|
157
|
-
# Umlaut-y names and print deprecation warning in the logs.
|
158
|
-
old_to_new_mappings = {
|
159
|
-
:base_path => :base_url,
|
160
|
-
:base_view_id => :vid,
|
161
|
-
:link_to_search_text => :holding_search_text
|
162
|
-
}
|
163
|
-
old_to_new_mappings.each do |old_param, new_param|
|
164
|
-
unless config["#{old_param}"].nil?
|
165
|
-
config["#{new_param}"] = config["#{old_param}"] if config["#{new_param}"].nil?
|
166
|
-
Rails.logger.warn("Parameter '#{old_param}' is deprecated. Please use '#{new_param}' instead.")
|
167
|
-
end
|
168
|
-
end # End backward compatibility maintenance
|
169
|
-
super(config)
|
170
|
-
# For backward compatibility, handle the special case where holding_search_institution was not included.
|
171
|
-
# Set holding_search_institution to vid and print warning in the logs.
|
172
|
-
if @service_types.include?("holding_search") and @holding_search_institution.nil?
|
173
|
-
@holding_search_institution = @institution
|
174
|
-
Rails.logger.warn("Required parameter 'holding_search_institution' was not set. Please set the appropriate value in services.yml. Defaulting institution to view id, #{@vid}.")
|
175
|
-
end # End backward compatibility maintenance
|
176
|
-
raise ArgumentError.new(
|
177
|
-
"Missing Service configuration parameter. Service type #{self.class} (id: #{self.id}) requires a config parameter named 'holding_search_institution'. Check your config/umlaut_config/services.yml file."
|
178
|
-
) if @service_types.include?("holding_search") and @holding_search_institution.nil?
|
179
|
-
end
|
180
|
-
|
181
|
-
# Overwrites Service#service_types_generated.
|
182
|
-
def service_types_generated
|
183
|
-
types = Array.new
|
184
|
-
@service_types.each do |type|
|
185
|
-
types.push(ServiceTypeValue[type.to_sym])
|
186
|
-
end
|
187
|
-
return types
|
188
|
-
end
|
189
|
-
|
190
|
-
# Overwrites Service#handle.
|
191
|
-
def handle(request)
|
192
|
-
@identifier = request.referrer_id
|
193
|
-
@primo_id = @identifier.match(/primo-(.+)/)[1] if primo_identifier? unless @identifier.nil? or @identifier.match(/primo-(.+)/).nil?
|
194
|
-
# DEPRECATED
|
195
|
-
# Extend OpenURL standard to take Primo Doc Id
|
196
|
-
@primo_id = request.referent.metadata['primo'] unless request.referent.metadata['primo'].nil?
|
197
|
-
Rails.logger.warn("Use of 'rft.primo' is deprecated. Please use the identifier instead.") unless request.referent.metadata['primo'].nil?
|
198
|
-
# End DEPRECATED
|
199
|
-
searcher_setup = {
|
200
|
-
:base_url => @base_url, :vid => @vid, :institution => @institution,
|
201
|
-
:config => primo_config
|
202
|
-
}
|
203
|
-
# don't send mal-formed issn
|
204
|
-
@issn = request.referent.metadata['issn'] if request.referent.metadata['issn'] =~ /\d{4}(-)?\d{3}(\d|X)/
|
205
|
-
@isbn = request.referent.metadata['isbn']
|
206
|
-
@title = title(request)
|
207
|
-
search_params = {
|
208
|
-
:primo_id => @primo_id,
|
209
|
-
:isbn => @isbn,
|
210
|
-
:issn => @issn,
|
211
|
-
:title => @title,
|
212
|
-
:author => author(request),
|
213
|
-
:genre => request.referent.metadata['genre']
|
214
|
-
}
|
215
|
-
begin
|
216
|
-
primo_searcher = Exlibris::Primo::Searcher.new(searcher_setup, search_params)
|
217
|
-
rescue Exception => e
|
218
|
-
# Log error and return finished
|
219
|
-
Rails.logger.error(
|
220
|
-
"Error in Exlibris::Primo::Searcher. "+
|
221
|
-
"Returning 0 Primo services for search #{search_params.inspect}. "+
|
222
|
-
"Exlibris::Primo::Searcher raised the following exception:\n#{e}\n#{e.backtrace.inspect}")
|
223
|
-
return request.dispatched(self, true)
|
224
|
-
end
|
225
|
-
# Enhance the referent with metadata from Primo Searcher if primo id is present
|
226
|
-
# i.e. if we did our search with the Primo system number
|
227
|
-
if @primo_id and @service_types.include?("referent_enhance")
|
228
|
-
@referent_enhancements.each do |key, options|
|
229
|
-
value = (options[:value].nil?) ? key.to_sym : options[:value].to_sym
|
230
|
-
request.referent.enhance_referent(
|
231
|
-
key.to_s, primo_searcher.method(value).call,
|
232
|
-
true, false, options
|
233
|
-
) if primo_searcher.respond_to? value and not primo_searcher.method(value).call.nil?
|
234
|
-
end
|
235
|
-
end
|
236
|
-
# Get cover image only if @primo_id is defined
|
237
|
-
# TODO: make cover image service smarter and only
|
238
|
-
# include things that are actually URLs.
|
239
|
-
if @primo_id and @service_types.include?("cover_image")
|
240
|
-
cover_image = primo_searcher.cover_image
|
241
|
-
unless cover_image.nil?
|
242
|
-
request.add_service_response(
|
243
|
-
:service => self,
|
244
|
-
:display_text => 'Cover Image',
|
245
|
-
:key => 'medium',
|
246
|
-
:url => cover_image,
|
247
|
-
:size => 'medium',
|
248
|
-
:service_type_value => :cover_image)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
# Get holdings from Primo Searcher
|
252
|
-
if @service_types.include?("holding") or @service_types.include?("primo_source")
|
253
|
-
holdings = primo_searcher.holdings # Array of Exlibris::Primo::Holding
|
254
|
-
holdings.each do |holding|
|
255
|
-
next if @suppress_holdings.find {|suppress| suppress === holding.availlibrary}
|
256
|
-
service_data = {}
|
257
|
-
@holding_attributes.each do |attr|
|
258
|
-
service_data[attr] = holding.method(attr).call
|
259
|
-
end
|
260
|
-
# Umlaut specific attributes.
|
261
|
-
service_data[:match_reliability] =
|
262
|
-
(reliable_match?(:title => holding.title, :author => holding.author)) ?
|
263
|
-
ServiceResponse::MatchExact : ServiceResponse::MatchUnsure
|
264
|
-
service_data[:request_link_supports_ajax_call] =
|
265
|
-
(holding.respond_to?(:request_link_supports_ajax_call)) ?
|
266
|
-
holding.request_link_supports_ajax_call : false
|
267
|
-
# Only add one service type, either "primo_source" OR "holding", not both.
|
268
|
-
service_type = (@service_types.include?("primo_source")) ? "primo_source" : "holding"
|
269
|
-
# Add some other holding information for compatibility with default holding partial
|
270
|
-
service_data.merge!({
|
271
|
-
:call_number => holding.call_number, :collection => holding.collection,
|
272
|
-
:collection_str => "#{holding.library} #{holding.collection}",
|
273
|
-
:coverage_str => holding.coverage.join("<br />"),
|
274
|
-
:coverage_str_array => holding.coverage }) if service_type.eql? "holding"
|
275
|
-
request.add_service_response(
|
276
|
-
service_data.merge(
|
277
|
-
:service => self,
|
278
|
-
:service_type_value => service_type
|
279
|
-
)
|
280
|
-
)
|
281
|
-
end
|
282
|
-
# Provide title search functionality in the absence of available holdings.
|
283
|
-
if @service_types.include?("holding_search")
|
284
|
-
if holdings.empty? and
|
285
|
-
not primo_identifier? and
|
286
|
-
not @title.nil?
|
287
|
-
service_data = {}
|
288
|
-
service_data[:type] = "link_to_search"
|
289
|
-
service_data[:display_text] = (@holding_search_text.nil?) ? "Search for this title." : @holding_search_text
|
290
|
-
service_data[:note] = ""
|
291
|
-
service_data[:url] = @base_url+"/primo_library/libweb/action/dlSearch.do?institution=#{@holding_search_institution}&vid=#{@vid}&onCampus=false&query=#{CGI::escape("title,exact,"+@title)}&indx=1&bulkSize=10&group=GUEST"
|
292
|
-
request.add_service_response(
|
293
|
-
service_data.merge(
|
294
|
-
:service => self,
|
295
|
-
:service_type_value => 'holding_search'
|
296
|
-
)
|
297
|
-
)
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
# Get fulltext
|
302
|
-
if @service_types.include?("fulltext")
|
303
|
-
# Get RSRCs from Primo Searcher (executes search)
|
304
|
-
# Let's find any URLs, and add full text responses for those.
|
305
|
-
urls_seen = [] # for de-duplicating urls from catalog.
|
306
|
-
primo_searcher.rsrcs.each do |rsrc|
|
307
|
-
# No url? Forget it.
|
308
|
-
next if rsrc.url.nil?
|
309
|
-
# Next if duplicate.
|
310
|
-
next if urls_seen.include?(rsrc.url)
|
311
|
-
# Don't add the URL if it matches our SFXUrl finder (unless fulltext is empty,
|
312
|
-
# [assuming something is better than nothing]), because
|
313
|
-
# that means we think this is an SFX controlled URL.
|
314
|
-
next if SfxUrl.sfx_controls_url?(handle_ezproxy(rsrc.url)) and
|
315
|
-
request.referent.metadata['genre'] != "book" and
|
316
|
-
!request.get_service_type("fulltext", { :refresh => true }).empty?
|
317
|
-
# We have our own list of URLs to suppress, array of strings
|
318
|
-
# or regexps.
|
319
|
-
next if @suppress_urls.find {|suppress| suppress === rsrc.url}
|
320
|
-
urls_seen.push(rsrc.url)
|
321
|
-
service_data = {}
|
322
|
-
@rsrc_attributes.each do |attr|
|
323
|
-
service_data[attr] = rsrc.method(attr).call
|
324
|
-
end
|
325
|
-
# Default display text to URL.
|
326
|
-
service_data[:display_text] = (service_data[:display].nil?) ? service_data[:url] : service_data[:display]
|
327
|
-
# Add the response
|
328
|
-
request.add_service_response(
|
329
|
-
service_data.merge(
|
330
|
-
:service => self,
|
331
|
-
:service_type_value => 'fulltext'
|
332
|
-
)
|
333
|
-
)
|
334
|
-
end
|
335
|
-
end
|
336
|
-
# Get TOCs
|
337
|
-
if @service_types.include?("table_of_contents")
|
338
|
-
# Let's find any TOCs, and add table of contents responses for those.
|
339
|
-
tocs_seen = [] # for de-duplicating urls from catalog.
|
340
|
-
primo_searcher.tocs.each do |toc|
|
341
|
-
url = toc.url # actual url
|
342
|
-
next if tocs_seen.include?(toc.url)
|
343
|
-
# We have our own list of URLs to suppress, array of strings
|
344
|
-
# or regexps.
|
345
|
-
next if @suppress_tocs.find {|suppress| suppress === toc.url}
|
346
|
-
# No url? Forget it.
|
347
|
-
next if toc.url.nil?
|
348
|
-
tocs_seen.push(toc.url)
|
349
|
-
service_data = {}
|
350
|
-
@toc_attributes.each do |attr|
|
351
|
-
service_data[attr] = toc.method(attr).call
|
352
|
-
end
|
353
|
-
# Default display text to URL.
|
354
|
-
service_data[:display_text] = (service_data[:display].nil?) ? service_data[:url] : service_data[:display]
|
355
|
-
# Add the response
|
356
|
-
request.add_service_response(
|
357
|
-
service_data.merge(
|
358
|
-
:service => self,
|
359
|
-
:service_type_value => 'table_of_contents'
|
360
|
-
)
|
361
|
-
)
|
362
|
-
end
|
363
|
-
end
|
364
|
-
if @service_types.include?("highlighted_link")
|
365
|
-
# Let's find any related links, and add highlighted link responses for those.
|
366
|
-
related_links_seen = [] # for de-duplicating urls from catalog.
|
367
|
-
primo_searcher.related_links.each do |related_link|
|
368
|
-
url = related_link.url # actual url
|
369
|
-
next if related_links_seen.include?(related_link.url)
|
370
|
-
# We have our own list of URLs to suppress, array of strings
|
371
|
-
# or regexps.
|
372
|
-
next if @suppress_related_links.find {|suppress| suppress === related_link.url}
|
373
|
-
# No url? Forget it.
|
374
|
-
next if related_link.url.nil?
|
375
|
-
related_links_seen.push(related_link.url)
|
376
|
-
service_data = {}
|
377
|
-
@related_link_attributes.each do |attr|
|
378
|
-
service_data[attr] = related_link.method(attr).call
|
379
|
-
end
|
380
|
-
# Default display text to URL.
|
381
|
-
service_data[:display_text] = (service_data[:display].nil?) ? service_data[:url] : service_data[:display]
|
382
|
-
# Add the response
|
383
|
-
request.add_service_response(
|
384
|
-
service_data.merge(
|
385
|
-
:service => self,
|
386
|
-
:service_type_value => 'highlighted_link'
|
387
|
-
)
|
388
|
-
)
|
389
|
-
end
|
390
|
-
end
|
391
|
-
return request.dispatched(self, true)
|
392
|
-
end
|
393
|
-
|
394
|
-
# Called by ServiceType#view_data to provide custom functionality for Primo sources.
|
395
|
-
# For more information on Primo sources see PrimoSource.
|
396
|
-
def to_primo_source(service_response)
|
397
|
-
source_parameters = { :base_url => @base_url, :vid => @vid, :config => primo_config }
|
398
|
-
@holding_attributes.each { |attr|
|
399
|
-
source_parameters[attr] = service_response.data_values[attr] }
|
400
|
-
return Exlibris::Primo::Holding.new(source_parameters).to_source
|
401
|
-
end
|
402
|
-
|
403
|
-
private
|
404
|
-
# Determine how sure we are that this is a match.
|
405
|
-
# Dynamically compares record metadata to input values
|
406
|
-
# based on the values passed in.
|
407
|
-
# Minimum requirement is to check title.
|
408
|
-
def reliable_match?(record_metadata)
|
409
|
-
return true unless (@primo_id.nil? or @primo_id.empty?)
|
410
|
-
return true unless (@issn.nil? or @issn.empty?) and (@isbn.nil? or @isbn.empty?)
|
411
|
-
return false if (record_metadata.nil? or record_metadata.empty? or record_metadata[:title].nil? or record_metadata[:title].empty?)
|
412
|
-
# Titles must be equal
|
413
|
-
return false unless record_metadata[:title].downcase.eql?(@title.downcase)
|
414
|
-
# Compare record metadata with metadata that was passed in.
|
415
|
-
# Only check if the record metadata value contains the input value since we can't be too strict.
|
416
|
-
record_metadata.each { |type, value| return false if value.downcase.match("#{self.method(type).call}".downcase).nil?}
|
417
|
-
return true
|
418
|
-
end
|
419
|
-
|
420
|
-
def primo_config
|
421
|
-
default_file = "#{Rails.root}/config/primo.yml"
|
422
|
-
config_file = @primo_config.nil? ? default_file : "#{Rails.root}/config/"+ @primo_config
|
423
|
-
Rails.logger.warn("Primo config file not found: #{config_file}.") and return {} unless File.exists?(config_file)
|
424
|
-
config_hash = YAML.load_file(config_file)
|
425
|
-
return (config_hash.nil?) ? {} : config_hash
|
426
|
-
end
|
427
|
-
|
428
|
-
# If an ezproxy prefix (on any other regexp) is hardcoded in the URL,
|
429
|
-
# strip it out for matching against SFXUrls
|
430
|
-
def handle_ezproxy(str)
|
431
|
-
return str if @ez_proxy.nil?
|
432
|
-
return (str.gsub(@ez_proxy, '').nil? ? str : str.gsub(@ez_proxy, ''))
|
433
|
-
end
|
434
|
-
|
435
|
-
def title(request)
|
436
|
-
return request.referent.metadata['jtitle'] unless request.referent.metadata['jtitle'].nil? or request.referent.metadata['jtitle'].empty?
|
437
|
-
return request.referent.metadata['btitle'] unless request.referent.metadata['btitle'].nil? or request.referent.metadata['btitle'].empty?
|
438
|
-
return request.referent.metadata['title'] unless request.referent.metadata['title'].nil? or request.referent.metadata['title'].empty?
|
439
|
-
return request.referent.metadata['atitle'] unless request.referent.metadata['atitle'].nil? or request.referent.metadata['atitle'].empty?
|
440
|
-
end
|
441
|
-
|
442
|
-
def author(request)
|
443
|
-
return request.referent.metadata['au'] unless request.referent.metadata['au'].nil? or request.referent.metadata['au'].empty?
|
444
|
-
return request.referent.metadata['aulast'] unless request.referent.metadata['aulast'].nil? or request.referent.metadata['aulast'].empty?
|
445
|
-
return request.referent.metadata['aucorp'] unless request.referent.metadata['aucorp'].nil? or request.referent.metadata['aucorp'].empty?
|
446
|
-
end
|
447
|
-
|
448
|
-
def primo_identifier?
|
449
|
-
return false if @identifier.nil?
|
450
|
-
return @identifier.start_with?('info:sid/primo.exlibrisgroup.com')
|
451
|
-
end
|
452
|
-
end
|