relaton-nist 1.16.3 → 1.16.4

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
2
  SHA256:
3
- metadata.gz: b00f5d1fb998afa9409df9108f6336cf067fc41faef13e8aca3a95cc8b289596
4
- data.tar.gz: 17f09df20a20798c1a56b5b7b887d7be9a8509e3a948b731603cbd95e684346e
3
+ metadata.gz: 9584f82c13f12da662266b2de0e11eb37241a6b3c4994d28720af44bdb713632
4
+ data.tar.gz: 1d14d47f043644e96cd42a8419117e12111623e5e80a7a2cb37ac6c1420d37c1
5
5
  SHA512:
6
- metadata.gz: 1dfc55cfa95ad85bf38a3a582d5d92fea954f7fd7e66537d59d78f672efd798f10bb1bed8ee804c4c9b062017fa7202edd38295b9456c990368883bb77861436
7
- data.tar.gz: 0e3b65872354a4c48dfd1f752ec160d3d2bdd47bafa9e678a3a5e200189589ce1e09b25e17df7c05bf6f643290f10ad3925bd9efb415525cf1c91894d3c6f92a
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
- => <RelatonNist::HitCollection:0x007fc069d19da0 @ref=8200 @fetched=false>
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[1].fetch
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="SP800-160Vol.1Ver.1Rev.1" type="standard" schema-version="v1.2.1">
105
- <fetched>2022-12-05</fetched>
106
- <title format="text/plain" language="en" script="Latn">Engineering Trustworthy Secure Systems</title>
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.1">
115
- <fetched>2022-12-05</fetched>
116
- <title format="text/plain" language="en" script="Latn">Engineering Trustworthy Secure Systems</title>
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 IR 8200) fetching...
129
- [relaton-nist] (NIST IR 8200) found `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) (PD)")
157
- [relaton-nist] (SP 800-205) fetching...
158
- [relaton-nist] (SP 800-205) found `SP 800-205 (Draft)`
159
- => #<RelatonNist::NistBibliographicItem:0x007fc059934768
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) fetching...
176
- [relaton-nist] (NIST SP 800-67r1) found `SP 800-67 Rev. 1`
177
- => #<RelatonNist::NistBibliographicItem:0x00007fab748ae978
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) fetching...
185
- [relaton-nist] (SP 800-38A/Add) found `SP 800-38A-Add`
186
- => #<RelatonNist::NistBibliographicItem:0x007fd88c21d880
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:0x00007f901971dc10 @content=#<Addressable::URI:0x62c URI:https://csrc.nist.gov/publications/detail/sp/800-67/rev-2/final>, @type="src">,
201
- #<RelatonBib::TypedUri:0x00007f901971d6e8 @content=#<Addressable::URI:0x640 URI:https://doi.org/10.6028/NIST.SP.800-67r2>, @type="doi">]
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] == parts[:draft] && refparts[:add] == parts[:add]
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
- url: h["uri"], status: h["status"],
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 "(#{code}) found `#{ret[:ret].docidentifier.first.id}`"
87
+ Util.warn "(#{result.reference}) Found: `#{ret[:ret].docidentifier.first.id}`"
88
88
  ret[:ret]
89
89
  else
90
- fetch_ref_err(code, year, ret[:years])
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.each_slice(3) do |s| # ISO website only allows 3 connections
118
- fetch_pages(s, 3).each_with_index do |r, _i|
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
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
- r.date.select { |d| d.type == "published" }.each do |d|
127
- return { ret: r } if year.to_i == d.on(:year)
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
- missed_years << d.on(:year)
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
- workers = RelatonBib::WorkersPool.new threads
146
- workers.worker { |w| { i: w[:i], hit: w[:hit].fetch } }
147
- hits.each_with_index { |hit, i| workers << { i: i, hit: hit } }
148
- workers.end
149
- workers.result.sort_by { |a| a[:i] }.map { |x| x[:hit] }
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] code reference
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(code, year, missed_years) # rubocop:disable Metrics/MethodLength
178
- id = year ? "#{code}:#{year}" : code
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? code
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(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 = doc["iteration"] == "initial" ? 1 : doc["iteration"]
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(doc)
221
+ def fetch_relations_json(hit)
222
+ doc = hit[:json]
214
223
  relations = doc["supersedes"].map do |r|
215
- doc_relation "supersedes", r["docidentifier"], r["uri"]
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", r["docidentifier"], r["uri"]
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
- DocumentRelation.new(
234
- type: t,
235
- description: descr,
236
- bibitem: RelatonBib::BibliographicItem.new(
237
- formattedref: RelatonBib::FormattedRef.new(
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]
@@ -1,3 +1,3 @@
1
1
  module RelatonNist
2
- VERSION = "1.16.3".freeze
2
+ VERSION = "1.16.4".freeze
3
3
  end
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.3
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-04 00:00:00.000000000 Z
11
+ date: 2023-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: relaton-bib