exlibris-primo 0.1.5 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012 YOURNAME
1
+ Copyright 2012 Scot Dalton
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Exlibris::Primo
2
+ [![Build Status](https://secure.travis-ci.org/scotdalton/exlibris-primo.png)](https://secure.travis-ci.org/scotdalton/exlibris-primo)
3
+ [![Dependency Status](https://gemnasium.com/scotdalton/exlibris-primo.png)](https://gemnasium.com/scotdalton/exlibris-primo)
4
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/scotdalton/exlibris-primo)
5
+
6
+ Exlibris::Primo offers a set of classes for interacting with the ExLibris Primo APIs.
7
+
8
+ ## Exlibris::Primo::Search
9
+ The Exlibris::Primo::Search class performs a search against Primo for given parameters
10
+ and exposes the set of holdings, fulltext links, table of contents links, and related links for each record retrieved.
11
+
12
+ ### Example of Exlibris::Primo::Search in action
13
+ Search can search by a query
14
+
15
+ search = Exlibris::Primo::Search.new(:base_url => "http://primo.institution.edu",
16
+ :institution => "INSTITUTION", :page_size => "20")
17
+ search.add_query_term "0143039008", "isbn", "exact"
18
+ count = search.size #=> 20+ (assuming there are 20+ records with this isbn)
19
+ facets = search.facets #=> Array of Primo facets
20
+ records = search.records #=> Array of Primo records
21
+ records.size #=> 20 (assuming there are 20+ records with this isbn)
22
+ records.each do |record_id, record|
23
+ holdings = record.holdings #=> Array of Primo holdings
24
+ fulltexts = record.fulltexts #=> Array of Primo full texts
25
+ table_of_contents = record.table_of_contents #=> Array of Primo tables of contents
26
+ related_links = record.related_links #=> Array of Primo related links
27
+ end
28
+
29
+ Or by a given record id
30
+
31
+ search = Exlibris::Primo::Search.new(:base_url => "http://primo.institution.edu",
32
+ :institution => "INSTITUTION")
33
+ search.record_id! "aleph0123456789"
34
+ count = search.size #=> 1
35
+ records = search.records #=> Array of Primo records
36
+ records.size #=> 1
37
+ record = records.first #=> Primo record
38
+ holdings = record.holdings #=> Array of Primo holdings
39
+ fulltexts = record.fulltexts #=> Array of Primo full texts
40
+ table_of_contents = record.table_of_contents #=> Array of Primo tables of contents
41
+ related_links = record.related_links #=> Array of Primo related links
42
+
43
+ Search has some methods for setting search params
44
+
45
+ search = Exlibris::Primo::Search.new(:base_url => "http://primo.institution.edu",
46
+ :institution => "INSTITUTION")
47
+ search.isbn_is "0143039008" #=> Equivalent to search.add_query_term "0143039008", "isbn", "exact"
48
+ search.title_begins_with "Travels" #=> Equivalent to search.add_query_term "Travels", "title", "begins_with"
49
+ search.creator_contains "Greene" #=> Equivalent to search.add_query_term "Greene", "creator", "contains"
50
+
51
+ Search can take a record id the initial hash
52
+
53
+ search = Exlibris::Primo::Search.new(:base_url => "http://primo.institution.edu",
54
+ :institution => "INSTITUTION", :record_id => "aleph0123456789")
55
+
56
+ Search can also be chained using the ! version of the attribute writer
57
+
58
+ search = Exlibris::Primo::Search.new.base_url!("http://primo.institution.edu").
59
+ institution!("INSTITUTION").record_id!("aleph0123456789")
60
+
61
+ Or
62
+
63
+ search = Exlibris::Primo::Search.new.base_url!("http://primo.institution.edu").
64
+ institution!("INSTITUTION").title_begins_with("Travels").
65
+ creator_contains("Greene").genre_is("Book")
66
+
67
+ ## Exlibris::Primo::Config
68
+ Exlibris::Primo::Config allows you to specify global configuration parameter for Exlibris::Primo
69
+
70
+ Exlibris::Primo.configure do |config|
71
+ config.base_url = "http://primo.institution.edu"
72
+ config.institution = "INSTITUTION"
73
+ config.libraries = { "LIB_CODE1" => "Library Decoded 1", "LIB_CODE2" => "Library Decoded 2",
74
+ "LIB_CODE3" => "Library Decoded 3" }
75
+ end
76
+
77
+ Exlibris::Primo::Config can also read in from a YAML file that specifies the various config elements
78
+
79
+ Exlibris::Primo.configure do |config|
80
+ config.load_yaml "./config/primo.yml"
81
+ end
82
+
83
+ ## Exlibris::Primo::EShelf
84
+ The Exlibris::Primo::EShelf class provides methods for reading a given user's Primo eshelf
85
+ and eshelf structure as well as adding and removing records.
86
+
87
+ ## Example of Exlibris::Primo::EShelf in action
88
+ eshelf = Exlibris::Primo::EShelf.new(:user_id => "USER_ID",
89
+ :base_url => "http://primo.institution.edu", :insitution => "INSTITUTION")
90
+ records = eshelf.records
91
+ size = eshelf.size
92
+ basket_id = eshelf.basket_id
93
+ eshelf.add_records(["PrimoRecordId","PrimoRecordId2"], basket_id)
94
+
95
+ ## Exlibris::Primo::Reviews
96
+ The Exlibris::Primo::Reviews class provides methods for reading a given user's Primo reviews
97
+ features.
98
+
99
+ ## Example of Exlibris::Primo::Reviews in action
100
+ reviews = Exlibris::Primo::Reviews.new(:record_id => "aleph0123456789", :user_id => "USER_ID",
101
+ :base_url => "http://primo.institution.edu", :insitution => "INSTITUTION")
102
+ user_record_reviews = reviews.reviews #=> Array of Primo reviews
103
+
104
+ ## Exlibris::Primo::Tags
105
+ The Exlibris::Primo::Tags class provides methods for reading a given user's Primo tags
106
+ features.
107
+
108
+ ## Example of Exlibris::Primo::Tags in action
109
+ tags = Exlibris::Primo::Tags.new(:record_id => "aleph0123456789", :user_id => "USER_ID",
110
+ :base_url => "http://primo.institution.edu", :insitution => "INSTITUTION")
111
+ user_record_tags = tags.tags #=> Array of Primo tags
data/Rakefile CHANGED
@@ -27,7 +27,8 @@ require 'rake/testtask'
27
27
  Rake::TestTask.new(:test) do |t|
28
28
  t.libs << 'lib'
29
29
  t.libs << 'test'
30
- t.pattern = 'test/**/*_test.rb'
30
+ t.test_files = FileList['test/*_test.rb',
31
+ 'test/**/*_test.rb', 'test/**/**/*_test.rb']
31
32
  t.verbose = false
32
33
  end
33
34
 
@@ -1,14 +1,4 @@
1
- PRIMO_PATH = File.dirname(__FILE__) + "/exlibris/primo/"
2
- [
3
- 'record',
4
- 'eshelf',
5
- 'web_service',
6
- 'holding',
7
- 'related_link',
8
- 'rsrc',
9
- 'toc',
10
- 'searcher',
11
- 'source/aleph'
12
- ].each do |library|
13
- require PRIMO_PATH + library
14
- end
1
+ # Leverage ActiveSupport core extensions
2
+ require 'active_support/core_ext'
3
+ require "require_all"
4
+ require_all "#{File.dirname(__FILE__)}/exlibris/"
@@ -0,0 +1,13 @@
1
+ module Exlibris
2
+ module Primo
3
+ class << self
4
+ def configure
5
+ yield config
6
+ end
7
+
8
+ def config
9
+ @config ||= Config
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ module Exlibris
2
+ module Primo
3
+ #
4
+ # If a class is abstract, it can't be instantiated.
5
+ #
6
+ module Abstract
7
+ def self.included(klass)
8
+ klass.class_eval do
9
+ extend ClassAttributes
10
+ end
11
+ end
12
+
13
+ module ClassAttributes
14
+ def abstract
15
+ @abstract ||= false
16
+ end
17
+ alias :abstract? :abstract
18
+
19
+ attr_writer :abstract
20
+ protected :abstract=
21
+ end
22
+
23
+ def initialize *args
24
+ raise NotImplementedError.new("Cannot instantiate #{self.class.name}. It is abstract") if self.class.abstract?
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ # ChainGang Modules
2
+ ChainGang modules contain methods that are "chainable", i.e. they return `self`.
3
+
4
+ ## ! vs =
5
+ ChainGang methods that take arguments are defined with a trailing `!` and aliased
6
+ with a trailing `=`. At the time of writing, the `=` version can't be chained because
7
+ the Ruby virtual machine seems to compile the two methods slightly differently and the
8
+ `=` version returns the arguments rather than `self`. The `=` version is intended to
9
+ be used as an `attr_writer`.
@@ -0,0 +1,121 @@
1
+ module Exlibris
2
+ module Primo
3
+ module ChainGang
4
+ # = Primo ChainGang Base Attributes
5
+ # These base attributes are included in
6
+ # Search, Eshelf, Tags and Reviews and allow
7
+ # for chaining methods together.
8
+ #
9
+ # == Examples
10
+ #
11
+ # search = Search.new.base_url!("http://primo.library.edu").
12
+ # institution!("PRIMO").ip!("127.0.0.1")
13
+ # #=> #<Exlibris::Primo::Search @base_url="http://primo.library.edu",
14
+ # @institution="PRIMO", @request_attributes={:base_url => "http://primo.library.edu",
15
+ # :institution => "PRIMO", :ip => "127.0.0.1"}>
16
+ #
17
+ # eshelf = Eshelf.new.base_url!("http://primo.library.edu").
18
+ # institution!("PRIMO").ip!("127.0.0.1")
19
+ # #=> #<Exlibris::Primo::Eshelf @base_url="http://primo.library.edu",
20
+ # @institution="PRIMO", @request_attributes={:base_url => "http://primo.library.edu",
21
+ # :institution => "PRIMO", :ip => "127.0.0.1"}>
22
+ #
23
+ # reviews = Reviews.new.base_url!("http://primo.library.edu").
24
+ # institution!("PRIMO").ip!("127.0.0.1")
25
+ # #=> #<Exlibris::Primo::Reviews @base_url="http://primo.library.edu",
26
+ # @institution="PRIMO", @request_attributes={:base_url => "http://primo.library.edu",
27
+ # :institution => "PRIMO", :ip => "127.0.0.1"}>
28
+ #
29
+ # tags = Tags.new.base_url!("http://primo.library.edu").
30
+ # institution!("PRIMO").ip!("127.0.0.1")
31
+ # #=> #<Exlibris::Primo::Tags @base_url="http://primo.library.edu",
32
+ # @institution="PRIMO", @request_attributes={:base_url => "http://primo.library.edu",
33
+ # :institution => "PRIMO", :ip => "127.0.0.1"}>
34
+ #
35
+
36
+ module Base
37
+ #
38
+ # Set base URL for the Primo request.
39
+ #
40
+ def base_url!(base_url)
41
+ @base_url = base_url
42
+ request_attributes[:base_url] = "#{base_url}"
43
+ self
44
+ end
45
+ alias :base_url= :base_url!
46
+
47
+ #
48
+ # Set institution for the Primo request.
49
+ #
50
+ def institution!(institution)
51
+ @institution = institution
52
+ request_attributes[:institution] = "#{institution}"
53
+ self
54
+ end
55
+ alias :institution= :institution!
56
+
57
+ #
58
+ # Set client IP for the Primo request.
59
+ #
60
+ def ip!(ip)
61
+ request_attributes[:ip] = "#{ip}"
62
+ self
63
+ end
64
+ alias :ip= :ip!
65
+ alias :client_ip! :ip!
66
+ alias :client_ip= :ip!
67
+
68
+ #
69
+ # Set the group for the Primo request.
70
+ #
71
+ def group!(group)
72
+ request_attributes[:group] = "#{group}"
73
+ self
74
+ end
75
+ alias :group= :group!
76
+
77
+ #
78
+ # Set the PDS handle for the Primo request.
79
+ #
80
+ def pds_handle!(pds_handle)
81
+ request_attributes[:pds_handle] = "#{pds_handle}"
82
+ self
83
+ end
84
+ alias :pds_handle= :pds_handle!
85
+
86
+ #
87
+ # Specifies that the Primo request is coming from on campus.
88
+ #
89
+ def on_campus
90
+ request_attributes[:on_campus] = "true"
91
+ self
92
+ end
93
+
94
+ #
95
+ # Specifies that the Primo request is coming from off campus.
96
+ #
97
+ def off_campus
98
+ request_attributes[:on_campus] = "false"
99
+ self
100
+ end
101
+
102
+ #
103
+ # Specifies that the Primo request user is logged in.
104
+ #
105
+ def logged_in
106
+ request_attributes[:is_logged_in] = "true"
107
+ self
108
+ end
109
+
110
+ #
111
+ # Specifies that the Primo request user is logged out.
112
+ #
113
+ def logged_out
114
+ request_attributes[:is_logged_in] = "false"
115
+ self
116
+ end
117
+ alias :logged_off :logged_out
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,18 @@
1
+ module Exlibris
2
+ module Primo
3
+ module ChainGang
4
+ module Record
5
+ attr_reader :record_id
6
+
7
+ #
8
+ # Set the record_id
9
+ #
10
+ def record_id!(record_id)
11
+ @record_id = record_id
12
+ self
13
+ end
14
+ alias :record_id= :record_id!
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,319 @@
1
+ module Exlibris
2
+ module Primo
3
+ module ChainGang
4
+ # = Primo ChainGang Search
5
+ # These search attributes are included in
6
+ # Exlibris::Primo::Search and allow for chaining methods together.
7
+ #
8
+ # == Examples
9
+ #
10
+ # Search.new.title("Travels", "title", "contains").
11
+ # and.add_query_term("Greene", "creator", "contains").search
12
+ #
13
+ module Search
14
+ def self.included(klass)
15
+ klass.class_eval do
16
+ extend ClassAttributes
17
+ end
18
+ end
19
+
20
+ module ClassAttributes
21
+ def indexes
22
+ @indexes ||= [:any, :stitle, :title, :creator, :genre, :author, :isbn]
23
+ end
24
+
25
+ def indexes_map
26
+ @indexes_map ||= {:author => :creator}
27
+ end
28
+
29
+ def precisions
30
+ @precisions ||= [:is, :begins_with, :contains, :starts_with]
31
+ end
32
+
33
+ def precisions_map
34
+ @precisions_map ||= {:is => :exact, :starts_with => :begins_with}
35
+ end
36
+ end
37
+
38
+ #
39
+ # Set the boolean operator for the search
40
+ # to "AND".
41
+ # Suitable for chaining, e.g.
42
+ #
43
+ # Search.new.add_query_term("Travels", "title", "contains").
44
+ # and.add_query_term("Greene", "creator", "contains").search
45
+ #
46
+ def and
47
+ search_request.boolean_operator = "AND"
48
+ self
49
+ end
50
+
51
+ #
52
+ # Set the boolean operator for the search
53
+ # to "OR".
54
+ # Suitable for chaining, e.g.
55
+ #
56
+ # Search.new.add_query_term("Travels", "title", "contains").
57
+ # or.add_query_term("Greene", "creator", "contains").search
58
+ #
59
+ def or
60
+ search_request.boolean_operator = "OR"
61
+ self
62
+ end
63
+
64
+ #
65
+ # Adds a query term to the search.
66
+ # Suitable for chaining, e.g.
67
+ #
68
+ # Search.new.add_query_term("Travels", "title", "begins_with").
69
+ # add_query_term("Greene", "creator", "contains").search
70
+ #
71
+ def add_query_term(*args)
72
+ search_request.add_query_term(*args)
73
+ self
74
+ end
75
+
76
+ #
77
+ # Dynamically sets chainable accessor for indexes and
78
+ # precisions
79
+ # Suitable for chaining, e.g.
80
+ #
81
+ # Search.new.title_begins_with("Travels").
82
+ # creator_contains("Greene").search
83
+ #
84
+ def method_missing(method, *args, &block)
85
+ if matches? method
86
+ self.class.send(:define_method, method) { |value|
87
+ index = indexize(method)
88
+ index = (indexes_map[index] || index)
89
+ precision = precisionize(method)
90
+ precision = (precisions_map[precision] || precision)
91
+ add_query_term value, index, precision
92
+ }
93
+ send method, *args, &block
94
+ else
95
+ super
96
+ end
97
+ end
98
+
99
+ # Returns true if the method can be evaluated to a method name
100
+ # and parameter.
101
+ def respond_to? method, include_private=false
102
+ if(matches? method)
103
+ return true
104
+ else
105
+ super
106
+ end
107
+ end
108
+
109
+ # Supported indexes
110
+ def indexes
111
+ @indexes ||= self.class.indexes
112
+ end
113
+ private :indexes
114
+
115
+ # Alternative indexes mapping
116
+ def indexes_map
117
+ @indexes_map ||= self.class.indexes_map
118
+ end
119
+ private :indexes_map
120
+
121
+ # Supported precisions
122
+ def precisions
123
+ @precisions ||= self.class.precisions
124
+ end
125
+ private :precisions
126
+
127
+ # Alternative precisions mapping
128
+ def precisions_map
129
+ @precisions_map ||= self.class.precisions_map
130
+ end
131
+ private :precisions_map
132
+
133
+ # Get the index from the method.
134
+ def indexize(method)
135
+ parse_method(method).first.to_sym
136
+ end
137
+ private :indexize
138
+
139
+ # Get the precision from the method.
140
+ def precisionize(method)
141
+ parse_method(method).last.to_sym
142
+ end
143
+ private :precisionize
144
+
145
+ # Parse the method on the first occurence of delimiter.
146
+ def parse_method(method, delimiter="_")
147
+ method.to_s.split(delimiter, 2)
148
+ end
149
+ private :parse_method
150
+
151
+ # Does this match our indexes and precisions.
152
+ def matches? method
153
+ indexes.include? indexize(method) and precisions.include? precisionize(method)
154
+ end
155
+ private :matches?
156
+
157
+ #
158
+ # Set start index for the search.
159
+ # Suitable for chaining, e.g.
160
+ #
161
+ # Search.new.start_index!(11).
162
+ # add_query_term("Digital divide", "any", "contains").
163
+ # search.records.first => 11th record from the search
164
+ #
165
+ def start_index!(start_index)
166
+ request_attributes[:start_index] = "#{start_index}"
167
+ self
168
+ end
169
+ alias :start_index= :start_index!
170
+
171
+ #
172
+ # Set page size for the search.
173
+ # Suitable for chaining, e.g.
174
+ #
175
+ # Search.new.page_size!(10).
176
+ # add_query_term("Digital divide", "any", "contains").
177
+ # search.records.size => 10
178
+ #
179
+ def page_size!(page_size)
180
+ request_attributes[:bulk_size] = "#{page_size}"
181
+ self
182
+ end
183
+ alias :page_size= :page_size!
184
+
185
+ #
186
+ # Enable "Did U Mean" functionality for the search.
187
+ # Suitable for chaining, e.g.
188
+ #
189
+ # Search.new.enable_did_u_mean.add_query_term("Digital dvide", "any", "contains").
190
+ # search.did_u_mean => "digital video"
191
+ #
192
+ def enable_did_u_mean
193
+ request_attributes[:did_u_mean_enabled] = "true"
194
+ self
195
+ end
196
+
197
+ #
198
+ # Disable "Did U Mean" functionality for the search.
199
+ # Suitable for chaining, e.g.
200
+ #
201
+ # Search.new.disable_did_u_mean.add_query_term("Digital dvide", "any", "contains").
202
+ # search.did_u_mean => nil
203
+ #
204
+ def disable_did_u_mean
205
+ request_attributes[:did_u_mean_enabled] = "false"
206
+ self
207
+ end
208
+
209
+ #
210
+ # Enable highlighting functionality for the search.
211
+ # Suitable for chaining, e.g.
212
+ #
213
+ # Search.new.enable_highlighting.add_query_term("Digital dvide", "any", "contains").
214
+ # search.did_u_mean => "digital d vide"
215
+ #
216
+ def enable_highlighting
217
+ request_attributes[:highlighting_enabled] = "true"
218
+ self
219
+ end
220
+
221
+ #
222
+ # Disable highlighting functionality for the search.
223
+ # Suitable for chaining, e.g.
224
+ #
225
+ # Search.new.disable_highlighting.add_query_term("Digital dvide", "any", "contains").
226
+ # search.did_u_mean => nil
227
+ #
228
+ def disable_highlighting
229
+ request_attributes[:highlighting_enabled] = "false"
230
+ self
231
+ end
232
+
233
+ #
234
+ # Adds a language to the search.
235
+ # Suitable for chaining, e.g.
236
+ #
237
+ # Search.new.add_language("eng").
238
+ # add_query_term("Greene", "creator", "contains").search
239
+ #
240
+ def add_language(*args)
241
+ search_request.add_language(*args)
242
+ self
243
+ end
244
+
245
+ #
246
+ # Adds a sort by to the search.
247
+ # Currently the Primo API only supports
248
+ # one sort by value. Add multiple
249
+ # sort bys at your own peril.
250
+ # Suitable for chaining, e.g.
251
+ #
252
+ # Search.new.add_sort_by("stitle").
253
+ # add_query_term("Greene", "creator", "contains").search
254
+ #
255
+ def add_sort_by(*args)
256
+ search_request.add_sort_by(*args)
257
+ self
258
+ end
259
+
260
+ #
261
+ # Adds a display field (for highlighting) to the search.
262
+ # Suitable for chaining, e.g.
263
+ #
264
+ # Search.new.add_display_field("creator").
265
+ # add_query_term("Greene", "creator", "contains").search
266
+ #
267
+ def add_display_field(*args)
268
+ search_request.add_display_field(*args)
269
+ self
270
+ end
271
+
272
+ #
273
+ # Adds a location to the search.
274
+ # Suitable for chaining, e.g.
275
+ #
276
+ # Search.new.add_location("local", "scope:(VOLCANO)").
277
+ # add_query_term("Greene", "creator", "contains").search
278
+ #
279
+ def add_location(*args)
280
+ search_request.add_location(*args)
281
+ self
282
+ end
283
+
284
+ #
285
+ # Adds a local location to the search.
286
+ # Suitable for chaining, e.g.
287
+ #
288
+ # Search.new.add_local_location("scope:(VOLCANO)").
289
+ # add_query_term("Greene", "creator", "contains").search
290
+ #
291
+ def add_local_location(location)
292
+ add_location("local", location)
293
+ end
294
+
295
+ #
296
+ # Adds an adaptor location to the search.
297
+ # Suitable for chaining, e.g.
298
+ #
299
+ # Search.new.add_adaptor_location("primo_central_multiple_fe").
300
+ # add_query_term("Greene", "creator", "contains").search
301
+ #
302
+ def add_adaptor_location(location)
303
+ add_location("adaptor", location)
304
+ end
305
+
306
+ #
307
+ # Adds a remote location to the search.
308
+ # Suitable for chaining, e.g.
309
+ #
310
+ # Search.new.add_remote_location("quickset_name").
311
+ # add_query_term("Greene", "creator", "contains").search
312
+ #
313
+ def add_remote_location(location)
314
+ add_location("remote", location)
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end