exlibris-primo 0.1.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +1 -1
- data/README.md +111 -0
- data/Rakefile +2 -1
- data/lib/exlibris-primo.rb +4 -14
- data/lib/exlibris/primo.rb +13 -0
- data/lib/exlibris/primo/abstract.rb +28 -0
- data/lib/exlibris/primo/chain_gang/README.md +9 -0
- data/lib/exlibris/primo/chain_gang/base.rb +121 -0
- data/lib/exlibris/primo/chain_gang/record.rb +18 -0
- data/lib/exlibris/primo/chain_gang/search.rb +319 -0
- data/lib/exlibris/primo/chain_gang/user.rb +18 -0
- data/lib/exlibris/primo/config.rb +69 -0
- data/lib/exlibris/primo/eshelf.rb +115 -62
- data/lib/exlibris/primo/facet.rb +40 -0
- data/lib/exlibris/primo/facet_value.rb +40 -0
- data/lib/exlibris/primo/holding.rb +81 -152
- data/lib/exlibris/primo/link.rb +32 -0
- data/lib/exlibris/primo/namespaces.rb +44 -0
- data/lib/exlibris/primo/pnx/dedup_mgr.rb +91 -0
- data/lib/exlibris/primo/pnx/elements.rb +79 -0
- data/lib/exlibris/primo/pnx/frbr.rb +24 -0
- data/lib/exlibris/primo/pnx/holdings.rb +36 -0
- data/lib/exlibris/primo/pnx/links.rb +54 -0
- data/lib/exlibris/primo/pnx/openurl.rb +24 -0
- data/lib/exlibris/primo/pnx/subfields.rb +18 -0
- data/lib/exlibris/primo/record.rb +20 -106
- data/lib/exlibris/primo/request_attributes.rb +28 -0
- data/lib/exlibris/primo/review.rb +46 -0
- data/lib/exlibris/primo/reviews.rb +81 -0
- data/lib/exlibris/primo/search.rb +82 -0
- data/lib/exlibris/primo/source/aleph.rb +77 -31
- data/lib/exlibris/primo/tag.rb +34 -0
- data/lib/exlibris/primo/tags.rb +103 -0
- data/lib/exlibris/primo/version.rb +1 -1
- data/lib/exlibris/primo/web_service/client/base.rb +30 -0
- data/lib/exlibris/primo/web_service/client/base/endpoint.rb +29 -0
- data/lib/exlibris/primo/web_service/client/base/savon_client.rb +24 -0
- data/lib/exlibris/primo/web_service/client/base/savon_config.rb +19 -0
- data/lib/exlibris/primo/web_service/client/base/soap_actions.rb +55 -0
- data/lib/exlibris/primo/web_service/client/base/wsdl.rb +14 -0
- data/lib/exlibris/primo/web_service/client/eshelf.rb +22 -0
- data/lib/exlibris/primo/web_service/client/reviews.rb +15 -0
- data/lib/exlibris/primo/web_service/client/search.rb +15 -0
- data/lib/exlibris/primo/web_service/client/tags.rb +14 -0
- data/lib/exlibris/primo/web_service/request/base.rb +77 -0
- data/lib/exlibris/primo/web_service/request/base/base_elements.rb +71 -0
- data/lib/exlibris/primo/web_service/request/base/call.rb +19 -0
- data/lib/exlibris/primo/web_service/request/base/client.rb +45 -0
- data/lib/exlibris/primo/web_service/request/base/soap_action.rb +29 -0
- data/lib/exlibris/primo/web_service/request/eshelf.rb +71 -0
- data/lib/exlibris/primo/web_service/request/reviews.rb +57 -0
- data/lib/exlibris/primo/web_service/request/search.rb +49 -0
- data/lib/exlibris/primo/web_service/request/search/display_fields.rb +30 -0
- data/lib/exlibris/primo/web_service/request/search/languages.rb +32 -0
- data/lib/exlibris/primo/web_service/request/search/location.rb +15 -0
- data/lib/exlibris/primo/web_service/request/search/locations.rb +33 -0
- data/lib/exlibris/primo/web_service/request/search/query_term.rb +43 -0
- data/lib/exlibris/primo/web_service/request/search/query_terms.rb +40 -0
- data/lib/exlibris/primo/web_service/request/search/search_elements.rb +97 -0
- data/lib/exlibris/primo/web_service/request/search/sort_bys.rb +32 -0
- data/lib/exlibris/primo/web_service/request/tags.rb +56 -0
- data/lib/exlibris/primo/web_service/response/base.rb +28 -0
- data/lib/exlibris/primo/web_service/response/base/error.rb +25 -0
- data/lib/exlibris/primo/web_service/response/base/util.rb +19 -0
- data/lib/exlibris/primo/web_service/response/did_u_mean.rb +17 -0
- data/lib/exlibris/primo/web_service/response/eshelf.rb +68 -0
- data/lib/exlibris/primo/web_service/response/facets.rb +21 -0
- data/lib/exlibris/primo/web_service/response/records.rb +17 -0
- data/lib/exlibris/primo/web_service/response/reviews.rb +49 -0
- data/lib/exlibris/primo/web_service/response/search.rb +36 -0
- data/lib/exlibris/primo/web_service/response/search_stats.rb +48 -0
- data/lib/exlibris/primo/web_service/response/tags.rb +54 -0
- data/lib/exlibris/primo/write_attributes.rb +38 -0
- data/lib/exlibris/primo/xml_util.rb +63 -0
- data/test/{unit/eshelf_test.rb → bak/eshelf_test.rb.bak} +0 -0
- data/test/{unit/record_test.rb → bak/record_test.rb.bak} +0 -0
- data/test/{unit/searcher_test.rb → bak/searcher_test.rb.bak} +0 -0
- data/test/{unit/web_service_test.rb → bak/web_service_test.rb.bak} +0 -0
- data/test/config_test.rb +72 -0
- data/test/eshelf_test.rb +66 -0
- data/test/exlibris-primo_test.rb +0 -1
- data/test/facet_test.rb +27 -0
- data/test/facet_value_test.rb +62 -0
- data/test/holding_test.rb +26 -0
- data/test/link_test.rb +42 -0
- data/test/pnx/dedup_mgr_test.rb +16 -0
- data/test/pnx/elements_test.rb +16 -0
- data/test/pnx/frbr_test.rb +12 -0
- data/test/pnx/holdings_test.rb +53 -0
- data/test/pnx/links_test.rb +44 -0
- data/test/pnx/openurl_test.rb +10 -0
- data/test/record_test.rb +11 -0
- data/test/review_test.rb +15 -0
- data/test/reviews_test.rb +50 -0
- data/test/search_test.rb +328 -0
- data/test/source/aleph_test.rb +52 -0
- data/test/support/config.yml +35 -0
- data/test/tag_test.rb +12 -0
- data/test/tags_test.rb +65 -0
- data/test/test_helper.rb +536 -4
- data/test/vcr_cassettes/client_action_no_arguments.yml +38 -0
- data/test/vcr_cassettes/client_get_all_my_reviews.yml +49 -0
- data/test/vcr_cassettes/client_get_all_my_tags.yml +49 -0
- data/test/vcr_cassettes/client_get_eshelf.yml +13812 -0
- data/test/vcr_cassettes/client_get_record.yml +222 -0
- data/test/vcr_cassettes/client_get_reviews.yml +39 -0
- data/test/vcr_cassettes/client_get_tags.yml +42 -0
- data/test/vcr_cassettes/client_search_brief_isbn.yml +288 -0
- data/test/vcr_cassettes/client_search_brief_issn.yml +282 -0
- data/test/vcr_cassettes/client_too_many_arguments.yml +38 -0
- data/test/vcr_cassettes/eshelf.yml +13845 -0
- data/test/vcr_cassettes/eshelf_add_folder.yml +109 -0
- data/test/vcr_cassettes/eshelf_add_record.yml +14237 -0
- data/test/vcr_cassettes/eshelf_add_records.yml +14156 -0
- data/test/vcr_cassettes/eshelf_basket_id.yml +36 -0
- data/test/vcr_cassettes/eshelf_records.yml +13460 -0
- data/test/vcr_cassettes/eshelf_remove_folder.yml +76 -0
- data/test/vcr_cassettes/eshelf_remove_record.yml +13500 -0
- data/test/vcr_cassettes/eshelf_remove_records.yml +13741 -0
- data/test/vcr_cassettes/{web_service_single_document.yml → remote_record_call.yml} +12 -23
- data/test/vcr_cassettes/{searcher_dedupmrg_by_id.yml → remote_record_dedupmgr.yml} +19 -31
- data/test/vcr_cassettes/request_add_folder_to_eshelf.yml +43 -0
- data/test/vcr_cassettes/request_add_to_eshelf.yml +43 -0
- data/test/vcr_cassettes/request_did_u_mean_enabled.yml +48 -0
- data/test/vcr_cassettes/request_full_view.yml +222 -0
- data/test/vcr_cassettes/request_get_eshelf.yml +13812 -0
- data/test/vcr_cassettes/request_get_eshelf_structure.yml +36 -0
- data/test/vcr_cassettes/request_get_reviews.yml +39 -0
- data/test/vcr_cassettes/request_get_tags.yml +42 -0
- data/test/vcr_cassettes/request_remove_folder_from_eshelf.yml +43 -0
- data/test/vcr_cassettes/request_remove_from_eshelf.yml +43 -0
- data/test/vcr_cassettes/request_search_author.yml +1258 -0
- data/test/vcr_cassettes/request_search_did_u_mean.yml +48 -0
- data/test/vcr_cassettes/request_search_genre.yml +1321 -0
- data/test/vcr_cassettes/request_search_isbn.yml +288 -0
- data/test/vcr_cassettes/request_search_issn.yml +282 -0
- data/test/vcr_cassettes/request_search_locations.yml +288 -0
- data/test/vcr_cassettes/request_search_title.yml +1024 -0
- data/test/vcr_cassettes/request_search_title_author_genre.yml +708 -0
- data/test/vcr_cassettes/response_add_folder_to_eshelf.yml +43 -0
- data/test/vcr_cassettes/response_add_review.yml +39 -0
- data/test/vcr_cassettes/response_add_tag.yml +39 -0
- data/test/vcr_cassettes/response_add_to_eshelf.yml +43 -0
- data/test/vcr_cassettes/response_did_u_mean_disabled.yml +46 -0
- data/test/vcr_cassettes/response_did_u_mean_enabled.yml +48 -0
- data/test/vcr_cassettes/response_full_view.yml +222 -0
- data/test/vcr_cassettes/response_get_all_my_reviews.yml +49 -0
- data/test/vcr_cassettes/response_get_all_my_tags.yml +49 -0
- data/test/vcr_cassettes/response_get_eshelf.yml +13633 -0
- data/test/vcr_cassettes/response_get_eshelf_structure.yml +36 -0
- data/test/vcr_cassettes/response_get_reviews.yml +39 -0
- data/test/vcr_cassettes/response_get_reviews_by_rating.yml +49 -0
- data/test/vcr_cassettes/response_get_reviews_for_record.yml +39 -0
- data/test/vcr_cassettes/response_get_tags.yml +42 -0
- data/test/vcr_cassettes/response_get_tags_for_record.yml +42 -0
- data/test/vcr_cassettes/response_remove_folder_from_eshelf.yml +43 -0
- data/test/vcr_cassettes/response_remove_from_eshelf.yml +43 -0
- data/test/vcr_cassettes/response_remove_review.yml +39 -0
- data/test/vcr_cassettes/response_remove_tag.yml +39 -0
- data/test/vcr_cassettes/response_remove_user_tags.yml +39 -0
- data/test/vcr_cassettes/response_search.yml +288 -0
- data/test/vcr_cassettes/response_search_did_u_mean.yml +48 -0
- data/test/vcr_cassettes/reviews.yml +49 -0
- data/test/vcr_cassettes/reviews_add_review.yml +39 -0
- data/test/vcr_cassettes/reviews_check_empty_reviews_first.yml +39 -0
- data/test/vcr_cassettes/reviews_check_empty_reviews_last.yml +39 -0
- data/test/vcr_cassettes/reviews_rating.yml +168 -0
- data/test/vcr_cassettes/reviews_record.yml +49 -0
- data/test/vcr_cassettes/reviews_remove_review.yml +39 -0
- data/test/vcr_cassettes/reviews_reviews.yml +49 -0
- data/test/vcr_cassettes/reviews_user.yml +58 -0
- data/test/vcr_cassettes/search_chaining_author_title.yml +938 -0
- data/test/vcr_cassettes/search_chaining_contains_any.yml +1453 -0
- data/test/vcr_cassettes/search_chaining_contains_author_starts_with_title.yml +1055 -0
- data/test/vcr_cassettes/search_chaining_isbn.yml +288 -0
- data/test/vcr_cassettes/search_chaining_page_size_author.yml +5933 -0
- data/test/vcr_cassettes/search_did_u_mean.yml +48 -0
- data/test/vcr_cassettes/search_enable_highlighting.yml +1337 -0
- data/test/vcr_cassettes/search_isbn.yml +288 -0
- data/test/vcr_cassettes/search_languages.yml +1332 -0
- data/test/vcr_cassettes/search_locations.yml +1440 -0
- data/test/vcr_cassettes/search_record_id.yml +222 -0
- data/test/vcr_cassettes/search_record_id_chaining.yml +222 -0
- data/test/vcr_cassettes/search_sort_by.yml +1289 -0
- data/test/vcr_cassettes/search_sort_by_locations.yml +1387 -0
- data/test/vcr_cassettes/tags.yml +56 -0
- data/test/vcr_cassettes/tags_add_extra_tag.yml +39 -0
- data/test/vcr_cassettes/tags_add_tag.yml +39 -0
- data/test/vcr_cassettes/tags_add_tags.yml +111 -0
- data/test/vcr_cassettes/tags_check_1_tags.yml +56 -0
- data/test/vcr_cassettes/tags_check_2_tags.yml +68 -0
- data/test/vcr_cassettes/tags_check_empty_tags_first.yml +42 -0
- data/test/vcr_cassettes/tags_check_empty_tags_last.yml +42 -0
- data/test/vcr_cassettes/tags_remove_tag.yml +39 -0
- data/test/vcr_cassettes/tags_remove_tags.yml +111 -0
- data/test/vcr_cassettes/tags_remove_user_tags.yml +39 -0
- data/test/vcr_cassettes/tags_tags.yml +104 -0
- data/test/vcr_cassettes/tags_user.yml +73 -0
- data/test/web_service/client/abstract_test.rb +29 -0
- data/test/web_service/client/eshelf_test.rb +22 -0
- data/test/web_service/client/reviews_test.rb +31 -0
- data/test/web_service/client/savon_client_test.rb +17 -0
- data/test/web_service/client/search_benchmarks.rb +29 -0
- data/test/web_service/client/search_test.rb +44 -0
- data/test/web_service/client/soap_actions_test.rb +45 -0
- data/test/web_service/client/tags_test.rb +31 -0
- data/test/web_service/request/abstract_test.rb +68 -0
- data/test/web_service/request/base_elements_test.rb +231 -0
- data/test/web_service/request/build_xml_test.rb +23 -0
- data/test/web_service/request/client_test.rb +53 -0
- data/test/web_service/request/eshelf_test.rb +26 -0
- data/test/web_service/request/location_test.rb +25 -0
- data/test/web_service/request/query_term_test.rb +29 -0
- data/test/web_service/request/reviews_test.rb +27 -0
- data/test/web_service/request/search_test.rb +234 -0
- data/test/web_service/request/soap_action_test.rb +120 -0
- data/test/web_service/request/tags_test.rb +27 -0
- data/test/web_service/response/abstract_test.rb +200 -0
- data/test/web_service/response/did_u_mean_test.rb +44 -0
- data/test/web_service/response/error_test.rb +31 -0
- data/test/web_service/response/eshelf_test.rb +28 -0
- data/test/web_service/response/facets_test.rb +42 -0
- data/test/web_service/response/records_test.rb +56 -0
- data/test/web_service/response/reviews_test.rb +28 -0
- data/test/web_service/response/search_stats_test.rb +75 -0
- data/test/web_service/response/search_test.rb +40 -0
- data/test/web_service/response/tags_test.rb +28 -0
- data/test/xml_util_test.rb +23 -0
- metadata +456 -114
- data/README.rdoc +0 -68
- data/lib/exlibris/primo/related_link.rb +0 -20
- data/lib/exlibris/primo/rsrc.rb +0 -20
- data/lib/exlibris/primo/searcher.rb +0 -277
- data/lib/exlibris/primo/toc.rb +0 -20
- data/lib/exlibris/primo/web_service.rb +0 -203
- data/test/unit/searcher_benchmarks.rb +0 -74
- data/test/unit/web_service_benchmarks.rb +0 -58
- data/test/vcr_cassettes/eshelf_add_invalid_records.yml +0 -107
- data/test/vcr_cassettes/eshelf_add_same_record_twice.yml +0 -159
- data/test/vcr_cassettes/eshelf_add_to_empty_basket.yml +0 -107
- data/test/vcr_cassettes/eshelf_add_to_invalid_basket.yml +0 -55
- data/test/vcr_cassettes/eshelf_invalid_eshelf.yml +0 -55
- data/test/vcr_cassettes/eshelf_invalid_institution.yml +0 -55
- data/test/vcr_cassettes/eshelf_valid_eshelf.yml +0 -2553
- data/test/vcr_cassettes/eshelf_valid_eshelf_structure.yml +0 -47
- data/test/vcr_cassettes/record.yml +0 -212
- data/test/vcr_cassettes/record_invalid_record.yml +0 -55
- data/test/vcr_cassettes/record_sub_record.yml +0 -212
- data/test/vcr_cassettes/record_valid_record.yml +0 -212
- data/test/vcr_cassettes/searcher_base_holdings_by_id.yml +0 -212
- data/test/vcr_cassettes/searcher_diacritics1_by_id.yml +0 -207
- data/test/vcr_cassettes/searcher_diacritics2_by_id.yml +0 -232
- data/test/vcr_cassettes/searcher_holdings_by_id.yml +0 -212
- data/test/vcr_cassettes/searcher_invalid_id.yml +0 -55
- data/test/vcr_cassettes/searcher_rsrcs_by_id.yml +0 -270
- data/test/vcr_cassettes/searcher_search_by_isbn.yml +0 -278
- data/test/vcr_cassettes/searcher_search_by_issn.yml +0 -297
- data/test/vcr_cassettes/searcher_search_by_title_author_genre.yml +0 -671
- data/test/vcr_cassettes/searcher_test_bug_1361.yml +0 -224
- data/test/vcr_cassettes/searcher_test_problem_by_id.yml +0 -194
- data/test/vcr_cassettes/searcher_tocs_by_id.yml +0 -217
- data/test/vcr_cassettes/web_service_author_search.yml +0 -1269
- data/test/vcr_cassettes/web_service_bogus_200.yml +0 -392
- data/test/vcr_cassettes/web_service_brief_search.yml +0 -299
- data/test/vcr_cassettes/web_service_get_eshelf.yml +0 -11823
- data/test/vcr_cassettes/web_service_get_eshelf_structure_search.yml +0 -47
- data/test/vcr_cassettes/web_service_invalid_document.yml +0 -54
- data/test/vcr_cassettes/web_service_isbn_search.yml +0 -299
- data/test/vcr_cassettes/web_service_issn_search.yml +0 -293
- data/test/vcr_cassettes/web_service_problem_document.yml +0 -193
- data/test/vcr_cassettes/web_service_title_author_genre_search.yml +0 -719
- data/test/vcr_cassettes/web_service_title_search.yml +0 -1035
@@ -0,0 +1,32 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
#
|
4
|
+
# Abstract class representing a link in Primo.
|
5
|
+
#
|
6
|
+
class Link
|
7
|
+
include Abstract
|
8
|
+
include Config::Attributes
|
9
|
+
include WriteAttributes
|
10
|
+
|
11
|
+
self.abstract = true
|
12
|
+
|
13
|
+
attr_accessor :record_id, :original_id,
|
14
|
+
:url, :display, :notes, :subfields
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Primo fulltext link.
|
19
|
+
#
|
20
|
+
class Fulltext < Link; end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Primo table of contents link.
|
24
|
+
#
|
25
|
+
class TableOfContents < Link; end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Primo related link.
|
29
|
+
#
|
30
|
+
class RelatedLink < Link; end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
#
|
4
|
+
# Primo namespaces used in Primo XML
|
5
|
+
#
|
6
|
+
module Namespaces
|
7
|
+
def self.included(klass)
|
8
|
+
klass.class_eval do
|
9
|
+
extend ClassAttributes
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassAttributes
|
14
|
+
def response_namespaces
|
15
|
+
@response_namespaces = {
|
16
|
+
"search" => "http://www.exlibrisgroup.com/xsd/jaguar/search",
|
17
|
+
"eshelf" => "http://www.exlibris.com/primo/xsd/primoeshelffolder",
|
18
|
+
"pnx" => "http://www.exlibrisgroup.com/xsd/primo/primo_nm_bib",
|
19
|
+
"tags_reviews" => "http://com/exlibris/primo/xsd/tagsAndReview/config"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def request_namespaces
|
24
|
+
@request_namespaces = {
|
25
|
+
"xmlns" => "http://www.exlibris.com/primo/xsd/wsRequest",
|
26
|
+
"xmlns:uic" => "http://www.exlibris.com/primo/xsd/primoview/uicomponents"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns response namespaces
|
32
|
+
def response_namespaces
|
33
|
+
@response_namespaces ||= self.class.response_namespaces
|
34
|
+
end
|
35
|
+
protected :response_namespaces
|
36
|
+
|
37
|
+
# Returns request namespaces
|
38
|
+
def request_namespaces
|
39
|
+
@request_namespaces ||= self.class.request_namespaces
|
40
|
+
end
|
41
|
+
protected :request_namespaces
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
module Pnx
|
4
|
+
#
|
5
|
+
# Handle PNX dedupmgr elements
|
6
|
+
#
|
7
|
+
module DedupMgr
|
8
|
+
|
9
|
+
def self.included(klass)
|
10
|
+
klass.class_eval do
|
11
|
+
extend ClassAttributes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassAttributes
|
16
|
+
def duplicated_control_attributes
|
17
|
+
@duplicated_control_attributes ||= self.superclass.respond_to?(:duplicated_control_attributes) ?
|
18
|
+
self.superclass.duplicated_control_attributes.dup : []
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_duplicated_control_attributes *elements
|
22
|
+
elements.each do |element|
|
23
|
+
duplicated_control_attributes << element unless duplicated_control_attributes.include? element
|
24
|
+
end
|
25
|
+
end
|
26
|
+
protected :add_duplicated_control_attributes
|
27
|
+
|
28
|
+
def remove_duplicated_control_attributes *elements
|
29
|
+
duplicated_control_attributes.delete_if do |element|
|
30
|
+
elements.include? element
|
31
|
+
end
|
32
|
+
end
|
33
|
+
protected :remove_duplicated_control_attributes
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Is the record a dedupmrg record?
|
38
|
+
#
|
39
|
+
def dedupmgr?
|
40
|
+
@dedupmgr ||= recordid.match /\Adedupmrg/
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Return the class level duplicated control attributes
|
45
|
+
#
|
46
|
+
def duplicated_control_attributes
|
47
|
+
@duplicated_control_attributes ||= self.class.duplicated_control_attributes
|
48
|
+
end
|
49
|
+
protected :duplicated_control_attributes
|
50
|
+
|
51
|
+
#
|
52
|
+
# Dynamically set the duplicated control attributes.
|
53
|
+
#
|
54
|
+
def method_missing(method, *args, &block)
|
55
|
+
if(duplicated_control_attributes.include? method)
|
56
|
+
control_attribute = method.id2name.singularize
|
57
|
+
self.class.send(:define_method, method) do
|
58
|
+
eval("@#{method} ||= (dedupmgr?) ?
|
59
|
+
map_values_to_origins(\"#{control_attribute}\") : {recordid => #{control_attribute}}")
|
60
|
+
end
|
61
|
+
send method, *args, &block
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Tell users we respond to pluralized PNX control elements
|
69
|
+
#
|
70
|
+
def respond_to?(method, include_private=false)
|
71
|
+
(duplicated_control_attributes.include? method) ? true : super
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Map values to origins for the given field
|
76
|
+
#
|
77
|
+
def map_values_to_origins(field)
|
78
|
+
values_to_origins_map = {}
|
79
|
+
xml.root.xpath("control/#{field}").each do |element|
|
80
|
+
# Parse subfields, O is origin, V is value
|
81
|
+
subfields = parse_subfields(element.inner_text)
|
82
|
+
# Map values to the origin
|
83
|
+
values_to_origins_map[subfields["O"]] = subfields["V"]
|
84
|
+
end
|
85
|
+
values_to_origins_map
|
86
|
+
end
|
87
|
+
private :map_values_to_origins
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
module Pnx
|
4
|
+
#
|
5
|
+
# Provides access to PNX elements
|
6
|
+
#
|
7
|
+
module Elements
|
8
|
+
#
|
9
|
+
# Parses elements from PNX base on the pattern
|
10
|
+
# parentname_childname e.g.
|
11
|
+
# record.display_title #=> "Travels with my aunt"
|
12
|
+
# based on the XML
|
13
|
+
# <record>
|
14
|
+
# ...
|
15
|
+
# <display>
|
16
|
+
# ...
|
17
|
+
# <title>Travels with my aunt</title>
|
18
|
+
# ...
|
19
|
+
# </display>
|
20
|
+
# ...
|
21
|
+
# </record>
|
22
|
+
#
|
23
|
+
def method_missing(method, *args, &block)
|
24
|
+
if(attr_read(method))
|
25
|
+
self.class.send(:define_method, method) {
|
26
|
+
if "#{method}".start_with? "all_"
|
27
|
+
eval("@#{method} ||= #{attr_read(method).inspect}")
|
28
|
+
else
|
29
|
+
eval("@#{method} ||= #{attr_read(method).inspect}")
|
30
|
+
end
|
31
|
+
}
|
32
|
+
send method, *args, &block
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Tell user we respond to PNX elements
|
40
|
+
#
|
41
|
+
def respond_to?(method, include_private=false)
|
42
|
+
(attr_read(method)) ? true : super
|
43
|
+
end
|
44
|
+
|
45
|
+
def attr_read method
|
46
|
+
if("#{method}".start_with? "all_")
|
47
|
+
(inner_text_all(xpathize(method)) || inner_text_all(controlize(method)))
|
48
|
+
else
|
49
|
+
(inner_text_at(xpathize(method)) || inner_text_at(controlize(method)))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
private :attr_read
|
53
|
+
|
54
|
+
def inner_text_all xpath
|
55
|
+
xml.root.xpath(xpath).collect do |element|
|
56
|
+
element.inner_text
|
57
|
+
end
|
58
|
+
end
|
59
|
+
private :inner_text_all
|
60
|
+
|
61
|
+
def inner_text_at xpath
|
62
|
+
xml_at = xml.root.at_xpath(xpath)
|
63
|
+
xml_at.inner_text if xml_at
|
64
|
+
end
|
65
|
+
private :inner_text_at
|
66
|
+
|
67
|
+
def controlize s
|
68
|
+
"control/#{xpathize s.to_s}"
|
69
|
+
end
|
70
|
+
private :controlize
|
71
|
+
|
72
|
+
def xpathize s
|
73
|
+
"#{s.to_s}".gsub(/^all_/, "").gsub(/_/, "/").gsub(/[=\[\]]/, "")
|
74
|
+
end
|
75
|
+
private :xpathize
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
module Pnx
|
4
|
+
#
|
5
|
+
# Handle frbr records
|
6
|
+
#
|
7
|
+
module Frbr
|
8
|
+
#
|
9
|
+
# Is this a frbr'd record
|
10
|
+
#
|
11
|
+
def frbr?
|
12
|
+
@frbr ||= (respond_to? :facets_frbrgroupid)
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Returns the frbr id of this record if there is one.
|
17
|
+
#
|
18
|
+
def frbr_id
|
19
|
+
@frbr_id ||= facets_frbrgroupid if frbr?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
module Pnx
|
4
|
+
#
|
5
|
+
# Handle holdings in availlibrary tags.
|
6
|
+
#
|
7
|
+
module Holdings
|
8
|
+
#
|
9
|
+
# Gather Holdings for this record.
|
10
|
+
#
|
11
|
+
def holdings
|
12
|
+
@holdings ||= xml.root.xpath("display/availlibrary").collect do |availlibrary|
|
13
|
+
subfields = parse_subfields availlibrary.inner_text
|
14
|
+
# Get original id for dealing w/ dedup merger records
|
15
|
+
original_id = (subfields["O"]) ? subfields["O"] : recordid
|
16
|
+
# Get some info that may or may not be in the PNX metadata
|
17
|
+
title = self.display_title if self.respond_to? :display_title
|
18
|
+
author = self.display_creator if self.respond_to? :display_creator
|
19
|
+
display_type = self.display_type if self.respond_to? :display_type
|
20
|
+
# Add a new holding to the record's holdings.
|
21
|
+
Exlibris::Primo::Holding.new(
|
22
|
+
:availlibrary => availlibrary.inner_text,
|
23
|
+
:record_id => recordid, :original_id => original_id,
|
24
|
+
:title => title, :author => author, :display_type => display_type,
|
25
|
+
:original_source_id => originalsourceids[original_id], :source_id => sourceids[original_id],
|
26
|
+
:source_record_id => sourcerecordids[original_id], :ils_api_id => ilsapiids[original_id],
|
27
|
+
:institution_code => subfields["I"],
|
28
|
+
:library_code => subfields["L"],
|
29
|
+
:collection => subfields["1"], :call_number => subfields["2"],
|
30
|
+
:subfields => subfields, :availability_status_code => subfields["S"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
module Pnx
|
4
|
+
#
|
5
|
+
# Handle links in links tags.
|
6
|
+
#
|
7
|
+
module Links
|
8
|
+
#
|
9
|
+
# Parse linktorsrc tags to find full text links
|
10
|
+
#
|
11
|
+
def fulltexts
|
12
|
+
@fulltexts ||=
|
13
|
+
links("linktorsrc").collect { |link_attributes|
|
14
|
+
Exlibris::Primo::Fulltext.new link_attributes }
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Parse addlink tags to find related links
|
19
|
+
#
|
20
|
+
def related_links
|
21
|
+
@fulltexts ||=
|
22
|
+
links("addlink").collect { |link_attributes|
|
23
|
+
Exlibris::Primo::RelatedLink.new link_attributes }
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Parse linktotoc tags to find table of contents links
|
28
|
+
#
|
29
|
+
def tables_of_contents
|
30
|
+
@tables_of_contents ||=
|
31
|
+
links("linktotoc").collect { |link_attributes|
|
32
|
+
Exlibris::Primo::TableOfContents.new link_attributes }
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Parse links tags
|
37
|
+
#
|
38
|
+
def links(link)
|
39
|
+
xml.root.xpath("links/#{link}").collect do |link|
|
40
|
+
subfields = parse_subfields link.inner_text
|
41
|
+
# Get original id for dealing w/ dedup merger records
|
42
|
+
original_id = (subfields["O"]) ? subfields["O"] : recordid
|
43
|
+
# We're not interested if we don't have a URL
|
44
|
+
next if subfields["U"].nil?
|
45
|
+
{ :institution => subfields["I"],
|
46
|
+
:record_id => recordid, :original_id => original_id,
|
47
|
+
:url => subfields["U"], :display => subfields["D"] }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
private :links
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
module Pnx
|
4
|
+
#
|
5
|
+
# Handle OpenURL elements
|
6
|
+
#
|
7
|
+
module Openurl
|
8
|
+
#
|
9
|
+
# Parse addata to provide an OpenURL query string
|
10
|
+
#
|
11
|
+
def openurl
|
12
|
+
@openurl ||= ""
|
13
|
+
if @openurl.blank?
|
14
|
+
xml.root.xpath("addata/*").each do |addata|
|
15
|
+
@openurl << "rft.#{addata.name}=#{addata.inner_text}&" unless (addata.inner_text.nil? or addata.inner_text.strip.empty?)
|
16
|
+
end
|
17
|
+
@openurl << "rft.primo=#{@record_id}"
|
18
|
+
end
|
19
|
+
@openurl
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Exlibris
|
2
|
+
module Primo
|
3
|
+
module Pnx
|
4
|
+
#
|
5
|
+
# Handle PNX subfields
|
6
|
+
#
|
7
|
+
module Subfields
|
8
|
+
#
|
9
|
+
# Return a Hash of subfields as keys with their corresponding values
|
10
|
+
#
|
11
|
+
def parse_subfields s
|
12
|
+
Hash[s.scan(/\${2}([^\$])([^\$]+)/)]
|
13
|
+
end
|
14
|
+
protected :parse_subfields
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,116 +1,30 @@
|
|
1
1
|
module Exlibris
|
2
2
|
module Primo
|
3
|
-
# == Overview
|
4
|
-
# Exlibris::Primo::Record is an abstract representation of a Primo record.
|
5
|
-
# An instance of Exlibris::Primo::Record can be created by passing
|
6
|
-
# in a hash with setup parameters.
|
7
|
-
# Valid parameters include:
|
8
|
-
# :base_url, :resolver_base_url, :vid, :institution, :record_id, :record
|
9
|
-
# A URL to the native record (dlDisplay.do) and an OpenUrl are generated by default.
|
10
|
-
# If no resolver_base_url is provided, an OpenUrl querystring will be returned.
|
11
|
-
# A raw_xml attribute is generated either by the record XML passed in or by fetching it from the record_id.
|
12
|
-
# By default the raw_xml is not included in the hash representation, but can be overridden to.
|
13
3
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
4
|
+
# Primo record
|
5
|
+
# Includes PNX elements such as
|
6
|
+
# holdings, links, openurl, frbr status
|
7
|
+
# dedupmgr status.
|
18
8
|
#
|
19
|
-
# 2. The following methods are available for overriding:
|
20
|
-
# to_h - if a sub class creates more instance variables, these should be added to the hash
|
21
|
-
# raw - cleans up characters and spaces in raw record and wraps in <record /> tag, implementations may differ
|
22
|
-
#
|
23
|
-
# == Examples of usage
|
24
|
-
# Record.new({ :base_url => @base_url, :vid => @vid, :record => doc.at("//record") })
|
25
9
|
class Record
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# Get base url of link resolver, if blank openurl generates just querystring
|
38
|
-
resolver_base_url = parameters[:resolver_base_url]
|
39
|
-
# Get vid from parameters, required
|
40
|
-
vid = parameters.fetch(:vid, "DEFAULT")
|
41
|
-
raise_required_setup_parameter_error :vid if vid.nil?
|
42
|
-
# Get institution from parameters, required
|
43
|
-
institution = parameters.fetch(:institution, "PRIMO")
|
44
|
-
raise_required_setup_parameter_error :institution if institution.nil?
|
45
|
-
# Get record: either fetch record from Web Service based on DocId or use passed in record xml, required
|
46
|
-
record = (parameters[:record].nil?) ?
|
47
|
-
(parameters[:record_id].nil?) ?
|
48
|
-
nil : record_from_id(parameters.delete(:record_id), base_url, {:institution => institution, :vid => vid}) : parameters.delete(:record)
|
49
|
-
raise_required_setup_parameter_error "record or record_id" if record.nil?
|
50
|
-
# Set instance variables for record
|
51
|
-
@record_id = record.at("control/recordid",record.namespaces).inner_text unless record.at("control/recordid",record.namespaces).nil?
|
52
|
-
@type = record.at("display/type",record.namespaces).inner_text unless record.at("display/type",record.namespaces).nil?
|
53
|
-
@title = record.at("display/title",record.namespaces).inner_text unless record.at("display/title",record.namespaces).nil?
|
54
|
-
@url = construct_url(base_url, @record_id, institution, vid)
|
55
|
-
@openurl = construct_openurl(resolver_base_url, record, @record_id)
|
56
|
-
@creator = record.at("display/creator",record.namespaces).inner_text unless record.at("display/creator",record.namespaces).nil?
|
57
|
-
@raw_xml = raw(record)
|
58
|
-
end
|
10
|
+
include Config::Attributes
|
11
|
+
include Namespaces
|
12
|
+
include WriteAttributes
|
13
|
+
include XmlUtil
|
14
|
+
include Exlibris::Primo::Pnx::DedupMgr
|
15
|
+
include Exlibris::Primo::Pnx::Elements
|
16
|
+
include Exlibris::Primo::Pnx::Frbr
|
17
|
+
include Exlibris::Primo::Pnx::Holdings
|
18
|
+
include Exlibris::Primo::Pnx::Links
|
19
|
+
include Exlibris::Primo::Pnx::Openurl
|
20
|
+
include Exlibris::Primo::Pnx::Subfields
|
59
21
|
|
60
|
-
|
61
|
-
|
62
|
-
return {
|
63
|
-
"format" => @type.capitalize,
|
64
|
-
"title" => @title,
|
65
|
-
"author" => @creator,
|
66
|
-
"url" => @url,
|
67
|
-
"openurl" => @openurl
|
68
|
-
}
|
69
|
-
end
|
70
|
-
|
71
|
-
# Return a JSON representation of the PNX record
|
72
|
-
def to_json
|
73
|
-
# Leverage ActiveSupport's Hash#from_xml method to transform PNX to JSON.
|
74
|
-
Hash.from_xml(raw_xml).to_json
|
75
|
-
end
|
76
|
-
|
77
|
-
# Method for cleaning up raw xml from record
|
78
|
-
def raw(record)
|
79
|
-
record.to_xml(:indent => 0, :encoding => 'UTF-8')
|
80
|
-
end
|
81
|
-
|
82
|
-
private
|
83
|
-
# Method for consturcting openurl from record
|
84
|
-
def construct_openurl(resolver_base_url, record, record_id)
|
85
|
-
raise_required_setup_parameter_error :record if record.nil?
|
86
|
-
raise_required_setup_parameter_error :record_id if record_id.nil?
|
87
|
-
openurl = (resolver_base_url.nil?) ? "?" : "#{resolver_base_url}?"
|
88
|
-
record.search("addata/*",record.namespaces).each do |addata|
|
89
|
-
openurl << "rft.#{addata.name}=#{addata.inner_text}&" unless (addata.inner_text.nil? or addata.inner_text.strip.empty?)
|
90
|
-
end
|
91
|
-
openurl << "rft.primo=#{record_id}"
|
92
|
-
return openurl
|
93
|
-
end
|
94
|
-
|
95
|
-
# Method for constructing deep link url from record
|
96
|
-
def construct_url(base_url, record_id, institution, vid)
|
97
|
-
raise_required_setup_parameter_error :base_url if base_url.nil?
|
98
|
-
raise_required_setup_parameter_error :record_id if record_id.nil?
|
99
|
-
raise_required_setup_parameter_error :institution if institution.nil?
|
100
|
-
raise_required_setup_parameter_error :vid if vid.nil?
|
101
|
-
url = "#{base_url}/primo_library/libweb/action/dlDisplay.do?dym=false&onCampus=false&docId=#{record_id}&institution=#{institution}&vid=#{vid}"
|
102
|
-
return url
|
103
|
-
end
|
104
|
-
|
105
|
-
# Fetch record from Primo Web Service
|
106
|
-
def record_from_id(record_id, base_url, options={})
|
107
|
-
doc = Exlibris::Primo::WebService::GetRecord.new(record_id, base_url, options).response.at("//sear:DOC", SEAR_NS)
|
108
|
-
return doc.at("//xmlns:record",doc.namespaces)
|
109
|
-
end
|
22
|
+
add_duplicated_control_attributes :sourcerecordids, :sourceids,
|
23
|
+
:originalsourceids, :sourceformats, :sourcesystems, :ilsapiids
|
110
24
|
|
111
|
-
|
112
|
-
|
113
|
-
|
25
|
+
def initialize *args
|
26
|
+
@raw_xml = args.last.delete(:raw_xml)
|
27
|
+
super
|
114
28
|
end
|
115
29
|
end
|
116
30
|
end
|