alma 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a61f0bfe79181cdb4d99e0eca51ba16b1be6550f
4
- data.tar.gz: 8f024c368175b3a8ac0fe2e6eb836f436516a566
3
+ metadata.gz: 3bcedc3a4e5136aa43268412c062c91dc2d905dd
4
+ data.tar.gz: 37f3892ff4a0fc27e8c6a79a540ea52f0f5199d4
5
5
  SHA512:
6
- metadata.gz: 58b8bcfbe9b5c4f6ccd688df845bfb86e3fe8115199b06862c03b6faeaf31e08e4f9a33cca5209c082fa69f8416461dc9c45bef34a9c57179a48d4f29f7b2397
7
- data.tar.gz: 60e8ea0221d2dce2001e53afd41d0f046cb822e56c74f2e07ecffcacc7fa9e94ce9c4730572f79cd0463d12c09506e64a4af9b52ed871cefa2be625a650e6cbb
6
+ metadata.gz: 120bef80c621c53709475f2c54dd2a7b3379fe307ac0f1227adb1f0a8627e064ea19f87260432a5a45ad65d342623fbc314e5079aea7fae930a0ac719bbf5f7c
7
+ data.tar.gz: 2e190810b76aa0b0041b021364d5879cff6a6122ee9f0c17be212cc69bb1d1c2af63059c801752754f6b711ec4e948777d2a1285ef428b1838a7ce1c6fc5eb80
@@ -1 +1 @@
1
- ruby-2.3.3
1
+ ruby-2.4.1
data/README.md CHANGED
@@ -36,27 +36,20 @@ end
36
36
  Now you can access those configuration attributes with `Alma.configuration.apikey`
37
37
 
38
38
  ### Making Requests
39
-
40
- #### Get a list of Users
41
- ```ruby
42
- users = Alma::User.find
43
-
44
- users.total count
45
- > 402
46
-
47
- users.list.first.id
48
- > 123456789
49
- ```
50
39
 
51
40
  #### Get a Single user
52
41
  ```ruby
53
- user = Alma::User.find({:user_id => 123456789})
42
+ user = Alma::User.find(123456789)
54
43
 
55
44
  user.first_name
56
45
  > Chad
57
46
 
58
47
  user.email
59
48
  > chad.nelson@fictional.edu
49
+
50
+ user.keys
51
+ >{first_name: "Chad",
52
+ ...}
60
53
  ```
61
54
 
62
55
  #### Get details on a users fines
@@ -69,18 +62,18 @@ Now you can access those configuration attributes with `Alma.configuration.apike
69
62
  fines.total_record_count
70
63
  > "2"
71
64
 
72
- fines.list
65
+ fines
73
66
  > [#<Alma::AlmaRecord:0x000000038b7b50
74
67
  ...>,
75
68
  #<Alma::AlmaRecord:0x000000038b7b28
76
69
  ...>]
77
70
 
78
- fines.list.first.title
71
+ fines.first.title
79
72
  > "Practical Object Oriented Design with Ruby"
80
73
 
81
74
  ```
82
75
 
