relaton 1.6.0 → 1.7.pre7
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/.github/workflows/rake.yml +46 -0
- data/docs/README.adoc +233 -3
- data/globalcache/iec/iec_60050_102_2007.xml +58 -0
- data/globalcache/iec/version +1 -0
- data/lib/relaton.rb +8 -7
- data/lib/relaton/config.rb +3 -2
- data/lib/relaton/db.rb +247 -35
- data/lib/relaton/db_cache.rb +38 -7
- data/lib/relaton/processor.rb +11 -0
- data/lib/relaton/registry.rb +1 -1
- data/lib/relaton/version.rb +1 -1
- data/lib/relaton/workers_pool.rb +23 -0
- data/relaton.gemspec +18 -16
- data/spec/relaton/db_cache_spec.rb +26 -1
- data/spec/relaton/db_spec.rb +145 -0
- data/spec/relaton/processor_spec.rb +4 -0
- data/spec/relaton/regirtry_spec.rb +54 -44
- data/spec/relaton_spec.rb +121 -20
- data/spec/vcr_cassetes/19133_2005.yml +22 -22
- data/spec/vcr_cassetes/cc_dir_10005_2019.yml +10 -10
- data/spec/vcr_cassetes/cie_001_1980.yml +120 -0
- data/spec/vcr_cassetes/ecma_6.yml +159 -0
- data/spec/vcr_cassetes/fisp_140.yml +6 -6
- data/spec/vcr_cassetes/gb_t_20223_2006.yml +15 -11
- data/spec/vcr_cassetes/hist_cmbined_included.yml +105 -0
- data/spec/vcr_cassetes/iec_60050_102_2007.yml +285 -0
- data/spec/vcr_cassetes/iec_combined_included.yml +945 -0
- data/spec/vcr_cassetes/ieee_528_2019.yml +14 -14
- data/spec/vcr_cassetes/iho_b_11.yml +15 -15
- data/spec/vcr_cassetes/iso_111111119115_1.yml +4 -4
- data/spec/vcr_cassetes/iso_19115.yml +23 -23
- data/spec/vcr_cassetes/iso_19115_1.yml +22 -22
- data/spec/vcr_cassetes/iso_19115_1_2.yml +44 -44
- data/spec/vcr_cassetes/iso_awi_24229.yml +21 -21
- data/spec/vcr_cassetes/iso_combined_applied.yml +361 -0
- data/spec/vcr_cassetes/iso_combined_included.yml +361 -0
- data/spec/vcr_cassetes/itu_combined_included.yml +1296 -0
- data/spec/vcr_cassetes/ogc_19_025r1.yml +2569 -1910
- data/spec/vcr_cassetes/ogm_ami4ccm_1_0.yml +7 -7
- data/spec/vcr_cassetes/rfc_8341.yml +47 -15
- data/spec/vcr_cassetes/rfc_unsuccess.yml +70 -0
- data/spec/vcr_cassetes/sp_800_38b.yml +6 -6
- data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +31 -31
- data/spec/vcr_cassetes/w3c_json_ld11.yml +18 -12
- metadata +81 -71
- data/.github/workflows/macos.yml +0 -34
- data/.github/workflows/ubuntu.yml +0 -32
- data/.github/workflows/windows.yml +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 669c9390b4e3b0a3be1a928f3a13db65cff18d9e36d1ee434662ebccab367402
|
4
|
+
data.tar.gz: 9d285c4d6e00df82eb38baff1a191d8a4527456d689556312db1bef74c1fc364
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0489929bc69ac678f9a3b5b2f4a73961102d72e9f0917807a422dbf495d3319b94e84c11cdfb46fc9cc423a523f04af20a1bacdd6964988e9deb2a87676470a
|
7
|
+
data.tar.gz: 792fa2b3c0cf6f95362ff7039c867ec57766fe691fb75dd71e0413b77c3982b3bfdf7ee57748ae4de9aaea18b2e76a1f0c3ae67eb9c01a81ec594865e4a20531
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Auto-generated by Cimas: Do not edit it manually!
|
2
|
+
# See https://github.com/metanorma/cimas
|
3
|
+
name: rake
|
4
|
+
|
5
|
+
on:
|
6
|
+
push:
|
7
|
+
branches: [ master, main ]
|
8
|
+
tags: [ v* ]
|
9
|
+
pull_request:
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
rake:
|
13
|
+
name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
|
14
|
+
runs-on: ${{ matrix.os }}
|
15
|
+
continue-on-error: ${{ matrix.experimental }}
|
16
|
+
strategy:
|
17
|
+
fail-fast: false
|
18
|
+
matrix:
|
19
|
+
ruby: [ '2.7', '2.6', '2.5', '2.4' ]
|
20
|
+
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
21
|
+
experimental: [ false ]
|
22
|
+
include:
|
23
|
+
- ruby: '3.0'
|
24
|
+
os: 'ubuntu-latest'
|
25
|
+
experimental: true
|
26
|
+
- ruby: '3.0'
|
27
|
+
os: 'windows-latest'
|
28
|
+
experimental: true
|
29
|
+
- ruby: '3.0'
|
30
|
+
os: 'macos-latest'
|
31
|
+
experimental: true
|
32
|
+
steps:
|
33
|
+
- uses: actions/checkout@v2
|
34
|
+
with:
|
35
|
+
submodules: true
|
36
|
+
|
37
|
+
# https://github.com/ruby-debug/debase/issues/89#issuecomment-686827382
|
38
|
+
- if: matrix.os == 'macos-latest' && matrix.ruby == '2.5'
|
39
|
+
run: echo BUNDLE_BUILD__DEBASE="--with-cflags=\"-Wno-error=implicit-function-declaration\"" >> $GITHUB_ENV
|
40
|
+
|
41
|
+
- uses: ruby/setup-ruby@v1
|
42
|
+
with:
|
43
|
+
ruby-version: ${{ matrix.ruby }}
|
44
|
+
bundler-cache: true
|
45
|
+
|
46
|
+
- run: bundle exec rake
|
data/docs/README.adoc
CHANGED
@@ -62,6 +62,13 @@ e.g. `get("ISO 19115-1", "2014", all_parts: true)` is transformed into a referen
|
|
62
62
|
|
63
63
|
== Usage
|
64
64
|
|
65
|
+
=== Create DB
|
66
|
+
|
67
|
+
`Relaton::Db#new(globalcache, localcache)` creates new DB. Returns Relaton::Db instance.
|
68
|
+
|
69
|
+
* `globalcache` - (String or nil) path to globalcache directory
|
70
|
+
* `localcache` - (String or nil) path to localcache directory
|
71
|
+
|
65
72
|
[source,ruby]
|
66
73
|
----
|
67
74
|
require "relaton"
|
@@ -93,7 +100,51 @@ db = Relaton::Db.new("globalcache", "localcache")
|
|
93
100
|
@local_db=#<Relaton::DbCache:0x007faabc8fa5c0 @dir="localcache", @ext="xml">,
|
94
101
|
@local_db_name="localcache",
|
95
102
|
...
|
103
|
+
----
|
104
|
+
|
105
|
+
=== Modify DB
|
106
|
+
|
107
|
+
==== Move DB
|
108
|
+
|
109
|
+
`Relaton::Db#mv(new_dir, type: :global)` moves DB directory to new location. Returns path to new directory if successful, or `nil` if target directiory exists.
|
110
|
+
|
111
|
+
* `new_dir` - (String) new cache location
|
112
|
+
* `type` - (Symbol) type of cache DB. Allowed values are: `:global`, `:local`. Default is `:global`.
|
113
|
+
|
114
|
+
[source,ruby]
|
115
|
+
----
|
116
|
+
db.mv("new_global_dir")
|
117
|
+
=> "new_global_dir"
|
118
|
+
|
119
|
+
db.mv("new_local_dir", type: :local)
|
120
|
+
=> "new_local_dir"
|
121
|
+
----
|
96
122
|
|
123
|
+
==== Clear DB
|
124
|
+
|
125
|
+
`Relaton::Db#clear` removes all entries form DB
|
126
|
+
|
127
|
+
=== Fetch documens
|
128
|
+
|
129
|
+
==== Fetch document by references
|
130
|
+
|
131
|
+
There are 3 fetching methods:
|
132
|
+
|
133
|
+
* `Relaton::Db#fetch(reference, year, options)` - fetches document from local cache or remote source.
|
134
|
+
* `Relaton::Db#fetch_db(reference, year, options)` - fetches document from local cache
|
135
|
+
* `Relaton::Db#fetch_async(reference, year, options, &block)` - fetches document asynchronously
|
136
|
+
|
137
|
+
Arguments:
|
138
|
+
|
139
|
+
* `reference` - (String) reference to fethc document
|
140
|
+
* `year` - (String or nil) year to filter relult (optional)
|
141
|
+
* `options` - (Hash) hash of options. Alloved options:
|
142
|
+
- `:all_parts` - (Boolean) should be `true` if all-parts reference is required
|
143
|
+
- `:keep_yer` - (Boolean) should be `true` if undated reference should return actual reference with year
|
144
|
+
- `:retries` - (Number) number of network retries. Default 1
|
145
|
+
|
146
|
+
[source,ruby]
|
147
|
+
----
|
97
148
|
x = db.fetch("IEEE 19011")
|
98
149
|
[relaton-ieee] ("IEEE 19011") fetching...
|
99
150
|
[relaton-ieee] WARNING: no match found online for IEEE 19011. The code must be exactly like it is on the standards website.
|
@@ -105,7 +156,7 @@ x = db.fetch("ISO 19011")
|
|
105
156
|
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d0ab2f00
|
106
157
|
...
|
107
158
|
|
108
|
-
x = db.fetch("ISO 19011", "2011")
|
159
|
+
x = db.fetch("ISO 19011", "2011", retries: 3)
|
109
160
|
[relaton-iso] ("ISO 19011") fetching...
|
110
161
|
[relaton-iso] ("ISO 19011") found ISO 19011:2011
|
111
162
|
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d2593068
|
@@ -117,9 +168,185 @@ x = db.fetch("ISO 19115", nil, all_parts: true)
|
|
117
168
|
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d0ae8bf0
|
118
169
|
...
|
119
170
|
|
171
|
+
# Fetchig from local cache
|
172
|
+
|
173
|
+
x = db.fetch("ISO 19011")
|
174
|
+
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fde5f48a9f0
|
175
|
+
...
|
176
|
+
|
177
|
+
x = db.fetch_db("ISO 5749")
|
178
|
+
=> nil
|
179
|
+
|
180
|
+
# Fetching asynchronously
|
181
|
+
|
182
|
+
# prepare queue for results
|
183
|
+
results = Queue.new
|
184
|
+
|
185
|
+
# fetch document
|
186
|
+
db.fetch_async("ISO 19115") do |result|
|
187
|
+
results << { "ISO 19115" => result }
|
188
|
+
end
|
189
|
+
# fetch other documets the same way
|
190
|
+
|
191
|
+
# wait until documets fetching
|
192
|
+
while x = results.pop
|
193
|
+
# do thatever you need with result x
|
194
|
+
end
|
195
|
+
----
|
196
|
+
|
197
|
+
==== Fetch by URN
|
198
|
+
|
199
|
+
This functionality works only for IEC documents.
|
200
|
+
|
201
|
+
[source,ruby]
|
202
|
+
----
|
203
|
+
x = db.fetch "urn:iec:std:iec:60050-102:2007:::"
|
204
|
+
[relaton-iec] ("IEC 60050-102") fetching...
|
205
|
+
[relaton-iec] ("IEC 60050-102") found IEC 60050-102:2007
|
206
|
+
=> #<RelatonIec::IecBibliographicItem:0x007fbd6c3790e8
|
207
|
+
...
|
208
|
+
----
|
209
|
+
|
210
|
+
=== Fetch combined documents
|
211
|
+
|
212
|
+
This functionality works only for ISO, IEC, ITU, and NIST documents.
|
213
|
+
|
214
|
+
==== Fetch included documents
|
215
|
+
[source,ruby]
|
216
|
+
----
|
217
|
+
bib = db.fetch "ISO 19115-1 + Amd 1"
|
218
|
+
[relaton-iso] ("ISO 19115-1") fetching...
|
219
|
+
[relaton-iso] ("ISO 19115-1") found ISO 19115-1:2014
|
220
|
+
[relaton-iso] ("ISO 19115-1/Amd 1") fetching...
|
221
|
+
[relaton-iso] ("ISO 19115-1/Amd 1") found ISO 19115-1:2014/Amd 1:2018
|
222
|
+
=> #<RelatonIsoBib::IsoBibliographicItem:0x007f95a929a748
|
223
|
+
|
224
|
+
bib.docidentifier[0].id
|
225
|
+
=> "ISO 19115-1 + Amd 1"
|
226
|
+
|
227
|
+
bib.relation[0].type
|
228
|
+
=> "updates"
|
229
|
+
|
230
|
+
bib.relation[0].bibitem.docidentifier[0].id
|
231
|
+
=> "ISO 19115-1"
|
232
|
+
|
233
|
+
bib.relation[1].type
|
234
|
+
=> "derivedFrom"
|
235
|
+
|
236
|
+
bib.relation[1].bibitem.docidentifier[0].id
|
237
|
+
=> "ISO 19115-1/Amd 1:2018"
|
238
|
+
|
239
|
+
bib.docidentifier[0].id
|
240
|
+
=> "ISO 19115-1, Amd 1"
|
241
|
+
|
242
|
+
bib.relation[0].type
|
243
|
+
=> "updates"
|
244
|
+
|
245
|
+
bib.relation[0].bibitem.docidentifier[0].id
|
246
|
+
=> "ISO 19115-1"
|
247
|
+
|
248
|
+
bib.relation[1].type
|
249
|
+
=> "complements"
|
250
|
+
|
251
|
+
bib.relation[1].description
|
252
|
+
=> "amendment"
|
253
|
+
|
254
|
+
bib.relation[1].bibitem.docidentifier[0].id
|
255
|
+
=> "ISO 19115-1/Amd 1:2018"
|
256
|
+
----
|
257
|
+
|
258
|
+
==== Fetch applied documents
|
259
|
+
[source,ruby]
|
260
|
+
----
|
261
|
+
bib = db.fetch "ISO 19115-1, Amd 1"
|
262
|
+
=> ["Chinese Standard", "GB/T 1.1"]
|
263
|
+
[relaton-iso] ("ISO 19115-1") fetching...
|
264
|
+
[relaton-iso] ("ISO 19115-1") found ISO 19115-1:2014
|
265
|
+
[relaton-iso] ("ISO 19115-1/Amd 1") fetching...
|
266
|
+
[relaton-iso] ("ISO 19115-1/Amd 1") found ISO 19115-1:2014/Amd 1:2018
|
267
|
+
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb09b36d1b8
|
268
|
+
...
|
269
|
+
----
|
270
|
+
|
271
|
+
==== Fetch all documents from cache
|
272
|
+
|
273
|
+
`Relaton::Db#fetch_all(text = nil, edition: nil, year: nil)` - fetches all document from local cache
|
274
|
+
|
275
|
+
* `text` - (String) filter entries by a text (optional)
|
276
|
+
* `edition` - (String) filter entries by an edition (optional)
|
277
|
+
* `year` - (Integer) filter entries by a year (optional)
|
278
|
+
|
279
|
+
[source,ruby]
|
280
|
+
----
|
281
|
+
# query for all entries in a cahche
|
282
|
+
|
283
|
+
items = db.fetch_all
|
284
|
+
=> [#<RelatonIec::IecBibliographicItem:0x007facda8fdc28
|
285
|
+
...
|
286
|
+
|
287
|
+
items.size
|
288
|
+
=> 6
|
289
|
+
|
290
|
+
# query for all entries in a cahche for a certain string
|
291
|
+
|
292
|
+
items = db.fetch_all("mathematical terminology")
|
293
|
+
=> [#<RelatonIec::IecBibliographicItem:0x007ffeae5bd240
|
294
|
+
...
|
295
|
+
|
296
|
+
items.size
|
297
|
+
=> 1
|
298
|
+
|
299
|
+
items[0].docidentifier[0].id
|
300
|
+
=> "IEC 60050-102:2007"
|
301
|
+
|
302
|
+
# query for all entries in a cahche for a certain string and edition
|
303
|
+
|
304
|
+
items = db.fetch_all("system", edition: "2")
|
305
|
+
=> [#<RelatonIsoBib::IsoBibliographicItem:0x007ffebe2d1be8
|
306
|
+
...
|
307
|
+
|
308
|
+
items.size
|
309
|
+
=> 1
|
310
|
+
|
311
|
+
items[0].docidentifier[0].id
|
312
|
+
=> "ISO 19011:2011"
|
313
|
+
|
314
|
+
# query for all entries in a cahche for a certain string and year
|
315
|
+
|
316
|
+
items = db.fetch_all("system", year: 2018)
|
317
|
+
=> [#<RelatonIsoBib::IsoBibliographicItem:0x007ffeae645fa0
|
318
|
+
...
|
319
|
+
|
320
|
+
items.size
|
321
|
+
=> 1
|
322
|
+
|
323
|
+
items[0].docidentifier[0].id
|
324
|
+
=> "ISO 19011 (all parts)"
|
325
|
+
----
|
326
|
+
|
327
|
+
=== Static DB
|
328
|
+
|
329
|
+
This gem has a static DB which is distributed with it. Now the static contains documents:
|
330
|
+
----
|
331
|
+
ISO/IEC DIR 1 IEC SUP
|
332
|
+
ISO/IEC DIR 1 ISO SUP
|
333
|
+
ISO/IEC DIR 1
|
334
|
+
ISO/IEC DIR 2 IEC
|
335
|
+
ISO/IEC DIR 2 ISO
|
336
|
+
ISO/IEC DIR IEC SUP
|
337
|
+
ISO/IEC DIR 1 JTC SUP
|
338
|
+
----
|
339
|
+
|
340
|
+
=== Get document type
|
341
|
+
[source,ruby]
|
342
|
+
----
|
120
343
|
db.docid_type("CN(GB/T 1.1)")
|
121
344
|
=> ["Chinese Standard", "GB/T 1.1"]
|
345
|
+
----
|
122
346
|
|
347
|
+
=== Serializing
|
348
|
+
[source,ruby]
|
349
|
+
----
|
123
350
|
x.to_xml
|
124
351
|
=> "<bibitem id="ISO19115(allparts)" type="standard">
|
125
352
|
...
|
@@ -145,12 +372,15 @@ x.to_xml bibdata: true
|
|
145
372
|
db.load_entry("ISO(ISO 19011)")
|
146
373
|
=> "<bibdata type="standard">
|
147
374
|
...
|
148
|
-
|
375
|
+
</bibdata>"
|
376
|
+
----
|
149
377
|
|
378
|
+
=== Entry manipulation
|
379
|
+
[source,ruby]
|
380
|
+
----
|
150
381
|
db.save_entry("ISO(ISO 19011)", nil)
|
151
382
|
=> nil
|
152
383
|
|
153
384
|
db.load_entry("ISO(ISO 19011)")
|
154
385
|
=> nil
|
155
|
-
|
156
386
|
----
|
@@ -0,0 +1,58 @@
|
|
1
|
+
<bibdata type="standard">
|
2
|
+
<fetched>2021-02-03</fetched>
|
3
|
+
<title type="title-main" format="text/plain" language="en" script="Latn">International Electrotechnical Vocabulary (IEV)</title>
|
4
|
+
<title type="title-part" format="text/plain" language="en" script="Latn">Part 102: Mathematics -- General concepts and linear algebra</title>
|
5
|
+
<title type="main" format="text/plain" language="en" script="Latn">International Electrotechnical Vocabulary (IEV) - Part 102: Mathematics -- General concepts and linear algebra</title>
|
6
|
+
<uri type="src">https://webstore.iec.ch/publication/160</uri>
|
7
|
+
<uri type="obp">/preview/info_iec60050-102%7Bed1.0%7Db.pdf</uri>
|
8
|
+
<docidentifier type="IEC">IEC 60050-102:2007</docidentifier>
|
9
|
+
<docidentifier type="URN">urn:iec:std:iec:60050-102:2007:::en</docidentifier>
|
10
|
+
<date type="published">
|
11
|
+
<on>2007-08-27</on>
|
12
|
+
</date>
|
13
|
+
<contributor>
|
14
|
+
<role type="publisher"/>
|
15
|
+
<organization>
|
16
|
+
<name>International Electrotechnical Commission</name>
|
17
|
+
<abbreviation>IEC</abbreviation>
|
18
|
+
<uri>www.iec.ch</uri>
|
19
|
+
</organization>
|
20
|
+
</contributor>
|
21
|
+
<edition>1.0</edition>
|
22
|
+
<language>en</language>
|
23
|
+
<script>Latn</script>
|
24
|
+
<abstract format="text/plain" language="en" script="Latn">This part of IEC 60050 gives the general mathematical terminology used in the fields of electricity, electronics and telecommunications, together with basic concepts in linear algebra. It maintains a clear distinction between mathematical concepts and physical concepts, even if some terms are used in both cases. Another part will deal with functions.
|
25
|
+
It has the status of a horizontal standard in accordance with IEC Guide 108.</abstract>
|
26
|
+
<status>
|
27
|
+
<stage>60</stage>
|
28
|
+
<substage>60</substage>
|
29
|
+
</status>
|
30
|
+
<copyright>
|
31
|
+
<from>2007</from>
|
32
|
+
<owner>
|
33
|
+
<organization>
|
34
|
+
<name>International Electrotechnical Commission</name>
|
35
|
+
<abbreviation>IEC</abbreviation>
|
36
|
+
<uri>www.iec.ch</uri>
|
37
|
+
</organization>
|
38
|
+
</owner>
|
39
|
+
</copyright>
|
40
|
+
<place>Geneva</place>
|
41
|
+
<ext>
|
42
|
+
<doctype>international-standard</doctype>
|
43
|
+
<editorialgroup>
|
44
|
+
<technical-committee number="1" type="technicalCommittee">TC 1 - Terminology</technical-committee>
|
45
|
+
</editorialgroup>
|
46
|
+
<ics>
|
47
|
+
<code>01.040.07</code>
|
48
|
+
<text>Natural and applied sciences (Vocabularies)</text>
|
49
|
+
</ics>
|
50
|
+
<ics>
|
51
|
+
<code>07.020</code>
|
52
|
+
<text>Mathematics</text>
|
53
|
+
</ics>
|
54
|
+
<structuredidentifier type="IEC">
|
55
|
+
<project-number>60050</project-number>
|
56
|
+
</structuredidentifier>
|
57
|
+
</ext>
|
58
|
+
</bibdata>
|
@@ -0,0 +1 @@
|
|
1
|
+
407d6f5afdc9ae9ea7abe6e84d27f40b
|
data/lib/relaton.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require "relaton/util"
|
2
|
+
require "relaton/config"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
require "relaton/workers_pool"
|
5
|
+
require "relaton/db"
|
6
|
+
require "relaton/db_cache"
|
7
|
+
require "relaton/version"
|
8
|
+
require "relaton/registry"
|
9
|
+
require "relaton/processor"
|
data/lib/relaton/config.rb
CHANGED
@@ -12,10 +12,11 @@ module Relaton
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class Configuration
|
15
|
-
attr_accessor :logs
|
15
|
+
attr_accessor :logs, :use_api
|
16
16
|
|
17
17
|
def initialize
|
18
|
-
@logs
|
18
|
+
@logs = %i(warning error)
|
19
|
+
@use_api = false # @TODO change to true when we start using api.relaton.org
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
data/lib/relaton/db.rb
CHANGED
@@ -10,39 +10,121 @@ module Relaton
|
|
10
10
|
# @param local_cache [String] directory of local DB
|
11
11
|
def initialize(global_cache, local_cache)
|
12
12
|
@registry = Relaton::Registry.instance
|
13
|
-
|
14
|
-
@
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
@
|
13
|
+
gpath = global_cache && File.expand_path(global_cache)
|
14
|
+
@db = open_cache_biblio(gpath, type: :global)
|
15
|
+
lpath = local_cache && File.expand_path(local_cache)
|
16
|
+
@local_db = open_cache_biblio(lpath, type: :local)
|
17
|
+
@static_db = open_cache_biblio File.expand_path("../relaton/static_cache", __dir__)
|
18
|
+
@queues = {}
|
19
19
|
end
|
20
20
|
|
21
|
+
# Move global or local caches to anothe dirs
|
22
|
+
# @param new_dir [String, nil]
|
23
|
+
# @param type: [Symbol]
|
24
|
+
# @return [String, nil]
|
25
|
+
def mv(new_dir, type: :global)
|
26
|
+
case type
|
27
|
+
when :global
|
28
|
+
@db&.mv new_dir
|
29
|
+
when :local
|
30
|
+
@local_db&.mv new_dir
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Clear global and local databases
|
35
|
+
def clear
|
36
|
+
@db&.clear
|
37
|
+
@local_db&.clear
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
21
41
|
# The class of reference requested is determined by the prefix of the code:
|
22
42
|
# GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for iecbib,
|
43
|
+
#
|
23
44
|
# @param code [String] the ISO standard Code to look up (e.g. "ISO 9000")
|
24
45
|
# @param year [String] the year the standard was published (optional)
|
25
|
-
#
|
26
|
-
# @
|
46
|
+
#
|
47
|
+
# @param opts [Hash] options
|
48
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
49
|
+
# @option opts [Boolean] :keep_year If undated reference should return actual reference with year
|
50
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
51
|
+
#
|
52
|
+
# @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
|
27
53
|
# RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
|
28
|
-
#
|
54
|
+
# RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
|
55
|
+
# RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
|
56
|
+
# RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
|
57
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
58
|
+
# RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
|
59
|
+
# RelatonW3c::W3cBibliographicItem
|
60
|
+
##
|
29
61
|
def fetch(code, year = nil, opts = {})
|
30
62
|
stdclass = standard_class(code) || return
|
31
|
-
|
63
|
+
processor = @registry.processors[stdclass]
|
64
|
+
ref = processor.respond_to?(:urn_to_code) ? processor.urn_to_code(code)&.first : code
|
65
|
+
ref ||= code
|
66
|
+
result = combine_doc ref, year, opts, stdclass
|
67
|
+
result ||= check_bibliocache(ref, year, opts, stdclass)
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
# @see Relaton::Db#fetch
|
72
|
+
def fetch_db(code, year = nil, opts = {})
|
73
|
+
opts[:fetch_db] = true
|
74
|
+
fetch code, year, opts
|
75
|
+
end
|
76
|
+
|
77
|
+
# fetch all standards from DB
|
78
|
+
# @param test [String, nil]
|
79
|
+
# @param edition [String], nil
|
80
|
+
# @param year [Integer, nil]
|
81
|
+
# @return [Array]
|
82
|
+
def fetch_all(text = nil, edition: nil, year: nil)
|
83
|
+
result = @static_db.all { |file, yml| search_yml file, yml, text, edition, year }.compact
|
84
|
+
db = @db || @local_db
|
85
|
+
result += db.all { |file, xml| search_xml file, xml, text, edition, year }.compact if db
|
86
|
+
result
|
87
|
+
end
|
88
|
+
|
89
|
+
# Fetch asynchronously
|
90
|
+
def fetch_async(code, year = nil, opts = {}, &_block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
91
|
+
stdclass = standard_class code
|
92
|
+
if stdclass
|
93
|
+
unless @queues[stdclass]
|
94
|
+
processor = @registry.processors[stdclass]
|
95
|
+
wp = WorkersPool.new(processor.threads) { |args| yield fetch *args }
|
96
|
+
@queues[stdclass] = { queue: Queue.new, workers_pool: wp }
|
97
|
+
Thread.new { process_queue @queues[stdclass] }
|
98
|
+
end
|
99
|
+
@queues[stdclass][:queue] << [code, year, opts]
|
100
|
+
else yield nil
|
101
|
+
end
|
32
102
|
end
|
33
103
|
|
34
104
|
# @param code [String]
|
35
105
|
# @param year [String, NilClass]
|
36
106
|
# @param stdclass [Symbol, NilClass]
|
107
|
+
#
|
37
108
|
# @param opts [Hash]
|
109
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
110
|
+
# @option opts [Boolean] :keep_year If undated reference should return actual reference with year
|
111
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
112
|
+
#
|
113
|
+
# @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
|
114
|
+
# RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
|
115
|
+
# RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
|
116
|
+
# RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
|
117
|
+
# RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
|
118
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
119
|
+
# RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
|
120
|
+
# RelatonW3c::W3cBibliographicItem
|
38
121
|
def fetch_std(code, year = nil, stdclass = nil, opts = {})
|
39
122
|
std = nil
|
40
123
|
@registry.processors.each do |name, processor|
|
41
124
|
std = name if processor.prefix == stdclass
|
42
125
|
end
|
43
|
-
unless std
|
44
|
-
|
45
|
-
end
|
126
|
+
std = standard_class(code) or return nil unless std
|
127
|
+
|
46
128
|
check_bibliocache(code, year, opts, std)
|
47
129
|
end
|
48
130
|
|
@@ -86,27 +168,115 @@ module Relaton
|
|
86
168
|
|
87
169
|
private
|
88
170
|
|
171
|
+
# @param file [String] file path
|
172
|
+
# @param yml [String] content in YAML format
|
173
|
+
# @param text [String, nil] text to serach
|
174
|
+
# @param edition [String, nil] edition to filter
|
175
|
+
# @param year [Integer, nil] year to filter
|
176
|
+
# @return [BibliographicItem, nil]
|
177
|
+
def search_yml(file, yml, text, edition, year)
|
178
|
+
item = search_edition_year(file, yml, edition, year)
|
179
|
+
return unless item
|
180
|
+
|
181
|
+
item if match_xml_text(item.to_xml(bibdata: true), text)
|
182
|
+
end
|
183
|
+
|
184
|
+
# @param file [String] file path
|
185
|
+
# @param xml [String] content in XML format
|
186
|
+
# @param text [String, nil] text to serach
|
187
|
+
# @param edition [String, nil] edition to filter
|
188
|
+
# @param year [Integer, nil] year to filter
|
189
|
+
# @return [BibliographicItem, nil]
|
190
|
+
def search_xml(file, xml, text, edition, year)
|
191
|
+
return unless text.nil? || match_xml_text(xml, text)
|
192
|
+
|
193
|
+
search_edition_year(file, xml, edition, year)
|
194
|
+
end
|
195
|
+
|
196
|
+
# @param file [String] file path
|
197
|
+
# @param content [String] content in XML or YAmL format
|
198
|
+
# @param edition [String, nil] edition to filter
|
199
|
+
# @param year [Integer, nil] year to filter
|
200
|
+
# @return [BibliographicItem, nil]
|
201
|
+
def search_edition_year(file, content, edition, year) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
202
|
+
processor = @registry.processors[standard_class(file.split("/")[-2])]
|
203
|
+
item = file.match?(/xml$/) ? processor.from_xml(content) : processor.hash_to_bib(YAML.safe_load(content))
|
204
|
+
item if (edition.nil? || item.edition == edition) &&
|
205
|
+
(year.nil? || item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s })
|
206
|
+
end
|
207
|
+
|
208
|
+
# @param xml [String] content in XML format
|
209
|
+
# @param text [String, nil] text to serach
|
210
|
+
# @return [Boolean]
|
211
|
+
def match_xml_text(xml, text)
|
212
|
+
%r{((?<attr>=((?<apstr>')|"))|>).*?#{text}.*?(?(<attr>)(?(<apstr>)'|")|<)}mi.match?(xml)
|
213
|
+
end
|
214
|
+
|
215
|
+
# @param code [String]
|
216
|
+
# @param year [String, nil]
|
217
|
+
# @param stdslass [String]
|
218
|
+
#
|
219
|
+
# @param opts [Hash] options
|
220
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
221
|
+
# @option opts [Boolean] :keep_year If undated reference should return actual reference with year
|
222
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
223
|
+
#
|
224
|
+
# @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
|
225
|
+
# RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
|
226
|
+
# RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
|
227
|
+
# RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
|
228
|
+
# RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
|
229
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
230
|
+
# RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
|
231
|
+
# RelatonW3c::W3cBibliographicItem
|
232
|
+
def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
233
|
+
if (refs = code.split " + ").size > 1
|
234
|
+
reltype = "derivedFrom"
|
235
|
+
reldesc = nil
|
236
|
+
elsif (refs = code.split ", ").size > 1
|
237
|
+
reltype = "complements"
|
238
|
+
reldesc = RelatonBib::FormattedString.new content: "amendment"
|
239
|
+
else return
|
240
|
+
end
|
241
|
+
|
242
|
+
doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
|
243
|
+
ref = refs[0]
|
244
|
+
updates = check_bibliocache(ref, year, opts, stdclass)
|
245
|
+
doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates") if updates
|
246
|
+
refs[1..-1].each_with_object(doc) do |c, d|
|
247
|
+
bib = check_bibliocache("#{ref}/#{c}", year, opts, stdclass)
|
248
|
+
if bib
|
249
|
+
d.relation << RelatonBib::DocumentRelation.new(type: reltype, description: reldesc, bibitem: bib)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
89
254
|
# @param code [String] code of standard
|
90
255
|
# @return [Symbol] standard class name
|
91
256
|
def standard_class(code)
|
92
257
|
@registry.processors.each do |name, processor|
|
93
|
-
return name if
|
258
|
+
return name if /^(urn:)?#{processor.prefix}/i.match?(code) ||
|
94
259
|
processor.defaultprefix.match(code)
|
95
260
|
end
|
96
261
|
allowed = @registry.processors.reduce([]) do |m, (_k, v)|
|
97
262
|
m << v.prefix
|
98
263
|
end
|
99
264
|
warn <<~WARN
|
100
|
-
|
101
|
-
|
102
|
-
|
265
|
+
#{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
266
|
+
See https://github.com/relaton/relaton/ for instructions on prefixing and wrapping document identifiers to disambiguate them.
|
267
|
+
WARN
|
103
268
|
end
|
104
269
|
|
105
270
|
# TODO: i18n
|
106
271
|
# Fofmat ID
|
107
272
|
# @param code [String]
|
108
273
|
# @param year [String]
|
274
|
+
#
|
109
275
|
# @param opts [Hash]
|
276
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
277
|
+
# @option opts [Boolean] :keep_year If undated reference should return actual reference with year
|
278
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
279
|
+
#
|
110
280
|
# @param stdClass [Symbol]
|
111
281
|
# @return [Array<String>] docid and code
|
112
282
|
def std_id(code, year, opts, stdclass)
|
@@ -129,23 +299,36 @@ module Relaton
|
|
129
299
|
|
130
300
|
# @param entry [String] XML string
|
131
301
|
# @param stdclass [Symbol]
|
132
|
-
# @
|
133
|
-
# @return [NilClass, RelatonIsoBib::IsoBibliographicItem,
|
302
|
+
# @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
|
134
303
|
# RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
|
135
|
-
#
|
136
|
-
|
137
|
-
|
304
|
+
# RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
|
305
|
+
# RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
|
306
|
+
# RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
|
307
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
308
|
+
# RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
|
309
|
+
# RelatonW3c::W3cBibliographicItem
|
310
|
+
def bib_retval(entry, stdclass)
|
311
|
+
entry.nil? || entry.match?(/^not_found/) ? nil : @registry.processors[stdclass].from_xml(entry)
|
138
312
|
end
|
139
313
|
|
140
314
|
# @param code [String]
|
141
315
|
# @param year [String]
|
316
|
+
#
|
142
317
|
# @param opts [Hash]
|
318
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
319
|
+
# @option opts [Boolean] :keep_year If undated reference should return actual reference with year
|
320
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
321
|
+
#
|
143
322
|
# @param stdclass [Symbol]
|
144
|
-
# @return [
|
323
|
+
# @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
|
145
324
|
# RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
|
325
|
+
# RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
|
146
326
|
# RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
|
147
327
|
# RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
|
148
|
-
|
328
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
329
|
+
# RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
|
330
|
+
# RelatonW3c::W3cBibliographicItem
|
331
|
+
def check_bibliocache(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
149
332
|
id, searchcode = std_id(code, year, opts, stdclass)
|
150
333
|
yaml = @static_db[id]
|
151
334
|
return @registry.processors[stdclass].hash_to_bib YAML.safe_load(yaml) if yaml
|
@@ -153,31 +336,41 @@ module Relaton
|
|
153
336
|
db = @local_db || @db
|
154
337
|
altdb = @local_db && @db ? @db : nil
|
155
338
|
if db.nil?
|
339
|
+
return if opts[:fetch_db]
|
340
|
+
|
156
341
|
bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
|
157
|
-
return bib_retval(bibentry, stdclass
|
342
|
+
return bib_retval(bibentry, stdclass)
|
158
343
|
end
|
159
344
|
|
160
345
|
db.delete(id) unless db.valid_entry?(id, year)
|
161
346
|
if altdb
|
162
|
-
|
163
|
-
|
347
|
+
return bib_retval(altdb[id], stdclass) if opts[:fetch_db]
|
348
|
+
|
349
|
+
db.clone_entry id, altdb if altdb.valid_entry? id, year
|
164
350
|
db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
|
165
351
|
altdb.clone_entry(id, db) if !altdb.valid_entry?(id, year)
|
166
352
|
else
|
353
|
+
return bib_retval(db[id], stdclass) if opts[:fetch_db]
|
354
|
+
|
167
355
|
db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
|
168
356
|
end
|
169
|
-
bib_retval(db[id], stdclass
|
357
|
+
bib_retval(db[id], stdclass)
|
170
358
|
end
|
171
359
|
|
172
360
|
# @param code [String]
|
173
361
|
# @param year [String]
|
362
|
+
#
|
174
363
|
# @param opts [Hash]
|
364
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
365
|
+
# @option opts [Boolean] :keep_year If undated reference should return actual reference with year
|
366
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
367
|
+
#
|
175
368
|
# @param stdclass [Symbol]
|
176
369
|
# @param db [Relaton::DbCache,`NilClass]
|
177
370
|
# @param id [String] docid
|
178
371
|
# @return [String]
|
179
|
-
def new_bib_entry(code, year, opts, stdclass, **args)
|
180
|
-
bib =
|
372
|
+
def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
373
|
+
bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
|
181
374
|
bib_id = bib&.docidentifier&.first&.id
|
182
375
|
|
183
376
|
# when docid doesn't match bib's id then return a reference to bib's id
|
@@ -185,11 +378,19 @@ module Relaton
|
|
185
378
|
bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
|
186
379
|
args[:db][bid] ||= bib_entry bib
|
187
380
|
"redirection #{bid}"
|
188
|
-
else
|
189
|
-
bib_entry bib
|
381
|
+
else bib_entry bib
|
190
382
|
end
|
191
383
|
end
|
192
384
|
|
385
|
+
# @raise [RelatonBib::RequestError]
|
386
|
+
def net_retry(code, year, opts, stdclass, retries)
|
387
|
+
@registry.processors[stdclass].get(code, year, opts)
|
388
|
+
rescue RelatonBib::RequestError => e
|
389
|
+
raise e unless retries > 1
|
390
|
+
|
391
|
+
net_retry(code, year, opts, stdclass, retries - 1)
|
392
|
+
end
|
393
|
+
|
193
394
|
# @param bib [RelatonGb::GbBibliongraphicItem, RelatonIsoBib::IsoBibliographicItem,
|
194
395
|
# RelatonIetf::IetfBibliographicItem, RelatonItu::ItuBibliographicItem,
|
195
396
|
# RelatonNist::NistBibliongraphicItem, RelatonOgc::OgcBibliographicItem]
|
@@ -202,21 +403,32 @@ module Relaton
|
|
202
403
|
end
|
203
404
|
end
|
204
405
|
|
205
|
-
# @param dir [String] DB directory
|
406
|
+
# @param dir [String, nil] DB directory
|
206
407
|
# @param type [Symbol]
|
207
408
|
# @return [Relaton::DbCache, NilClass]
|
208
409
|
def open_cache_biblio(dir, type: :static)
|
209
410
|
return nil if dir.nil?
|
210
411
|
|
211
412
|
db = DbCache.new dir, type == :static ? "yml" : "xml"
|
413
|
+
return db if type == :static
|
212
414
|
|
213
415
|
Dir["#{dir}/*/"].each do |fdir|
|
214
|
-
next if
|
416
|
+
next if db.check_version?(fdir)
|
215
417
|
|
216
|
-
FileUtils.rm_rf(
|
418
|
+
FileUtils.rm_rf(fdir, secure: true)
|
419
|
+
# db.set_version fdir
|
217
420
|
warn "[relaton] cache #{fdir}: version is obsolete and cache is cleared."
|
218
421
|
end
|
219
422
|
db
|
220
423
|
end
|
424
|
+
|
425
|
+
# @param qwp [Hash]
|
426
|
+
# @option qwp [Queue] :queue The queue of references to fetch
|
427
|
+
# @option qwp [Relaton::WorkersPool] :workers_pool The pool of workers
|
428
|
+
def process_queue(qwp)
|
429
|
+
while args = qwp[:queue].pop
|
430
|
+
qwp[:workers_pool] << args
|
431
|
+
end
|
432
|
+
end
|
221
433
|
end
|
222
434
|
end
|