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
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/app/models/permalink.rb
CHANGED
@@ -1,29 +1,24 @@
|
|
1
1
|
# attribute context_obj_serialized has an XML OpenURL ContextObject sufficient to restore
|
2
2
|
# the original request and resolve the permalink. A link to a referent is
|
3
3
|
# also stored. But the referent may be purged, so self.referent may be null.
|
4
|
-
# The serialized contextobject will still be there.
|
4
|
+
# The serialized contextobject will still be there.
|
5
5
|
class Permalink < ActiveRecord::Base
|
6
6
|
belongs_to :referent
|
7
7
|
|
8
8
|
# You should create Permalinks with this. Pass in a referent and referrer
|
9
9
|
#. Will save permalink to db
|
10
10
|
def self.new_with_values!(rft, rfr_id)
|
11
|
-
permalink = Permalink.new
|
12
|
-
|
11
|
+
permalink = Permalink.new
|
13
12
|
permalink.referent = rft
|
14
13
|
permalink.orig_rfr_id = rfr_id
|
15
|
-
|
16
14
|
permalink.context_obj_serialized = permalink.referent.to_context_object.xml
|
17
|
-
|
18
15
|
permalink.save!
|
19
|
-
|
20
16
|
return permalink
|
21
17
|
end
|
22
18
|
|
23
|
-
|
24
19
|
# Takes the XML stored in self.context_obj_serialized, and turns it back
|
25
20
|
# into an OpenURL ContextObject
|
26
21
|
def restore_context_object
|
27
22
|
return OpenURL::ContextObject.new_from_xml(self.context_obj_serialized)
|
28
23
|
end
|
29
|
-
end
|
24
|
+
end
|
data/app/models/referent.rb
CHANGED
@@ -19,9 +19,6 @@ class Referent < ActiveRecord::Base
|
|
19
19
|
# :permalink => false if you already have a permalink and don't
|
20
20
|
# need to create one. Caller should attach that permalink to this referent!
|
21
21
|
def self.create_by_context_object(co, options = {})
|
22
|
-
options = { :permalink => UmlautController.umlaut_config.create_permalinks
|
23
|
-
}.merge(options)
|
24
|
-
|
25
22
|
self.clean_up_context_object(co)
|
26
23
|
|
27
24
|
rft = Referent.new
|
@@ -33,10 +30,12 @@ class Referent < ActiveRecord::Base
|
|
33
30
|
|
34
31
|
rft.set_values_from_context_object(co)
|
35
32
|
|
36
|
-
|
37
|
-
|
33
|
+
# Permalinks created on-demand later. But if set config to :force, can
|
34
|
+
# force old behavior.
|
35
|
+
if options[:permalink] == :force
|
36
|
+
permalink = Permalink.new_with_values!(rft, co.referrer.identifier)
|
38
37
|
end
|
39
|
-
|
38
|
+
|
40
39
|
# Add shortcuts.
|
41
40
|
rft.referent_values.each do | val |
|
42
41
|
rft.atitle = val.normalized_value if val.key_name == 'atitle' and val.metadata?
|
@@ -289,19 +288,19 @@ class Referent < ActiveRecord::Base
|
|
289
288
|
|
290
289
|
if my_metadata['atitle'] && ! my_metadata['atitle'].blank?
|
291
290
|
citation[:title] = my_metadata['atitle']
|
292
|
-
citation[:title_label], citation[:
|
291
|
+
citation[:title_label], citation[:container_label] =
|
293
292
|
case my_metadata['genre']
|
294
|
-
when /article|journal|issue/ then ['Article Title', '
|
295
|
-
when /bookitem|book/ then ['Chapter/Part Title', '
|
296
|
-
when /proceeding|conference/ then ['Proceeding Title', '
|
297
|
-
when 'report' then ['Report Title','
|
293
|
+
when /article|journal|issue/ then ['Article Title', 'journal']
|
294
|
+
when /bookitem|book/ then ['Chapter/Part Title', 'book']
|
295
|
+
when /proceeding|conference/ then ['Proceeding Title', 'conference']
|
296
|
+
when 'report' then ['Report Title','report']
|
298
297
|
else
|
299
298
|
if self.format == 'book'
|
300
|
-
['Chapter/Part Title', '
|
299
|
+
['Chapter/Part Title', 'book']
|
301
300
|
elsif self.format == 'journal'
|
302
|
-
['Article Title', '
|
301
|
+
['Article Title', 'journal']
|
303
302
|
else # default fall through, use much what SFX uses.
|
304
|
-
['Title', '
|
303
|
+
['Title', '']
|
305
304
|
end
|
306
305
|
end
|
307
306
|
['title','btitle','jtitle'].each do | t_type |
|
@@ -313,11 +312,11 @@ class Referent < ActiveRecord::Base
|
|
313
312
|
end
|
314
313
|
else
|
315
314
|
citation[:title_label] = case my_metadata["genre"]
|
316
|
-
when /article|journal|issue/ then '
|
317
|
-
when /bookitem|book/ then '
|
318
|
-
when /proceeding|conference/ then '
|
319
|
-
when 'report' then '
|
320
|
-
else'
|
315
|
+
when /article|journal|issue/ then 'journal'
|
316
|
+
when /bookitem|book/ then 'book'
|
317
|
+
when /proceeding|conference/ then 'conference'
|
318
|
+
when 'report' then 'report'
|
319
|
+
else ''
|
321
320
|
end
|
322
321
|
['title','btitle','jtitle'].each do | t_type |
|
323
322
|
if ! my_metadata[t_type].blank?
|
@@ -372,13 +371,22 @@ class Referent < ActiveRecord::Base
|
|
372
371
|
def type_of_thing
|
373
372
|
genre = self.metadata["genre"]
|
374
373
|
genre = nil if genre =~ /^unknown$/i
|
375
|
-
genre ||= "resource"
|
376
|
-
|
377
374
|
genre = "book section" if genre =~ /^bookitem$/i
|
378
375
|
|
379
376
|
return genre
|
380
377
|
end
|
381
378
|
|
379
|
+
# Like type_of_thing, but if it's a contained item, give container name instead.
|
380
|
+
# TODO: All of this should be I18n'd.
|
381
|
+
def container_type_of_thing
|
382
|
+
case self.metadata["genre"]
|
383
|
+
when 'article' then 'journal'
|
384
|
+
when 'bookitem' then 'book'
|
385
|
+
else self.metadata['genre']
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
|
382
390
|
def remove_value(key)
|
383
391
|
referent_values.find(:all, :conditions=> ['key_name =?', key]).each do |rv|
|
384
392
|
referent_values.delete(rv)
|
data/app/models/request.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'digest/md5'
|
2
|
+
require 'cgi'
|
2
3
|
|
3
4
|
# An ActiveRecord which represents a parsed OpenURL resolve service request,
|
4
5
|
# and other persistent state related to Umlaut's handling of that OpenURL
|
@@ -24,6 +25,9 @@ class Request < ActiveRecord::Base
|
|
24
25
|
# options[:allow_create] => false, will not create a new request, return
|
25
26
|
# nil if no existing request can be found.
|
26
27
|
def self.find_or_create(params, session, a_rails_request, options = {} )
|
28
|
+
|
29
|
+
|
30
|
+
|
27
31
|
# Pull out the http params that are for the context object,
|
28
32
|
# returning a CGI::parse style hash, customized for what
|
29
33
|
# ContextObject.new_from_form_vars wants.
|
@@ -47,8 +51,15 @@ class Request < ActiveRecord::Base
|
|
47
51
|
request_id = nil if req == nil
|
48
52
|
|
49
53
|
# Serialized fingerprint of openurl http params, suitable for looking
|
50
|
-
# up in the db to see if we've seen it before.
|
51
|
-
|
54
|
+
# up in the db to see if we've seen it before. We got our co_params
|
55
|
+
# direct from parsing path ourselves, but in case a before_filter
|
56
|
+
# added in certain other params after that, we want to merge them in
|
57
|
+
# too.
|
58
|
+
fingerprintable_params = co_params.merge(
|
59
|
+
{"umlaut.service_group" => params["umlaut.service_group"]}.delete_if {|k, v| v.blank?}
|
60
|
+
)
|
61
|
+
param_fingerprint = self.co_params_fingerprint( fingerprintable_params )
|
62
|
+
|
52
63
|
client_ip = params['req.ip'] || a_rails_request.remote_ip()
|
53
64
|
|
54
65
|
unless (req || params["umlaut.force_new_request"] == "true" || param_fingerprint.blank? )
|
@@ -80,14 +91,13 @@ class Request < ActiveRecord::Base
|
|
80
91
|
# We pull out a hash of request params (get and post) that
|
81
92
|
# define a context object. We use CGI::parse instead of relying
|
82
93
|
# on Rails parsing because rails parsing ignores multiple params
|
83
|
-
# with same key value, which is legal in CGI.
|
94
|
+
# with same key value, which is legal in CGI and is sometimes used in OpenURLs.
|
84
95
|
#
|
85
96
|
# So in general values of this hash will be an array.
|
86
97
|
# ContextObject.new_from_form_vars is good with that.
|
87
98
|
# Exception is url_ctx_fmt and url_ctx_val, which we'll
|
88
99
|
# convert to single values, because ContextObject wants it so.
|
89
|
-
def self.context_object_params(a_rails_request)
|
90
|
-
require 'cgi'
|
100
|
+
def self.context_object_params(a_rails_request)
|
91
101
|
|
92
102
|
# GET params
|
93
103
|
co_params = CGI::parse( a_rails_request.query_string )
|
@@ -102,9 +112,9 @@ class Request < ActiveRecord::Base
|
|
102
112
|
co_params.delete(nil)
|
103
113
|
|
104
114
|
# Exclude params that are for Rails or Umlaut, and don't belong to the
|
105
|
-
# context object. Except leave in umlaut
|
106
|
-
#
|
107
|
-
excluded_keys = ["action", "controller", "page",
|
115
|
+
# context object. Except leave in umlaut.* keys that DO matter for
|
116
|
+
# cacheability, like umlaut.institution (legacy) and umlaut.service_group
|
117
|
+
excluded_keys = ["action", "controller", "page", /\Aumlaut\.(?!(institution|service_group\[\])\Z)/, 'rft.action', 'rft.controller']
|
108
118
|
co_params.keys.each do |key|
|
109
119
|
excluded_keys.each do |exclude|
|
110
120
|
co_params.delete(key) if exclude === key;
|
@@ -409,6 +419,7 @@ class Request < ActiveRecord::Base
|
|
409
419
|
#
|
410
420
|
# Returns nil if there aren't any params to include in the fingerprint.
|
411
421
|
def self.co_params_fingerprint(params)
|
422
|
+
|
412
423
|
# Don't use ctx_time, consider two co's equal if they are equal but for ctx_tim.
|
413
424
|
# exclude cache-busting "_" key that JQuery adds. Fine to bust HTTP cache, but
|
414
425
|
# don't want to it to force new Umlaut processing.
|
@@ -11,6 +11,10 @@ ServiceResponses have a few basic attributes stored in columns in the db: 'displ
|
|
11
11
|
|
12
12
|
In addition, there's a Hash (automatically serialized by ActiveRecord) that's stored in service_data, for arbitrary additional data that a Service can store--whatever you want, just put it in. However, there are conventions that Views expect, see below. You can access ALL the arbitrary key/values in a ServiceResponse, built-in in attributes or from the serialized Hash, by the proxy object returned from #data_values.
|
13
13
|
|
14
|
+
You can create a ServiceResponse object with ServiceResponse.create_from_hash,
|
15
|
+
where the hash keys may be direct iVar columns, or serialized in the
|
16
|
+
service_data hash, you don't have to care.
|
17
|
+
|
14
18
|
ServiceResponse is connected to a Request via the ServiceType join table. The data architecture allows a ServiceResponse to be tied to multiple requests, perhaps to support some kind of cacheing re-use in the future. But at present, the code doesn't do this, a ServiceResponse will really only be related to one request. However, a ServiceResponse can be related to a single Request more than once--once per each type of service response. ServiceType is really a three way join, representing a ServiceResponse, attached to a particular Request, with a particular ServiceTypeValue.
|
15
19
|
|
16
20
|
|
@@ -42,6 +46,12 @@ These are applicable only when the incoming OpenURL is an article-level citation
|
|
42
46
|
|
43
47
|
[:coverage_checked] boolean, default true. False for links from, eg, the catalog, where we weren't able to pre-check if the particular citation is included at this link.
|
44
48
|
[:can_link_to_article] boolean, default true. False if the links is _known_ not to deliver user to actual article requested, but just to a title-level page. Even though SFX links sometimes incorrectly do this, they are still not set to false here.
|
49
|
+
|
50
|
+
== Coverage dates
|
51
|
+
Generally only for fulltext. Right now only supplied by SFX.
|
52
|
+
|
53
|
+
[:coverage_begin_date] Ruby Date object representing start of coverage
|
54
|
+
[:coverage_end_date] Ruby Date object representing end of coverage
|
45
55
|
|
46
56
|
== highlighted_link (see also)
|
47
57
|
[:source] (optional, otherwise service's display_name is used)
|
@@ -80,7 +90,7 @@ These are applicable only when the incoming OpenURL is an article-level citation
|
|
80
90
|
|
81
91
|
=end
|
82
92
|
class ServiceResponse < ActiveRecord::Base
|
83
|
-
@@built_in_fields = [:display_text, :url, :notes, :response_key, :value_string, :value_alt_string, :value_text]
|
93
|
+
@@built_in_fields = [:display_text, :url, :notes, :response_key, :value_string, :value_alt_string, :value_text, :id]
|
84
94
|
belongs_to :request
|
85
95
|
serialize :service_data
|
86
96
|
# This value is not stored in db, but is set temporarily so
|
@@ -98,6 +108,15 @@ class ServiceResponse < ActiveRecord::Base
|
|
98
108
|
super(params)
|
99
109
|
self.service_data = {} unless self.service_data
|
100
110
|
end
|
111
|
+
|
112
|
+
# Create from a hash of key/values, where some keys
|
113
|
+
# may be direct iVars, some may end up serialized in service_data,
|
114
|
+
# you don't have to care, it will do the right thing.
|
115
|
+
def self.create_from_hash(hash)
|
116
|
+
r = ServiceResponse.new
|
117
|
+
r.take_key_values(hash)
|
118
|
+
return r
|
119
|
+
end
|
101
120
|
|
102
121
|
# Instantiates and returns a new Service associated with this response.
|
103
122
|
def service
|
@@ -135,9 +154,11 @@ class ServiceResponse < ActiveRecord::Base
|
|
135
154
|
def take_key_values(hash)
|
136
155
|
# copy it, cause we're gonna modify it
|
137
156
|
hash = hash.clone
|
157
|
+
|
138
158
|
hash.each_pair do |key, value|
|
139
|
-
|
140
|
-
|
159
|
+
setter = "#{key.to_s}="
|
160
|
+
if ( self.respond_to?(setter))
|
161
|
+
self.send(setter, value)
|
141
162
|
hash.delete(key)
|
142
163
|
end
|
143
164
|
end
|
data/app/models/service_store.rb
CHANGED
@@ -1,63 +1,132 @@
|
|
1
|
-
#
|
2
|
-
# instantiates services from definitions, by id.
|
1
|
+
# A ServiceStore is a collection of umlaut service definitions, with identifiers.
|
3
2
|
#
|
4
|
-
#
|
5
|
-
#
|
3
|
+
# There is one default global one that is typically used; originally this
|
4
|
+
# was all neccesarily global state, but we refactored to be an actual object,
|
5
|
+
# although there's still a default global one used, with class methods
|
6
|
+
# that delegate to it, for backwards compat and convenience.
|
7
|
+
#
|
8
|
+
# By default, a ServiceStore loads service definitions from
|
9
|
+
# Rails.root/config/umlaut_services.yml . Although in testing,
|
10
|
+
# or for future architectural expansion, services can be manually supplied
|
11
|
+
# instead.
|
12
|
+
#
|
13
|
+
# A ServiceStore instantiates services from definitions, by id,
|
14
|
+
# ServiceStore.instantiate_service!("our_sfx")
|
15
|
+
#
|
16
|
+
# A ServiceStore's cached service definitions can be reset, useful in
|
17
|
+
# testing: ServiceStore.reset!
|
18
|
+
#
|
19
|
+
# They'll then be lazily reloaded on next access, unless manually set.
|
6
20
|
class ServiceStore
|
7
|
-
|
21
|
+
@@global_service_store = ServiceStore.new
|
22
|
+
def self.global_service_store
|
23
|
+
@@global_service_store
|
24
|
+
end
|
25
|
+
|
26
|
+
# certain class methods all default to global default ServiceStore,
|
27
|
+
# for global ServiceStore. For convenience, and backwards-compat.
|
28
|
+
[ :config, :"config=", :service_definitions, :service_definition_for,
|
29
|
+
:'instantiate_service!', :'reset!' ].each do |method|
|
30
|
+
self.define_singleton_method(method) do |*args|
|
31
|
+
global_service_store.send(method, *args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
8
36
|
# Returns complete hash loaded from services.yml
|
9
|
-
def
|
10
|
-
# cache hash loaded from YAML, ensure it has the keys we expect.
|
11
|
-
unless defined?
|
37
|
+
def config
|
38
|
+
# cache hash loaded from YAML, ensure it has the keys we expect.
|
39
|
+
unless defined? @services_config_list
|
12
40
|
yaml_path = File.expand_path("config/umlaut_services.yml", Rails.root)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@@services_config_list = {}
|
17
|
-
end
|
18
|
-
@@services_config_list["default"] ||= {}
|
19
|
-
@@services_config_list["default"]["services"] ||= {}
|
41
|
+
@services_config_list = (File.exists? yaml_path) ? YAML::load(File.open(yaml_path)) : {}
|
42
|
+
@services_config_list["default"] ||= {}
|
43
|
+
@services_config_list["default"]["services"] ||= {}
|
20
44
|
end
|
21
|
-
return
|
45
|
+
return @services_config_list
|
22
46
|
end
|
23
|
-
|
47
|
+
|
48
|
+
# Manually set a config hash, as would normally be found serialized
|
49
|
+
# in config/umlaut_services.yml. Useful in testing. All keys
|
50
|
+
# should be strings!!
|
51
|
+
#
|
52
|
+
# Needs to have the somewhat cumbersome expected structure:
|
53
|
+
# ["default"]["services"] => { "service_id" => definition_hash }
|
54
|
+
def config=(hash)
|
55
|
+
reset!
|
56
|
+
@services_config_list = hash
|
57
|
+
end
|
58
|
+
|
24
59
|
# Returns hash keyed by unique service name, value service definition
|
25
|
-
# hash.
|
26
|
-
def
|
27
|
-
unless defined?
|
28
|
-
|
60
|
+
# hash.
|
61
|
+
def service_definitions
|
62
|
+
unless defined? @service_definitions
|
63
|
+
@service_definitions = {}
|
29
64
|
config.each_pair do |group_name, group|
|
30
|
-
|
65
|
+
if group["services"]
|
66
|
+
# Add the group name to each service
|
67
|
+
# in the group
|
68
|
+
group["services"].each_pair do |service_id, service|
|
69
|
+
service["group"] = group_name
|
70
|
+
end
|
71
|
+
# Merge the group's services into the service definitions.
|
72
|
+
@service_definitions.merge!( group["services"] )
|
73
|
+
end
|
31
74
|
end
|
32
75
|
# set service_id key in each based on hash key
|
33
|
-
|
76
|
+
@service_definitions.each_pair do |key, hash|
|
34
77
|
hash["service_id"] = key
|
35
78
|
end
|
36
79
|
end
|
37
|
-
return
|
80
|
+
return @service_definitions
|
38
81
|
end
|
39
|
-
|
40
|
-
|
82
|
+
|
83
|
+
# Reset cached service definitions. They'll be lazily loaded when asked for,
|
84
|
+
# typically by being looked up from disk again. Typically used for testing.
|
85
|
+
def reset!
|
86
|
+
remove_instance_variable "@service_definitions" if defined? @service_definitions
|
87
|
+
remove_instance_variable "@services_config_list" if defined? @services_config_list
|
88
|
+
end
|
89
|
+
|
90
|
+
def service_definition_for(service_id)
|
41
91
|
return service_definitions[service_id]
|
42
92
|
end
|
43
|
-
|
44
|
-
# pass in
|
93
|
+
|
94
|
+
# pass in array of service group ids. eg. ["group1", "-group2"]
|
95
|
+
#
|
96
|
+
# Returns a list of service definition hashes.
|
97
|
+
#
|
98
|
+
# Start with default group(s). Remove any that are mentioned with "-group_id" in
|
99
|
+
# the group list, add in any that are mentioned with "group_id"
|
100
|
+
def determine_services(specified_groups = [])
|
101
|
+
services = {}
|
102
|
+
|
103
|
+
activated_service_groups = self.config.select do |group_id, group_definition|
|
104
|
+
((group_id == "default" || group_definition["default"] == true) ||
|
105
|
+
specified_groups.include?(group_id)) &&
|
106
|
+
! specified_groups.include?("-#{group_id}")
|
107
|
+
end
|
108
|
+
|
109
|
+
activated_service_groups.each_pair do |group_id, group_definition|
|
110
|
+
services.merge! (group_definition["services"] || {})
|
111
|
+
end
|
112
|
+
|
113
|
+
# Remove any disabled services
|
114
|
+
services.reject! {|service_id, hash| hash && hash["disabled"] == true}
|
115
|
+
|
116
|
+
return services
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# pass in string unique key OR a service definition hash,
|
45
121
|
# and a current UmlautRequest.
|
46
|
-
# get back instantiated Service object.
|
47
|
-
def
|
122
|
+
# get back instantiated Service object.
|
123
|
+
def instantiate_service!(service, request)
|
48
124
|
definition = service.kind_of?(Hash) ? service : service_definition_for(service.to_s)
|
49
|
-
|
50
|
-
if definition.nil?
|
51
|
-
raise "Service '#{service}'' does not exist in umlaut-services.yml"
|
52
|
-
end
|
53
|
-
|
125
|
+
raise "Service '#{service}'' does not exist in umlaut-services.yml" if definition.nil?
|
54
126
|
className = definition["type"] || definition["service_id"]
|
55
127
|
classConst = Kernel.const_get(className)
|
56
128
|
service = classConst.new(definition)
|
57
129
|
service.request = request
|
58
|
-
|
59
|
-
return service
|
130
|
+
return service
|
60
131
|
end
|
61
|
-
|
62
|
-
|
63
132
|
end
|