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.
Files changed (272) hide show
  1. data/MIT-LICENSE +1 -1
  2. data/README.md +111 -0
  3. data/Rakefile +2 -1
  4. data/lib/exlibris-primo.rb +4 -14
  5. data/lib/exlibris/primo.rb +13 -0
  6. data/lib/exlibris/primo/abstract.rb +28 -0
  7. data/lib/exlibris/primo/chain_gang/README.md +9 -0
  8. data/lib/exlibris/primo/chain_gang/base.rb +121 -0
  9. data/lib/exlibris/primo/chain_gang/record.rb +18 -0
  10. data/lib/exlibris/primo/chain_gang/search.rb +319 -0
  11. data/lib/exlibris/primo/chain_gang/user.rb +18 -0
  12. data/lib/exlibris/primo/config.rb +69 -0
  13. data/lib/exlibris/primo/eshelf.rb +115 -62
  14. data/lib/exlibris/primo/facet.rb +40 -0
  15. data/lib/exlibris/primo/facet_value.rb +40 -0
  16. data/lib/exlibris/primo/holding.rb +81 -152
  17. data/lib/exlibris/primo/link.rb +32 -0
  18. data/lib/exlibris/primo/namespaces.rb +44 -0
  19. data/lib/exlibris/primo/pnx/dedup_mgr.rb +91 -0
  20. data/lib/exlibris/primo/pnx/elements.rb +79 -0
  21. data/lib/exlibris/primo/pnx/frbr.rb +24 -0
  22. data/lib/exlibris/primo/pnx/holdings.rb +36 -0
  23. data/lib/exlibris/primo/pnx/links.rb +54 -0
  24. data/lib/exlibris/primo/pnx/openurl.rb +24 -0
  25. data/lib/exlibris/primo/pnx/subfields.rb +18 -0
  26. data/lib/exlibris/primo/record.rb +20 -106
  27. data/lib/exlibris/primo/request_attributes.rb +28 -0
  28. data/lib/exlibris/primo/review.rb +46 -0
  29. data/lib/exlibris/primo/reviews.rb +81 -0
  30. data/lib/exlibris/primo/search.rb +82 -0
  31. data/lib/exlibris/primo/source/aleph.rb +77 -31
  32. data/lib/exlibris/primo/tag.rb +34 -0
  33. data/lib/exlibris/primo/tags.rb +103 -0
  34. data/lib/exlibris/primo/version.rb +1 -1
  35. data/lib/exlibris/primo/web_service/client/base.rb +30 -0
  36. data/lib/exlibris/primo/web_service/client/base/endpoint.rb +29 -0
  37. data/lib/exlibris/primo/web_service/client/base/savon_client.rb +24 -0
  38. data/lib/exlibris/primo/web_service/client/base/savon_config.rb +19 -0
  39. data/lib/exlibris/primo/web_service/client/base/soap_actions.rb +55 -0
  40. data/lib/exlibris/primo/web_service/client/base/wsdl.rb +14 -0
  41. data/lib/exlibris/primo/web_service/client/eshelf.rb +22 -0
  42. data/lib/exlibris/primo/web_service/client/reviews.rb +15 -0
  43. data/lib/exlibris/primo/web_service/client/search.rb +15 -0
  44. data/lib/exlibris/primo/web_service/client/tags.rb +14 -0
  45. data/lib/exlibris/primo/web_service/request/base.rb +77 -0
  46. data/lib/exlibris/primo/web_service/request/base/base_elements.rb +71 -0
  47. data/lib/exlibris/primo/web_service/request/base/call.rb +19 -0
  48. data/lib/exlibris/primo/web_service/request/base/client.rb +45 -0
  49. data/lib/exlibris/primo/web_service/request/base/soap_action.rb +29 -0
  50. data/lib/exlibris/primo/web_service/request/eshelf.rb +71 -0
  51. data/lib/exlibris/primo/web_service/request/reviews.rb +57 -0
  52. data/lib/exlibris/primo/web_service/request/search.rb +49 -0
  53. data/lib/exlibris/primo/web_service/request/search/display_fields.rb +30 -0
  54. data/lib/exlibris/primo/web_service/request/search/languages.rb +32 -0
  55. data/lib/exlibris/primo/web_service/request/search/location.rb +15 -0
  56. data/lib/exlibris/primo/web_service/request/search/locations.rb +33 -0
  57. data/lib/exlibris/primo/web_service/request/search/query_term.rb +43 -0
  58. data/lib/exlibris/primo/web_service/request/search/query_terms.rb +40 -0
  59. data/lib/exlibris/primo/web_service/request/search/search_elements.rb +97 -0
  60. data/lib/exlibris/primo/web_service/request/search/sort_bys.rb +32 -0
  61. data/lib/exlibris/primo/web_service/request/tags.rb +56 -0
  62. data/lib/exlibris/primo/web_service/response/base.rb +28 -0
  63. data/lib/exlibris/primo/web_service/response/base/error.rb +25 -0
  64. data/lib/exlibris/primo/web_service/response/base/util.rb +19 -0
  65. data/lib/exlibris/primo/web_service/response/did_u_mean.rb +17 -0
  66. data/lib/exlibris/primo/web_service/response/eshelf.rb +68 -0
  67. data/lib/exlibris/primo/web_service/response/facets.rb +21 -0
  68. data/lib/exlibris/primo/web_service/response/records.rb +17 -0
  69. data/lib/exlibris/primo/web_service/response/reviews.rb +49 -0
  70. data/lib/exlibris/primo/web_service/response/search.rb +36 -0
  71. data/lib/exlibris/primo/web_service/response/search_stats.rb +48 -0
  72. data/lib/exlibris/primo/web_service/response/tags.rb +54 -0
  73. data/lib/exlibris/primo/write_attributes.rb +38 -0
  74. data/lib/exlibris/primo/xml_util.rb +63 -0
  75. data/test/{unit/eshelf_test.rb → bak/eshelf_test.rb.bak} +0 -0
  76. data/test/{unit/record_test.rb → bak/record_test.rb.bak} +0 -0
  77. data/test/{unit/searcher_test.rb → bak/searcher_test.rb.bak} +0 -0
  78. data/test/{unit/web_service_test.rb → bak/web_service_test.rb.bak} +0 -0
  79. data/test/config_test.rb +72 -0
  80. data/test/eshelf_test.rb +66 -0
  81. data/test/exlibris-primo_test.rb +0 -1
  82. data/test/facet_test.rb +27 -0
  83. data/test/facet_value_test.rb +62 -0
  84. data/test/holding_test.rb +26 -0
  85. data/test/link_test.rb +42 -0
  86. data/test/pnx/dedup_mgr_test.rb +16 -0
  87. data/test/pnx/elements_test.rb +16 -0
  88. data/test/pnx/frbr_test.rb +12 -0
  89. data/test/pnx/holdings_test.rb +53 -0
  90. data/test/pnx/links_test.rb +44 -0
  91. data/test/pnx/openurl_test.rb +10 -0
  92. data/test/record_test.rb +11 -0
  93. data/test/review_test.rb +15 -0
  94. data/test/reviews_test.rb +50 -0
  95. data/test/search_test.rb +328 -0
  96. data/test/source/aleph_test.rb +52 -0
  97. data/test/support/config.yml +35 -0
  98. data/test/tag_test.rb +12 -0
  99. data/test/tags_test.rb +65 -0
  100. data/test/test_helper.rb +536 -4
  101. data/test/vcr_cassettes/client_action_no_arguments.yml +38 -0
  102. data/test/vcr_cassettes/client_get_all_my_reviews.yml +49 -0
  103. data/test/vcr_cassettes/client_get_all_my_tags.yml +49 -0
  104. data/test/vcr_cassettes/client_get_eshelf.yml +13812 -0
  105. data/test/vcr_cassettes/client_get_record.yml +222 -0
  106. data/test/vcr_cassettes/client_get_reviews.yml +39 -0
  107. data/test/vcr_cassettes/client_get_tags.yml +42 -0
  108. data/test/vcr_cassettes/client_search_brief_isbn.yml +288 -0
  109. data/test/vcr_cassettes/client_search_brief_issn.yml +282 -0
  110. data/test/vcr_cassettes/client_too_many_arguments.yml +38 -0
  111. data/test/vcr_cassettes/eshelf.yml +13845 -0
  112. data/test/vcr_cassettes/eshelf_add_folder.yml +109 -0
  113. data/test/vcr_cassettes/eshelf_add_record.yml +14237 -0
  114. data/test/vcr_cassettes/eshelf_add_records.yml +14156 -0
  115. data/test/vcr_cassettes/eshelf_basket_id.yml +36 -0
  116. data/test/vcr_cassettes/eshelf_records.yml +13460 -0
  117. data/test/vcr_cassettes/eshelf_remove_folder.yml +76 -0
  118. data/test/vcr_cassettes/eshelf_remove_record.yml +13500 -0
  119. data/test/vcr_cassettes/eshelf_remove_records.yml +13741 -0
  120. data/test/vcr_cassettes/{web_service_single_document.yml → remote_record_call.yml} +12 -23
  121. data/test/vcr_cassettes/{searcher_dedupmrg_by_id.yml → remote_record_dedupmgr.yml} +19 -31
  122. data/test/vcr_cassettes/request_add_folder_to_eshelf.yml +43 -0
  123. data/test/vcr_cassettes/request_add_to_eshelf.yml +43 -0
  124. data/test/vcr_cassettes/request_did_u_mean_enabled.yml +48 -0
  125. data/test/vcr_cassettes/request_full_view.yml +222 -0
  126. data/test/vcr_cassettes/request_get_eshelf.yml +13812 -0
  127. data/test/vcr_cassettes/request_get_eshelf_structure.yml +36 -0
  128. data/test/vcr_cassettes/request_get_reviews.yml +39 -0
  129. data/test/vcr_cassettes/request_get_tags.yml +42 -0
  130. data/test/vcr_cassettes/request_remove_folder_from_eshelf.yml +43 -0
  131. data/test/vcr_cassettes/request_remove_from_eshelf.yml +43 -0
  132. data/test/vcr_cassettes/request_search_author.yml +1258 -0
  133. data/test/vcr_cassettes/request_search_did_u_mean.yml +48 -0
  134. data/test/vcr_cassettes/request_search_genre.yml +1321 -0
  135. data/test/vcr_cassettes/request_search_isbn.yml +288 -0
  136. data/test/vcr_cassettes/request_search_issn.yml +282 -0
  137. data/test/vcr_cassettes/request_search_locations.yml +288 -0
  138. data/test/vcr_cassettes/request_search_title.yml +1024 -0
  139. data/test/vcr_cassettes/request_search_title_author_genre.yml +708 -0
  140. data/test/vcr_cassettes/response_add_folder_to_eshelf.yml +43 -0
  141. data/test/vcr_cassettes/response_add_review.yml +39 -0
  142. data/test/vcr_cassettes/response_add_tag.yml +39 -0
  143. data/test/vcr_cassettes/response_add_to_eshelf.yml +43 -0
  144. data/test/vcr_cassettes/response_did_u_mean_disabled.yml +46 -0
  145. data/test/vcr_cassettes/response_did_u_mean_enabled.yml +48 -0
  146. data/test/vcr_cassettes/response_full_view.yml +222 -0
  147. data/test/vcr_cassettes/response_get_all_my_reviews.yml +49 -0
  148. data/test/vcr_cassettes/response_get_all_my_tags.yml +49 -0
  149. data/test/vcr_cassettes/response_get_eshelf.yml +13633 -0
  150. data/test/vcr_cassettes/response_get_eshelf_structure.yml +36 -0
  151. data/test/vcr_cassettes/response_get_reviews.yml +39 -0
  152. data/test/vcr_cassettes/response_get_reviews_by_rating.yml +49 -0
  153. data/test/vcr_cassettes/response_get_reviews_for_record.yml +39 -0
  154. data/test/vcr_cassettes/response_get_tags.yml +42 -0
  155. data/test/vcr_cassettes/response_get_tags_for_record.yml +42 -0
  156. data/test/vcr_cassettes/response_remove_folder_from_eshelf.yml +43 -0
  157. data/test/vcr_cassettes/response_remove_from_eshelf.yml +43 -0
  158. data/test/vcr_cassettes/response_remove_review.yml +39 -0
  159. data/test/vcr_cassettes/response_remove_tag.yml +39 -0
  160. data/test/vcr_cassettes/response_remove_user_tags.yml +39 -0
  161. data/test/vcr_cassettes/response_search.yml +288 -0
  162. data/test/vcr_cassettes/response_search_did_u_mean.yml +48 -0
  163. data/test/vcr_cassettes/reviews.yml +49 -0
  164. data/test/vcr_cassettes/reviews_add_review.yml +39 -0
  165. data/test/vcr_cassettes/reviews_check_empty_reviews_first.yml +39 -0
  166. data/test/vcr_cassettes/reviews_check_empty_reviews_last.yml +39 -0
  167. data/test/vcr_cassettes/reviews_rating.yml +168 -0
  168. data/test/vcr_cassettes/reviews_record.yml +49 -0
  169. data/test/vcr_cassettes/reviews_remove_review.yml +39 -0
  170. data/test/vcr_cassettes/reviews_reviews.yml +49 -0
  171. data/test/vcr_cassettes/reviews_user.yml +58 -0
  172. data/test/vcr_cassettes/search_chaining_author_title.yml +938 -0
  173. data/test/vcr_cassettes/search_chaining_contains_any.yml +1453 -0
  174. data/test/vcr_cassettes/search_chaining_contains_author_starts_with_title.yml +1055 -0
  175. data/test/vcr_cassettes/search_chaining_isbn.yml +288 -0
  176. data/test/vcr_cassettes/search_chaining_page_size_author.yml +5933 -0
  177. data/test/vcr_cassettes/search_did_u_mean.yml +48 -0
  178. data/test/vcr_cassettes/search_enable_highlighting.yml +1337 -0
  179. data/test/vcr_cassettes/search_isbn.yml +288 -0
  180. data/test/vcr_cassettes/search_languages.yml +1332 -0
  181. data/test/vcr_cassettes/search_locations.yml +1440 -0
  182. data/test/vcr_cassettes/search_record_id.yml +222 -0
  183. data/test/vcr_cassettes/search_record_id_chaining.yml +222 -0
  184. data/test/vcr_cassettes/search_sort_by.yml +1289 -0
  185. data/test/vcr_cassettes/search_sort_by_locations.yml +1387 -0
  186. data/test/vcr_cassettes/tags.yml +56 -0
  187. data/test/vcr_cassettes/tags_add_extra_tag.yml +39 -0
  188. data/test/vcr_cassettes/tags_add_tag.yml +39 -0
  189. data/test/vcr_cassettes/tags_add_tags.yml +111 -0
  190. data/test/vcr_cassettes/tags_check_1_tags.yml +56 -0
  191. data/test/vcr_cassettes/tags_check_2_tags.yml +68 -0
  192. data/test/vcr_cassettes/tags_check_empty_tags_first.yml +42 -0
  193. data/test/vcr_cassettes/tags_check_empty_tags_last.yml +42 -0
  194. data/test/vcr_cassettes/tags_remove_tag.yml +39 -0
  195. data/test/vcr_cassettes/tags_remove_tags.yml +111 -0
  196. data/test/vcr_cassettes/tags_remove_user_tags.yml +39 -0
  197. data/test/vcr_cassettes/tags_tags.yml +104 -0
  198. data/test/vcr_cassettes/tags_user.yml +73 -0
  199. data/test/web_service/client/abstract_test.rb +29 -0
  200. data/test/web_service/client/eshelf_test.rb +22 -0
  201. data/test/web_service/client/reviews_test.rb +31 -0
  202. data/test/web_service/client/savon_client_test.rb +17 -0
  203. data/test/web_service/client/search_benchmarks.rb +29 -0
  204. data/test/web_service/client/search_test.rb +44 -0
  205. data/test/web_service/client/soap_actions_test.rb +45 -0
  206. data/test/web_service/client/tags_test.rb +31 -0
  207. data/test/web_service/request/abstract_test.rb +68 -0
  208. data/test/web_service/request/base_elements_test.rb +231 -0
  209. data/test/web_service/request/build_xml_test.rb +23 -0
  210. data/test/web_service/request/client_test.rb +53 -0
  211. data/test/web_service/request/eshelf_test.rb +26 -0
  212. data/test/web_service/request/location_test.rb +25 -0
  213. data/test/web_service/request/query_term_test.rb +29 -0
  214. data/test/web_service/request/reviews_test.rb +27 -0
  215. data/test/web_service/request/search_test.rb +234 -0
  216. data/test/web_service/request/soap_action_test.rb +120 -0
  217. data/test/web_service/request/tags_test.rb +27 -0
  218. data/test/web_service/response/abstract_test.rb +200 -0
  219. data/test/web_service/response/did_u_mean_test.rb +44 -0
  220. data/test/web_service/response/error_test.rb +31 -0
  221. data/test/web_service/response/eshelf_test.rb +28 -0
  222. data/test/web_service/response/facets_test.rb +42 -0
  223. data/test/web_service/response/records_test.rb +56 -0
  224. data/test/web_service/response/reviews_test.rb +28 -0
  225. data/test/web_service/response/search_stats_test.rb +75 -0
  226. data/test/web_service/response/search_test.rb +40 -0
  227. data/test/web_service/response/tags_test.rb +28 -0
  228. data/test/xml_util_test.rb +23 -0
  229. metadata +456 -114
  230. data/README.rdoc +0 -68
  231. data/lib/exlibris/primo/related_link.rb +0 -20
  232. data/lib/exlibris/primo/rsrc.rb +0 -20
  233. data/lib/exlibris/primo/searcher.rb +0 -277
  234. data/lib/exlibris/primo/toc.rb +0 -20
  235. data/lib/exlibris/primo/web_service.rb +0 -203
  236. data/test/unit/searcher_benchmarks.rb +0 -74
  237. data/test/unit/web_service_benchmarks.rb +0 -58
  238. data/test/vcr_cassettes/eshelf_add_invalid_records.yml +0 -107
  239. data/test/vcr_cassettes/eshelf_add_same_record_twice.yml +0 -159
  240. data/test/vcr_cassettes/eshelf_add_to_empty_basket.yml +0 -107
  241. data/test/vcr_cassettes/eshelf_add_to_invalid_basket.yml +0 -55
  242. data/test/vcr_cassettes/eshelf_invalid_eshelf.yml +0 -55
  243. data/test/vcr_cassettes/eshelf_invalid_institution.yml +0 -55
  244. data/test/vcr_cassettes/eshelf_valid_eshelf.yml +0 -2553
  245. data/test/vcr_cassettes/eshelf_valid_eshelf_structure.yml +0 -47
  246. data/test/vcr_cassettes/record.yml +0 -212
  247. data/test/vcr_cassettes/record_invalid_record.yml +0 -55
  248. data/test/vcr_cassettes/record_sub_record.yml +0 -212
  249. data/test/vcr_cassettes/record_valid_record.yml +0 -212
  250. data/test/vcr_cassettes/searcher_base_holdings_by_id.yml +0 -212
  251. data/test/vcr_cassettes/searcher_diacritics1_by_id.yml +0 -207
  252. data/test/vcr_cassettes/searcher_diacritics2_by_id.yml +0 -232
  253. data/test/vcr_cassettes/searcher_holdings_by_id.yml +0 -212
  254. data/test/vcr_cassettes/searcher_invalid_id.yml +0 -55
  255. data/test/vcr_cassettes/searcher_rsrcs_by_id.yml +0 -270
  256. data/test/vcr_cassettes/searcher_search_by_isbn.yml +0 -278
  257. data/test/vcr_cassettes/searcher_search_by_issn.yml +0 -297
  258. data/test/vcr_cassettes/searcher_search_by_title_author_genre.yml +0 -671
  259. data/test/vcr_cassettes/searcher_test_bug_1361.yml +0 -224
  260. data/test/vcr_cassettes/searcher_test_problem_by_id.yml +0 -194
  261. data/test/vcr_cassettes/searcher_tocs_by_id.yml +0 -217
  262. data/test/vcr_cassettes/web_service_author_search.yml +0 -1269
  263. data/test/vcr_cassettes/web_service_bogus_200.yml +0 -392
  264. data/test/vcr_cassettes/web_service_brief_search.yml +0 -299
  265. data/test/vcr_cassettes/web_service_get_eshelf.yml +0 -11823
  266. data/test/vcr_cassettes/web_service_get_eshelf_structure_search.yml +0 -47
  267. data/test/vcr_cassettes/web_service_invalid_document.yml +0 -54
  268. data/test/vcr_cassettes/web_service_isbn_search.yml +0 -299
  269. data/test/vcr_cassettes/web_service_issn_search.yml +0 -293
  270. data/test/vcr_cassettes/web_service_problem_document.yml +0 -193
  271. data/test/vcr_cassettes/web_service_title_author_genre_search.yml +0 -719
  272. data/test/vcr_cassettes/web_service_title_search.yml +0 -1035
