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 +5 -5
- data/README.md +5 -3
- data/lib/fieldhand/options.rb +9 -0
- data/lib/fieldhand/paginator.rb +8 -6
- data/lib/fieldhand/repository.rb +6 -6
- data/spec/fieldhand/options_spec.rb +20 -0
- data/spec/fieldhand/paginator_spec.rb +21 -10
- data/spec/fieldhand/repository_spec.rb +18 -8
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9c93850935147ebbd65f18c017647d95fb92f0a8
|
4
|
+
data.tar.gz: aa07bb08297620d753ffd50f62fa393450932ec1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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.
|
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
|
|
data/lib/fieldhand/options.rb
CHANGED
@@ -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
|
data/lib/fieldhand/paginator.rb
CHANGED
@@ -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, :
|
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
|
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
|
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
|
-
@
|
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
|
-
|
107
|
+
headers.each do |key, value|
|
108
|
+
request[key] = value
|
109
|
+
end
|
108
110
|
|
109
111
|
request
|
110
112
|
end
|
data/lib/fieldhand/repository.rb
CHANGED
@@ -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, :
|
17
|
+
attr_reader :uri, :logger, :timeout, :headers
|
18
18
|
|
19
|
-
# Return a new repository with the given base URL and an optional logger, timeout
|
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
|
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
|
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
|
-
@
|
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, :
|
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 '#
|
150
|
-
it 'defaults to
|
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.
|
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', :
|
157
|
+
paginator = described_class.new('http://www.example.com/oai', :headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
|
158
158
|
|
159
|
-
expect(paginator.
|
159
|
+
expect(paginator.headers).to eq({ 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
|
160
160
|
end
|
161
161
|
|
162
|
-
it '
|
163
|
-
request = stub_oai_request('http://www.example.com/oai?verb=Identify', 'identify.xml')
|
164
|
-
|
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
|
174
|
-
paginator = described_class.new('http://www.example.com/oai', :bearer_token => '
|
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 '#
|
228
|
-
it 'defaults to
|
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.
|
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', :
|
235
|
+
repository = described_class.new('http://www.example.com/oai', :headers => { 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
|
236
236
|
|
237
|
-
expect(repository.
|
237
|
+
expect(repository.headers).to eq({ 'Crossref-Plus-API-Token' => 'Bearer decafbad' })
|
238
238
|
end
|
239
239
|
|
240
|
-
it '
|
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
|
-
|
243
|
-
repository = described_class.new('http://www.example.com/oai', :
|
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.
|
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-
|
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.
|
143
|
+
rubygems_version: 2.6.14
|
144
144
|
signing_key:
|
145
145
|
specification_version: 4
|
146
146
|
summary: An OAI-PMH harvester
|