dor-fetcher 1.1.7 → 1.3.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 -13
- data/lib/dor-fetcher.rb +128 -156
- metadata +47 -20
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZDFiMDgzZmVjOGJjNmE4MjIzZGQyMzE0ZmM0YjRmMTcxYzA5YjQwNA==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6727b5b0868d3d588ed20a80df170a3e62eedf5d88dd0aee1b9fcd6104cf4a39
|
4
|
+
data.tar.gz: 6d042f0c65981a841c1950e28b4fd472928a378d78b613ca103a233cc883cf8d
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZGViOTdlYjAzMDMyMzAyMWZhODBkNTNmNTZjOGUwNDM1MmMxMDFjNjg2ZjJi
|
11
|
-
YmEzOWE2YWVlNjBhZDhmM2VlMmE2MDQ3OTZlNTVjNmU2NTI5ZTA=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
OGEwZDE2ZGJhNWNjYzA0ODgwOWMzN2RhN2FhNGJlMjIzZjNjZmNmZDJkNTk0
|
14
|
-
NmM1NWJlYzZkY2JhODc0MWFhZWE3ODFhZjRlNTU2NDFlMDY1OTYyMTJhOTM5
|
15
|
-
NzRiMjdiOWYyYzM2NzI5ZWVkMTRlY2U5MjBjMzk2ZDJjMzM4ZGE=
|
6
|
+
metadata.gz: d293c213247d7649ffa0b85605c98ff1240ed2a25e3b847cf2134ceddabaf6b5a0b250936cead592cab1408021b7254216a8b55c24bf58763f68edf08d6bb67d
|
7
|
+
data.tar.gz: 1371ec72bf0c36de3ecfd406333c6861d75b0ebda3da045f0b34cd06f5c2e7f95808870e16f6f4cab248065b2fe256a337a49970825d22658f1d9edb3f7294cb
|
data/lib/dor-fetcher.rb
CHANGED
@@ -3,196 +3,168 @@ require 'json'
|
|
3
3
|
require 'addressable/uri'
|
4
4
|
|
5
5
|
module DorFetcher
|
6
|
-
|
7
6
|
class Client
|
8
|
-
|
9
7
|
@@supported_params = [:first_modified, :last_modified, :count_only, :status]
|
10
|
-
@@count_only_param =
|
8
|
+
@@count_only_param = 'rows=0'
|
11
9
|
@@default_service_url = 'http://127.0.0.1:3000'
|
12
10
|
@@counts_key = 'counts'
|
13
|
-
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
11
|
+
|
12
|
+
attr_reader :service_url # Base URL this instance will run RESTful API calls against
|
13
|
+
|
14
|
+
# Create a new instance of DorFetcher::Client
|
15
|
+
# @param options [Hash]
|
16
|
+
# @option options [String] :service_url base url for API queries. Default: http://127.0.0.1:3000
|
17
|
+
# @option options [Boolean] :skip_heartbeat skip querying :service_url to confirm API is responsive. Default: false
|
18
|
+
# @example
|
19
|
+
# df = DorFetcher::Client.new(:service_url => 'http://SERVICEURL')
|
20
|
+
def initialize(options = {})
|
21
|
+
# TODO: Check for a well formed URL and a 200 from the destination before just accepting this
|
22
22
|
@service_url = options[:service_url] || @@default_service_url
|
23
23
|
@site = RestClient::Resource.new(@service_url)
|
24
|
-
|
25
|
-
if not options[:skip_heartbeat]
|
26
|
-
raise "DorFetcher::Client Error! No response from #{@service_url}" if not self.is_alive?
|
27
|
-
end
|
24
|
+
raise "DorFetcher::Client Error! No response from #{@service_url}" unless options[:skip_heartbeat] || is_alive?
|
28
25
|
end
|
29
|
-
|
26
|
+
|
30
27
|
# Return service info (rails env, version deployed, last restart and last deploy)
|
31
|
-
|
28
|
+
# @return [hash] Hash containing service info
|
32
29
|
def service_info
|
33
30
|
resp = @site['about/version.json'].get
|
34
|
-
|
31
|
+
JSON[resp]
|
35
32
|
end
|
36
|
-
|
37
|
-
#Check to see if the dor-fetcher-service is responding to requests, this is a basic
|
38
|
-
|
33
|
+
|
34
|
+
# Check to see if the dor-fetcher-service is responding to requests, this is a basic heartbeat checker
|
35
|
+
# @return [Boolean] True for a service that responds, False for a service that does not.
|
39
36
|
def is_alive?
|
40
37
|
resp = @site.get
|
41
|
-
|
38
|
+
200.eql?(resp.code) && /PASSED/.match?(resp.body)
|
42
39
|
end
|
43
|
-
|
44
|
-
|
45
|
-
#Get a hash of all members of a collection and the collection itself
|
40
|
+
|
41
|
+
# Get a hash of all members of a collection and the collection itself
|
46
42
|
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
#pid/druid, title, date last modified, and count
|
43
|
+
# @param collection [String] we expect pid/druid
|
44
|
+
# @param params [Hash] we expect :count_only or any of @@supported_params
|
45
|
+
# @return [Hash] Hash of all objects in the collection including: pid/druid, title, date last modified, and count
|
51
46
|
def get_collection(collection, params = {})
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
#Get the count of the number of items in a collection, including the
|
56
|
-
#collection
|
57
|
-
|
58
|
-
|
59
|
-
#@return [Integer] Number found
|
47
|
+
query_api('collections', collection, params)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get the count of the number of items in a collection, including the collection object itself
|
51
|
+
# @param collection [String] we expect pid/druid
|
52
|
+
# @param params [Hash] any of @@supported_params
|
53
|
+
# @return [Integer] Number found
|
60
54
|
def get_count_for_collection(collection, params = {})
|
61
|
-
|
55
|
+
query_api('collections', collection, params.merge!(:count_only => true))
|
62
56
|
end
|
63
|
-
|
64
|
-
#Get a Hash of all the collections in the digital repository that are accessioned
|
65
|
-
|
66
|
-
#date last modified, and count
|
57
|
+
|
58
|
+
# Get a Hash of all the collections in the digital repository that are accessioned
|
59
|
+
# @return [Hash] All collections including: pid/druid, title, date last modified, and count
|
67
60
|
def list_all_collections
|
68
|
-
|
61
|
+
query_api('collections', '', {})
|
69
62
|
end
|
70
|
-
|
71
|
-
#Get a Hash of all the collections in the digital repository
|
72
|
-
|
73
|
-
#date last modified, and count
|
63
|
+
|
64
|
+
# Get a Hash of all the collections in the digital repository
|
65
|
+
# @return [Hash] All registered collections including: pid/druid, title, date last modified, and count
|
74
66
|
def list_registered_collections
|
75
|
-
|
67
|
+
query_api('collections', '', :status => 'registered')
|
76
68
|
end
|
77
|
-
|
78
|
-
#Get a Count of all the collections in the digital repository
|
79
|
-
|
69
|
+
|
70
|
+
# Get a Count of all the collections in the digital repository
|
71
|
+
# @return [Integer] Number of all collections
|
80
72
|
def total_collection_count
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
#Get the APO and all objects governed by the APO
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
#
|
94
|
-
#
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
#
|
103
|
-
#@return [Hash] Hash of all APOs including pid/druid, title,
|
104
|
-
#date last modified, and count
|
73
|
+
query_api('collections', '', :count_only => true)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get the APO and all objects governed by the APO
|
77
|
+
# @param apo [String] pid/druid of the APO
|
78
|
+
# @param params [Hash] we expect :count_only or any of @@supported_params
|
79
|
+
# @return [Hash] All objects governed by the APO including: pid/druid, title, date last modified, and count
|
80
|
+
def get_apo(apo, params = {})
|
81
|
+
query_api('apos', apo, params)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Get the count of the number of objects in an APO, including the
|
85
|
+
# APO object itself
|
86
|
+
# @param apo [String] we expect pid/druid
|
87
|
+
# @param params [Hash] we expect :count_only or any of @@supported_params
|
88
|
+
# @return [Integer] Number found
|
89
|
+
def get_count_for_apo(apo, params = {})
|
90
|
+
query_api('apos', apo, params.merge!(:count_only => true))
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get a Hash of all the APOs in the digital repository that are accessioned
|
94
|
+
# @return [Hash] All APOs including: pid/druid, title, date last modified, and count
|
105
95
|
def list_all_apos
|
106
|
-
|
96
|
+
query_api('apos', '', {})
|
107
97
|
end
|
108
98
|
|
109
|
-
#Get a Hash of all the APOs in the digital repository that are registered
|
110
|
-
|
111
|
-
#date last modified, and count
|
99
|
+
# Get a Hash of all the APOs in the digital repository that are registered
|
100
|
+
# @return [Hash] All registered APOs including: pid/druid, title, date last modified, and count
|
112
101
|
def list_registered_apos
|
113
|
-
|
102
|
+
query_api('apos', '', :status => 'registered')
|
114
103
|
end
|
115
|
-
|
116
|
-
#Get a Count of all the APOs in the digital repository
|
117
|
-
|
104
|
+
|
105
|
+
# Get a Count of all the APOs in the digital repository
|
106
|
+
# @return [Integer] Number of all APOs
|
118
107
|
def total_apo_count
|
119
|
-
|
108
|
+
query_api('apos', '', :count_only => true)
|
120
109
|
end
|
121
|
-
|
122
|
-
#
|
123
|
-
#
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
def druid_array(response,params={})
|
110
|
+
|
111
|
+
# Parses full Hash into an array containing only the druids
|
112
|
+
# @param response [Hash] Hash as returned by query_api
|
113
|
+
# @param params [Hash{Symbol=>Boolean}] options
|
114
|
+
# @option params [Boolean] :no_prefix if true (default), remove the 'druid:' prefix on all druids
|
115
|
+
# @return [Array{String}] all druids in the supplied Hash
|
116
|
+
def druid_array(response, params = {})
|
128
117
|
return_list = []
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
druid.gsub!('druid:','') if params[:no_prefix]
|
136
|
-
return_list << druid
|
137
|
-
end
|
138
|
-
end
|
118
|
+
response.each do |key, items|
|
119
|
+
next if key == @@counts_key
|
120
|
+
items.each do |item|
|
121
|
+
next if item['druid'].nil?
|
122
|
+
druid = item['druid'].downcase
|
123
|
+
return_list << (params[:no_prefix] ? druid.gsub('druid:', '') : druid)
|
139
124
|
end
|
140
125
|
end
|
141
|
-
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
#
|
146
|
-
|
147
|
-
|
148
|
-
#@param params [Hash] we expect :count_only or any of @@supported_params
|
149
|
-
#@return [Hash] Hash of all objects governed by the APO including
|
150
|
-
#pid/druid, title, date last modified, and count
|
151
|
-
def query_api(base, druid, params)
|
126
|
+
return_list
|
127
|
+
end
|
128
|
+
|
129
|
+
# Synthesize URL from base, druid and params
|
130
|
+
# @see #query_api for args
|
131
|
+
# @return [String] URL
|
132
|
+
def query_url(base, druid, params)
|
152
133
|
url = "#{@site}/#{base}"
|
153
|
-
url +="/#{druid}" unless druid.nil? || druid.empty?
|
154
|
-
url +=
|
134
|
+
url += "/#{druid}" unless druid.nil? || druid.empty?
|
135
|
+
url += add_params(params).to_s unless params.nil? || params.empty?
|
136
|
+
url
|
137
|
+
end
|
138
|
+
|
139
|
+
# Query a RESTful API and return the JSON result as a Hash
|
140
|
+
# @param base [String] The name of controller of the Rails App you wish to route to
|
141
|
+
# @param druid [String] The druid/pid of the object you wish to query, or empty string for no specific druid
|
142
|
+
# @param params [Hash] we expect :count_only or any of @@supported_params
|
143
|
+
# @option params [Hash] :count_only
|
144
|
+
# @return [Hash,Integer] All objects governed by the APO including pid/druid, title, date last modified, and count -- or just the count if :count_only
|
145
|
+
def query_api(base, druid, params)
|
146
|
+
url = query_url(base, druid, params)
|
155
147
|
begin
|
156
|
-
#We
|
157
|
-
resp = RestClient::Request.execute(:method=> :get, :url=>url, :timeout=>
|
158
|
-
rescue
|
159
|
-
|
148
|
+
# We use RestClient::Request.execute here for the longer timeout option
|
149
|
+
resp = RestClient::Request.execute(:method => :get, :url => url, :timeout => 180)
|
150
|
+
rescue RestClient::Exception => e
|
151
|
+
warn "Connection Error with url #{url}: #{e.message}"
|
152
|
+
raise e
|
160
153
|
end
|
161
|
-
|
162
|
-
#RestClient monkey patches its response so it looks like a string, but really isn't.
|
163
|
-
#If you just dd resp.to_i, you'll get the HTML Code, normally 200, not the actually body text you want
|
164
|
-
return resp[0..resp.size].to_i if params[:count_only] == true
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
uri.query_values=input_params
|
177
|
-
qs=uri.query.gsub("count_only=true",@@count_only_param)
|
178
|
-
return "?#{qs}"
|
179
|
-
end
|
180
|
-
|
181
|
-
#Add the parameter so query_api knows only to get a count of the documents in solr
|
182
|
-
#
|
183
|
-
#@param params [Hash] {The existing parameters, eg time and tag}
|
184
|
-
#@return [Hash] the params Hash plus the key/value set :count_only=>true
|
185
|
-
def add_count_only_param(params)
|
186
|
-
params.store(:count_only, true)
|
187
|
-
return params
|
188
|
-
end
|
189
|
-
|
190
|
-
#Get the Base URL this instance will run RESTful API calls against
|
191
|
-
#@return [String] the url
|
192
|
-
def service_url
|
193
|
-
return @service_url
|
194
|
-
end
|
195
|
-
|
154
|
+
|
155
|
+
# RestClient monkey patches its response so it looks like a string, but really isn't.
|
156
|
+
# If you just dd resp.to_i, you'll get the HTML Code, normally 200, not the actually body text you want
|
157
|
+
return resp[0..resp.size].to_i if params[:count_only] == true
|
158
|
+
JSON[resp] # Convert the response JSON to a Ruby Hash
|
159
|
+
end
|
160
|
+
|
161
|
+
# Transform a parameter hash into a RESTful API parameter format
|
162
|
+
# @param input_params [Hash{Symbol=>Object}] The existing parameters, eg time and tag
|
163
|
+
# @return [String] parameters in the Hash now formatted into a RESTful parameter string
|
164
|
+
def add_params(input_params)
|
165
|
+
uri = Addressable::URI.new
|
166
|
+
uri.query_values = input_params.select { |key, _val| @@supported_params.include?(key) }
|
167
|
+
'?' + uri.query.gsub('count_only=true', @@count_only_param)
|
168
|
+
end
|
196
169
|
end
|
197
|
-
|
198
|
-
end
|
170
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dor-fetcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carrick Rogers
|
@@ -12,102 +12,130 @@ bindir: bin
|
|
12
12
|
cert_chain: []
|
13
13
|
date: 2014-12-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: rubocop
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
15
43
|
- !ruby/object:Gem::Dependency
|
16
44
|
name: rspec
|
17
45
|
requirement: !ruby/object:Gem::Requirement
|
18
46
|
requirements:
|
19
|
-
- -
|
47
|
+
- - ">="
|
20
48
|
- !ruby/object:Gem::Version
|
21
49
|
version: '0'
|
22
50
|
type: :development
|
23
51
|
prerelease: false
|
24
52
|
version_requirements: !ruby/object:Gem::Requirement
|
25
53
|
requirements:
|
26
|
-
- -
|
54
|
+
- - ">="
|
27
55
|
- !ruby/object:Gem::Version
|
28
56
|
version: '0'
|
29
57
|
- !ruby/object:Gem::Dependency
|
30
58
|
name: vcr
|
31
59
|
requirement: !ruby/object:Gem::Requirement
|
32
60
|
requirements:
|
33
|
-
- -
|
61
|
+
- - ">="
|
34
62
|
- !ruby/object:Gem::Version
|
35
63
|
version: '0'
|
36
64
|
type: :development
|
37
65
|
prerelease: false
|
38
66
|
version_requirements: !ruby/object:Gem::Requirement
|
39
67
|
requirements:
|
40
|
-
- -
|
68
|
+
- - ">="
|
41
69
|
- !ruby/object:Gem::Version
|
42
70
|
version: '0'
|
43
71
|
- !ruby/object:Gem::Dependency
|
44
72
|
name: webmock
|
45
73
|
requirement: !ruby/object:Gem::Requirement
|
46
74
|
requirements:
|
47
|
-
- -
|
75
|
+
- - ">="
|
48
76
|
- !ruby/object:Gem::Version
|
49
77
|
version: '0'
|
50
78
|
type: :development
|
51
79
|
prerelease: false
|
52
80
|
version_requirements: !ruby/object:Gem::Requirement
|
53
81
|
requirements:
|
54
|
-
- -
|
82
|
+
- - ">="
|
55
83
|
- !ruby/object:Gem::Version
|
56
84
|
version: '0'
|
57
85
|
- !ruby/object:Gem::Dependency
|
58
86
|
name: yard
|
59
87
|
requirement: !ruby/object:Gem::Requirement
|
60
88
|
requirements:
|
61
|
-
- -
|
89
|
+
- - ">="
|
62
90
|
- !ruby/object:Gem::Version
|
63
91
|
version: '0'
|
64
92
|
type: :development
|
65
93
|
prerelease: false
|
66
94
|
version_requirements: !ruby/object:Gem::Requirement
|
67
95
|
requirements:
|
68
|
-
- -
|
96
|
+
- - ">="
|
69
97
|
- !ruby/object:Gem::Version
|
70
98
|
version: '0'
|
71
99
|
- !ruby/object:Gem::Dependency
|
72
100
|
name: coveralls
|
73
101
|
requirement: !ruby/object:Gem::Requirement
|
74
102
|
requirements:
|
75
|
-
- -
|
103
|
+
- - ">="
|
76
104
|
- !ruby/object:Gem::Version
|
77
105
|
version: '0'
|
78
106
|
type: :development
|
79
107
|
prerelease: false
|
80
108
|
version_requirements: !ruby/object:Gem::Requirement
|
81
109
|
requirements:
|
82
|
-
- -
|
110
|
+
- - ">="
|
83
111
|
- !ruby/object:Gem::Version
|
84
112
|
version: '0'
|
85
113
|
- !ruby/object:Gem::Dependency
|
86
114
|
name: rest-client
|
87
115
|
requirement: !ruby/object:Gem::Requirement
|
88
116
|
requirements:
|
89
|
-
- -
|
117
|
+
- - ">="
|
90
118
|
- !ruby/object:Gem::Version
|
91
119
|
version: '0'
|
92
120
|
type: :runtime
|
93
121
|
prerelease: false
|
94
122
|
version_requirements: !ruby/object:Gem::Requirement
|
95
123
|
requirements:
|
96
|
-
- -
|
124
|
+
- - ">="
|
97
125
|
- !ruby/object:Gem::Version
|
98
126
|
version: '0'
|
99
127
|
- !ruby/object:Gem::Dependency
|
100
128
|
name: addressable
|
101
129
|
requirement: !ruby/object:Gem::Requirement
|
102
130
|
requirements:
|
103
|
-
- -
|
131
|
+
- - ">="
|
104
132
|
- !ruby/object:Gem::Version
|
105
133
|
version: '0'
|
106
134
|
type: :runtime
|
107
135
|
prerelease: false
|
108
136
|
version_requirements: !ruby/object:Gem::Requirement
|
109
137
|
requirements:
|
110
|
-
- -
|
138
|
+
- - ">="
|
111
139
|
- !ruby/object:Gem::Version
|
112
140
|
version: '0'
|
113
141
|
description: Wrapper for the Dor Fetcher Services RESTful API.
|
@@ -120,7 +148,7 @@ extensions: []
|
|
120
148
|
extra_rdoc_files: []
|
121
149
|
files:
|
122
150
|
- lib/dor-fetcher.rb
|
123
|
-
homepage:
|
151
|
+
homepage: https://github.com/sul-dlss/dor-fetcher
|
124
152
|
licenses:
|
125
153
|
- Apache-2.0
|
126
154
|
metadata: {}
|
@@ -130,19 +158,18 @@ require_paths:
|
|
130
158
|
- lib
|
131
159
|
required_ruby_version: !ruby/object:Gem::Requirement
|
132
160
|
requirements:
|
133
|
-
- -
|
161
|
+
- - ">="
|
134
162
|
- !ruby/object:Gem::Version
|
135
163
|
version: '0'
|
136
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
165
|
requirements:
|
138
|
-
- -
|
166
|
+
- - ">="
|
139
167
|
- !ruby/object:Gem::Version
|
140
168
|
version: '0'
|
141
169
|
requirements: []
|
142
170
|
rubyforge_project:
|
143
|
-
rubygems_version: 2.
|
171
|
+
rubygems_version: 2.7.8
|
144
172
|
signing_key:
|
145
173
|
specification_version: 4
|
146
174
|
summary: DorFetcher Gem
|
147
175
|
test_files: []
|
148
|
-
has_rdoc:
|