@@ -0,0 +1,18 @@
1
+ module Exlibris
2
+ module Primo
3
+ module ChainGang
4
+ module User
5
+ attr_reader :user_id
6
+
7
+ #
8
+ # Set the user id
9
+ #
10
+ def user_id!(user_id)
11
+ @user_id = user_id
12
+ self
13
+ end
14
+ alias :user_id= :user_id!
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,69 @@
1
+ module Exlibris
2
+ module Primo
3
+ #
4
+ # Specify global configuration settings for
5
+ #
6
+ module Config
7
+ class << self
8
+ include WriteAttributes
9
+ attr_accessor :base_url, :institution, :institutions, :libraries, :availability_statuses, :sources,
10
+ :facet_labels, :facet_top_level, :facet_collections, :facet_resource_types, :load_time
11
+
12
+ def load_yaml file
13
+ write_attributes YAML.load_file(file)
14
+ self.load_time = Time.now
15
+ end
16
+ end
17
+
18
+ #
19
+ # These attributes default to the global config settings if not
20
+ # specified locally.
21
+ #
22
+ module Attributes
23
+ def config
24
+ @config ||= Config
25
+ end
26
+
27
+ def base_url
28
+ @base_url ||= String.new config.base_url.to_s
29
+ end
30
+
31
+ def institution
32
+ @institution ||= String.new config.institution.to_s
33
+ end
34
+
35
+ def institutions
36
+ @institutions ||= (config.institutions) ? config.institutions.dup : {}
37
+ end
38
+
39
+ def libraries
40
+ @libraries ||= (config.libraries) ? config.libraries.dup : {}
41
+ end
42
+
43
+ def availability_statuses
44
+ @availability_statuses ||= (config.availability_statuses) ? config.availability_statuses.dup : {}
45
+ end
46
+
47
+ def sources
48
+ @sources ||= (config.sources) ? config.sources.dup : {}
49
+ end
50
+
51
+ def facet_labels
52
+ @facet_labels ||= (config.facet_labels) ? config.facet_labels.dup : {}
53
+ end
54
+
55
+ def facet_top_level
56
+ @facet_top_level ||= (config.facet_top_level) ? config.facet_top_level.dup : {}
57
+ end
58
+
59
+ def facet_collections
60
+ @facet_collections ||= (config.facet_collections) ? config.facet_collections.dup : {}
61
+ end
62
+
63
+ def facet_resource_types
64
+ @facet_resource_types ||= (config.facet_resource_types) ? config.facet_resource_types.dup : {}
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,81 +1,134 @@
1
1
  module Exlibris
