fieldhand 0.9.0 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: fc45bc1384bec75919f2d929ee512748554511d90b0818024b930f4c133a70b2
4
- data.tar.gz: c31b6bb9872a34e3bd65bc94cb76364c645c767970e3a277a3c69b6b1831f3c2
2
+ SHA1:
3
+ metadata.gz: 9c93850935147ebbd65f18c017647d95fb92f0a8
4
+ data.tar.gz: aa07bb08297620d753ffd50f62fa393450932ec1
5
5
  SHA512:
6
- metadata.gz: 76896e2562bd40ed991d10fe57bb07532a42aa08f5653c78342756819010d62ff66b854c39cf3fb74d6004ab049623870091a9725fbd960de8a89bcc25d02b83
7
- data.tar.gz: 071e2ee3300fa813699eda02ab107c02f1362241a893e7beb2b1d2becba8ac14364ab7890a870fe4de43f0dde1f87a593856a310c19b26b3740f76baf4802d84
6
+ metadata.gz: 5c17919de0da4c4f435724db51eabf4953ae4d9ad5fbad608fe4b35d3425fef5f65d9fd4492c3cc756ba6bb182ecae913b15156ef42a9502019457603d995e9a
7
+ data.tar.gz: efa32effd77a428477c16debc10030df6dacc9b2e40e70300613de3d82bed1f09525974006d517d61faf0bc5c05e63b7d4e7bcc57f8990b08b53e51f468df69a
data/README.md CHANGED
@@ -2,19 +2,19 @@
2
2
 
