relaton 3.0.0.pre.alpha.17 → 3.0.0.pre.alpha.18
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 +4 -4
- data/data/equivalence/adoption-chains.yaml +38 -0
- data/lib/relaton/3gpp/CLAUDE.md +187 -0
- data/lib/relaton/3gpp/README.adoc +149 -0
- data/lib/relaton/adobe/CLAUDE.md +104 -0
- data/lib/relaton/bib/CLAUDE.md +130 -0
- data/lib/relaton/bib/README.adoc +330 -0
- data/lib/relaton/bib/model/series.rb +1 -1
- data/lib/relaton/bipm/CLAUDE.md +173 -0
- data/lib/relaton/bipm/README.adoc +352 -0
- data/lib/relaton/bipm/data_fetcher.rb +3 -2
- data/lib/relaton/bsi/CLAUDE.md +35 -0
- data/lib/relaton/bsi/README.adoc +112 -0
- data/lib/relaton/calconnect/CLAUDE.md +177 -0
- data/lib/relaton/calconnect/README.adoc +140 -0
- data/lib/relaton/ccsds/CLAUDE.md +74 -0
- data/lib/relaton/ccsds/README.adoc +154 -0
- data/lib/relaton/cen/CLAUDE.md +219 -0
- data/lib/relaton/cen/README.adoc +155 -0
- data/lib/relaton/cie/CLAUDE.md +90 -0
- data/lib/relaton/cie/README.adoc +121 -0
- data/lib/relaton/core/CLAUDE.md +140 -0
- data/lib/relaton/core/README.adoc +64 -0
- data/lib/relaton/core/data_fetcher.rb +50 -3
- data/lib/relaton/db/CLAUDE.md +373 -0
- data/lib/relaton/db.rb +19 -1
- data/lib/relaton/doi/CLAUDE.md +105 -0
- data/lib/relaton/doi/README.adoc +89 -0
- data/lib/relaton/easc/CLAUDE.md +85 -0
- data/lib/relaton/ecma/CLAUDE.md +217 -0
- data/lib/relaton/ecma/README.adoc +178 -0
- data/lib/relaton/equivalence.rb +89 -0
- data/lib/relaton/etsi/CLAUDE.md +219 -0
- data/lib/relaton/etsi/README.adoc +137 -0
- data/lib/relaton/evs/CLAUDE.md +120 -0
- data/lib/relaton/evs/README.adoc +27 -0
- data/lib/relaton/gb/CLAUDE.md +47 -0
- data/lib/relaton/gb/README.adoc +169 -0
- data/lib/relaton/gost/CLAUDE.md +100 -0
- data/lib/relaton/iala/CLAUDE.md +97 -0
- data/lib/relaton/iana/CLAUDE.md +105 -0
- data/lib/relaton/iana/README.adoc +107 -0
- data/lib/relaton/iec/CLAUDE.md +13 -0
- data/lib/relaton/iec/README.adoc +280 -0
- data/lib/relaton/iec/data_fetcher.rb +24 -8
- data/lib/relaton/iec/project_fetcher.rb +48 -0
- data/lib/relaton/iec/project_parser.rb +111 -0
- data/lib/relaton/iec.rb +5 -0
- data/lib/relaton/ieee/CLAUDE.md +176 -0
- data/lib/relaton/ieee/README.adoc +131 -0
- data/lib/relaton/ietf/CLAUDE.md +357 -0
- data/lib/relaton/ietf/README.adoc +167 -0
- data/lib/relaton/iho/CLAUDE.md +70 -0
- data/lib/relaton/iho/README.adoc +119 -0
- data/lib/relaton/index/CLAUDE.md +207 -0
- data/lib/relaton/index/README.adoc +221 -0
- data/lib/relaton/index/dataset_lock.rb +122 -0
- data/lib/relaton/index/family.rb +63 -0
- data/lib/relaton/index/type.rb +32 -0
- data/lib/relaton/index.rb +3 -0
- data/lib/relaton/isbn/CLAUDE.md +47 -0
- data/lib/relaton/isbn/README.adoc +91 -0
- data/lib/relaton/iso/CLAUDE.md +38 -0
- data/lib/relaton/iso/README.adoc +370 -0
- data/lib/relaton/iso/data_fetcher.rb +16 -1
- data/lib/relaton/itu/CLAUDE.md +685 -0
- data/lib/relaton/itu/README.adoc +188 -0
- data/lib/relaton/jcgm/CLAUDE.md +107 -0
- data/lib/relaton/jis/CLAUDE.md +64 -0
- data/lib/relaton/jis/README.adoc +167 -0
- data/lib/relaton/logger/CLAUDE.md +37 -0
- data/lib/relaton/logger/README.adoc +120 -0
- data/lib/relaton/nist/CLAUDE.md +180 -0
- data/lib/relaton/nist/README.adoc +389 -0
- data/lib/relaton/nist/bibliography.rb +17 -1
- data/lib/relaton/nist/data_fetcher.rb +60 -4
- data/lib/relaton/nist/hit_collection.rb +121 -59
- data/lib/relaton/nist/scraper.rb +21 -7
- data/lib/relaton/oasis/CLAUDE.md +251 -0
- data/lib/relaton/oasis/README.adoc +132 -0
- data/lib/relaton/ogc/CLAUDE.md +242 -0
- data/lib/relaton/ogc/README.adoc +134 -0
- data/lib/relaton/oiml/CLAUDE.md +47 -0
- data/lib/relaton/oiml/README.adoc +70 -0
- data/lib/relaton/omg/CLAUDE.md +137 -0
- data/lib/relaton/omg/README.adoc +101 -0
- data/lib/relaton/plateau/CLAUDE.md +126 -0
- data/lib/relaton/plateau/README.adoc +139 -0
- data/lib/relaton/sdo/CLAUDE.md +81 -0
- data/lib/relaton/un/CLAUDE.md +91 -0
- data/lib/relaton/un/README.adoc +125 -0
- data/lib/relaton/version.rb +1 -1
- data/lib/relaton/w3c/CLAUDE.md +369 -0
- data/lib/relaton/w3c/README.adoc +140 -0
- data/lib/relaton/w3c/data_fetcher.rb +1 -1
- data/lib/relaton/xsf/CLAUDE.md +189 -0
- data/lib/relaton/xsf/README.adoc +127 -0
- data/lib/relaton.rb +1 -0
- metadata +83 -2
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
= Relaton for NIST: bibliographic retrieval of NIST publications
|
|
2
|
+
|
|
3
|
+
== Purpose
|
|
4
|
+
|
|
5
|
+
Relaton for NIST provides bibliographic information of NIST publications using
|
|
6
|
+
the
|
|
7
|
+
https://github.com/metanorma/metanorma-model-nist#nist-bibliographic-item-model[NistBibliographicItem model].
|
|
8
|
+
|
|
9
|
+
Relaton for NIST has been developed in cooperation with the NIST Cybersecurity
|
|
10
|
+
Resource Center (CSRC) and the Computer Security Division (ITL/CSD).
|
|
11
|
+
|
|
12
|
+
== Data sources
|
|
13
|
+
|
|
14
|
+
=== General
|
|
15
|
+
|
|
16
|
+
Relaton for NIST retrieves bibliographic information from two sources,
|
|
17
|
+
in the following priority:
|
|
18
|
+
|
|
19
|
+
. NIST Cybersecurity Resource Center (CSRC)
|
|
20
|
+
|
|
21
|
+
. NIST Library of the NIST Information Services Office (ISO)
|
|
22
|
+
|
|
23
|
+
=== NIST Cybersecurity Resource Center (CSRC)
|
|
24
|
+
|
|
25
|
+
The NIST CSRC bibliographic feed is used as the primary source for all CSRC
|
|
26
|
+
publications.
|
|
27
|
+
|
|
28
|
+
Bibliographic information offered through CSRC is provided with enhanced
|
|
29
|
+
metadata unavailable from the NIST Library dataset, including:
|
|
30
|
+
|
|
31
|
+
* versioned drafts (the NIST Library dataset only contains the latest publication: latest draft or final publication)
|
|
32
|
+
* revision information: revision number, iteration
|
|
33
|
+
* document stage information: retired, withdrawn, etc.
|
|
34
|
+
* bibliographic dates, including issued date, updated date, published date,
|
|
35
|
+
obsolete date, commenting period
|
|
36
|
+
* document relationships: supersession and replacements
|
|
37
|
+
* contacts: enhanced name parts and affiliation information
|
|
38
|
+
|
|
39
|
+
The NIST CSRC provides the following documents:
|
|
40
|
+
|
|
41
|
+
* NIST SP 800-*
|
|
42
|
+
* NIST SP 500-*
|
|
43
|
+
* NIST SP 1800-*
|
|
44
|
+
* NIST FIPS {31, 39, 41, 46, 46-$$*$$, 48, 65, 73, 74, 81, 83, 87, 102, 112, 113, 139, 140-$$*$$, 141, 171, 180, 180-$$*$$, 181, 186, 186-$$*$$, 188, 190, 191, 196, 197, 198, 198-1, 199, 200, 201, 201-*, 202}
|
|
45
|
+
|
|
46
|
+
As this feed is provided by CSRC in the native Relaton JSON format, no data
|
|
47
|
+
transform is necessary.
|
|
48
|
+
|
|
49
|
+
=== NIST Library
|
|
50
|
+
|
|
51
|
+
The NIST Library offers the full NIST Technical Publications dataset at
|
|
52
|
+
https://github.com/usnistgov/NIST-Tech-Pubs[GitHub].
|
|
53
|
+
|
|
54
|
+
The library data is managed internally using MARC21, and the GitHub repository
|
|
55
|
+
offers this information via MARC21 XML and MODS (in XML).
|
|
56
|
+
|
|
57
|
+
Relaton for NIST uses the MODS dataset obtained from the following location:
|
|
58
|
+
|
|
59
|
+
* https://github.com/usnistgov/NIST-Tech-Pubs/releases[NIST-Tech-Pubs/releases],
|
|
60
|
+
the `allrecords-MODS.xml` file
|
|
61
|
+
|
|
62
|
+
The MODS XML file is parsed using the
|
|
63
|
+
https://github.com/relaton/loc_mods[`loc_mods`] library and its data mapped to
|
|
64
|
+
the Relaton model.
|
|
65
|
+
|
|
66
|
+
The NIST Library dataset provides documents listed in the
|
|
67
|
+
https://github.com/relaton/relaton-data-nist/blob/v2/index-v2.yaml[index].
|
|
68
|
+
|
|
69
|
+
== Usage
|
|
70
|
+
|
|
71
|
+
=== Retrieving an entry
|
|
72
|
+
|
|
73
|
+
==== By NIST PubID
|
|
74
|
+
|
|
75
|
+
Relaton supports using the
|
|
76
|
+
https://www.nist.gov/system/files/documents/2022/04/01/PubID_Syntax_NIST_TechPubs.pdf[NIST PubID]
|
|
77
|
+
as the retrieval key for bibliographic entries.
|
|
78
|
+
|
|
79
|
+
NOTE: Relaton for NIST is the first public implementation of the
|
|
80
|
+
https://www.nist.gov/news-events/news/2021/08/nist-technical-series-publications-proposed-publication-identifier-syntax[NIST PubID].
|
|
81
|
+
|
|
82
|
+
.Retrieving a bibliographic entry using NIST PubID
|
|
83
|
+
[example]
|
|
84
|
+
====
|
|
85
|
+
[source,ruby]
|
|
86
|
+
----
|
|
87
|
+
require 'relaton/nist'
|
|
88
|
+
=> true
|
|
89
|
+
|
|
90
|
+
hit_collection = Relaton::Nist::Bibliography.search("NISTIR 8200")
|
|
91
|
+
[relaton-nist] INFO: (NIST IR 8200) Fetching from csrc.nist.gov ...
|
|
92
|
+
[relaton-nist] INFO: (NIST IR 8200) Fetching from Relaton repository ...
|
|
93
|
+
=> <Relaton::Nist::HitCollection:0x00000000002c10 @ref=NIST IR 8200 @fetched=false>
|
|
94
|
+
|
|
95
|
+
item = hit_collection[0].item
|
|
96
|
+
=> #<Relaton::Nist::ItemData:0x000000012c1d8008
|
|
97
|
+
# ...
|
|
98
|
+
----
|
|
99
|
+
====
|
|
100
|
+
|
|
101
|
+
The publication year can also be given if the publication has seen multiple
|
|
102
|
+
revisions or editions.
|
|
103
|
+
|
|
104
|
+
.Retrieving a bibliographic entry using NIST PubID with year
|
|
105
|
+
[example]
|
|
106
|
+
====
|
|
107
|
+
[source,ruby]
|
|
108
|
+
----
|
|
109
|
+
Relaton::Nist::Bibliography.get("NIST IR 8200", "2018")
|
|
110
|
+
[relaton-nist] INFO: (NIST IR 8200) Fetching from csrc.nist.gov ...
|
|
111
|
+
[relaton-nist] INFO: (NIST IR 8200) Fetching from Relaton repository ...
|
|
112
|
+
[relaton-nist] INFO: (NIST IR 8200) Found: `NIST IR 8200`
|
|
113
|
+
=> #<Relaton::Nist::ItemData:0x000000012c5e7590
|
|
114
|
+
# ...
|
|
115
|
+
----
|
|
116
|
+
====
|
|
117
|
+
|
|
118
|
+
A NIST PubID can contain these optional parameters `{ptN}{vN}{verN}{rN}{/Add}`:
|
|
119
|
+
|
|
120
|
+
* Part is specified as `ptN` (SP 800-57pt1)
|
|
121
|
+
* Volume is specified as `vN` (SP 800-60v1)
|
|
122
|
+
* Version is specified as `verN` (SP 800-45ver2)
|
|
123
|
+
* Revision is specified as `rN` (SP 800-40r3) or `-N`
|
|
124
|
+
* Addendum is specified as `/Add` (SP 800-38A/Add)
|
|
125
|
+
|
|
126
|
+
.Retrieving a bibliographic entry with a PubID that contains revision
|
|
127
|
+
[example]
|
|
128
|
+
====
|
|
129
|
+
[source,ruby]
|
|
130
|
+
----
|
|
131
|
+
item = Relaton::Nist::Bibliography.get 'NIST SP 800-67r1'
|
|
132
|
+
[relaton-nist] INFO: (NIST SP 800-67r1) Fetching from csrc.nist.gov ...
|
|
133
|
+
[relaton-nist] INFO: (NIST SP 800-67r1) Found: `NIST SP 800-67r1 fpd`
|
|
134
|
+
=> #<Relaton::Nist::ItemData:0x000000012cf294c8
|
|
135
|
+
...
|
|
136
|
+
|
|
137
|
+
item.docidentifier.first.content
|
|
138
|
+
=> "NIST SP 800-67r1 fpd"
|
|
139
|
+
----
|
|
140
|
+
====
|
|
141
|
+
|
|
142
|
+
.Retrieving a bibliographic entry with a PubID that specifies an addendum
|
|
143
|
+
[example]
|
|
144
|
+
====
|
|
145
|
+
[source,ruby]
|
|
146
|
+
----
|
|
147
|
+
item = Relaton::Nist::Bibliography.get 'NIST SP 800-38A/Add'
|
|
148
|
+
[relaton-nist] INFO: (NIST SP 800-38A Add) Fetching from csrc.nist.gov ...
|
|
149
|
+
[relaton-nist] INFO: (NIST SP 800-38A Add) Found: `NIST SP 800-38A fpd Add`
|
|
150
|
+
=> #<Relaton::Nist::ItemData:0x0000000124864190
|
|
151
|
+
...
|
|
152
|
+
|
|
153
|
+
item.docidentifier.first.content
|
|
154
|
+
=> "NIST SP 800-38A fpd Add"
|
|
155
|
+
----
|
|
156
|
+
====
|
|
157
|
+
|
|
158
|
+
==== By NIST PubID abbreviated form
|
|
159
|
+
|
|
160
|
+
The NIST PubID "abbreviated form" is the form of PubID printed on the inner
|
|
161
|
+
cover of a NIST publication.
|
|
162
|
+
|
|
163
|
+
The NIST PubID abbreviated format has the following syntax:
|
|
164
|
+
|
|
165
|
+
* `NIST {abbrev(series)} {docnumber} {(edition), optional} {(stage), optional}`, or
|
|
166
|
+
* `{abbrev(series)} {docnumber} {(edition), optional} {(stage), optional}`
|
|
167
|
+
|
|
168
|
+
Where,
|
|
169
|
+
|
|
170
|
+
`(stage)`::
|
|
171
|
+
empty if the state is "final" (published).
|
|
172
|
+
In case the state is "draft" it should be:
|
|
173
|
+
`PD`::: for the public draft
|
|
174
|
+
`IPD`::: for the initial public draft
|
|
175
|
+
`{n}PD`::: for subsequent public drafts, such as 2PD, 3PD and so on.
|
|
176
|
+
`FPD`::: for the final public draft
|
|
177
|
+
|
|
178
|
+
`(edition)`:: the date of publication or update
|
|
179
|
+
`docnumber`:: the full NIST document number, e.g., 800-52.
|
|
180
|
+
|
|
181
|
+
.Retrieving an entry using the NIST PubID abbreviated form
|
|
182
|
+
[example]
|
|
183
|
+
====
|
|
184
|
+
[source,ruby]
|
|
185
|
+
----
|
|
186
|
+
Relaton::Nist::Bibliography.get("NIST SP 800-205 (February 2019) (IPD)")
|
|
187
|
+
[relaton-nist] INFO: (NIST SP 800-205) Fetching from csrc.nist.gov ...
|
|
188
|
+
[relaton-nist] INFO: (NIST SP 800-205) Found: `NIST SP 800-205 ipd`
|
|
189
|
+
=> #<Relaton::Nist::ItemData:0x000000012494fb40
|
|
190
|
+
# ...
|
|
191
|
+
----
|
|
192
|
+
====
|
|
193
|
+
|
|
194
|
+
==== By FIPS PubID
|
|
195
|
+
|
|
196
|
+
The format for FIPS publications is:
|
|
197
|
+
|
|
198
|
+
* `FIPS {docnumber}`, or
|
|
199
|
+
* `NIST FIPS {docnumber}`
|
|
200
|
+
|
|
201
|
+
.Retrieving an entry using the FIPS PubID
|
|
202
|
+
[example]
|
|
203
|
+
====
|
|
204
|
+
[source,ruby]
|
|
205
|
+
----
|
|
206
|
+
Relaton::Nist::Bibliography.get("NIST FIPS 140-3")
|
|
207
|
+
[relaton-nist] INFO: (NIST FIPS 140-3) Fetching from csrc.nist.gov ...
|
|
208
|
+
[relaton-nist] INFO: (NIST FIPS 140-3) Found: `NIST FIPS 140-3 2pd`
|
|
209
|
+
=> #<Relaton::Nist::ItemData:0x0000000124d8dfe0
|
|
210
|
+
# ...
|
|
211
|
+
----
|
|
212
|
+
====
|
|
213
|
+
|
|
214
|
+
=== Serializing an entry
|
|
215
|
+
|
|
216
|
+
==== To Relaton XML
|
|
217
|
+
|
|
218
|
+
.Serializing an entry to Relaton XML
|
|
219
|
+
[example]
|
|
220
|
+
====
|
|
221
|
+
[source,ruby]
|
|
222
|
+
----
|
|
223
|
+
item.to_xml
|
|
224
|
+
=> "<bibitem id="NISTSP80038AfpdAdd" type="standard" schema-version="v1.4.1">
|
|
225
|
+
<fetched>2026-02-26</fetched>
|
|
226
|
+
<title language="en" script="Latn">Recommendation for Block Cipher Modes of Operation - Three Variants of Ciphertext Stealing for CBC Mode</title>
|
|
227
|
+
<uri type="src">https://csrc.nist.gov/pubs/sp/800/38/a/sup/final</uri>
|
|
228
|
+
<uri type="doi">https://doi.org/10.6028/NIST.SP.800-38A-Add</uri>
|
|
229
|
+
<docidentifier type="NIST" primary="true">NIST SP 800-38A fpd Add</docidentifier>
|
|
230
|
+
<docidentifier type="DOI">NIST.SP.800-38A-Add</docidentifier>
|
|
231
|
+
...
|
|
232
|
+
</bibitem>"
|
|
233
|
+
----
|
|
234
|
+
====
|
|
235
|
+
|
|
236
|
+
When the option `bibdata: true` is given, the method outputs XML wrapped by
|
|
237
|
+
the `bibdata` element and adds a flavor-specific `ext` element.
|
|
238
|
+
|
|
239
|
+
.Serializing an entry to Relaton XML with `bibdata: true`
|
|
240
|
+
[example]
|
|
241
|
+
====
|
|
242
|
+
[source,ruby]
|
|
243
|
+
----
|
|
244
|
+
item.to_xml bibdata: true
|
|
245
|
+
=> "<bibdata type="standard" schema-version="v1.4.1">
|
|
246
|
+
<fetched>2026-02-26</fetched>
|
|
247
|
+
<title language="en" script="Latn">Recommendation for Block Cipher Modes of Operation - Three Variants of Ciphertext Stealing for CBC Mode</title>
|
|
248
|
+
<uri type="src">https://csrc.nist.gov/pubs/sp/800/38/a/sup/final</uri>
|
|
249
|
+
<uri type="doi">https://doi.org/10.6028/NIST.SP.800-38A-Add</uri>
|
|
250
|
+
<docidentifier type="NIST" primary="true">NIST SP 800-38A fpd Add</docidentifier>
|
|
251
|
+
<docidentifier type="DOI">NIST.SP.800-38A-Add</docidentifier>
|
|
252
|
+
...
|
|
253
|
+
<ext schema-version="v1.0.0">
|
|
254
|
+
<doctype>standard</doctype>
|
|
255
|
+
<flavor>nist</flavor>
|
|
256
|
+
</ext>
|
|
257
|
+
</bibdata>
|
|
258
|
+
----
|
|
259
|
+
====
|
|
260
|
+
|
|
261
|
+
=== Accessing attributes
|
|
262
|
+
|
|
263
|
+
==== Identifier components
|
|
264
|
+
|
|
265
|
+
A NIST PubID can contain these optional parameters `{ptN}{vN}{verN}{rN}{/Add}`.
|
|
266
|
+
|
|
267
|
+
They can be accessed through the following methods:
|
|
268
|
+
|
|
269
|
+
* `part`
|
|
270
|
+
* `volume`
|
|
271
|
+
* `version`
|
|
272
|
+
* `revision`
|
|
273
|
+
* `addendum`
|
|
274
|
+
|
|
275
|
+
==== Typed links
|
|
276
|
+
|
|
277
|
+
NIST publications may have `src` and `doi` links, obtained using the `#link`
|
|
278
|
+
method.
|
|
279
|
+
|
|
280
|
+
.Accessing source links of a NIST bibliographic item
|
|
281
|
+
[example]
|
|
282
|
+
====
|
|
283
|
+
[source,ruby]
|
|
284
|
+
----
|
|
285
|
+
item.source[0].type
|
|
286
|
+
=> "src"
|
|
287
|
+
|
|
288
|
+
item.source[0].content
|
|
289
|
+
=> "https://csrc.nist.gov/pubs/sp/800/38/a/sup/final"
|
|
290
|
+
----
|
|
291
|
+
====
|
|
292
|
+
|
|
293
|
+
=== Loading entries
|
|
294
|
+
|
|
295
|
+
// ==== From XML
|
|
296
|
+
|
|
297
|
+
==== From YAML
|
|
298
|
+
|
|
299
|
+
Offline Relaton YAML files can be loaded directly as bibliographic items.
|
|
300
|
+
|
|
301
|
+
.Loading a Relaton YAML file
|
|
302
|
+
[example]
|
|
303
|
+
====
|
|
304
|
+
[source,ruby]
|
|
305
|
+
----
|
|
306
|
+
Relaton::Nist::Item.from_yaml File.read("spec/fixtures/item.yaml")
|
|
307
|
+
=> #<Relaton::Nist::ItemData:0x0000000124d4ab50
|
|
308
|
+
...
|
|
309
|
+
----
|
|
310
|
+
====
|
|
311
|
+
|
|
312
|
+
=== Fetching data
|
|
313
|
+
|
|
314
|
+
On a search, the CSRC data sources are fetched and stored in the user's cache.
|
|
315
|
+
|
|
316
|
+
This gem uses the https://github.com/usnistgov/NIST-Tech-Pubs/releases/download/May2024/allrecords-MODS.xml dataset as NIST-Tech-Pubs data source.
|
|
317
|
+
|
|
318
|
+
The following method fetches all the documents from the NIST-Tech-Pubs dataset, then saves them to the `./data` folder in YAML format.
|
|
319
|
+
|
|
320
|
+
.Fetching all data with default configuration
|
|
321
|
+
[example]
|
|
322
|
+
====
|
|
323
|
+
[source,ruby]
|
|
324
|
+
----
|
|
325
|
+
require "relaton/nist/data_fetcher"
|
|
326
|
+
|
|
327
|
+
Relaton::Nist::DataFetcher.fetch
|
|
328
|
+
Started at: 2021-09-01 18:01:01 +0200
|
|
329
|
+
Stopped at: 2021-09-01 18:01:43 +0200
|
|
330
|
+
Done in: 42 sec.
|
|
331
|
+
=> nil
|
|
332
|
+
----
|
|
333
|
+
====
|
|
334
|
+
|
|
335
|
+
.Fetching all data to the `data` folder
|
|
336
|
+
[example]
|
|
337
|
+
====
|
|
338
|
+
[source,ruby]
|
|
339
|
+
----
|
|
340
|
+
> Relaton::Nist::DataFetcher.fetch(output: "data", format: "yaml")
|
|
341
|
+
----
|
|
342
|
+
====
|
|
343
|
+
|
|
344
|
+
Options:
|
|
345
|
+
|
|
346
|
+
`output`:: folder to save documents (default `./data`).
|
|
347
|
+
`format`:: format in which the documents are saved. Possible formats are:
|
|
348
|
+
`yaml`::: (default) save in Relaton YAML format
|
|
349
|
+
`xml`::: save in Relaton XML format
|
|
350
|
+
`bibxml`::: save in the IETF BibXML format
|
|
351
|
+
|
|
352
|
+
=== Logging
|
|
353
|
+
|
|
354
|
+
Relaton for NIST uses https://github.com/relaton/relaton-logger[relaton-logger]
|
|
355
|
+
for logging.
|
|
356
|
+
|
|
357
|
+
By default, it logs to `$STDOUT`. To change log levels and add other loggers,
|
|
358
|
+
refer to the https://github.com/relaton/relaton-logger#usage[relaton-logger]
|
|
359
|
+
documentation.
|
|
360
|
+
|
|
361
|
+
== Development
|
|
362
|
+
|
|
363
|
+
=== Updating test fixtures
|
|
364
|
+
|
|
365
|
+
The test suite uses local copies of the NIST index and CSRC pubs-export data
|
|
366
|
+
to avoid network requests. To update the fixtures:
|
|
367
|
+
|
|
368
|
+
[source,sh]
|
|
369
|
+
----
|
|
370
|
+
$ rake spec:update_index
|
|
371
|
+
$ rake spec:update_pubs_export
|
|
372
|
+
----
|
|
373
|
+
|
|
374
|
+
`spec:update_index` downloads the latest `index-v2.zip` from the
|
|
375
|
+
https://github.com/relaton/relaton-data-nist[relaton-data-nist] repository.
|
|
376
|
+
|
|
377
|
+
`spec:update_pubs_export` downloads the latest `pubs-export.zip` from
|
|
378
|
+
the NIST Cybersecurity Resource Center (CSRC).
|
|
379
|
+
|
|
380
|
+
== Contributing
|
|
381
|
+
|
|
382
|
+
Bug reports and pull requests are welcome.
|
|
383
|
+
|
|
384
|
+
== License
|
|
385
|
+
|
|
386
|
+
Copyright Ribose.
|
|
387
|
+
|
|
388
|
+
The gem is available as open source under the terms of the
|
|
389
|
+
https://opensource.org/licenses/MIT[MIT License].
|
|
@@ -94,6 +94,22 @@ module Relaton
|
|
|
94
94
|
def nistbib_results_filter(result, year, opts)
|
|
95
95
|
missed_years = []
|
|
96
96
|
iteration = parse_iteration(opts[:stage])
|
|
97
|
+
# A pubid-stage reference ("NIST FIPS 197 ipd") carries its stage
|
|
98
|
+
# in the identifier, not the parenthetical form parse_iteration
|
|
99
|
+
# reads. The stage-matched hit is already sorted first
|
|
100
|
+
# (HitCollection#sort_hits!), so the per-item iteration filter
|
|
101
|
+
# is not applied to it.
|
|
102
|
+
unless iteration
|
|
103
|
+
st = begin
|
|
104
|
+
::Pubid::Nist::Identifier.parse(result.reference)&.stage
|
|
105
|
+
rescue StandardError
|
|
106
|
+
nil
|
|
107
|
+
end
|
|
108
|
+
if st
|
|
109
|
+
iteration = "#{st.id}#{st.type}"
|
|
110
|
+
pubid_stage = true
|
|
111
|
+
end
|
|
112
|
+
end
|
|
97
113
|
|
|
98
114
|
# A stageless query means "the published document". Multiple
|
|
99
115
|
# editions can match once stage is excluded (e.g. a final "r2"
|
|
@@ -109,7 +125,7 @@ module Relaton
|
|
|
109
125
|
ordered.each do |h|
|
|
110
126
|
r = h.item
|
|
111
127
|
next if opts[:date] && !match_date?(r, opts[:date])
|
|
112
|
-
next if iteration && r.status&.iteration != iteration
|
|
128
|
+
next if iteration && !pubid_stage && r.status&.iteration != iteration
|
|
113
129
|
return { ret: r } unless year
|
|
114
130
|
next unless match_year?(r, year) { |y| missed_years << y }
|
|
115
131
|
|
|
@@ -5,6 +5,7 @@ require "mechanize"
|
|
|
5
5
|
require "loc_mods"
|
|
6
6
|
require_relative "../nist"
|
|
7
7
|
require_relative "mods_parser"
|
|
8
|
+
require_relative "pubs_export"
|
|
8
9
|
|
|
9
10
|
module Relaton
|
|
10
11
|
module Nist
|
|
@@ -13,19 +14,71 @@ module Relaton
|
|
|
13
14
|
MODS_ASSET = "allrecords-MODS.xml"
|
|
14
15
|
|
|
15
16
|
def fetch(source = nil)
|
|
16
|
-
|
|
17
|
+
# An incremental run keeps the tree: unchanged records are not
|
|
18
|
+
# rewritten (Core#force_write) and files this crawl no longer produces
|
|
19
|
+
# are pruned after it completes (Core::DataFetcher.fetch(prune: true)).
|
|
20
|
+
FileUtils.rm Dir[File.join(@output, "*.#{@ext}")] unless prune
|
|
17
21
|
fetch_tech_pubs source
|
|
22
|
+
fetch_csrc
|
|
18
23
|
# add_static_files
|
|
19
24
|
index.save
|
|
20
25
|
report_errors
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
def fetch_tech_pubs(source = nil)
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
page = Mechanize.new.get(source_url(source))
|
|
30
|
+
# The resolved URI names the concrete release the redirect landed on
|
|
31
|
+
# (latest/download moves as NIST-Tech-Pubs publishes) — log it so every
|
|
32
|
+
# crawl proves which release it read.
|
|
33
|
+
Util.info "NIST-Tech-Pubs release: #{page.uri}", key: "nist"
|
|
34
|
+
docs = LocMods::Collection.from_xml page.body
|
|
26
35
|
docs.mods.each { |doc| write_file ModsParser.new(doc, series, @errors).parse }
|
|
27
36
|
end
|
|
28
37
|
|
|
38
|
+
# Supplements the MODS collection with the CSRC pubs-export feed
|
|
39
|
+
# (csrc.nist.gov feeds/metanorma/pubs-export.zip, the same zip
|
|
40
|
+
# PubsExport caches for the runtime): the MODS carries no draft-stage
|
|
41
|
+
# records at all, while the CSRC feed lists them (e.g. FIPS 197 as the
|
|
42
|
+
# 2001 final, upd1, and upd1.ipd). Only draft rows are supplemented —
|
|
43
|
+
# the finals already come from the MODS pass, and a draft row never
|
|
44
|
+
# shadows its base document (relaton#313, the root of relaton#146).
|
|
45
|
+
#
|
|
46
|
+
# A row is built exactly as the runtime builds a CSRC hit
|
|
47
|
+
# (HitCollection#hit_data → Scraper.parse_page), so the crawled record
|
|
48
|
+
# and the live one share one id: the stage, revision and update all come
|
|
49
|
+
# from the row's uri and DOI ("NIST FIPS 197/Upd1 ipd",
|
|
50
|
+
# "NIST SP 800-108r1 ipd", "NIST SP 1800-12 2pd"). A row whose id
|
|
51
|
+
# carries no stage is a final, and is skipped.
|
|
52
|
+
#
|
|
53
|
+
# CSRC lists a republished draft twice, at …/ipd and …/ipd-(1), with one
|
|
54
|
+
# DOI and so one id: the plain uri goes first, and each id is written once.
|
|
55
|
+
def fetch_csrc(rows = PubsExport.instance.data)
|
|
56
|
+
hits = HitCollection.new ""
|
|
57
|
+
codes = Set.new
|
|
58
|
+
plain, republished = rows.partition { |doc| doc["uri"].to_s !~ /-\(\d+\)\z/ }
|
|
59
|
+
(plain + republished).each do |doc|
|
|
60
|
+
bib = csrc_bib hits, doc
|
|
61
|
+
write_file bib if bib && codes.add?(bib.docidentifier.first.content)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Builds the record of a draft-stage CSRC row, or nil for a final row or
|
|
66
|
+
# a row that fails to build (recorded in #failures). Write errors are not
|
|
67
|
+
# rescued here: they stop the crawl, as they do in the MODS pass.
|
|
68
|
+
def csrc_bib(hits, doc)
|
|
69
|
+
data = hits.hit_data doc
|
|
70
|
+
return unless pubid(data[:code])&.stage
|
|
71
|
+
|
|
72
|
+
bib = Scraper.parse_page data
|
|
73
|
+
# The runtime stamps the fetch date; a crawled record must not, or it
|
|
74
|
+
# changes every day and Core#force_write rewrites it on each crawl.
|
|
75
|
+
bib.fetched = nil
|
|
76
|
+
bib
|
|
77
|
+
rescue StandardError => e
|
|
78
|
+
failures << "CSRC record skipped: #{e.message} (#{doc['docidentifier']}, #{doc['uri']})"
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
|
|
29
82
|
# Build the MODS download URL for a NIST-Tech-Pubs release. With no tag
|
|
30
83
|
# (nil, blank, or "latest") use GitHub's `latest/download` redirect so new
|
|
31
84
|
# releases are picked up automatically by the crawler; a concrete tag
|
|
@@ -53,6 +106,9 @@ module Relaton
|
|
|
53
106
|
elsif file != output_file(docid)
|
|
54
107
|
Util.warn "File #{output_file docid} exists. Docid: #{id.content}. Writing #{file} instead."
|
|
55
108
|
end
|
|
109
|
+
# Serialize before indexing: a record that fails to serialize must not
|
|
110
|
+
# leave an index row that names a file never written.
|
|
111
|
+
content = serialize(bib)
|
|
56
112
|
@files << file
|
|
57
113
|
pid = pubid id.content
|
|
58
114
|
if pid
|
|
@@ -60,7 +116,7 @@ module Relaton
|
|
|
60
116
|
else
|
|
61
117
|
failures << "Unparseable id `#{id.content}` was not indexed (#{file})"
|
|
62
118
|
end
|
|
63
|
-
|
|
119
|
+
force_write file, content
|
|
64
120
|
end
|
|
65
121
|
|
|
66
122
|
# A human-readable label for a bib with no usable docidentifier, so the
|