2
2
  module Primo
3
- # == Overview
4
- # Exlibris::Primo::EShelf provides access to the Primo Eshelf for a given user.
5
- # An instance of Exlibris::Primo::EShelf can be created by passing
6
- # in a hash with setup parameters, a user_id and an institution.
7
- # Valid setup parameters include:
8
- # :base_url, :resolver_base_url, :vid, :config
9
3
  #
10
- # == Examples of usage
11
- # Exlibris::Primo::EShelf.new({ :base_url => "http://primo.institution.edu", :vid => "VID", :resolver_base_url => "http://resolver.institution.edu"} , "USER_ID", "PRIMO").count
12
- # Exlibris::Primo::EShelf.new(@eshelf_setup, @valid_user_id, @valid_institute).basket_id
4
+ # Manipulate a user's Primo eshelf using Exlibris::Primo::Eshelf
5
+ #
6
+ # eshelf = Eshelf.new.base_url!("http://primo.library.edu").institution!("PRIMO").user_id!("USER_ID")
7
+ # eshelf.records #=> Array for Primo records
8
+ #
13
9
  class EShelf
14
-
15
- #Namespaces
16
- SEAR_NS = {'sear' => 'http://www.exlibrisgroup.com/xsd/jaguar/search'}
17
- PRIM_NS = {'prim' => 'http://www.exlibris.com/primo/xsd/primoeshelffolder'}
18
- PRIM_BIB_NS = {'bib' => 'http://www.exlibrisgroup.com/xsd/primo/primo_nm_bib'}
19
-
20
- def initialize(setup, user_id, institution)
21
- @base_url = setup[:base_url]
22
- raise_required_setup_parameter_error :base_url if @base_url.nil?
23
- @resolver_base_url = setup[:resolver_base_url]
24
- @vid = setup.fetch(:vid, "DEFAULT")
25
- raise_required_setup_parameter_error :vid if @vid.nil?
26
- @config = setup.fetch(:config, {})
27
- raise_required_setup_parameter_error :config if @config.nil?
28
- @user_id = user_id
29
- raise_required_setup_parameter_error :user_id if @user_id.nil?
30
- @institution = institution
31
- raise_required_setup_parameter_error :institution if @institution.nil?
32
- @records = []
10
+ include Config::Attributes
11
+ include ChainGang::Base
12
+ include ChainGang::User
13
+ include RequestAttributes
14
+ include WriteAttributes
15
+
16
+ attr_reader :user_id
17
+
18
+ def initialize *args
19
+ super
33
20
  end
