relaton-nist 1.16.3 → 1.16.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +34 -27
- data/lib/relaton_nist/hit_collection.rb +21 -9
- data/lib/relaton_nist/nist_bibliography.rb +24 -28
- data/lib/relaton_nist/scrapper.rb +22 -18
- data/lib/relaton_nist/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9584f82c13f12da662266b2de0e11eb37241a6b3c4994d28720af44bdb713632
|
4
|
+
data.tar.gz: 1d14d47f043644e96cd42a8419117e12111623e5e80a7a2cb37ac6c1420d37c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d86cd19ea38a1743044ce99e28c6c5c0adc4805d5c45d6145ff4f724b10a9f9115a495cd226514fbd66e2213dce3ba807baddf3275528ae438917c36f3784a8
|
7
|
+
data.tar.gz: 0c8f579f4b9eca0402d1a28c986ad188d72b2dac57a8f4cc92d18a17ea235d7fe7ebd03a3f38dcd17e91496adc595ce347b8a1c73f449d48008e54655c5ce9e1
|
data/README.adoc
CHANGED
@@ -89,10 +89,12 @@ end
|
|
89
89
|
|
90
90
|
[source,ruby]
|
91
91
|
----
|
92
|
-
hit_collection = RelatonNist::NistBibliography.search("8200")
|
93
|
-
|
92
|
+
hit_collection = RelatonNist::NistBibliography.search("NISTIR 8200")
|
93
|
+
[relaton-nist] (NIST IR 8200) Fetching from csrc.nist.gov ...
|
94
|
+
[relaton-nist] (NIST IR 8200) Fetching from Relaton repository ...
|
95
|
+
=> <RelatonNist::HitCollection:0x00000000004b28 @ref=NIST IR 8200 @fetched=false>
|
94
96
|
|
95
|
-
item = hit_collection[
|
97
|
+
item = hit_collection[0].fetch
|
96
98
|
=> #<RelatonNist::NistBibliographicItem:0x007fc049aa6778
|
97
99
|
...
|
98
100
|
----
|
@@ -101,9 +103,9 @@ item = hit_collection[1].fetch
|
|
101
103
|
[source,ruby]
|
102
104
|
----
|
103
105
|
item.to_xml
|
104
|
-
=> "<bibitem id="
|
105
|
-
<fetched>
|
106
|
-
<title format="text/plain" language="en" script="Latn">
|
106
|
+
=> "<bibitem id="NISTIR8200" type="standard" schema-version="v1.2.4">
|
107
|
+
<fetched>2023-10-16</fetched>
|
108
|
+
<title format="text/plain" language="en" script="Latn">Interagency report on the status of international cybersecurity standardization for the internet of things (IoT)</title>
|
107
109
|
...
|
108
110
|
<bibitem>"
|
109
111
|
----
|
@@ -111,9 +113,9 @@ With argument `bibdata: true` it outputs XML wrapped by `bibdata` element and ad
|
|
111
113
|
[source,ruby]
|
112
114
|
----
|
113
115
|
item.to_xml bibdata: true
|
114
|
-
=> "<bibdata type="standard" schema-version="v1.2.
|
115
|
-
<fetched>
|
116
|
-
<title format="text/plain" language="en" script="Latn">
|
116
|
+
=> "<bibdata type="standard" schema-version="v1.2.4">
|
117
|
+
<fetched>2023-10-16</fetched>
|
118
|
+
<title format="text/plain" language="en" script="Latn">Interagency report on the status of international cybersecurity standardization for the internet of things (IoT)</title>
|
117
119
|
...
|
118
120
|
<ext schema-version="v1.0.0">
|
119
121
|
<doctype>standard</doctype>
|
@@ -124,9 +126,10 @@ item.to_xml bibdata: true
|
|
124
126
|
=== Get code, and year
|
125
127
|
[source,ruby]
|
126
128
|
----
|
127
|
-
RelatonNist::NistBibliography.get("NIST IR 8200", "2018"
|
128
|
-
[relaton-nist] (NIST
|
129
|
-
[relaton-nist] (NIST IR 8200)
|
129
|
+
RelatonNist::NistBibliography.get("NIST IR 8200", "2018")
|
130
|
+
[relaton-nist] (NIST SP 8200:2018) Fetching from csrc.nist.gov ...
|
131
|
+
[relaton-nist] (NIST IR 8200:2018) Fetching from Relaton repository...
|
132
|
+
[relaton-nist] (NIST IR 8200:2018) Found: `NIST IR 8200`
|
130
133
|
=> #<RelatonNist::NistBibliographicItem:0x00007fab74a572c0
|
131
134
|
...
|
132
135
|
----
|
@@ -153,10 +156,10 @@ NIST FIPS {docnumber}
|
|
153
156
|
----
|
154
157
|
[source,ruby]
|
155
158
|
----
|
156
|
-
RelatonNist::NistBibliography.get("SP 800-205 (February 2019) (
|
157
|
-
[relaton-nist] (SP 800-205)
|
158
|
-
[relaton-nist] (SP 800-205)
|
159
|
-
=> #<RelatonNist::NistBibliographicItem:
|
159
|
+
RelatonNist::NistBibliography.get("NIST SP 800-205 (February 2019) (IPD)")
|
160
|
+
[relaton-nist] (NIST SP 800-205) Fetching from csrc.nist.gov ...
|
161
|
+
[relaton-nist] (NIST SP 800-205) Found: `NIST SP 800-205 (Draft)`
|
162
|
+
=> #<RelatonNist::NistBibliographicItem:0x00000001105afdc8
|
160
163
|
...
|
161
164
|
----
|
162
165
|
|
@@ -172,22 +175,22 @@ Referehces can contain optional parameters `{ptN}{vN}{verN}{rN}{/Add}`:
|
|
172
175
|
[source,ruby]
|
173
176
|
----
|
174
177
|
item = RelatonNist::NistBibliography.get 'NIST SP 800-67r1'
|
175
|
-
[relaton-nist] (NIST SP 800-67r1)
|
176
|
-
[relaton-nist] (NIST SP 800-67r1)
|
177
|
-
=> #<RelatonNist::NistBibliographicItem:
|
178
|
+
[relaton-nist] (NIST SP 800-67r1) Fetching from csrc.nist.gov ...
|
179
|
+
[relaton-nist] (NIST SP 800-67r1) Found: `NIST SP 800-67 Rev. 1`
|
180
|
+
=> #<RelatonNist::NistBibliographicItem:0x00000001105acd08
|
178
181
|
...
|
179
182
|
|
180
183
|
item.docidentifier.first.id
|
181
|
-
=> "SP 800-67 Rev. 1"
|
184
|
+
=> "NIST SP 800-67 Rev. 1"
|
182
185
|
|
183
|
-
item = RelatonNist::NistBibliography.get 'SP 800-38A/Add'
|
184
|
-
[relaton-nist] (SP 800-38A/Add)
|
185
|
-
[relaton-nist] (SP 800-38A/Add)
|
186
|
-
=> #<RelatonNist::NistBibliographicItem:
|
186
|
+
item = RelatonNist::NistBibliography.get 'NIST SP 800-38A/Add'
|
187
|
+
[relaton-nist] (NIST SP 800-38A/Add) Fetching from csrc.nist.gov ...
|
188
|
+
[relaton-nist] (NIST SP 800-38A/Add) Found: `NIST SP 800-38A-Add`
|
189
|
+
=> #<RelatonNist::NistBibliographicItem:0x00000001105abf48
|
187
190
|
...
|
188
191
|
|
189
192
|
item.docidentifier.first.id
|
190
|
-
=> "SP 800-38A-Add"
|
193
|
+
=> "NIST SP 800-38A-Add"
|
191
194
|
----
|
192
195
|
|
193
196
|
=== Typed links
|
@@ -197,8 +200,12 @@ NIST documents may have `src` and `doi` link types.
|
|
197
200
|
[source,ruby]
|
198
201
|
----
|
199
202
|
item.link
|
200
|
-
=> [#<RelatonBib::TypedUri:
|
201
|
-
|
203
|
+
=> [#<RelatonBib::TypedUri:0x0000000111087a98
|
204
|
+
@content=#<Addressable::URI:0x8c0 URI:https://csrc.nist.gov/pubs/sp/800/38/a/sup/final>,
|
205
|
+
@language=nil,
|
206
|
+
@script=nil,
|
207
|
+
@type="src">,
|
208
|
+
#<RelatonBib::TypedUri:0x00000001110879a8 @content=#<Addressable::URI:0x8d4 URI:https://doi.org/10.6028/NIST.SP.800-38A-Add>, @language=nil, @script=nil, @type="doi">]
|
202
209
|
----
|
203
210
|
|
204
211
|
=== Create bibliographic item from YAML
|
@@ -12,6 +12,9 @@ module RelatonNist
|
|
12
12
|
GHNISTDATA = "https://raw.githubusercontent.com/relaton/relaton-data-nist/main/"
|
13
13
|
INDEX_FILE = "index-v1.yaml"
|
14
14
|
|
15
|
+
attr_reader :reference
|
16
|
+
attr_accessor :array
|
17
|
+
|
15
18
|
#
|
16
19
|
# @param [String] text reference
|
17
20
|
# @param [String, nil] year reference
|
@@ -20,6 +23,7 @@ module RelatonNist
|
|
20
23
|
#
|
21
24
|
def initialize(text, year = nil, opts = {})
|
22
25
|
super text, year
|
26
|
+
@reference = year && !text.match?(/:\d{4}$/) ? "#{text}:#{year}" : text
|
23
27
|
@opts = opts
|
24
28
|
end
|
25
29
|
|
@@ -54,16 +58,21 @@ module RelatonNist
|
|
54
58
|
# @return [Array<RelatonNist::Hit>] hits
|
55
59
|
#
|
56
60
|
def search_filter # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
|
57
|
-
@array.select do |item|
|
61
|
+
arr = @array.select do |item|
|
58
62
|
parts = doi_parts(item.hit[:json]) || code_parts(item.hit[:code])
|
63
|
+
iteration = item.hit.dig(:json, "iteration")
|
64
|
+
draft = parts[:draft] || (!iteration.nil? && iteration.match?(/\wpd/i))
|
59
65
|
refparts[:code] && [parts[:series], item.hit[:series]].include?(refparts[:series]) &&
|
60
66
|
refparts[:code].casecmp(parts[:code].upcase).zero? &&
|
61
67
|
refparts[:prt] == parts[:prt] &&
|
62
68
|
(refparts[:vol].nil? || refparts[:vol] == parts[:vol]) &&
|
63
69
|
(refparts[:ver].nil? || refparts[:ver] == parts[:ver]) &&
|
64
70
|
(refparts[:rev].nil? || refparts[:rev] == parts[:rev]) &&
|
65
|
-
refparts[:draft] ==
|
71
|
+
refparts[:draft] == draft && refparts[:add] == parts[:add]
|
66
72
|
end
|
73
|
+
dup = self.dup
|
74
|
+
dup.array = arr
|
75
|
+
dup
|
67
76
|
end
|
68
77
|
|
69
78
|
private
|
@@ -99,7 +108,7 @@ module RelatonNist
|
|
99
108
|
ver: match(/v(?:er)?(?<val>[\d.]+)/, id),
|
100
109
|
rev: match(/r(?<val>\d+)/, id),
|
101
110
|
add: match(/-Add(?<val>\d*)/, id),
|
102
|
-
draft: !match(/\.ipd/, id).nil?,
|
111
|
+
draft: !match(/\.ipd|-draft/, id).nil?,
|
103
112
|
}
|
104
113
|
end
|
105
114
|
|
@@ -181,7 +190,10 @@ module RelatonNist
|
|
181
190
|
# @raise [OpenURI::HTTPError] if GitHub repo is not available
|
182
191
|
#
|
183
192
|
def from_ga # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
193
|
+
Util.warn "(#{@reference}) Fetching from Relaton repository ..."
|
184
194
|
ref = full_ref
|
195
|
+
return [] if ref.empty?
|
196
|
+
|
185
197
|
# fn = ref.gsub(%r{[/\s:.]}, "_").upcase
|
186
198
|
index = Relaton::Index.find_or_create :nist, url: "#{GHNISTDATA}index-v1.zip", file: INDEX_FILE
|
187
199
|
rows = index.search(ref).sort_by { |r| r[:id] }
|
@@ -209,20 +221,20 @@ module RelatonNist
|
|
209
221
|
#
|
210
222
|
# @return [Array<RelatonNist::Hit>] hits
|
211
223
|
#
|
212
|
-
def from_json
|
224
|
+
def from_json # rubocop:disable Metrics/AbcSize
|
225
|
+
Util.warn "(#{@reference}) Fetching from csrc.nist.gov ..."
|
213
226
|
select_data.map do |h|
|
214
227
|
/(?<series>(?<=-)\w+$)/ =~ h["series"]
|
215
228
|
title = [h["title-main"], h["title-sub"]].compact.join " - "
|
216
229
|
release_date = RelatonBib.parse_date h["published-date"], false
|
217
|
-
Hit.new({ code: docidentifier(h), series: series.upcase, title: title,
|
218
|
-
|
219
|
-
release_date: release_date, json: h }, self)
|
230
|
+
Hit.new({ code: docidentifier(h), series: series.upcase, title: title, url: h["uri"],
|
231
|
+
status: h["status"], release_date: release_date, json: h }, self)
|
220
232
|
end
|
221
233
|
end
|
222
234
|
|
223
235
|
def docidentifier(json) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
224
|
-
parts = doi_parts json
|
225
|
-
return json["docidentifier"] unless parts
|
236
|
+
parts = doi_parts(json) || code_parts(json["docidentifier"])
|
237
|
+
# return json["docidentifier"] unless parts
|
226
238
|
|
227
239
|
id = parts[:code]
|
228
240
|
id = "NIST #{parts[:series]} #{id}" if parts[:series]
|
@@ -84,10 +84,10 @@ module RelatonNist
|
|
84
84
|
result = nistbib_search_filter(code, year, opts) || (return nil)
|
85
85
|
ret = nistbib_results_filter(result, year, opts)
|
86
86
|
if ret[:ret]
|
87
|
-
Util.warn "(#{
|
87
|
+
Util.warn "(#{result.reference}) Found: `#{ret[:ret].docidentifier.first.id}`"
|
88
88
|
ret[:ret]
|
89
89
|
else
|
90
|
-
fetch_ref_err(
|
90
|
+
fetch_ref_err(result.reference, year, ret[:years])
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -114,20 +114,19 @@ module RelatonNist
|
|
114
114
|
when "F" then "final"
|
115
115
|
else iter
|
116
116
|
end
|
117
|
-
result.
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
117
|
+
result.each do |h|
|
118
|
+
r = h.fetch
|
119
|
+
if opts[:date]
|
120
|
+
dates = r.date.select { |d| d.on(:date) == opts[:date] }
|
121
|
+
next if dates.empty?
|
122
|
+
end
|
123
|
+
next if iter && r.status.iteration != iteration
|
124
|
+
return { ret: r } if !year
|
125
125
|
|
126
|
-
|
127
|
-
|
126
|
+
r.date.select { |d| d.type == "published" }.each do |d|
|
127
|
+
return { ret: r } if year.to_i == d.on(:year)
|
128
128
|
|
129
|
-
|
130
|
-
end
|
129
|
+
missed_years << d.on(:year)
|
131
130
|
end
|
132
131
|
end
|
133
132
|
{ years: missed_years }
|
@@ -141,13 +140,13 @@ module RelatonNist
|
|
141
140
|
#
|
142
141
|
# @return [Array<RelatonNist::NistBibliographicItem>] bibliographic items
|
143
142
|
#
|
144
|
-
def fetch_pages(hits, threads)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
143
|
+
# def fetch_pages(hits, threads)
|
144
|
+
# workers = RelatonBib::WorkersPool.new threads
|
145
|
+
# workers.worker { |w| { i: w[:i], hit: w[:hit].fetch } }
|
146
|
+
# hits.each_with_index { |hit, i| workers << { i: i, hit: hit } }
|
147
|
+
# workers.end
|
148
|
+
# workers.result.sort_by { |a| a[:i] }.map { |x| x[:hit] }
|
149
|
+
# end
|
151
150
|
|
152
151
|
#
|
153
152
|
# Get search results and filter them by code and year
|
@@ -160,7 +159,6 @@ module RelatonNist
|
|
160
159
|
# @return [RelatonNist::HitCollection] hits collection
|
161
160
|
#
|
162
161
|
def nistbib_search_filter(code, year, opts)
|
163
|
-
Util.warn "(#{code}) fetching..."
|
164
162
|
result = search(code, year, opts)
|
165
163
|
result.search_filter
|
166
164
|
end
|
@@ -168,21 +166,19 @@ module RelatonNist
|
|
168
166
|
#
|
169
167
|
# Outputs warning message if no match found
|
170
168
|
#
|
171
|
-
# @param [String]
|
169
|
+
# @param [String] ref reference
|
172
170
|
# @param [String, nil] year year
|
173
171
|
# @param [Array<String>] missed_years missed years
|
174
172
|
#
|
175
173
|
# @return [nil] nil
|
176
174
|
#
|
177
|
-
def fetch_ref_err(
|
178
|
-
|
179
|
-
Util.warn "WARNING: no match found online for `#{id}`. " \
|
180
|
-
"The code must be exactly like it is on the standards website."
|
175
|
+
def fetch_ref_err(ref, year, missed_years)
|
176
|
+
Util.warn "(#{ref}) No found."
|
181
177
|
unless missed_years.empty?
|
182
178
|
Util.warn "(There was no match for #{year}, though there " \
|
183
179
|
"were matches found for `#{missed_years.join('`, `')}`.)"
|
184
180
|
end
|
185
|
-
if /\d-\d/.match?
|
181
|
+
if /\d-\d/.match? ref
|
186
182
|
Util.warn "The provided document part may not exist, " \
|
187
183
|
"or the document may no longer be published in parts."
|
188
184
|
end
|
@@ -51,7 +51,7 @@ module RelatonNist
|
|
51
51
|
script: [json["script"]],
|
52
52
|
docstatus: fetch_status(json), # hit_data[:status]),
|
53
53
|
copyright: fetch_copyright(json["published-date"]),
|
54
|
-
relation: fetch_relations_json(
|
54
|
+
relation: fetch_relations_json(hit_data),
|
55
55
|
place: ["Gaithersburg, MD"],
|
56
56
|
keyword: fetch_keywords(json),
|
57
57
|
commentperiod: fetch_commentperiod_json(json),
|
@@ -80,10 +80,18 @@ module RelatonNist
|
|
80
80
|
def fetch_status(doc)
|
81
81
|
stage = doc["status"]
|
82
82
|
subst = doc["substage"]
|
83
|
-
iter =
|
83
|
+
iter = iteration(doc["iteration"])
|
84
84
|
RelatonNist::DocumentStatus.new stage: stage, substage: subst, iteration: iter.to_s
|
85
85
|
end
|
86
86
|
|
87
|
+
def iteration(iter)
|
88
|
+
case iter
|
89
|
+
when "initial", "ipd" then 1
|
90
|
+
when /(\d)pd/i then $1
|
91
|
+
else iter
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
87
95
|
# Fetch titles.
|
88
96
|
# @param hit_data [Hash]
|
89
97
|
# @return [Array<Hash>]
|
@@ -109,7 +117,7 @@ module RelatonNist
|
|
109
117
|
# d = doc.at("//span[@id='pub-release-date']")&.text&.strip
|
110
118
|
# issued = RelatonBib.parse_date d
|
111
119
|
# end
|
112
|
-
dates << { type: "issued", on: issued.to_s }
|
120
|
+
dates << { type: "issued", on: issued.to_s } if issued
|
113
121
|
dates
|
114
122
|
end
|
115
123
|
|
@@ -182,9 +190,9 @@ module RelatonNist
|
|
182
190
|
# @return [String, NilClass]
|
183
191
|
def fetch_edition(doc)
|
184
192
|
# if doc.is_a? Hash
|
185
|
-
return unless doc["edition"]
|
193
|
+
return unless doc["edition"] || doc["revision"]
|
186
194
|
|
187
|
-
rev = doc["edition"]
|
195
|
+
rev = doc["edition"] || doc["revision"]
|
188
196
|
"Revision #{rev}"
|
189
197
|
end
|
190
198
|
|
@@ -210,13 +218,14 @@ module RelatonNist
|
|
210
218
|
links
|
211
219
|
end
|
212
220
|
|
213
|
-
def fetch_relations_json(
|
221
|
+
def fetch_relations_json(hit)
|
222
|
+
doc = hit[:json]
|
214
223
|
relations = doc["supersedes"].map do |r|
|
215
|
-
doc_relation "supersedes",
|
224
|
+
doc_relation "supersedes", hit[:code], r["uri"]
|
216
225
|
end
|
217
226
|
|
218
227
|
relations + doc["superseded-by"].map do |r|
|
219
|
-
doc_relation "updates",
|
228
|
+
doc_relation "updates", hit[:code], r["uri"]
|
220
229
|
end
|
221
230
|
end
|
222
231
|
|
@@ -230,16 +239,11 @@ module RelatonNist
|
|
230
239
|
t = "obsoletes"
|
231
240
|
else t = type
|
232
241
|
end
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
content: ref, language: lang, script: script, format: "text/plain",
|
239
|
-
),
|
240
|
-
link: [RelatonBib::TypedUri.new(type: "src", content: uri)],
|
241
|
-
),
|
242
|
-
)
|
242
|
+
ids = [RelatonBib::DocumentIdentifier.new(id: ref, type: "NIST", primary: true)]
|
243
|
+
fref = RelatonBib::FormattedRef.new(content: ref, language: lang, script: script, format: "text/plain")
|
244
|
+
link = [RelatonBib::TypedUri.new(type: "src", content: uri)]
|
245
|
+
bib = RelatonBib::BibliographicItem.new(formattedref: fref, link: link, docid: ids)
|
246
|
+
DocumentRelation.new(type: t, description: descr, bibitem: bib)
|
243
247
|
end
|
244
248
|
|
245
249
|
# @param doc [Hash]
|
data/lib/relaton_nist/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relaton-nist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.16.
|
4
|
+
version: 1.16.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: relaton-bib
|