alma 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +54 -0
- data/.circleci/setup-rubygems.sh +3 -0
- data/.github/dependabot.yml +7 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +134 -0
- data/.ruby-version +1 -1
- data/Gemfile +4 -3
- data/Rakefile +3 -1
- data/alma.gemspec +17 -17
- data/lib/alma.rb +34 -26
- data/lib/alma/alma_record.rb +3 -3
- data/lib/alma/api_defaults.rb +10 -1
- data/lib/alma/availability_response.rb +49 -52
- data/lib/alma/bib.rb +23 -21
- data/lib/alma/bib_holding.rb +25 -0
- data/lib/alma/bib_item.rb +22 -9
- data/lib/alma/bib_item_set.rb +19 -8
- data/lib/alma/config.rb +3 -1
- data/lib/alma/course.rb +47 -0
- data/lib/alma/course_set.rb +17 -0
- data/lib/alma/electronic.rb +1 -1
- data/lib/alma/electronic/batch_utils.rb +11 -11
- data/lib/alma/error.rb +4 -3
- data/lib/alma/fine.rb +3 -2
- data/lib/alma/fine_set.rb +1 -1
- data/lib/alma/item_request_options.rb +4 -3
- data/lib/alma/library.rb +29 -0
- data/lib/alma/library_set.rb +21 -0
- data/lib/alma/loan.rb +4 -2
- data/lib/alma/loan_set.rb +3 -3
- data/lib/alma/location.rb +29 -0
- data/lib/alma/location_set.rb +21 -0
- data/lib/alma/renewal_response.rb +8 -8
- data/lib/alma/request.rb +16 -14
- data/lib/alma/request_options.rb +9 -7
- data/lib/alma/request_set.rb +1 -1
- data/lib/alma/user.rb +61 -59
- data/lib/alma/user_request.rb +3 -1
- data/lib/alma/version.rb +3 -1
- metadata +46 -5
- data/.travis.yml +0 -13
data/lib/alma/library.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alma
|
4
|
+
class Library < AlmaRecord
|
5
|
+
extend Alma::ApiDefaults
|
6
|
+
|
7
|
+
def self.all(args: {})
|
8
|
+
response = HTTParty.get("#{configuration_base_path}/libraries", query: args, headers: headers, timeout: timeout)
|
9
|
+
if response.code == 200
|
10
|
+
LibrarySet.new(response)
|
11
|
+
else
|
12
|
+
raise StandardError, get_body_from(response)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find(library_code:, args: {})
|
17
|
+
response = HTTParty.get("#{configuration_base_path}/libraries/#{library_code}", query: args, headers: headers, timeout: timeout)
|
18
|
+
if response.code == 200
|
19
|
+
AlmaRecord.new(response)
|
20
|
+
else
|
21
|
+
raise StandardError, get_body_from(response)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.get_body_from(response)
|
26
|
+
JSON.parse(response.body)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alma
|
4
|
+
class LibrarySet < ResultSet
|
5
|
+
def_delegators :results, :[], :empty?
|
6
|
+
|
7
|
+
def each(&block)
|
8
|
+
results.each(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def results
|
12
|
+
@results ||= @response.fetch(key, [])
|
13
|
+
.map { |item| single_record_class.new(item) }
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
def key
|
18
|
+
"library"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/alma/loan.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Alma
|
2
4
|
class Loan < AlmaRecord
|
3
5
|
extend Alma::ApiDefaults
|
@@ -16,10 +18,10 @@ module Alma
|
|
16
18
|
end
|
17
19
|
|
18
20
|
def renew
|
19
|
-
Alma::User.renew_loan({user_id: user_id, loan_id: loan_id})
|
21
|
+
Alma::User.renew_loan({ user_id: user_id, loan_id: loan_id })
|
20
22
|
end
|
21
23
|
|
22
|
-
def self.where_user(user_id, args={})
|
24
|
+
def self.where_user(user_id, args = {})
|
23
25
|
# Always expand renewable unless you really don't want to
|
24
26
|
args[:expand] ||= "renewable"
|
25
27
|
# Default to upper limit
|
data/lib/alma/loan_set.rb
CHANGED
@@ -11,7 +11,7 @@ module Alma
|
|
11
11
|
attr_reader :results, :raw_response
|
12
12
|
def_delegators :results, :empty?
|
13
13
|
|
14
|
-
def initialize(raw_response, search_args={})
|
14
|
+
def initialize(raw_response, search_args = {})
|
15
15
|
@raw_response = raw_response
|
16
16
|
@response = raw_response.parsed_response
|
17
17
|
@search_args = search_args
|
@@ -40,7 +40,7 @@ module Alma
|
|
40
40
|
Enumerator.new do |yielder|
|
41
41
|
offset = 0
|
42
42
|
loop do
|
43
|
-
extra_args = @search_args.merge({limit: 100, offset: offset})
|
43
|
+
extra_args = @search_args.merge({ limit: 100, offset: offset })
|
44
44
|
r = (offset == 0) ? self : single_record_class.where_user(user_id, extra_args)
|
45
45
|
unless r.empty?
|
46
46
|
r.map { |item| yielder << item }
|
@@ -53,7 +53,7 @@ module Alma
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def each(&block)
|
56
|
-
|
56
|
+
@results.each(&block)
|
57
57
|
end
|
58
58
|
|
59
59
|
def success?
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alma
|
4
|
+
class Location < AlmaRecord
|
5
|
+
extend Alma::ApiDefaults
|
6
|
+
|
7
|
+
def self.all(library_code:, args: {})
|
8
|
+
response = HTTParty.get("#{configuration_base_path}/libraries/#{library_code}/locations", query: args, headers: headers, timeout: timeout)
|
9
|
+
if response.code == 200
|
10
|
+
LocationSet.new(response)
|
11
|
+
else
|
12
|
+
raise StandardError, get_body_from(response)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find(library_code:, location_code:, args: {})
|
17
|
+
response = HTTParty.get("#{configuration_base_path}/libraries/#{library_code}/locations/#{location_code}", query: args, headers: headers, timeout: timeout)
|
18
|
+
if response.code == 200
|
19
|
+
AlmaRecord.new(response)
|
20
|
+
else
|
21
|
+
raise StandardError, get_body_from(response)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.get_body_from(response)
|
26
|
+
JSON.parse(response.body)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alma
|
4
|
+
class LocationSet < ResultSet
|
5
|
+
def_delegators :results, :[], :empty?
|
6
|
+
|
7
|
+
def each(&block)
|
8
|
+
results.each(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def results
|
12
|
+
@results ||= @response.fetch(key, [])
|
13
|
+
.map { |item| single_record_class.new(item) }
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
def key
|
18
|
+
"location"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Alma
|
2
4
|
class RenewalResponse
|
3
|
-
|
4
5
|
def initialize(response)
|
5
6
|
@raw_response = response
|
6
7
|
@response = response.parsed_response
|
7
|
-
@success = response.has_key?(
|
8
|
+
@success = response.has_key?("loan_id")
|
8
9
|
end
|
9
10
|
|
10
11
|
def loggable
|
@@ -21,19 +22,19 @@ module Alma
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def due_date
|
24
|
-
@response.fetch(
|
25
|
+
@response.fetch("due_date", "")
|
25
26
|
end
|
26
27
|
|
27
28
|
|
28
29
|
def due_date_pretty
|
29
|
-
Time.parse(due_date).strftime(
|
30
|
+
Time.parse(due_date).strftime("%m-%e-%y %H:%M")
|
30
31
|
end
|
31
32
|
|
32
33
|
def item_title
|
33
34
|
if renewed?
|
34
|
-
@response[
|
35
|
+
@response["title"]
|
35
36
|
else
|
36
|
-
|
37
|
+
"This Item"
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
@@ -46,8 +47,7 @@ module Alma
|
|
46
47
|
end
|
47
48
|
|
48
49
|
def error_message
|
49
|
-
|
50
|
+
@response unless renewed?
|
50
51
|
end
|
51
|
-
|
52
52
|
end
|
53
53
|
end
|
data/lib/alma/request.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Alma
|
2
4
|
class BibRequest
|
3
5
|
class ItemAlreadyExists < Alma::StandardError
|
@@ -11,11 +13,11 @@ module Alma
|
|
11
13
|
request = new(args)
|
12
14
|
response = HTTParty.post(
|
13
15
|
"#{bibs_base_path}/#{request.mms_id}/requests",
|
14
|
-
query: {user_id: request.user_id},
|
16
|
+
query: { user_id: request.user_id },
|
15
17
|
headers: headers,
|
16
18
|
body: request.body.to_json
|
17
19
|
)
|
18
|
-
|
20
|
+
Alma::Response.new(response)
|
19
21
|
end
|
20
22
|
|
21
23
|
attr_reader :mms_id, :user_id, :body, :request_type
|
@@ -69,18 +71,18 @@ module Alma
|
|
69
71
|
def digitization_validation(args)
|
70
72
|
args.fetch(:target_destination) do
|
71
73
|
raise ArgumentError.new(
|
72
|
-
|
74
|
+
":target_destination option must be specified when request_type is DIGITIZATION"
|
73
75
|
)
|
74
76
|
end
|
75
77
|
pd = args.fetch(:partial_digitization) do
|
76
78
|
raise ArgumentError.new(
|
77
|
-
|
79
|
+
":partial_digitization option must be specified when request_type is DIGITIZATION"
|
78
80
|
)
|
79
81
|
end
|
80
82
|
if pd == true
|
81
83
|
args.fetch(:comment) do
|
82
84
|
raise ArgumentError.new(
|
83
|
-
|
85
|
+
":comment option must be specified when :request_type is DIGITIZATION and :partial_digitization is true"
|
84
86
|
)
|
85
87
|
end
|
86
88
|
end
|
@@ -95,22 +97,22 @@ module Alma
|
|
95
97
|
def booking_validation(args)
|
96
98
|
args.fetch(:booking_start_date) do
|
97
99
|
raise ArgumentError.new(
|
98
|
-
|
100
|
+
":booking_start_date option must be specified when request_type is BOOKING"
|
99
101
|
)
|
100
102
|
end
|
101
103
|
args.fetch(:booking_end_date) do
|
102
104
|
raise ArgumentError.new(
|
103
|
-
|
105
|
+
":booking_end_date option must be specified when request_type is BOOKING"
|
104
106
|
)
|
105
107
|
end
|
106
108
|
args.fetch(:pickup_location_type) do
|
107
109
|
raise ArgumentError.new(
|
108
|
-
|
110
|
+
":pickup_location_type option must be specified when request_type is BOOKING"
|
109
111
|
)
|
110
112
|
end
|
111
113
|
args.fetch(:pickup_location_library) do
|
112
114
|
raise ArgumentError.new(
|
113
|
-
|
115
|
+
":pickup_location_library option must be specified when request_type is BOOKING"
|
114
116
|
)
|
115
117
|
end
|
116
118
|
end
|
@@ -124,12 +126,12 @@ module Alma
|
|
124
126
|
def hold_validation(args)
|
125
127
|
args.fetch(:pickup_location_type) do
|
126
128
|
raise ArgumentError.new(
|
127
|
-
|
129
|
+
":pickup_location_type option must be specified when request_type is HOLD"
|
128
130
|
)
|
129
131
|
end
|
130
132
|
args.fetch(:pickup_location_library) do
|
131
133
|
raise ArgumentError.new(
|
132
|
-
|
134
|
+
":pickup_location_library option must be specified when request_type is HOLD"
|
133
135
|
)
|
134
136
|
end
|
135
137
|
end
|
@@ -140,11 +142,11 @@ module Alma
|
|
140
142
|
request = new(args)
|
141
143
|
response = HTTParty.post(
|
142
144
|
"#{bibs_base_path}/#{request.mms_id}/holdings/#{request.holding_id}/items/#{request.item_pid}/requests",
|
143
|
-
query: {user_id: request.user_id},
|
145
|
+
query: { user_id: request.user_id },
|
144
146
|
headers: headers,
|
145
147
|
body: request.body.to_json
|
146
148
|
)
|
147
|
-
|
149
|
+
Alma::Response.new(response)
|
148
150
|
end
|
149
151
|
|
150
152
|
attr_reader :holding_id, :item_pid
|
@@ -157,7 +159,7 @@ module Alma
|
|
157
159
|
def additional_validation!(args)
|
158
160
|
args.fetch(:description) do
|
159
161
|
raise ArgumentError.new(
|
160
|
-
|
162
|
+
":description option must be specified when request_type is DIGITIZATION"
|
161
163
|
)
|
162
164
|
end
|
163
165
|
end
|
data/lib/alma/request_options.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Alma
|
2
4
|
class RequestOptions
|
3
5
|
class ResponseError < Alma::StandardError
|
@@ -18,9 +20,9 @@ module Alma
|
|
18
20
|
end
|
19
21
|
|
20
22
|
|
21
|
-
def self.get(mms_id, options={})
|
23
|
+
def self.get(mms_id, options = {})
|
22
24
|
url = "#{bibs_base_path}/#{mms_id}/request-options"
|
23
|
-
options.select! {|k,_| REQUEST_OPTIONS_PERMITTED_ARGS.include? k }
|
25
|
+
options.select! { |k, _| REQUEST_OPTIONS_PERMITTED_ARGS.include? k }
|
24
26
|
response = HTTParty.get(url, headers: headers, query: options, timeout: timeout)
|
25
27
|
new(response)
|
26
28
|
end
|
@@ -38,26 +40,26 @@ module Alma
|
|
38
40
|
|
39
41
|
def hold_allowed?
|
40
42
|
!request_options.nil? &&
|
41
|
-
!request_options.select {|option| option["type"]["value"] == "HOLD" }.empty?
|
43
|
+
!request_options.select { |option| option["type"]["value"] == "HOLD" }.empty?
|
42
44
|
end
|
43
45
|
|
44
46
|
def digitization_allowed?
|
45
47
|
!request_options.nil? &&
|
46
|
-
!request_options.select {|option| option["type"]["value"] == "DIGITIZATION" }.empty?
|
48
|
+
!request_options.select { |option| option["type"]["value"] == "DIGITIZATION" }.empty?
|
47
49
|
end
|
48
50
|
|
49
51
|
def booking_allowed?
|
50
52
|
!request_options.nil? &&
|
51
|
-
!request_options.select {|option| option["type"]["value"] == "BOOKING" }.empty?
|
53
|
+
!request_options.select { |option| option["type"]["value"] == "BOOKING" }.empty?
|
52
54
|
end
|
53
55
|
|
54
56
|
def resource_sharing_broker_allowed?
|
55
57
|
!request_options.nil? &&
|
56
|
-
!request_options.select {|option| option["type"]["value"] == "RS_BROKER" }.empty?
|
58
|
+
!request_options.select { |option| option["type"]["value"] == "RS_BROKER" }.empty?
|
57
59
|
end
|
58
60
|
|
59
61
|
def ez_borrow_link
|
60
|
-
broker = request_options.select {|option| option["type"]["value"] == "RS_BROKER" }
|
62
|
+
broker = request_options.select { |option| option["type"]["value"] == "RS_BROKER" }
|
61
63
|
broker.collect { |opt| opt["request_url"] }.first
|
62
64
|
end
|
63
65
|
end
|
data/lib/alma/request_set.rb
CHANGED
@@ -35,7 +35,7 @@ module Alma
|
|
35
35
|
Enumerator.new do |yielder|
|
36
36
|
offset = 0
|
37
37
|
loop do
|
38
|
-
r = (offset == 0) ? self : single_record_class.where_user(user_id, {limit: 100, offset: offset})
|
38
|
+
r = (offset == 0) ? self : single_record_class.where_user(user_id, { limit: 100, offset: offset })
|
39
39
|
unless r.empty?
|
40
40
|
r.map { |item| yielder << item }
|
41
41
|
offset += 100
|
data/lib/alma/user.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Alma
|
2
4
|
class User
|
3
5
|
class ResponseError < Alma::StandardError
|
@@ -5,24 +7,24 @@ module Alma
|
|
5
7
|
extend Forwardable
|
6
8
|
extend Alma::ApiDefaults
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
def self.find(user_id, args = {})
|
11
|
+
args[:expand] ||= "fees,requests,loans"
|
12
|
+
response = HTTParty.get("#{self.users_base_path}/#{user_id}", query: args, headers: headers, timeout: timeout)
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
Alma::User.new response
|
15
|
+
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
# Authenticates a Alma user with their Alma Password
|
18
|
+
# @param [Hash] args
|
19
|
+
# @option args [String] :user_id The unique id of the user
|
20
|
+
# @option args [String] :password The users local alma password
|
21
|
+
# @return [Boolean] Whether or not the user Successfully authenticated
|
22
|
+
def self.authenticate(args)
|
23
|
+
user_id = args.delete(:user_id) { raise ArgumentError }
|
24
|
+
args.merge!({ op: "auth" })
|
25
|
+
response = HTTParty.post("#{users_base_path}/#{user_id}", query: args, headers: headers, timeout: timeout)
|
26
|
+
response.code == 204
|
27
|
+
end
|
26
28
|
|
27
29
|
|
28
30
|
# The User object can respond directly to Hash like access of attributes
|
@@ -52,19 +54,19 @@ module Alma
|
|
52
54
|
end
|
53
55
|
|
54
56
|
def id
|
55
|
-
self[
|
57
|
+
self["primary_id"]
|
56
58
|
end
|
57
59
|
|
58
60
|
def total_fines
|
59
|
-
response.dig(
|
61
|
+
response.dig("fees", "value") || "0"
|
60
62
|
end
|
61
63
|
|
62
64
|
def total_requests
|
63
|
-
response.dig(
|
65
|
+
response.dig("requests", "value") || "0"
|
64
66
|
end
|
65
67
|
|
66
68
|
def total_loans
|
67
|
-
response.dig(
|
69
|
+
response.dig("loans", "value") || "0"
|
68
70
|
end
|
69
71
|
|
70
72
|
|
@@ -95,12 +97,12 @@ module Alma
|
|
95
97
|
end
|
96
98
|
|
97
99
|
|
98
|
-
def loans(args={})
|
99
|
-
|
100
|
+
def loans(args = {})
|
101
|
+
@loans ||= Alma::Loan.where_user(id, args)
|
100
102
|
end
|
101
103
|
|
102
104
|
def renew_loan(loan_id)
|
103
|
-
response = self.class.send_loan_renewal_request({user_id: id, loan_id: loan_id})
|
105
|
+
response = self.class.send_loan_renewal_request({ user_id: id, loan_id: loan_id })
|
104
106
|
if response.renewed?
|
105
107
|
@recheck_loans ||= true
|
106
108
|
end
|
@@ -130,7 +132,7 @@ module Alma
|
|
130
132
|
|
131
133
|
def preferred_middle_name
|
132
134
|
pref_middle = self["pref_middle_name"] unless self["pref_middle_name"] == ""
|
133
|
-
pref_middle
|
135
|
+
pref_middle || self["middle_name"] || ""
|
134
136
|
end
|
135
137
|
|
136
138
|
def preferred_last_name
|
@@ -150,46 +152,46 @@ module Alma
|
|
150
152
|
|
151
153
|
private
|
152
154
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
155
|
+
# Attempts to renew a single item for a user
|
156
|
+
# @param [Hash] args
|
157
|
+
# @option args [String] :user_id The unique id of the user
|
158
|
+
# @option args [String] :loan_id The unique id of the loan
|
159
|
+
# @option args [String] :user_id_type Type of identifier being used to search. OPTIONAL
|
160
|
+
# @return [RenewalResponse] Object indicating the renewal message
|
161
|
+
def self.send_loan_renewal_request(args)
|
162
|
+
loan_id = args.delete(:loan_id) { raise ArgumentError }
|
163
|
+
user_id = args.delete(:user_id) { raise ArgumentError }
|
164
|
+
params = { op: "renew" }
|
165
|
+
response = HTTParty.post("#{users_base_path}/#{user_id}/loans/#{loan_id}", query: params, headers: headers)
|
166
|
+
RenewalResponse.new(response)
|
167
|
+
end
|
166
168
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
169
|
+
# Attempts to renew multiple items for a user
|
170
|
+
# @param [Hash] args
|
171
|
+
# @option args [String] :user_id The unique id of the user
|
172
|
+
# @option args [Array<String>] :loan_ids The unique ids of the loans
|
173
|
+
# @option args [String] :user_id_type Type of identifier being used to search. OPTIONAL
|
174
|
+
# @return [Array<RenewalResponse>] Array of Objects indicating the renewal messages
|
175
|
+
def self.send_multiple_loan_renewal_requests(args)
|
176
|
+
loan_ids = args.delete(:loan_ids) { raise ArgumentError }
|
177
|
+
loan_ids.map { |id| Alma::User.send_loan_renewal_request(args.merge(loan_id: id)) }
|
178
|
+
end
|
177
179
|
|
178
|
-
|
179
|
-
|
180
|
-
|
180
|
+
def get_body_from(response)
|
181
|
+
JSON.parse(response.body)
|
182
|
+
end
|
181
183
|
|
182
184
|
|
183
|
-
|
184
|
-
|
185
|
-
|
185
|
+
def self.users_base_path
|
186
|
+
"https://api-na.hosted.exlibrisgroup.com/almaws/v1/users"
|
187
|
+
end
|
186
188
|
|
187
|
-
|
188
|
-
|
189
|
-
|
189
|
+
def users_base_path
|
190
|
+
self.class.users_base_path
|
191
|
+
end
|
190
192
|
|
191
|
-
|
192
|
-
|
193
|
-
|
193
|
+
def headers
|
194
|
+
self.class.headers
|
195
|
+
end
|
194
196
|
end
|
195
197
|
end
|