34
-
35
- # Call Web Service to get Eshelf contents and return
21
+
22
+ #
23
+ # Call web service to get Eshelf contents and return
24
+ #
36
25
  def eshelf
37
- @eshelf ||= Exlibris::Primo::WebService::GetEShelf.new(@user_id, @institution, @base_url).response
26
+ @eshelf ||=
27
+ Exlibris::Primo::WebService::Request::GetEshelf.new(user_request_attributes).call
38
28
  end
39
-
40
- # Call Web Service to get Eshelf structure and return
41
- def eshelfStructure
42
- @eshelfStructure ||= Exlibris::Primo::WebService::GetEShelfStructure.new(@user_id, @institution, @base_url).response
29
+
30
+ #
31
+ # Call web service to get Eshelf structure and return
32
+ #
33
+ def eshelf_structure
34
+ @eshelf_structure ||=
35
+ Exlibris::Primo::WebService::Request::GetEshelfStructure.new(user_request_attributes).call
43
36
  end
44
-
45
- # Fetch the number of records in user's Eshelf
46
- def count
47
- @count ||= Integer(eshelf.at("//sear:DOCSET", SEAR_NS)["TOTALHITS"])
37
+
38
+ #
39
+ # Get the number of records in user's eshelf
40
+ #
41
+ def size
42
+ @size ||= eshelf.size
48
43
  end