83
- Each fine object reflects the available fields in the returned XML,[as documented on the Ex Libris Api docs](https://developers.exlibrisgroup.com/alma/apis/xsd/rest_fees.xsd?tags=GET)
76
+ Each fine object reflects the available fields in the returned JSON,[as documented on the Ex Libris Api docs](https://developers.exlibrisgroup.com/alma/apis/xsd/rest_fees.xsd?tags=GET)
84
77
 
85
78
  #### Get details on a users loans
86
79
 
@@ -90,37 +83,23 @@ loans = user.loans
90
83
  loans.total_record_count
91
84
  > "2"
92
85
 
93
- loans.list
86
+ loans
94
87
  > [#<Alma::Loan:0x000000038c6b79
95
88
  ...>,
96
89
  #<Alma::Loan:0x000000038c6b34
97
90
  ...>]
98
91
 
99
- loans.list.first.title
92
+ loans.first.title
100
93
  > "Javascript: The Good Parts"
101
94
 
102
- loans.list.first.due_date
95
+ loans.first.due_date
103
96
  "2016-12-26z
104
97
 
105
98
  ```
106
99
  Each loan object reflects the available fields in the returned XML,[as documented on the Ex Libris Api docs](https://developers.exlibrisgroup.com/alma/apis/xsd/rest_item_loans.xsd?tags=GET)
107
100
 
108
- To renew an item you can can call the Loan objects renew method
109
-
110
- ```ruby
111
- renewal = loans.list.first.renew
112
-
113
- renewal.renewed?
114
- > True
115
-
116
- renewal.message
117
- > "Javascript: The Good Parts is now due 02-20-17"
118
-
119
- ```
120
-
121
-
122
101
 
123
- #### Get details on a users requests
102
+ #### Get details on a users requests - WIP
124
103
  ```ruby
125
104
  requests = user.requests
126
105
 
@@ -160,7 +139,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
160
139
 
161
140
  ## Contributing
162
141
 
163
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/alma. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
142
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tulibraries/alma_rb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
164
143
 
165
144
 
166
145
  ## License
@@ -22,6 +22,10 @@ Gem::Specification.new do |spec|
22
22
  spec.require_paths = ["lib"]
23
23
 
24
24
  spec.add_dependency 'ezwadl'
25
+ spec.add_dependency 'httparty'
26
+ spec.add_dependency 'xml-simple'
27
+
28
+
25
29
 
26
30
 
27
31
  spec.add_development_dependency "bundler", "~> 1.13"
@@ -15,45 +15,12 @@ require 'alma/bib_set'
15
15
  require 'alma/request_set'
16
16
  require 'alma/renewal_response'
17
17
  require 'alma/availability_response'
18
+ require 'alma/bib_items'
18
19
 
19
20
  module Alma
20
21
 
21
22
  ROOT = File.dirname __dir__
22
23
  WADL_DIR = File.join(Alma::ROOT, 'lib','alma','wadl')
23
24
 
24
- INVENTORY_TO_SUBFIELD_TO_FIELDNAME =
25
- {
26
- 'AVA' => {
27
- 'INVENTORY_TYPE' => 'physical',
28
- 'a' => 'institution',
29
- 'b' => 'library_code',
30
- 'c' => 'location',
31
- 'd' => 'call_number',
32
- 'e' => 'availability',
33
- 'f' => 'total_items',
34
- 'g' => 'non_available_items',
35
- 'j' => 'location_code',
36
- 'k' => 'call_number_type',
37
- 'p' => 'priority',
38
- 'q' => 'library',
39
- },
40
- 'AVD' => {
41
- 'INVENTORY_TYPE' => 'digital',
42
- 'a' => 'institution',
43
- 'b' => 'representations_id',
44
- 'c' => 'representation',
45
- 'd' => 'repository_name',
46
- 'e' => 'label',
47
- },
48
- 'AVE' => {
49
- 'INVENTORY_TYPE' => 'electronic',
50
- 'l' => 'library_code',
51
- 'm' => 'collection',
52
- 'n' => 'public_note',
53
- 's' => 'coverage_statement',
54
- 't' => 'interface_name',
55
- 'u' => 'link_to_service_page',
56
- }
57
- }
58
25
 
59
26
  end
@@ -1,3 +1,5 @@
1
+ require 'xmlsimple'
2
+
1
3
  module Alma
2
4
  class AvailabilityResponse
3
5
 
@@ -6,45 +8,84 @@ module Alma
6
8
 
7
9
  def initialize(response)
8
10
  @availability = parse_bibs_data(response.list)
9
-
10
11
  end
11
12
 
13
+ # Data structure for holdings information of bib records.
14
+ # A hash with mms ids as keys, with values of an array of
15
+ # one or more hashes of holdings info
12
16
  def parse_bibs_data(bibs)
13
-
14
- bibs.map do |bib|
15
- record = Hash.new
16
-
17
- record['mms_id'] = bib.id
18
- record['holdings'] = build_holdings_for(bib)
19
-
20
- record
21
- end.reduce(Hash.new) do |acc, avail|
22
- acc[avail['mms_id']] = avail.select { |k, v| k != 'mms_id' }
23
- acc
24
- end
17
+ bibs.reduce(Hash.new) { |acc, bib|
18
+ acc.merge({"#{bib.id}" => {holdings: build_holdings_for(bib)}})
19
+ }
25
20
  end
26
21
 
27
-
28
22
  def build_holdings_for(bib)
29
-
30
23
  get_inventory_fields_for(bib).map do |inventory_field|
31
- subfield_codes_to_fieldnames = Alma::INVENTORY_TO_SUBFIELD_TO_FIELDNAME[inventory_field['tag']]
32
-
33
- # make sure subfields is always an Array (which isn't the case if there's only one subfield element)
34
- subfields = [inventory_field.fetch('subfield', [])].flatten(1)
35
-
36
- holding = subfields.reduce(Hash.new) do |acc, subfield|
37
- fieldname = subfield_codes_to_fieldnames[subfield['code']]
38
- acc[fieldname] = subfield['__content__']
39
- acc
40
- end
41
- holding['inventory_type'] = subfield_codes_to_fieldnames['INVENTORY_TYPE']
42
- holding
24
+ # Use the mapping for this inventory type
25
+ subfield_codes = Alma::INVENTORY_SUBFIELD_MAPPING[inventory_field['tag']]
26
+
27
+ inventory_field.
28
+ # Get all the subfields for this inventory field
29
+ fetch('subfield', []).
30
+ # Limit to only subfields codes for which we have a mapping
31
+ select {|sf| subfield_codes.key? sf['code'] }.
32
+ # Transform the array of subfields into a hash with mapped code as key
33
+ reduce(Hash.new) { |acc, subfield|
34
+ acc.merge({"#{subfield_codes[subfield['code']]}" => subfield['content']})
35
+ }.
36
+ # Include the inventory type
37
+ merge({'inventory_type' => subfield_codes['INVENTORY_TYPE']})
43
38
  end
44
39
  end
45
40
 
46
41
  def get_inventory_fields_for(bib)
47
- bib.record.fetch('datafield', []).select { |df| Alma::INVENTORY_TO_SUBFIELD_TO_FIELDNAME.key?(df['tag']) } || []
42
+ # Return only the datafields with tags AVA, AVD, or AVE
43
+ bib.record
44
+ .fetch('datafield', [])
45
+ .select { |df| Alma::INVENTORY_SUBFIELD_MAPPING.key?(df['tag']) }
48
46
  end
49
47
  end
48
+
49
+ INVENTORY_SUBFIELD_MAPPING =
50
+ {
51
+ 'AVA' => {
52
+ 'INVENTORY_TYPE' => 'physical',
53
+ 'a' => 'institution',
54
+ 'b' => 'library_code',
55
+ 'c' => 'location',
56
+ 'd' => 'call_number',
57
+ 'e' => 'availability',
58
+ 'f' => 'total_items',
59
+ 'g' => 'non_available_items',
60
+ 'j' => 'location_code',
61
+ 'k' => 'call_number_type',
62
+ 'p' => 'priority',
63
+ 'q' => 'library',
64
+ 't' => 'holding_info',
65
+ '8' => 'holding_id',
66
+ },
67
+ 'AVD' => {
68
+ 'INVENTORY_TYPE' => 'digital',
69
+ 'a' => 'institution',
70
+ 'b' => 'representations_id',
71
+ 'c' => 'representation',
72
+ 'd' => 'repository_name',
73
+ 'e' => 'label',
74
+ },
75
+ 'AVE' => {
76
+ 'INVENTORY_TYPE' => 'electronic',
77
+ 'c' => 'collection_id',
78
+ 'e' => 'activation_status',
79
+ 'l' => 'library_code',
80
+ 'm' => 'collection',
81
+ 'n' => 'public_note',
82
+ 's' => 'coverage_statement',
83
+ 't' => 'interface_name',
84
+ 'u' => 'link_to_service_page',
85
+ '8' => 'portfolio_pid',
86
+ }
87
+ }
88
+
89
+
90
+
50
91
  end
@@ -1,46 +1,87 @@
1
1
  module Alma
2
- class Bib < AlmaRecord
3
- extend Alma::Api
2
+ class Bib
3
+ extend Forwardable
4
+
5
+ def self.find(ids, args)
6
+ get_bibs(ids, args)
7
+ end
4
8
 
5
- attr_accessor :id, :record
9
+ def self.get_bibs(ids, args={})
10
+ response = HTTParty.get(
11
+ self.bibs_base_path,
12
+ query: {mms_id: ids_from_array(ids)},
13
+ headers: headers
14
+ )
6
15
 
7
- def post_initialize
8
- @id = response['mms_id'].to_s
9
- @record = response.fetch('record', {})
16
+ if response.code == 200
17
+ Alma::BibSet.new(get_body_from(response))
18
+ else
19
+ raise StandardError, get_body_from(response)
20
+ end
10
21
  end
11
22
 
12
- class << self
13
23
 
14
- def get_availability(ids, args={})
15
- args.merge!({expand: 'p_avail,e_avail,d_avail'})
16
- bibs = get_bibs(ids, args)
24
+ def self.get_availability(ids, args={})
25
+ args.merge!({expand: 'p_avail,e_avail,d_avail'})
26
+ bibs = get_bibs(ids, args)
17
27
 
18
- return bibs if bibs.has_error?
19
- Alma::AvailabilityResponse.new(bibs)
20
- end
28
+ Alma::AvailabilityResponse.new(bibs)
29
+ end
21
30
 
22
- def find(ids, args)
23
- get_bibs(ids, args)
24
- end
25
31
 
26
- def get_bibs(ids, args={})
27
- args[:mms_id] = ids_from_array(ids)
28
- params = query_merge(args)
29
- response = resources.almaws_v1_bibs.get(params)
30
32
 
31
- Alma::BibSet.new(response)
32
- end
33
+ attr_accessor :id, :response
34
+
35
+ # The User object can respond directly to Hash like access of attributes
36
+ def_delegators :response, :[], :[]=, :has_key?, :keys, :to_json, :each
37
+
38
+ def initialize(response_body)
39
+ @response = response_body
40
+ @id = @response['mms_id'].to_s
41
+ end
42
+
43
+ # The raw MARCXML record, converted to a Hash
44
+ def record
45
+ @record ||= XmlSimple.xml_in(response['anies'].first)
46
+ end
47
+
33
48
 
34
49
  private
35
50
 
36
- def ids_from_array(ids)
37
- ids.map(&:to_s).map(&:strip).join(',')
51
+ def self.bibs_base_path
52
+ "#{self.region}/almaws/v1/bibs"
38
53
  end
39
54
 
40
- def set_wadl_filename
41
- 'bib.wadl'
55
+ def bibs_base_path
56
+ self.class.bibs_base_path
42
57
  end
43
58
 
44
- end
59
+ def self.headers
60
+ { "Authorization": "apikey #{self.apikey}",
61
+ "Accept": "application/json",
62
+ "Content-Type": "application/json" }
63
+ end
64
+
65
+
66
+ def headers
67
+ self.class.headers
68
+ end
69
+
70
+
71
+ def self.apikey
72
+ Alma.configuration.apikey
73
+ end
74
+
75
+ def self.region
76
+ Alma.configuration.region
77
+ end
78
+
79
+ def self.get_body_from(response)
80
+ JSON.parse(response.body)
81
+ end
82
+
83
+ def self.ids_from_array(ids)
84
+ ids.map(&:to_s).map(&:strip).join(',')
85
+ end
45
86
  end
46
87
  end
@@ -0,0 +1,49 @@
1
+ module Alma
2
+ class BibItems
3
+ extend Forwardable
4
+
5
+ attr_accessor :items
6
+ def_delegators :items, :[], :[]=, :has_key?, :keys, :to_json
7
+
8
+ attr_reader :raw_response
9
+ def_delegators :raw_response, :response, :request
10
+
11
+ def initialize(response)
12
+ @raw_response = response
13
+ @items = JSON.parse(response.body)
14
+ end
15
+
16
+ PERMITTED_ARGS = [
17
+ :limit, :offset, :expand, :user_id, :current_library,
18
+ :current_location, :q, :order_by, :direction
19
+ ]
20
+
21
+ def self.find(mms_id, options={})
22
+ holding_id = options.delete(:holding_id) || "ALL"
23
+ options.select! {|k,_| PERMITTED_ARGS.include? k }
24
+ url = "#{bibs_base_path}/#{mms_id}/holdings/#{holding_id}/items"
25
+ response = HTTParty.get(url, headers: headers, query: options)
26
+ new(response)
27
+ end
28
+
29
+ private
30
+
31
+ def self.region
32
+ Alma.configuration.region
33
+ end
34
+
35
+ def self.bibs_base_path
36
+ "#{region}/almaws/v1/bibs"
37
+ end
38
+
39
+ def self.headers
40
+ { "Authorization": "apikey #{apikey}",
41
+ "Accept": "application/json",
42
+ "Content-Type": "application/json" }
43
+ end
44
+
45
+ def self.apikey
46
+ Alma.configuration.apikey
47
+ end
48
+ end
49
+ end
@@ -1,21 +1,30 @@
1
1
  module Alma
2
- class BibSet < ResultSet
2
+ class BibSet
3
3
 
4
- def top_level_key
5
- 'bibs'
4
+ extend Forwardable
5
+ include Enumerable
6
+ #include Alma::Error
7
+
8
+ attr_reader :response
9
+ def_delegators :list, :each, :size
10
+ def_delegators :response, :[], :fetch
11
+
12
+ def initialize(response_body_hash)
13
+ @response = response_body_hash
6
14
  end
7
15
 
8
- def response_records_key
9
- 'bib'
16
+ def list
17
+ @list ||= response.fetch(key, []).map do |record|
18
+ Alma::Bib.new(record)
19
+ end
10
20
  end
11
21
 
12
- def single_record_class
13
- Alma::Bib
22
+ def key
23
+ 'bib'
14
24
  end
15
25
 
16
- # Doesn't seem to actually return a total record count as documented.
17
26
  def total_record_count
18
- (response_records.is_a? Array) ? size : 1
27
+ size
19
28
  end
20
29
 
21
30
  end
@@ -1,21 +1,39 @@
1
1
  module Alma
2
- class FineSet < ResultSet
2
+ class FineSet
3
+ extend Forwardable
4
+ include Enumerable
5
+ #include Alma::Error
3
6
 
4
- def top_level_key
5
- 'fees'
7
+ attr_reader :response
8
+ def_delegators :list, :each, :size
9
+ def_delegators :response, :[], :fetch
10
+
11
+ def initialize(response_body_hash)
12
+ @response = response_body_hash
6
13
  end
7
14
 
8
- def response_records_key
15
+ def key
9
16
  'fee'
10
17
  end
11
18
 
19
+ def list
20
+ fetch(key, [])
21
+ end
22
+
12
23
  def sum
13
- @response[top_level_key].fetch('total_sum', 0)
24
+ fetch('total_sum', 0)
14
25
  end
26
+ alias :total_sum :sum
15
27
 
16
28
  def currency
17
- @response[top_level_key].fetch('currency', nil)
29
+ fetch('currency', nil)
18
30
  end
19
31
 
32
+ def total_record_count
33
+ fetch('total_record_count', 0)
34
+ end
35
+ alias :total_records :total_record_count
36
+
37
+
20
38
  end
21
- end
39
+ end
@@ -1,18 +1,29 @@
1
1
  module Alma
2
- class LoanSet < ResultSet
2
+ class LoanSet
3
+ extend Forwardable
4
+ include Enumerable
5
+ #include Alma::Error
3
6
 
7
+ attr_reader :response
8
+ def_delegators :list, :each, :size
9
+ def_delegators :response, :[], :fetch
4
10
 
5
- def top_level_key
6
- 'item_loans'
11
+ def initialize(response_body_hash)
12
+ @response = response_body_hash
7
13
  end
8
14
 
9
- def response_records_key
15
+ def list
16
+ fetch(key, [])
17
+ end
18
+
19
+ def key
10
20
  'item_loan'
11
21
  end
12
22
 
13
- def single_record_class
14
- Alma::Loan
23
+ def total_record_count
24
+ fetch('total_record_count', 0)
15
25
  end
26
+ alias :total_records :total_record_count
16
27
 
17
28
  end
18
29
  end
@@ -1,20 +1,19 @@
1
1
  module Alma
2
2
  class RenewalResponse
3
3
 
4
- include Alma::Error
4
+
5
5
 
6
6
  def initialize(response)
7
7
  @response = response
8
- @success = response.fetch('item_loan', {})
9
- @renewed = error.empty?
8
+ @success = response.has_key?('loan_id')
10
9
  end
11
10
 
12
11
  def renewed?
13
- @renewed
12
+ @success
14
13
  end
15
14
 
16
15
  def due_date
17
- @success.fetch('due_date', '')
16
+ @response.fetch('dueDate', '')
18
17
  end
19
18
 
20
19
 
@@ -23,20 +22,24 @@ module Alma
23
22
  end
24
23
 
25
24
  def item_title
26
- if @success
27
- @success['title']
25
+ if renewed?
26
+ @response['title']
28
27
  else
29
28
  'This Item'
30
29
  end
31
30
  end
32
31
 
33
32
  def message
34
- if @success
33
+ if renewed?
35
34
  "#{item_title} is now due #{due_date}"
36
35
  else
37
36
  "#{item_title} could not be renewed."
38
37
  end
39
38
  end
40
39
 
40
+ def error_message
41
+ @response unless renewed?
42
+ end
43
+
41
44
  end
42
- end
45
+ end
@@ -1,14 +1,29 @@
1
1
  module Alma
2
- class RequestSet < ResultSet
2
+ class RequestSet
3
+ extend Forwardable
4
+ include Enumerable
5
+ #include Alma::Error
3
6
 
7
+ attr_reader :response
8
+ def_delegators :list, :each, :size
9
+ def_delegators :response, :[], :fetch
4
10
 
5
- def top_level_key
6
- 'user_requests'
11
+ def initialize(response_body_hash)
12
+ @response = response_body_hash
7
13
  end
8
14
 
9
- def response_records_key
15
+ def list
16
+ fetch(key, [])
17
+ end
18
+
19
+ def total_record_count
20
+ fetch('total_record_count', 0)
21
+ end
22
+ alias :total_records :total_record_count
23
+
24
+ def key
10
25
  'user_request'
11
26
  end
12
27
 
13
28
  end
14
- end
29
+ end
@@ -1,141 +1,177 @@
1
1
  module Alma
2
- class User < AlmaRecord
3
- extend Alma::Api
2
+ class User
3
+ extend Forwardable
4
+
5
+ def self.find(user_id)
6
+ response = HTTParty.get("#{self.users_base_path}/#{user_id}", headers: headers)
7
+ if response.code == 200
8
+ Alma::User.new JSON.parse(response.body)
9
+ else
10
+ raise StandardError, parse(response.body)
11
+ end
12
+ end
13
+
14
+ # Authenticates a Alma user with their Alma Password
15
+ # @param [Hash] args
16
+ # @option args [String] :user_id The unique id of the user
17
+ # @option args [String] :password The users local alma password
18
+ # @return [Boolean] Whether or not the user Successfully authenticated
19
+ def self.authenticate(args)
20
+ user_id = args.delete(:user_id) { raise ArgumentError }
21
+ args.merge!({op: 'auth'})
22
+ response = HTTParty.post("#{users_base_path}/#{user_id}", query: args, headers: headers)
23
+ response.code == 204
24
+ end
4
25
 
5
- attr_accessor :id
6
26
 
7
- def post_initialize
8
- @id = response['primary_id'].to_s
27
+ # The User object can respond directly to Hash like access of attributes
28
+ def_delegators :response, :[], :[]=, :has_key?, :keys, :to_json
29
+
30
+ def initialize(response_body)
31
+ @response = response_body
9
32
  @recheck_loans = true
10
33
  end
11
34
 
35
+ def response
36
+ @response
37
+ end
38
+
39
+ def id
40
+ self['primary_id']
41
+ end
42
+
43
+
44
+ # Access the top level JSON attributes as object methods
45
+ def method_missing(name)
46
+ return response[name.to_s] if has_key?(name.to_s)
47
+ super.method_missing name
48
+ end
49
+
50
+ def respond_to_missing?(name, include_private = false)
51
+ has_key?(name.to_s) || super
52
+ end
53
+
54
+
55
+ # Persist the user in it's current state back to Alma
56
+ def save!
57
+ response = HTTParty.put("#{users_base_path}/#{id}", headers: headers, body: to_json)
58
+ get_body_from(response)
59
+ end
60
+
61
+
12
62
  def fines
13
- self.class.get_fines({user_id: self.id})
63
+ response = HTTParty.get("#{users_base_path}/#{id}/fees", headers: headers)
64
+ if response.code == 200
65
+ Alma::FineSet.new get_body_from(response)
66
+ else
67
+ raise StandardError, get_body_from(response)
68
+ end
69
+ end
70
+
71
+ def requests
72
+ #TODO Handle Additional Parameters
73
+ #TODO Handle Pagination
74
+ #TODO Handle looping through all results
75
+ response = HTTParty.get("#{users_base_path}/#{id}/requests", headers: headers)
76
+ Alma::RequestSet.new(get_body_from(response))
14
77
  end
15
78
 
79
+
16
80
  def loans
17
81
  unless @loans && !recheck_loans?
18
- @loans = self.class.get_loans({user_id: self.id})
82
+ @loans = send_loans_request
19
83
  @recheck_loans = false
20
84
  end
21
85
  @loans
22
86
  end
23
87
 
24
88
  def renew_loan(loan_id)
25
- response = self.class.renew_loan({user_id: self.id, loan_id: loan_id})
89
+ response = send_loan_renewal_request({user_id: id, loan_id: loan_id})
26
90
  if response.renewed?
27
91
  @recheck_loans ||= true
28
92
  end
29
- response
93
+ get_body_from response
30
94
  end
31
95
 
96
+
32
97
  def renew_multiple_loans(loan_ids)
33
98
  loan_ids.map { |id| renew_loan(id) }
34
99
  end
35
100
 
101
+
36
102
  def renew_all_loans
37
103
  renew_multiple_loans(loans.map(&:loan_id))
38
104
  end
39
105
 
106
+
40
107
  def recheck_loans?
41
108
  @recheck_loans
42
109
  end
43
110
 
44
- def requests
45
- self.class.get_requests({user_id:self.id})
111
+
112
+ def preferred_email
113
+ self["contact_info"]["email"].select { |k, v| k["preferred"] }.first["email_address"]
46
114
  end
47
115
 
48
- class << self
49
- # Static methods that do the actual querying
50
116
 
51
- def find(args = {})
52
- #TODO Handle Search Queries
53
- #TODO Handle Pagination
54
- #TODO Handle looping through all results
117
+ def email
118
+ self["contact_info"]["email"].map { |e| e["email_address"] }
119
+ end
55
120
 
56
- return find_by_id(user_id: args[:user_id]) if args.fetch(:user_id, nil)
57
- params = query_merge args
58
- response = resources.almaws_v1_users.get(params)
59
- Alma::UserSet.new(response)
60
- end
61
121
 
62
- def find_by_id(user_id_hash)
63
- params = query_merge user_id_hash
64
- response = resources.almaws_v1_users.user_id.get(params)
65
- User.new(response['user'])
66
- end
122
+ private
67
123
 
68
- def get_fines(args)
69
- #TODO Handle Additional Parameters
70
- #TODO Handle Pagination
71
- #TODO Handle looping through all results
72
- params = query_merge args
73
- response = resources.almaws_v1_users.user_id_fees.get(params)
74
- Alma::FineSet.new(response)
75
- end
124
+ def send_loans_request
125
+ #TODO Handle Additional Parameters
126
+ #TODO Handle Pagination
127
+ #TODO Handle looping through all results
128
+ response = HTTParty.get("#{users_base_path}/#{id}/loans", headers: headers)
129
+ Alma::LoanSet.new(get_body_from(response))
130
+ end
76
131
 
77
- def get_loans(args)
78
- #TODO Handle Additional Parameters
79
- #TODO Handle Pagination
80
- #TODO Handle looping through all results
81
- params = query_merge args
82
- response = resources.almaws_v1_users.user_id_loans.get(params)
83
- Alma::LoanSet.new(response)
84
- end
132
+ # Attempts to renew a single item for a user
133
+ # @param [Hash] args
134
+ # @option args [String] :user_id The unique id of the user
135
+ # @option args [String] :loan_id The unique id of the loan
136
+ # @option args [String] :user_id_type Type of identifier being used to search. OPTIONAL
137
+ # @return [RenewalResponse] Object indicating the renewal message
138
+ def send_loan_renewal_request(args)
139
+ user_id = args.delete(:user_id) { raise ArgumentError }
140
+ loan_id = args.delete(:loan_id) { raise ArgumentError }
141
+ params = {op: 'renew'}
142
+ response = HTTParty.post("#{users_base_path}/#{id}/loans/#{loan_id}", query: params, headers: headers)
143
+ RenewalResponse.new(get_body_from(response))
144
+ end
85
145
 
86
- def get_requests(args)
87
- #TODO Handle Additional Parameters
88
- #TODO Handle Pagination
89
- #TODO Handle looping through all results
90
- params = query_merge args
91
- response = resources.almaws_v1_users.user_id_requests.get(params)
92
- Alma::RequestSet.new(response)
93
- end
94
146
 
95
- def authenticate(args)
96
- # Authenticates a Alma user with their Alma Password
97
- args.merge!({op: 'auth'})
98
- params = query_merge args
99
- response = resources.almaws_v1_users.user_id.post(params)
100
- response.code == 204
101
- end
147
+ def get_body_from(response)
148
+ JSON.parse(response.body)
149
+ end
102
150
 
103
- # Attempts to renew a single item for a user
104
- # @param [Hash] args
105
- # @option args [String] :user_id The unique id of the user
106
- # @option args [String] :loan_id The unique id of the loan
107
- # @option args [String] :user_id_type Type of identifier being used to search. OPTIONAL
108
- # @return [RenewalResponse] Object indicating the renewal message
109
- def renew_loan(args)
110
- args.merge!({op: 'renew'})
111
- params = query_merge args
112
- response = resources.almaws_v1_users.user_id_loans_loan_id.post(params)
113
- RenewalResponse.new(response)
114
- end
115
151
 
116
- # Attempts to renew a multiple items for a user
117
- # @param [Hash] args
118
- # @option args [String] :user_id The unique id of the user
119
- # @option args [Array<String>] :loan_ids Array of loan ids
120
- # @option args [String] :user_id_type Type of identifier being used to search. OPTIONAL
121
- # @return [Array<RenewalResponse>] Object indicating the renewal message
122
- def renew_multiple_loans(args)
123
-
124
- if args.fetch(:loans_ids, nil).respond_to? :map
125
- args.delete(:loan_ids).map do |loan_id|
126
- renew_loan(args.merge(loan_id: loan_id))
127
- end
128
- else
129
- []
130
- end
131
- end
152
+ def self.users_base_path
153
+ "https://api-na.hosted.exlibrisgroup.com/almaws/v1/users"
154
+ end
132
155
 
156
+ def users_base_path
157
+ self.class.users_base_path
158
+ end
133
159
 
160
+ def self.headers
161
+ { "Authorization": "apikey #{self.apikey}",
162
+ "Accept": "application/json",
163
+ "Content-Type": "application/json" }
164
+ end
134
165
 
135
166
 
136
- def set_wadl_filename
137
- 'user.wadl'
138
- end
167
+ def headers
168
+ self.class.headers
169
+ end
170
+
171
+
172
+ def self.apikey
173
+ Alma.configuration.apikey
174
+ end
175
+
139
176
  end
140
177
  end
141
- end
@@ -1,3 +1,3 @@
1
1
  module Alma
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chad Nelson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-08 00:00:00.000000000 Z
11
+ date: 2018-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ezwadl
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httparty
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: xml-simple
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -119,6 +147,7 @@ files:
119
147
  - lib/alma/api.rb
120
148
  - lib/alma/availability_response.rb
121
149
  - lib/alma/bib.rb
150
+ - lib/alma/bib_items.rb
122
151
  - lib/alma/bib_set.rb
123
152
  - lib/alma/config.rb
124
153
  - lib/alma/error.rb
@@ -153,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
182
  version: '0'
154
183
  requirements: []
155
184
  rubyforge_project:
156
- rubygems_version: 2.5.2
185
+ rubygems_version: 2.6.11
157
186
  signing_key:
158
187
  specification_version: 4
159
188
  summary: Client for Ex Libris Alma Web Services