relaton 1.7.3 → 1.7.8
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 +151 -3
- data/lib/relaton.rb +8 -7
- data/lib/relaton/config.rb +5 -2
- data/lib/relaton/db.rb +283 -92
- data/lib/relaton/db_cache.rb +25 -3
- data/lib/relaton/processor.rb +11 -0
- data/lib/relaton/registry.rb +1 -1
- data/lib/relaton/util.rb +1 -1
- data/lib/relaton/version.rb +1 -1
- data/lib/relaton/workers_pool.rb +21 -0
- data/relaton.gemspec +6 -4
- data/spec/relaton/config_spec.rb +1 -1
- data/spec/relaton/db_spec.rb +154 -0
- data/spec/relaton/processor_spec.rb +4 -0
- data/spec/relaton/regirtry_spec.rb +51 -45
- data/spec/relaton_spec.rb +26 -17
- data/spec/vcr_cassetes/19133_2005.yml +22 -22
- data/spec/vcr_cassetes/async_fetch.yml +4423 -0
- data/spec/vcr_cassetes/bsi_bs_en_iso_8848.yml +159 -0
- data/spec/vcr_cassetes/cc_dir_10005_2019.yml +14 -14
- data/spec/vcr_cassetes/cie_001_1980.yml +120 -0
- data/spec/vcr_cassetes/ecma_6.yml +134 -67
- data/spec/vcr_cassetes/fisp_140.yml +4 -4
- data/spec/vcr_cassetes/gb_t_20223_2006.yml +11 -11
- data/spec/vcr_cassetes/iec_60050_102_2007.yml +30 -26
- data/spec/vcr_cassetes/iec_combined_included.yml +71 -73
- data/spec/vcr_cassetes/ieee_528_2019.yml +41 -39
- data/spec/vcr_cassetes/iho_b_11.yml +11 -11
- 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 +21 -21
- data/spec/vcr_cassetes/iso_19115_1_2.yml +43 -43
- data/spec/vcr_cassetes/iso_awi_24229.yml +20 -20
- data/spec/vcr_cassetes/iso_combined_applied.yml +41 -41
- data/spec/vcr_cassetes/iso_combined_included.yml +42 -42
- data/spec/vcr_cassetes/itu_combined_included.yml +219 -159
- data/spec/vcr_cassetes/ogc_19_025r1.yml +1520 -1124
- data/spec/vcr_cassetes/ogm_ami4ccm_1_0.yml +11 -23
- 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 +4 -4
- data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +34 -36
- data/spec/vcr_cassetes/w3c_json_ld11.yml +12 -12
- metadata +40 -39
- data/.github/workflows/macos.yml +0 -34
- data/.github/workflows/ubuntu.yml +0 -32
- data/.github/workflows/windows.yml +0 -35
- data/localcache/iec/iec_60050_102_2007.xml +0 -58
- data/localcache/iec/version +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d0ff67d3ebeb9332a6aa18ad88e8b585478c29adb27ccda935ab9b8af4b34e2b
|
|
4
|
+
data.tar.gz: 9aefca4601eb5bd7c4491dafc41fcee87cbb7e5d7508ee05086cfa39122bfbef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b69bf1fbbbc4258bd22304dda3d54b23bc8a8e2361aeff2f26487518236e6b46690d0a793dd076489749ae0dcd93a6c3da7bc1969d3e877149ad9722b9ed0e9e
|
|
7
|
+
data.tar.gz: '0682111008bcb648773cd0e90bb4f5a789007b5d5deca6aa2c5aa245b1f677a136eff936c6256b8e6bf76bcf4cb65f8371ba0cb5fe0c9ffe908e7d4640031342'
|
|
@@ -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
|
@@ -64,6 +64,11 @@ e.g. `get("ISO 19115-1", "2014", all_parts: true)` is transformed into a referen
|
|
|
64
64
|
|
|
65
65
|
=== Create DB
|
|
66
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
|
+
|
|
67
72
|
[source,ruby]
|
|
68
73
|
----
|
|
69
74
|
require "relaton"
|
|
@@ -97,9 +102,46 @@ db = Relaton::Db.new("globalcache", "localcache")
|
|
|
97
102
|
...
|
|
98
103
|
----
|
|
99
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
|
+
----
|
|
122
|
+
|
|
123
|
+
==== Clear DB
|
|
124
|
+
|
|
125
|
+
`Relaton::Db#clear` removes all entries form DB
|
|
126
|
+
|
|
100
127
|
=== Fetch documens
|
|
101
128
|
|
|
102
|
-
==== Fetch by references
|
|
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
|
|
103
145
|
|
|
104
146
|
[source,ruby]
|
|
105
147
|
----
|
|
@@ -114,7 +156,7 @@ x = db.fetch("ISO 19011")
|
|
|
114
156
|
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d0ab2f00
|
|
115
157
|
...
|
|
116
158
|
|
|
117
|
-
x = db.fetch("ISO 19011", "2011")
|
|
159
|
+
x = db.fetch("ISO 19011", "2011", retries: 3)
|
|
118
160
|
[relaton-iso] ("ISO 19011") fetching...
|
|
119
161
|
[relaton-iso] ("ISO 19011") found ISO 19011:2011
|
|
120
162
|
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d2593068
|
|
@@ -125,6 +167,36 @@ x = db.fetch("ISO 19115", nil, all_parts: true)
|
|
|
125
167
|
[relaton-iso] ("ISO 19115") found ISO 19115 (all parts)
|
|
126
168
|
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d0ae8bf0
|
|
127
169
|
...
|
|
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
|
+
# references ot fetch
|
|
186
|
+
refs = ["ISO 19011", "ISO 19115"]
|
|
187
|
+
|
|
188
|
+
# fetch documents
|
|
189
|
+
refs.each do |ref|
|
|
190
|
+
db.fetch_async(ref) do |doc|
|
|
191
|
+
results << [ref, doc]
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# wait until documets fetching
|
|
196
|
+
refs.size.times do
|
|
197
|
+
ref, doc = results.pop
|
|
198
|
+
# do thatever you need with result x
|
|
199
|
+
end
|
|
128
200
|
----
|
|
129
201
|
|
|
130
202
|
==== Fetch by URN
|
|
@@ -192,6 +264,82 @@ bib.relation[1].bibitem.docidentifier[0].id
|
|
|
192
264
|
[source,ruby]
|
|
193
265
|
----
|
|
194
266
|
bib = db.fetch "ISO 19115-1, Amd 1"
|
|
267
|
+
=> ["Chinese Standard", "GB/T 1.1"]
|
|
268
|
+
[relaton-iso] ("ISO 19115-1") fetching...
|
|
269
|
+
[relaton-iso] ("ISO 19115-1") found ISO 19115-1:2014
|
|
270
|
+
[relaton-iso] ("ISO 19115-1/Amd 1") fetching...
|
|
271
|
+
[relaton-iso] ("ISO 19115-1/Amd 1") found ISO 19115-1:2014/Amd 1:2018
|
|
272
|
+
=> #<RelatonIsoBib::IsoBibliographicItem:0x007fb09b36d1b8
|
|
273
|
+
...
|
|
274
|
+
----
|
|
275
|
+
|
|
276
|
+
==== Fetch all documents from cache
|
|
277
|
+
|
|
278
|
+
`Relaton::Db#fetch_all(text = nil, edition: nil, year: nil)` - fetches all document from local cache
|
|
279
|
+
|
|
280
|
+
* `text` - (String) filter entries by a text (optional)
|
|
281
|
+
* `edition` - (String) filter entries by an edition (optional)
|
|
282
|
+
* `year` - (Integer) filter entries by a year (optional)
|
|
283
|
+
|
|
284
|
+
[source,ruby]
|
|
285
|
+
----
|
|
286
|
+
# query for all entries in a cahche
|
|
287
|
+
|
|
288
|
+
items = db.fetch_all
|
|
289
|
+
=> [#<RelatonIec::IecBibliographicItem:0x007facda8fdc28
|
|
290
|
+
...
|
|
291
|
+
|
|
292
|
+
items.size
|
|
293
|
+
=> 6
|
|
294
|
+
|
|
295
|
+
# query for all entries in a cahche for a certain string
|
|
296
|
+
|
|
297
|
+
items = db.fetch_all("mathematical terminology")
|
|
298
|
+
=> [#<RelatonIec::IecBibliographicItem:0x007ffeae5bd240
|
|
299
|
+
...
|
|
300
|
+
|
|
301
|
+
items.size
|
|
302
|
+
=> 1
|
|
303
|
+
|
|
304
|
+
items[0].docidentifier[0].id
|
|
305
|
+
=> "IEC 60050-102:2007"
|
|
306
|
+
|
|
307
|
+
# query for all entries in a cahche for a certain string and edition
|
|
308
|
+
|
|
309
|
+
items = db.fetch_all("system", edition: "2")
|
|
310
|
+
=> [#<RelatonIsoBib::IsoBibliographicItem:0x007ffebe2d1be8
|
|
311
|
+
...
|
|
312
|
+
|
|
313
|
+
items.size
|
|
314
|
+
=> 1
|
|
315
|
+
|
|
316
|
+
items[0].docidentifier[0].id
|
|
317
|
+
=> "ISO 19011:2011"
|
|
318
|
+
|
|
319
|
+
# query for all entries in a cahche for a certain string and year
|
|
320
|
+
|
|
321
|
+
items = db.fetch_all("system", year: 2018)
|
|
322
|
+
=> [#<RelatonIsoBib::IsoBibliographicItem:0x007ffeae645fa0
|
|
323
|
+
...
|
|
324
|
+
|
|
325
|
+
items.size
|
|
326
|
+
=> 1
|
|
327
|
+
|
|
328
|
+
items[0].docidentifier[0].id
|
|
329
|
+
=> "ISO 19011 (all parts)"
|
|
330
|
+
----
|
|
331
|
+
|
|
332
|
+
=== Static DB
|
|
333
|
+
|
|
334
|
+
This gem has a static DB which is distributed with it. Now the static contains documents:
|
|
335
|
+
----
|
|
336
|
+
ISO/IEC DIR 1 IEC SUP
|
|
337
|
+
ISO/IEC DIR 1 ISO SUP
|
|
338
|
+
ISO/IEC DIR 1
|
|
339
|
+
ISO/IEC DIR 2 IEC
|
|
340
|
+
ISO/IEC DIR 2 ISO
|
|
341
|
+
ISO/IEC DIR IEC SUP
|
|
342
|
+
ISO/IEC DIR 1 JTC SUP
|
|
195
343
|
----
|
|
196
344
|
|
|
197
345
|
=== Get document type
|
|
@@ -229,7 +377,7 @@ x.to_xml bibdata: true
|
|
|
229
377
|
db.load_entry("ISO(ISO 19011)")
|
|
230
378
|
=> "<bibdata type="standard">
|
|
231
379
|
...
|
|
232
|
-
|
|
380
|
+
</bibdata>"
|
|
233
381
|
----
|
|
234
382
|
|
|
235
383
|
=== Entry manipulation
|
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,13 @@ 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 = %i(
|
|
18
|
+
@logs = %i(info error)
|
|
19
|
+
|
|
20
|
+
# @TODO change to true when we start using api.relaton.org
|
|
21
|
+
@use_api = false
|
|
19
22
|
end
|
|
20
23
|
end
|
|
21
24
|
|
data/lib/relaton/db.rb
CHANGED
|
@@ -10,83 +10,127 @@ 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",
|
|
18
|
+
__dir__)
|
|
19
|
+
@queues = {}
|
|
19
20
|
end
|
|
20
21
|
|
|
22
|
+
# Move global or local caches to anothe dirs
|
|
23
|
+
# @param new_dir [String, nil]
|
|
24
|
+
# @param type: [Symbol]
|
|
25
|
+
# @return [String, nil]
|
|
26
|
+
def mv(new_dir, type: :global)
|
|
27
|
+
case type
|
|
28
|
+
when :global
|
|
29
|
+
@db&.mv new_dir
|
|
30
|
+
when :local
|
|
31
|
+
@local_db&.mv new_dir
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Clear global and local databases
|
|
36
|
+
def clear
|
|
37
|
+
@db&.clear
|
|
38
|
+
@local_db&.clear
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
21
42
|
# The class of reference requested is determined by the prefix of the code:
|
|
22
|
-
# GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for
|
|
43
|
+
# GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for
|
|
44
|
+
# iecbib,
|
|
45
|
+
#
|
|
23
46
|
# @param code [String] the ISO standard Code to look up (e.g. "ISO 9000")
|
|
24
47
|
# @param year [String] the year the standard was published (optional)
|
|
25
|
-
#
|
|
26
|
-
# @
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
48
|
+
#
|
|
49
|
+
# @param opts [Hash] options
|
|
50
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
51
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
52
|
+
# actual reference with year
|
|
53
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
|
54
|
+
#
|
|
55
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
|
56
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
|
57
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
|
58
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
|
59
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
|
60
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
|
31
61
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
|
32
|
-
# RelatonOmg::OmgBibliographicItem
|
|
33
|
-
|
|
62
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
63
|
+
##
|
|
34
64
|
def fetch(code, year = nil, opts = {})
|
|
35
65
|
stdclass = standard_class(code) || return
|
|
36
66
|
processor = @registry.processors[stdclass]
|
|
37
|
-
ref = processor.respond_to?(:urn_to_code)
|
|
67
|
+
ref = if processor.respond_to?(:urn_to_code)
|
|
68
|
+
processor.urn_to_code(code)&.first
|
|
69
|
+
else code
|
|
70
|
+
end
|
|
38
71
|
ref ||= code
|
|
39
|
-
|
|
40
|
-
|
|
72
|
+
result = combine_doc ref, year, opts, stdclass
|
|
73
|
+
result ||= check_bibliocache(ref, year, opts, stdclass)
|
|
74
|
+
result
|
|
75
|
+
end
|
|
41
76
|
|
|
42
|
-
|
|
77
|
+
# @see Relaton::Db#fetch
|
|
78
|
+
def fetch_db(code, year = nil, opts = {})
|
|
79
|
+
opts[:fetch_db] = true
|
|
80
|
+
fetch code, year, opts
|
|
43
81
|
end
|
|
44
82
|
|
|
45
|
-
#
|
|
46
|
-
# @param
|
|
47
|
-
# @param
|
|
48
|
-
# @
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
reldesc = nil
|
|
60
|
-
elsif (refs = code.split ", ").size > 1
|
|
61
|
-
reltype = "complements"
|
|
62
|
-
reldesc = RelatonBib::FormattedString.new content: "amendment"
|
|
63
|
-
else return
|
|
83
|
+
# fetch all standards from DB
|
|
84
|
+
# @param test [String, nil]
|
|
85
|
+
# @param edition [String], nil
|
|
86
|
+
# @param year [Integer, nil]
|
|
87
|
+
# @return [Array]
|
|
88
|
+
def fetch_all(text = nil, edition: nil, year: nil)
|
|
89
|
+
result = @static_db.all do |file, yml|
|
|
90
|
+
search_yml file, yml, text, edition, year
|
|
91
|
+
end.compact
|
|
92
|
+
db = @db || @local_db
|
|
93
|
+
if db
|
|
94
|
+
result += db.all do |file, xml|
|
|
95
|
+
search_xml file, xml, text, edition, year
|
|
96
|
+
end.compact
|
|
64
97
|
end
|
|
98
|
+
result
|
|
99
|
+
end
|
|
65
100
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
101
|
+
# Fetch asynchronously
|
|
102
|
+
def fetch_async(code, year = nil, opts = {}, &_block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
103
|
+
stdclass = standard_class code
|
|
104
|
+
if stdclass
|
|
105
|
+
unless @queues[stdclass]
|
|
106
|
+
processor = @registry.processors[stdclass]
|
|
107
|
+
wp = WorkersPool.new(processor.threads) { |args| yield fetch *args }
|
|
108
|
+
@queues[stdclass] = { queue: Queue.new, workers_pool: wp }
|
|
109
|
+
Thread.new { process_queue @queues[stdclass] }
|
|
74
110
|
end
|
|
111
|
+
@queues[stdclass][:queue] << [code, year, opts]
|
|
112
|
+
else yield nil
|
|
75
113
|
end
|
|
76
114
|
end
|
|
77
115
|
|
|
78
116
|
# @param code [String]
|
|
79
117
|
# @param year [String, NilClass]
|
|
80
118
|
# @param stdclass [Symbol, NilClass]
|
|
119
|
+
#
|
|
81
120
|
# @param opts [Hash]
|
|
82
|
-
# @
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
121
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
122
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
123
|
+
# actual reference with year
|
|
124
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
|
125
|
+
#
|
|
126
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
|
127
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
|
128
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
|
129
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
|
130
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
|
131
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
|
87
132
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
|
88
|
-
# RelatonOmg::OmgBibliographicItem
|
|
89
|
-
# RelatonW3c::W3cBibliographicItem
|
|
133
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
90
134
|
def fetch_std(code, year = nil, stdclass = nil, opts = {})
|
|
91
135
|
std = nil
|
|
92
136
|
@registry.processors.each do |name, processor|
|
|
@@ -137,6 +181,98 @@ module Relaton
|
|
|
137
181
|
|
|
138
182
|
private
|
|
139
183
|
|
|
184
|
+
# @param file [String] file path
|
|
185
|
+
# @param yml [String] content in YAML 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_yml(file, yml, text, edition, year)
|
|
191
|
+
item = search_edition_year(file, yml, edition, year)
|
|
192
|
+
return unless item
|
|
193
|
+
|
|
194
|
+
item if match_xml_text(item.to_xml(bibdata: true), text)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# @param file [String] file path
|
|
198
|
+
# @param xml [String] content in XML format
|
|
199
|
+
# @param text [String, nil] text to serach
|
|
200
|
+
# @param edition [String, nil] edition to filter
|
|
201
|
+
# @param year [Integer, nil] year to filter
|
|
202
|
+
# @return [BibliographicItem, nil]
|
|
203
|
+
def search_xml(file, xml, text, edition, year)
|
|
204
|
+
return unless text.nil? || match_xml_text(xml, text)
|
|
205
|
+
|
|
206
|
+
search_edition_year(file, xml, edition, year)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# @param file [String] file path
|
|
210
|
+
# @param content [String] content in XML or YAmL format
|
|
211
|
+
# @param edition [String, nil] edition to filter
|
|
212
|
+
# @param year [Integer, nil] year to filter
|
|
213
|
+
# @return [BibliographicItem, nil]
|
|
214
|
+
def search_edition_year(file, content, edition, year) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
215
|
+
processor = @registry.processors[standard_class(file.split("/")[-2])]
|
|
216
|
+
item = if file.match?(/xml$/) then processor.from_xml(content)
|
|
217
|
+
else processor.hash_to_bib(YAML.safe_load(content))
|
|
218
|
+
end
|
|
219
|
+
item if (edition.nil? || item.edition == edition) && (year.nil? ||
|
|
220
|
+
item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s })
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# @param xml [String] content in XML format
|
|
224
|
+
# @param text [String, nil] text to serach
|
|
225
|
+
# @return [Boolean]
|
|
226
|
+
def match_xml_text(xml, text)
|
|
227
|
+
%r{((?<attr>=((?<apstr>')|"))|>).*?#{text}.*?(?(<attr>)(?(<apstr>)'|")|<)}mi.match?(xml)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# @param code [String]
|
|
231
|
+
# @param year [String, nil]
|
|
232
|
+
# @param stdslass [String]
|
|
233
|
+
#
|
|
234
|
+
# @param opts [Hash] options
|
|
235
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
236
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
237
|
+
# actual reference with year
|
|
238
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
|
239
|
+
#
|
|
240
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
|
241
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
|
242
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
|
243
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
|
244
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
|
245
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
|
246
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
|
247
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
248
|
+
def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
249
|
+
if (refs = code.split " + ").size > 1
|
|
250
|
+
reltype = "derivedFrom"
|
|
251
|
+
reldesc = nil
|
|
252
|
+
elsif (refs = code.split ", ").size > 1
|
|
253
|
+
reltype = "complements"
|
|
254
|
+
reldesc = RelatonBib::FormattedString.new content: "amendment"
|
|
255
|
+
else return
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
|
|
259
|
+
ref = refs[0]
|
|
260
|
+
updates = check_bibliocache(ref, year, opts, stdclass)
|
|
261
|
+
if updates
|
|
262
|
+
doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates,
|
|
263
|
+
type: "updates")
|
|
264
|
+
end
|
|
265
|
+
divider = stdclass == :relaton_itu ? " " : "/"
|
|
266
|
+
refs[1..-1].each_with_object(doc) do |c, d|
|
|
267
|
+
bib = check_bibliocache(ref + divider + c, year, opts, stdclass)
|
|
268
|
+
if bib
|
|
269
|
+
d.relation << RelatonBib::DocumentRelation.new(
|
|
270
|
+
type: reltype, description: reldesc, bibitem: bib
|
|
271
|
+
)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
140
276
|
# @param code [String] code of standard
|
|
141
277
|
# @return [Symbol] standard class name
|
|
142
278
|
def standard_class(code)
|
|
@@ -147,8 +283,8 @@ module Relaton
|
|
|
147
283
|
allowed = @registry.processors.reduce([]) do |m, (_k, v)|
|
|
148
284
|
m << v.prefix
|
|
149
285
|
end
|
|
150
|
-
|
|
151
|
-
#{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
|
286
|
+
Util.log <<~WARN, :info
|
|
287
|
+
[relaton] #{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
|
152
288
|
See https://github.com/relaton/relaton/ for instructions on prefixing and wrapping document identifiers to disambiguate them.
|
|
153
289
|
WARN
|
|
154
290
|
end
|
|
@@ -157,7 +293,13 @@ module Relaton
|
|
|
157
293
|
# Fofmat ID
|
|
158
294
|
# @param code [String]
|
|
159
295
|
# @param year [String]
|
|
296
|
+
#
|
|
160
297
|
# @param opts [Hash]
|
|
298
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
299
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
300
|
+
# actual reference with year
|
|
301
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
|
302
|
+
#
|
|
161
303
|
# @param stdClass [Symbol]
|
|
162
304
|
# @return [Array<String>] docid and code
|
|
163
305
|
def std_id(code, year, opts, stdclass)
|
|
@@ -180,79 +322,116 @@ module Relaton
|
|
|
180
322
|
|
|
181
323
|
# @param entry [String] XML string
|
|
182
324
|
# @param stdclass [Symbol]
|
|
183
|
-
# @
|
|
184
|
-
#
|
|
185
|
-
#
|
|
186
|
-
#
|
|
187
|
-
#
|
|
188
|
-
#
|
|
325
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
|
326
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
|
327
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
|
328
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
|
329
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
|
330
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
|
189
331
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
|
190
|
-
# RelatonOmg::OmgBibliographicItem
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
332
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
333
|
+
def bib_retval(entry, stdclass)
|
|
334
|
+
if entry.nil? || entry.match?(/^not_found/) then nil
|
|
335
|
+
else @registry.processors[stdclass].from_xml(entry)
|
|
336
|
+
end
|
|
194
337
|
end
|
|
195
338
|
|
|
196
339
|
# @param code [String]
|
|
197
340
|
# @param year [String]
|
|
341
|
+
#
|
|
198
342
|
# @param opts [Hash]
|
|
343
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
344
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
345
|
+
# actual reference with year
|
|
346
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
|
347
|
+
#
|
|
199
348
|
# @param stdclass [Symbol]
|
|
200
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
|
201
|
-
#
|
|
202
|
-
#
|
|
203
|
-
#
|
|
204
|
-
# RelatonOgc::OgcBibliographicItem,
|
|
349
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
|
350
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
|
351
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
|
352
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
|
353
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
|
354
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
|
205
355
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
|
206
|
-
# RelatonOmg::OmgBibliographicItem
|
|
207
|
-
# RelatonW3c::W3cBibliographicItem
|
|
356
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
208
357
|
def check_bibliocache(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
209
358
|
id, searchcode = std_id(code, year, opts, stdclass)
|
|
210
359
|
yaml = @static_db[id]
|
|
211
|
-
|
|
360
|
+
if yaml
|
|
361
|
+
return @registry.processors[stdclass].hash_to_bib YAML.safe_load(yaml)
|
|
362
|
+
end
|
|
212
363
|
|
|
213
364
|
db = @local_db || @db
|
|
214
365
|
altdb = @local_db && @db ? @db : nil
|
|
215
366
|
if db.nil?
|
|
216
|
-
|
|
217
|
-
|
|
367
|
+
return if opts[:fetch_db]
|
|
368
|
+
|
|
369
|
+
bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db,
|
|
370
|
+
id: id)
|
|
371
|
+
return bib_retval(bibentry, stdclass)
|
|
218
372
|
end
|
|
219
373
|
|
|
220
374
|
db.delete(id) unless db.valid_entry?(id, year)
|
|
221
375
|
if altdb
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
db
|
|
376
|
+
return bib_retval(altdb[id], stdclass) if opts[:fetch_db]
|
|
377
|
+
|
|
378
|
+
db.clone_entry id, altdb if altdb.valid_entry? id, year
|
|
379
|
+
db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db,
|
|
380
|
+
id: id)
|
|
225
381
|
altdb.clone_entry(id, db) if !altdb.valid_entry?(id, year)
|
|
226
382
|
else
|
|
227
|
-
db[id]
|
|
383
|
+
return bib_retval(db[id], stdclass) if opts[:fetch_db]
|
|
384
|
+
|
|
385
|
+
db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db,
|
|
386
|
+
id: id)
|
|
228
387
|
end
|
|
229
|
-
bib_retval(db[id], stdclass
|
|
388
|
+
bib_retval(db[id], stdclass)
|
|
230
389
|
end
|
|
231
390
|
|
|
232
391
|
# @param code [String]
|
|
233
392
|
# @param year [String]
|
|
393
|
+
#
|
|
234
394
|
# @param opts [Hash]
|
|
395
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
396
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
397
|
+
# actual reference with year
|
|
398
|
+
# @option opts [Integer] :retries (1) Number of network retries
|
|
399
|
+
#
|
|
235
400
|
# @param stdclass [Symbol]
|
|
236
401
|
# @param db [Relaton::DbCache,`NilClass]
|
|
237
402
|
# @param id [String] docid
|
|
238
403
|
# @return [String]
|
|
239
404
|
def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
240
|
-
bib =
|
|
405
|
+
bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
|
|
241
406
|
bib_id = bib&.docidentifier&.first&.id
|
|
242
407
|
|
|
243
408
|
# when docid doesn't match bib's id then return a reference to bib's id
|
|
244
|
-
if args[:db] && args[:id] &&
|
|
409
|
+
if args[:db] && args[:id] &&
|
|
410
|
+
bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}}
|
|
245
411
|
bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
|
|
246
412
|
args[:db][bid] ||= bib_entry bib
|
|
247
413
|
"redirection #{bid}"
|
|
248
|
-
else
|
|
249
|
-
bib_entry bib
|
|
414
|
+
else bib_entry bib
|
|
250
415
|
end
|
|
251
416
|
end
|
|
252
417
|
|
|
253
|
-
# @
|
|
254
|
-
|
|
255
|
-
|
|
418
|
+
# @raise [RelatonBib::RequestError]
|
|
419
|
+
def net_retry(code, year, opts, stdclass, retries)
|
|
420
|
+
@registry.processors[stdclass].get(code, year, opts)
|
|
421
|
+
rescue RelatonBib::RequestError => e
|
|
422
|
+
raise e unless retries > 1
|
|
423
|
+
|
|
424
|
+
net_retry(code, year, opts, stdclass, retries - 1)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
# @param bib [RelatonBib::BibliographicItem,
|
|
428
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
|
429
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
|
430
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
|
431
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
|
432
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
|
433
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
|
434
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
256
435
|
# @return [String] XML or "not_found mm-dd-yyyy"
|
|
257
436
|
def bib_entry(bib)
|
|
258
437
|
if bib.respond_to? :to_xml
|
|
@@ -262,21 +441,33 @@ module Relaton
|
|
|
262
441
|
end
|
|
263
442
|
end
|
|
264
443
|
|
|
265
|
-
# @param dir [String] DB directory
|
|
444
|
+
# @param dir [String, nil] DB directory
|
|
266
445
|
# @param type [Symbol]
|
|
267
446
|
# @return [Relaton::DbCache, NilClass]
|
|
268
|
-
def open_cache_biblio(dir, type: :static)
|
|
447
|
+
def open_cache_biblio(dir, type: :static) # rubocop:disable Metrics/MethodLength
|
|
269
448
|
return nil if dir.nil?
|
|
270
449
|
|
|
271
450
|
db = DbCache.new dir, type == :static ? "yml" : "xml"
|
|
451
|
+
return db if type == :static
|
|
272
452
|
|
|
273
453
|
Dir["#{dir}/*/"].each do |fdir|
|
|
274
|
-
next if
|
|
454
|
+
next if db.check_version?(fdir)
|
|
275
455
|
|
|
276
|
-
FileUtils.rm_rf(
|
|
277
|
-
|
|
456
|
+
FileUtils.rm_rf(fdir, secure: true)
|
|
457
|
+
Util.log(
|
|
458
|
+
"[relaton] WARNING: cache #{fdir}: version is obsolete and cache is "\
|
|
459
|
+
"cleared.",
|
|
460
|
+
:warning
|
|
461
|
+
)
|
|
278
462
|
end
|
|
279
463
|
db
|
|
280
464
|
end
|
|
465
|
+
|
|
466
|
+
# @param qwp [Hash]
|
|
467
|
+
# @option qwp [Queue] :queue The queue of references to fetch
|
|
468
|
+
# @option qwp [Relaton::WorkersPool] :workers_pool The pool of workers
|
|
469
|
+
def process_queue(qwp)
|
|
470
|
+
while args = qwp[:queue].pop; qwp[:workers_pool] << args end
|
|
471
|
+
end
|
|
281
472
|
end
|
|
282
473
|
end
|