49
-
50
- # Fetch all records from user's Eshelf as an array of Primo Record objects
51
- def records
52
- eshelf.search("//sear:DOC", SEAR_NS).each { |doc|
53
- @records.push(Record.new({ :base_url => @base_url, :resolver_base_url => @resolver_base_url, :vid => @vid, :record => doc.at("//bib:record", PRIM_BIB_NS), :institution => @institution }))
54
- } if @records.empty?
55
- return @records
44
+
45
+ #
46
+ # Get all the records from user's eshelf as an array of Primo Record objects
47
+ #
48
+ def records
49
+ @records ||= eshelf.records
56
50
  end
57
-
58
- # Fetch default basket id from eshelf structure web service call
51
+
52
+ #
53
+ # Get the default basket id from eshelf structure web service call
54
+ #
59
55
  def basket_id
60
- @basket_id ||= eshelfStructure.at(
61
- "//prim:eshelf_folders//prim:eshelf_folder[./prim:folder_name='Basket']", PRIM_NS).
62
- get_attribute("folder_id") unless eshelfStructure.at("//prim:eshelf_folders//prim:eshelf_folder[./prim:folder_name='Basket']", PRIM_NS).nil?
56
+ @basket_id ||= eshelf_structure.basket_id
63
57
  end
64
-
65
- # Call Web Service to add records to remote Eshelf
66
- def add_records(doc_ids, folder_id)
67
- Exlibris::Primo::WebService::AddToEShelf.new(doc_ids, folder_id, @user_id, @institution, @base_url) unless doc_ids.empty?
58
+
59
+ #
60
+ # Get the folder id from eshelf structure web service call
61
+ # for the given folder name.
62
+ #
63
+ def folder_id(folder_name)
64
+ eshelf_structure.folder_id(folder_name)
68
65
  end
69
66
 