3
3
  A Ruby library for harvesting metadata from [OAI-PMH](https://www.openarchives.org/OAI/openarchivesprotocol.html) repositories.
4
4
 
5
- **Current version:** 0.9.0
5
+ **Current version:** 0.10.0
6
6
  **Supported Ruby versions:** 1.8.7, 1.9.2, 1.9.3, 2.0, 2.1, 2.2
7
7
 
8
8
  ## Installation
9
9
 
10
10
  ```
11
- gem install fieldhand -v '~> 0.9'
11
+ gem install fieldhand -v '~> 0.10'
12
12
  ```
13
13
 
14
14
  Or, in your `Gemfile`:
15
15
 
16
16
  ```ruby
17
- gem 'fieldhand', '~> 0.9'
17
+ gem 'fieldhand', '~> 0.10'
18
18
  ```
19
19
 
20
20
  ## Usage
@@ -115,6 +115,7 @@ A class to represent [an OAI-PMH repository](https://www.openarchives.org/OAI/op
115
115
  Fieldhand::Repository.new('http://www.example.com/oai')
116
116
  Fieldhand::Repository.new(URI('http://www.example.com/oai'))
117
117
  Fieldhand::Repository.new('http://www.example.com/oai', :logger => Logger.new(STDOUT), :timeout => 10, :bearer_token => 'decafbad')
118
+ Fieldhand::Repository.new('http://www.example.com/oai', :logger => Logger.new(STDOUT), :timeout => 10, :headers => { 'Custom header' => 'decafbad')
118
119
  ```
119
120
 
120
121
  Return a new [`Repository`](#fieldhandrepository) instance accessible at the given `uri` (specified
@@ -124,6 +125,7 @@ something that can be coerced into a `URI` such as a `String`) with three option
124
125
  * `:logger`: a [`Logger`](http://ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger.html)-compatible `logger`, defaults to a platform-specific null logger;
125
126
  * `:timeout`: a `Numeric` number of seconds to wait before timing out any HTTP requests, defaults to 60;
126
127
  * `:bearer_token`: a `String` bearer token to authorize any HTTP requests, defaults to `nil`.
128
+ * `:headers`: a `Hash` containing custom HTTP headers, defaults to `{}`.
127
129
 
128
130
  #### `Fieldhand::Repository#identify`
129
131
 
@@ -17,6 +17,7 @@ module Fieldhand
17
17
  # null logger
18
18
  # * :timeout - A `Numeric` number of seconds to wait for any HTTP requests, defaults to 60 seconds
19
19
  # * :bearer_token - A `String` bearer token to use when sending any HTTP requests, defaults to nil
20
+ # * :headers - A `Hash` containing custom HTTP headers, defaults to {}.
20
21
  def initialize(logger_or_options = {})
21
22
  @logger_or_options = logger_or_options
22
23
  end
@@ -36,6 +37,14 @@ module Fieldhand
36
37
  options[:bearer_token]
37
38
  end
38
39
 
40
+ # Build custom headers
41
+ def headers
42
+ headers = options.fetch(:headers, {})
43
+ headers['Authorization'] = "Bearer #{bearer_token}" if bearer_token
44
+
45
+ headers
46
+ end
47
+
39
48
  private
40
49
 
41
50
  def options
@@ -11,21 +11,21 @@ module Fieldhand
11
11
  #
12
12
  # See https://www.openarchives.org/OAI/openarchivesprotocol.html#FlowControl
13
13
  class Paginator
14
- attr_reader :uri, :logger, :timeout, :bearer_token, :http
14
+ attr_reader :uri, :logger, :timeout, :headers, :http
15
15
 
16
- # Return a new paginator for the given repository base URI and optional logger, timeout and bearer token.
16
+ # Return a new paginator for the given repository base URI and optional logger, timeout, bearer token and headers.
17
17
  #
18
18
  # The URI can be passed as either a `URI` or something that can be parsed as a URI such as a string.
19
19
  #
20
- # The logger will default to a null logger appropriate to this platform, timeout will default to 60 seconds and the
21
- # bearer token will default to nil.
20
+ # The logger will default to a null logger appropriate to this platform, timeout will default to 60 seconds, the
21
+ # bearer token will default to nil and headers will default to empty hash.
22
22
  def initialize(uri, logger_or_options = {})
23
23
  @uri = uri.is_a?(::URI) ? uri : URI(uri)
24
24
 
25
25
  options = Options.new(logger_or_options)
26
26
  @logger = options.logger
27
27
  @timeout = options.timeout
28
- @bearer_token = options.bearer_token
28
+ @headers = options.headers
29
29
 
30
30
  @http = ::Net::HTTP.new(@uri.host, @uri.port)
31
31
  @http.read_timeout = @timeout
@@ -104,7 +104,9 @@ module Fieldhand
104
104
 
105
105
  def authenticated_request(uri)
106
106
  request = ::Net::HTTP::Get.new(uri)
107
- request['Authorization'] = "Bearer #{bearer_token}" if bearer_token
107
+ headers.each do |key, value|
108
+ request[key] = value
109
+ end
108
110
 
109
111
  request
110
112
  end
@@ -14,23 +14,23 @@ module Fieldhand
14
14
  #
15
15
  # See https://www.openarchives.org/OAI/openarchivesprotocol.html
16
16
  class Repository
17
- attr_reader :uri, :logger, :timeout, :bearer_token
17
+ attr_reader :uri, :logger, :timeout, :headers
18
18
 
19
- # Return a new repository with the given base URL and an optional logger, timeout and bearer token.
19
+ # Return a new repository with the given base URL and an optional logger, timeout, bearer token and headers.
20
20
  #
21
21
  # The base URL can be passed as a `URI` or anything that can be parsed as a URI such as a string.
22
22
  #
23
23
  # For backward compatibility, the second argument can either be a logger or a hash containing
24
- # a logger, timeout and bearer token.
24
+ # a logger, timeout, bearer token and headers.
25
25
  #
26
- # Defaults to using a null logger specific to this platform, a timeout of 60 seconds and no bearer token.
26
+ # Defaults to using a null logger specific to this platform, a timeout of 60 seconds, no bearer token and no headers.
27
27
  def initialize(uri, logger_or_options = {})
28
28
  @uri = uri.is_a?(::URI) ? uri : URI(uri)
29
29
 
30
30
  options = Options.new(logger_or_options)
31
31
  @logger = options.logger
32
32
  @timeout = options.timeout
33
- @bearer_token = options.bearer_token
33
+ @headers = options.headers
34
34
  end
35
35
 
36
36
  # Send an Identify request to the repository and return an `Identify` response.
@@ -134,7 +134,7 @@ module Fieldhand
134
134
  private
135
135
 
136
136
  def paginator
137
- @paginator ||= Paginator.new(uri, :logger => logger, :timeout => timeout, :bearer_token => bearer_token)
137
+ @paginator ||= Paginator.new(uri, :logger => logger, :timeout => timeout, :headers => headers)
138
138
  end
139
139
  end
140
140
  end
@@ -69,5 +69,25 @@ module Fieldhand
69
69
  expect(options.bearer_token).to eq('decafbad')
70
70
  end
71
71
  end
72
+
73
+ describe '#headers' do
74
+ it 'defaults to an empty hash' do
75
+ options = described_class.new({})
76
+
77
+ expect(options.headers).to be_empty
78
+ end
79
+
80
+ it 'can be overridden by passing headers in an option' do
81
+ options = described_class.new(:headers => { 'Crossref-Plus-API-Token' => 'decafbad' })
82
+
83
+ expect(options.headers).to eq({ 'Crossref-Plus-API-Token' => 'decafbad' })
84
+ end
85
+
86
+ it 'overrides authorization headers with a bearer_token' do
87
+ options = described_class.new(:headers => { 'Authorization' => 'Bearer aaabbbccc' }, :bearer_token => 'decafbad')
88
+
89
+ expect(options.headers).to eq({ 'Authorization' => 'Bearer decafbad' })
90
+ end
91
+ end
72
92
  end
73
93
  end
@@ -146,22 +146,23 @@ module Fieldhand
146
146
  end
147
147
  end
148
148
 
149
- describe '#bearer_token' do
150
- it 'defaults to nil' do
149
+ describe '#headers' do
150
+ it 'defaults to an empty hash' do
151
151
  paginator = described_class.new('http://www.example.com/oai')
152
152
 
153
- expect(paginator.bearer_token).to be_nil
153
+ expect(paginator.headers).to be_empty
154
154
  end
155
155
 
156
156
  it 'can be overridden with an option' do
157
- paginator = described_class.new('http://www.example.com/oai', :bearer_token => 'decafbad')
157
+ paginator = described_class.new('http://www.example.com/oai', :headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
158
158
 
159
- expect(paginator.bearer_token).to eq('decafbad')
159
+ expect(paginator.headers).to eq({ 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
160
160
  end
161
161
 
162
- it 'sends no authorization header without a bearer token' do
163
- request = stub_oai_request('http://www.example.com/oai?verb=Identify', 'identify.xml')
164
- paginator = described_class.new('http://www.example.com/oai')
162
+ it 'can add custom headers to HTTP request' do
163
+ request = stub_oai_request('http://www.example.com/oai?verb=Identify', 'identify.xml').
164
+ with(:headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
165
+ paginator = described_class.new('http://www.example.com/oai', :headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
165
166
 
166
167
  paginator.items('Identify', IdentifyParser).first
167
168
 
@@ -170,8 +171,18 @@ module Fieldhand
170
171
 
171
172
  it 'sends an authorization header with a bearer token' do
172
173
  request = stub_oai_request('http://www.example.com/oai?verb=Identify', 'identify.xml').
173
- with(:headers => { 'Authorization' => 'Bearer decafbad' })
174
- paginator = described_class.new('http://www.example.com/oai', :bearer_token => 'decafbad')
174
+ with(:headers => { 'Authorization' => 'Bearer ewterhtr' })
175
+ paginator = described_class.new('http://www.example.com/oai', :bearer_token => 'ewterhtr')
176
+
177
+ paginator.items('Identify', IdentifyParser).first
178
+
179
+ expect(request).to have_been_requested
180
+ end
181
+
182
+ it 'can add multiple custom headers to HTTP request' do
183
+ request = stub_oai_request('http://www.example.com/oai?verb=Identify', 'identify.xml').
184
+ with(:headers => { 'Authorization' => 'Bearer ewterhtr', 'Crossref-Plus-API-Token' => 'decafbad' })
185
+ paginator = described_class.new('http://www.example.com/oai', :bearer_token => 'ewterhtr', :headers => { 'Crossref-Plus-API-Token' => 'decafbad' })
175
186
 
176
187
  paginator.items('Identify', IdentifyParser).first
177
188
 
@@ -224,23 +224,33 @@ module Fieldhand
224
224
  end
225
225
  end
226
226
 
227
- describe '#bearer_token' do
228
- it 'defaults to nil' do
227
+ describe '#headers' do
228
+ it 'defaults to an empty hash' do
229
229
  repository = described_class.new('http://www.example.com/oai')
230
230
 
231
- expect(repository.bearer_token).to be_nil
231
+ expect(repository.headers).to be_empty
232
232
  end
233
233
 
234
234
  it 'can be overridden with an option' do
235
- repository = described_class.new('http://www.example.com/oai', :bearer_token => 'decafbad')
235
+ repository = described_class.new('http://www.example.com/oai', :headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
236
236
 
237
- expect(repository.bearer_token).to eq('decafbad')
237
+ expect(repository.headers).to eq({ 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
238
238
  end
239
239
 
240
- it 'uses the bearer token to authorize HTTP requests' do
240
+ it 'can add custom headers to HTTP request' do
241
241
  request = stub_oai_request('http://www.example.com/oai?verb=Identify', 'identify.xml').
242
- with(:headers => { 'Authorization' => 'Bearer decafbad' })
243
- repository = described_class.new('http://www.example.com/oai', :bearer_token => 'decafbad')
242
+ with(:headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
243
+ repository = described_class.new('http://www.example.com/oai', :headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
244
+
245
+ repository.identify
246
+
247
+ expect(request).to have_been_requested
248
+ end
249
+
250
+ it 'can use a bearer token to authorize HTTP requests' do
251
+ request = stub_oai_request('http://www.example.com/oai?verb=Identify', 'identify.xml').
252
+ with(:headers => { 'Authorization' => 'Bearer fhsfag' })
253
+ repository = described_class.new('http://www.example.com/oai', :bearer_token => 'fhsfag')
244
254
 
245
255
  repository.identify
246
256
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fieldhand
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Mucur
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-06-26 00:00:00.000000000 Z
14
+ date: 2018-10-18 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: ox
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
140
  version: '0'
141
141
  requirements: []
142
142
  rubyforge_project:
143
- rubygems_version: 2.7.3
143
+ rubygems_version: 2.6.14
144
144
  signing_key:
145
145
  specification_version: 4
146
146
  summary: An OAI-PMH harvester