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
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