70
- # Call Web Service to remove records from remote EShelf
71
- def remove_records(doc_ids, folder_id)
72
- Exlibris::Primo::WebService::RemoveFromEShelf.new(doc_ids, folder_id, @user_id, @institution, @base_url) unless doc_ids.empty?
67
+ #
68
+ # Call web service to add records to eshelf
69
+ #
70
+ def add_records(record_ids, folder_id)
71
+ record_ids.each do |record_id|
72
+ add_record record_id, folder_id
73
+ end
74
+ reset_eshelf
73
75
  end
74
-
75
- private
76
- def raise_required_setup_parameter_error(parameter)
77
- raise ArgumentError.new("Error in #{self.class}. Missing required setup parameter: #{parameter}.")
76
+
77
+ #
78
+ # Call web service to add record to eshelf
79
+ #
80
+ def add_record(record_id, folder_id)
81
+ Exlibris::Primo::WebService::Request::AddToEshelf.new(
82
+ user_request_attributes.merge :folder_id => folder_id, :doc_id => record_id).call
83
+ reset_eshelf
84
+ end
85
+
86
+ #
87
+ # Call web service to remove records from the eshelf
88
+ #
89
+ def remove_records(record_ids, folder_id)
90
+ record_ids.each do |record_id|
91
+ remove_record record_id, folder_id
92
+ end
93
+ reset_eshelf
94
+ end
95
+
96
+ #
97
+ # Call web service to remove a record from eshelf
98
+ #
99
+ def remove_record(record_id, folder_id)
100
+ Exlibris::Primo::WebService::Request::RemoveFromEshelf.new(
101
+ user_request_attributes.merge :folder_id => folder_id, :doc_id => record_id).call
102
+ reset_eshelf
103
+ end
104
+
105
+ #
106
+ # Call web service to add folder to eshelf
107
+ #
108
+ def add_folder(folder_name, parent_id)
109
+ Exlibris::Primo::WebService::Request::AddFolderToEshelf.new(
110
+ user_request_attributes.merge :folder_name => folder_name, :parent_folder => parent_id).call
111
+ reset_eshelf
112
+ end
113
+
114
+ #
115
+ # Call web service to remove folder from eshelf
116
+ #
117
+ def remove_folder(folder_id)
118
+ Exlibris::Primo::WebService::Request::RemoveFolderFromEshelf.new(
119
+ user_request_attributes.merge :folder_id => folder_id).call
120
+ reset_eshelf
121
+ end
122
+
123
+ # Reset eshelf instance variables
124
+ def reset_eshelf
125
+ @eshelf = nil
126
+ @eshelf_structure = nil
127
+ @size = nil
128
+ @records = nil
129
+ @basket_id = nil
78
130
  end
131
+ private :reset_eshelf
79
132
  end
80
133
  end
81
134
  end
@@ -0,0 +1,40 @@
1
+ module Exlibris
2
+ module Primo
3
+ #
4
+ # Primo facet holds the name of the facet
5
+ # and size (often approximate).
6
+ #
7
+ class Facet
8
+ include Config::Attributes
9
+ include WriteAttributes
10
+ include XmlUtil
11
+
12
+ attr_accessor :accurate
13
+ alias accurate? accurate
14
+
15
+ def initialize *args
16
+ @raw_xml = args.last.delete(:raw_xml)
17
+ super
18
+ end
19
+
20
+ def name
21
+ @name = xml.root["NAME"]
22
+ end
23
+
24
+ def display_name
25
+ @display_name ||= (config.facet_labels[name] || name)
26
+ end
27
+
28
+ def size
29
+ @size = Integer(xml.root["COUNT"])
30
+ end
31
+ alias :count :size
32
+
33
+ def facet_values
34
+ @facet_values ||= xml.root.search("//FACET_VALUES").collect do |facet_value|
35
+ FacetValue.new(:raw_xml => facet_value.to_xml, :facet => self)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ module Exlibris
2
+ module Primo
3
+ require 'iso-639'
4
+ #
5
+ # Primo facet value that holds the name of the value
6
+ # and the number of records that limiting by this facet
7
+ # value would return.
8
+ #
9
+ class FacetValue
10
+ include Config::Attributes
11
+ include WriteAttributes
12
+ include XmlUtil
13
+
14
+ attr_accessor :facet
15
+
16
+ def initialize *args
17
+ @raw_xml = args.last.delete(:raw_xml)
18
+ super
19
+ end
20
+
21
+ def name
22
+ @name ||= xml.root["KEY"]
23
+ end
24
+
25
+ def display_name
26
+ return @display_name ||= (ISO_639.find(name).english_name || name) if facet.name.eql? "lang"
27
+ return @display_name ||= (config.libraries[name] || name) if facet.name.eql? "library"
28
+ return @display_name ||= (config.facet_top_level[name] || name) if facet.name.eql? "tlevel"
29
+ return @display_name ||= (config.facet_collections[name] || name) if facet.name.eql? "domain"
30
+ return @display_name ||= (config.facet_resource_types[name] || name) if facet.name.eql? "rtype"
31
+ @display_name ||= name
32
+ end
33
+
34
+ def size
35
+ @size = Integer(xml.root["VALUE"])
36
+ end
37
+ alias :count :size
38
+ end
39
+ end
40
+ end
@@ -1,135 +1,83 @@
1
1
  module Exlibris
2
2
  module Primo
3
- # == Overview
4
- # Exlibris::Primo::Holding represents a Primo availibrary entry.
5
- # An instance of Exlibris::Primo::Holding can be created by passing
6
- # in a set of parameters containing the data for the holding.
7
- # Valid parameters include:
8
- # :record_id, :title, :author, :source_id, :original_source_id, :source_record_id,
9
- # :availlibrary,:institution_code, :library_code, :status_code, :id_one, :id_two,
10
- # :origin, :display_type, :coverage, :notes, :url, :request_url, :source_data
11
- # When creating an instance of Exlibris::Primo::Holding, calling
12
- # classes may send in a :config hash that contains config mappings
13
- # for decoding libraries and statuses. The :config hash should be
14
- # of the form
15
- # {"libraries" => {"library_code1" => "library_display_1", "library_code2" => "library_display_1"}, "statuses" => {"status_code1" => "status_display_1", "status_code2" => "status_display_2"}}
16
- # The config can also include information about Primo::Source classes in the form:
17
- # "sources" => {"source_id1" => {"class_name" => "SourceKlassName", "source_config1" => "source_config_one"}}
18
- # Primo::Source classes can be used to represent a Primo source for expanding holdings
19
- # information, linking to Primo sources, and storing additional metadata based on those sources.
20
- # In order to create a source class, implementations should extend Exlibris::Primo::Holding.
21
- #
22
- # == Tips on Extending
23
- # When extending the class, a few basics guidelines should be observed.
24
- # 1. A Exlibris::Primo::Holding is initialized from random Hash of parameters.
25
- # Instance variables are created from these parameters for use in the class.
26
- #
27
- # 2. A Exlibris::Primo::Holding can also be initialized from an input
28
- # Exlibris::Primo::Holding by specifying the reserved
29
- # parameter name :holding, i.e. :holding => input_holding.
30
- # If the input holding has instance variables that are also specified in
31
- # the random Hash, the value in the Hash takes precedence.
3
+
32
4
  #
33
- # 3. The following methods are available for overriding:
34
- # expand - expand holdings information based on data source. default: [self]
35
- # dedup? - does this data source contain duplicate holdings that need to be deduped? default: false
5
+ # Primo Holding.
36
6
  #
37
- # 4. Additional source data should be saved in the @source_data instance variable.
38
- # @source_data is a hash that can contain any number of string elements,
39
- # perfect for storing local source information.
7
+ # Object representing a holding in Primo.
8
+ #
9
+ # Primo holdings can be extended to create Primo source holdings.
10
+ # create a local class representing the source in the
11
+ # module Exlibris::Primo::Source which extends Exlibris::Primo::Holding.
12
+ # Two methods are then available for overriding:
13
+ # :expand - expand holdings based on information from the source
14
+ # default: [self]
15
+ # :dedup? - if this data source contain duplicate holdings that need to be deduped, set to true
16
+ # default: false
40
17
  #
41
- # == Examples
42
- # Example of Primo source implementations are:
18
+ # ==Examples
19
+ # An examples of a customized source is:
43
20
  # * Exlibris::Primo::Source::Aleph
44
21
  class Holding
45
- @base_attributes = [ :record_id, :title, :author, :source_id, :original_source_id,
46
- :source_record_id, :availlibrary, :institution_code, :institution, :library_code,
47
- :library, :status_code, :status, :id_one, :id_two, :origin, :display_type, :coverage,
48
- :notes, :url, :request_url, :source_data ]
49
- # Make sure attribute you're aliasing in in base_attributes
50
- @attribute_aliases = { :collection => :id_one, :call_number => :id_two }
51
- @required_parameters = [ :base_url, :record_id, :source_id,
52
- :original_source_id, :source_record_id, :availlibrary,
53
- :institution_code, :library_code, :id_one, :id_two, :status_code ]
54
- @parameter_default_values = { :vid => "DEFAULT", :config => {},
55
- :max_holdings => 10, :coverage => [], :source_data => {} }
56
- @decode_variables = {
57
- :institution => {},
58
- :library => { :address => "libraries" },
59
- :status => { :address => "statuses" }
60
- }
61
- class << self; attr_reader :base_attributes, :attribute_aliases, :required_parameters, :parameter_default_values, :decode_variables end
22
+ include Config::Attributes
23
+ include WriteAttributes
24
+
25
+ # Default values for the class.
26
+ def self.defaults
27
+ @defaults ||= { :coverage => [], :source_data => {} }
28
+ end
29
+
30
+ attr_accessor :availlibrary, :record_id, :original_id,
31
+ :title, :author, :display_type, :source_id, :original_source_id,
32
+ :source_record_id, :ils_api_id, :institution_code,
33
+ :library_code, :availability_status_code,
34
+ :collection, :call_number, :coverage, :notes,
35
+ :subfields, :source_class, :source_data
36
+
37
+ alias :status_code :availability_status_code
62
38
 
63
- def initialize(parameters={})
64
- # Set attr_readers
65
- base_attributes = (self.class.base_attributes.nil?) ?
66
- Exlibris::Primo::Holding.base_attributes : self.class.base_attributes
67
- base_attributes.each { |attribute|
68
- self.class.send(:attr_reader, attribute)
69
- }
70
- # Defensive copy the holding parameter.
71
- holding = parameters[:holding].clone unless parameters[:holding].nil?
72
- raise "Initialization error in #{self.class}. Unexpected holding parameter: #{holding.class}." unless holding.kind_of? Holding or holding.nil?
73
- # Copy the defensive copy of holding to self.
74
- holding.instance_variables.each { |name|
75
- instance_variable_set((name).to_sym, holding.instance_variable_get(name))
76
- } if holding.kind_of? Holding
77
- # Add required instance variables, raising an exception if they're missing
78
- # Params passed in overwrite instance variables copied from the holding
79
- required_parameters = (self.class.required_parameters.nil?) ?
80
- Exlibris::Primo::Holding.required_parameters : self.class.required_parameters
81
- required_parameters.each do |param|
82
- instance_variable_set(
83
- "@#{param}".to_sym,
84
- parameters.delete(param) {
85
- instance_variable_get("@#{param}") if instance_variable_defined?("@#{param}") }
86
- )
87
- raise_required_parameter_error param unless instance_variable_defined?("@#{param}")
39
+ # Initialize with a set of attributes and/or another :holding.
40
+ def initialize(attributes={})
41
+ # Get holding
42
+ holding = attributes.delete(:holding)
43
+ # Instantiate new holding from input holding
44
+ # if it exists.
45
+ unless holding.nil?
46
+ super holding.to_h.merge(attributes)
47
+ else
48
+ super self.class.defaults.merge(attributes)
88
49
  end
89
- # Set additional instance variables from passed parameters
90
- # Params passed in overwrite instance variables copied from the holding
91
- parameters.each { |param, value|
92
- instance_variable_set("@#{param}".to_sym, value)
93
- }
94
- # If appropriate, add defaults to non-required elements
95
- parameter_default_values = (self.class.parameter_default_values.nil?) ?
96
- Exlibris::Primo::Holding.parameter_default_values : self.class.parameter_default_values
97
- parameter_default_values.each { |param, default|
98
- instance_variable_set("@#{param}".to_sym, default) unless instance_variable_defined?("@#{param}")
99
- }
100
- # Set decoded fields
101
- decode_variables = (self.class.decode_variables.nil?) ?
102
- Exlibris::Primo::Holding.decode_variables : self.class.decode_variables
103
- decode_variables.each { |var, decode_params|
104
- decode var, decode_params, true
105
- }
106
- # Deep link URL to record
107
- @url = primo_url if @url.nil?
108
- # Set source parameters
109
- @source_config = @config["sources"][source_id] unless @config["sources"].nil?
110
- @source_class = @source_config["class_name"] unless @source_config.nil?
111
- @source_url = @source_config["base_url"] unless @source_config.nil?
112
- @source_type = @source_config["type"] unless @source_config.nil?
113
- @source_data = {
114
- :source_class => @source_class,
115
- :source_url => @source_url,
116
- :source_type => @source_type
117
- }
118
- # Set aliases for convenience
119
- attribute_aliases = (self.class.attribute_aliases.nil?) ?
120
- Exlibris::Primo::Holding.attribute_aliases : self.class.attribute_aliases
121
- attribute_aliases.each { |alias_name, method_name|
122
- begin
123
- self.class.send(:alias_method, alias_name.to_sym, method_name.to_sym)
124
- rescue NameError => ne
125
- raise NameError, "Error in #{self}. Make sure method, #{method_name}, is defined. You may need to add it to #{self} @base_attributes.\nRoot exception: #{ne.message}"
126
- end
127
- }
128
50
  end
129
-
51
+
52
+ # Get the source config from the Primo config, based on source_id, if not already set.
53
+ def source_config
54
+ @source_config ||= sources[source_id]
55
+ end
56
+
57
+ # Get the class name from the Primo source config, if not already set.
58
+ def source_class
59
+ @source_class ||= source_config["class_name"] unless source_config.nil?
60
+ end
61
+
62
+ # Get the institution from the Primo config based on institution code, if not already set.
63
+ def institution
64
+ @institution ||= (institutions[institution_code] || institution_code)
65
+ end
66
+
67
+ # Get the library from the Primo config based on library code, if not already set.
68
+ def library
69
+ @library ||= (libraries[library_code] || library_code)
70
+ end
71
+
72
+ # Get the availability status from the Primo config based on availability status code, if not already set.
73
+ def availability_status
74
+ @availability_status ||= (availability_statuses[availability_status_code] || availability_status_code)
75
+ end
76
+ alias :availability :availability_status
77
+ alias :status :availability_status
78
+
130
79
  # Returns an array of self.
131
- # Should be overridden by source subclasses to map multiple holdings
132
- # to one availlibrary.
80
+ # Should be overridden by source subclasses if appropriate.
133
81
  def expand
134
82
  return [self]
135
83
  end
@@ -139,42 +87,23 @@ module Exlibris
139
87
  def dedup?
140
88
  return false
141
89
  end
142
-
90
+
143
91
  # Return this holding as a new holdings subclass instance based on source
144
92
  def to_source
145
- return self if @source_class.nil?
93
+ return self if source_class.nil?
146
94
  # Get source class in Primo::Source module
147
- return Exlibris::Primo::Source.const_get(@source_class).new(:holding => self)
148
- end
149
-
150
- # Convenience method for making base attributes accessible via Hash-like syntax.
151
- def [](key)
152
- raise "Error in #{self.class}. #{key} doesn't exist or is restricted." unless self.class.base_attributes.include?(key)
153
- method(key).call
95
+ return Exlibris::Primo::Source.const_get(source_class).new(:holding => self)
154
96
  end
155
97
 
156
- protected
157
- # Decode based on the pased in config
158
- def decode(var, decode_params={}, refresh=false)
159
- return instance_variable_get("@#{var}") unless (not instance_variable_defined?("@#{var}")) or refresh
160
- code_sym = (decode_params[:code].nil?) ? "#{var}_code".to_sym : decode_params[:code]
161
- code = instance_variable_get("@#{code_sym}")
162
- config_sym = (decode_params[:config].nil?) ? :config : decode_params[:config]
163
- config = instance_variable_get("@#{config_sym}")
164
- address = (decode_params[:address].nil?) ? "#{var}s" : decode_params[:address]
165
- instance_variable_set("@#{var}",
166
- (config[address].nil? or config[address][code].nil?) ?
167
- code : config[address][code]) unless code.nil?
168
- end
169
-
170
- # Returns Primo deep link URL to record
171
- def primo_url
172
- "#{@base_url}/primo_library/libweb/action/dlDisplay.do?docId=#{@record_id}&institution=#{@institution_code}&vid=#{@vid}"
173
- end
174
-
175
- private
176
- def raise_required_parameter_error(parameter)
177
- raise "Initialization error in #{self.class}. Missing required parameter: #{parameter}."
98
+ # Return the attribute accessible instance variables as a hash.
99
+ def to_h
100
+ { :availlibrary => availlibrary, :record_id => record_id, :original_id => original_id,
101
+ :title => title, :author => author, :display_type => display_type, :source_id => source_id,
102
+ :original_source_id => original_source_id, :source_record_id => source_record_id,
103
+ :ils_api_id => ils_api_id, :institution_code => institution_code, :library_code => library_code,
104
+ :availability_status_code => availability_status_code, :collection => collection,
105
+ :call_number => call_number, :coverage => coverage, :notes => notes, :subfields => subfields,
106
+ :source_id => source_id, :source_class => source_class, :source_data => source_data }
178
107
  end
179
108
  end
180
109
  end