relaton 1.7.1 → 1.7.6

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +46 -0
  3. data/docs/README.adoc +155 -1
  4. data/globalcache/iec/iec_60050_102_2007.xml +58 -0
  5. data/globalcache/iec/version +1 -0
  6. data/lib/relaton.rb +8 -7
  7. data/lib/relaton/config.rb +2 -1
  8. data/lib/relaton/db.rb +225 -44
  9. data/lib/relaton/db_cache.rb +19 -3
  10. data/lib/relaton/processor.rb +11 -0
  11. data/lib/relaton/registry.rb +1 -1
  12. data/lib/relaton/version.rb +1 -1
  13. data/lib/relaton/workers_pool.rb +23 -0
  14. data/localcache/iec/iec_60050_102_2007.xml +58 -0
  15. data/localcache/iec/version +1 -0
  16. data/relaton.gemspec +5 -3
  17. data/spec/relaton/db_spec.rb +122 -0
  18. data/spec/relaton/processor_spec.rb +4 -0
  19. data/spec/relaton/regirtry_spec.rb +64 -54
  20. data/spec/relaton_spec.rb +50 -25
  21. data/spec/vcr_cassetes/19133_2005.yml +17 -17
  22. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +8 -8
  23. data/spec/vcr_cassetes/cie_001_1980.yml +120 -0
  24. data/spec/vcr_cassetes/ecma_6.yml +159 -0
  25. data/spec/vcr_cassetes/fisp_140.yml +6 -6
  26. data/spec/vcr_cassetes/gb_t_20223_2006.yml +15 -11
  27. data/spec/vcr_cassetes/iec_60050_102_2007.yml +283 -0
  28. data/spec/vcr_cassetes/iec_combined_included.yml +85 -434
  29. data/spec/vcr_cassetes/ieee_528_2019.yml +12 -12
  30. data/spec/vcr_cassetes/iho_b_11.yml +15 -15
  31. data/spec/vcr_cassetes/iso_111111119115_1.yml +4 -4
  32. data/spec/vcr_cassetes/iso_19115.yml +16 -16
  33. data/spec/vcr_cassetes/iso_19115_1.yml +16 -16
  34. data/spec/vcr_cassetes/iso_19115_1_2.yml +32 -32
  35. data/spec/vcr_cassetes/iso_awi_24229.yml +17 -17
  36. data/spec/vcr_cassetes/iso_combined_applied.yml +35 -35
  37. data/spec/vcr_cassetes/iso_combined_included.yml +32 -32
  38. data/spec/vcr_cassetes/itu_combined_included.yml +289 -145
  39. data/spec/vcr_cassetes/ogc_19_025r1.yml +2447 -1895
  40. data/spec/vcr_cassetes/ogm_ami4ccm_1_0.yml +7 -7
  41. data/spec/vcr_cassetes/rfc_8341.yml +47 -15
  42. data/spec/vcr_cassetes/rfc_unsuccess.yml +70 -0
  43. data/spec/vcr_cassetes/sp_800_38b.yml +6 -6
  44. data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +30 -32
  45. data/spec/vcr_cassetes/w3c_json_ld11.yml +12 -12
  46. metadata +43 -36
  47. data/.github/workflows/macos.yml +0 -34
  48. data/.github/workflows/ubuntu.yml +0 -32
  49. data/.github/workflows/windows.yml +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc35bc99d51868ba695706473d20391b5d9512108601fde9814630d14c31fad6
4
- data.tar.gz: 193358f99b616a9b93d422807ec25ff9b2a211a929cf27e8eaae480b78d35585
3
+ metadata.gz: fdf3d2a7e0d55bf5b5edf65ef0e6f1f3d3ce5648388b6bae43127040df90d881
4
+ data.tar.gz: d3cc65b7002c57f6e72c86dccfab92956a992fcfef9ce836ec5b3b4806646e88
5
5
  SHA512:
6
- metadata.gz: bc0cfd775e5d926a2496a15644684bcd3baeb15576f328f13b428f3f446f5345d4cc0a127efdb10f90811aeb60232f77da992ba6b6fd91e1dc2479c61d6fa0df
7
- data.tar.gz: d9899f2b4351417ed84b36ebb08ba818fbb6c022c0c5e5709d964b37f77da1d85b48114a79670b9f40578fbe242528cd3fbe9177caa5d7fd3958efb2f2db9149
6
+ metadata.gz: ae4cba856c12417b10308310c14aec5e2d4452c0c24a4fe30b597d57b7c142e138e858fb97ad452bb29488e3d5d4b0a6bc1fde8dcc41bd4bb10c837315dc7257
7
+ data.tar.gz: e47b6c8e2feb25956d77df52352a474936168854263aeb354d526890b63428d420eeebdc7be6f6547689ec5a25e5a1b2045c72d82680ae7e234c5d1d42023579
@@ -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,8 +102,43 @@ 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_globalcache_dir, new_localcahe_dir)` moves DB directories to new location.
110
+
111
+ * `new_globalcahe_dir` - (String or nil) new globalcache location
112
+ * `new_localcahe_dir` - (String or nil) new localcache location
113
+
114
+ [source,ruby]
115
+ ----
116
+ db.mv("new_globalcache_dir", "new_localcahe_dir")
117
+ ----
118
+
119
+ ==== Clear DB
120
+
121
+ `Relaton::Db#clear` removes all entries form DB
122
+
100
123
  === Fetch documens
101
124
 
125
+ ==== Fetch document by references
126
+
127
+ There are 3 fetching methods:
128
+
129
+ * `Relaton::Db#fetch(reference, year, options)` - fetches document from local cache or remote source.
130
+ * `Relaton::Db#fetch_db(reference, year, options)` - fetches document from local cache
131
+ * `Relaton::Db#fetch_async(reference, year, options, &block)` - fetches document asynchronously
132
+
133
+ Arguments:
134
+
135
+ * `reference` - (String) reference to fethc document
136
+ * `year` - (String or nil) year to filter relult (optional)
137
+ * `options` - (Hash) hash of options. Alloved options:
138
+ - `:all_parts` - (Boolean) should be `true` if all-parts reference is required
139
+ - `:keep_yer` - (Boolean) should be `true` if undated reference should return actual reference with year
140
+ - `:retries` - (Number) number of network retries. Default 1
141
+
102
142
  [source,ruby]
103
143
  ----
104
144
  x = db.fetch("IEEE 19011")
@@ -112,7 +152,7 @@ x = db.fetch("ISO 19011")
112
152
  => #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d0ab2f00
113
153
  ...
114
154
 
115
- x = db.fetch("ISO 19011", "2011")
155
+ x = db.fetch("ISO 19011", "2011", retries: 3)
116
156
  [relaton-iso] ("ISO 19011") fetching...
117
157
  [relaton-iso] ("ISO 19011") found ISO 19011:2011
118
158
  => #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d2593068
@@ -123,6 +163,44 @@ x = db.fetch("ISO 19115", nil, all_parts: true)
123
163
  [relaton-iso] ("ISO 19115") found ISO 19115 (all parts)
124
164
  => #<RelatonIsoBib::IsoBibliographicItem:0x007fb1d0ae8bf0
125
165
  ...
166
+
167
+ # Fetchig from local cache
168
+
169
+ x = db.fetch("ISO 19011")
170
+ => #<RelatonIsoBib::IsoBibliographicItem:0x007fde5f48a9f0
171
+ ...
172
+
173
+ x = db.fetch_db("ISO 5749")
174
+ => nil
175
+
176
+ # Fetching asynchronously
177
+
178
+ # prepare queue for results
179
+ results = Queue.new
180
+
181
+ # fetch document
182
+ db.fetch_async("ISO 19115") do |result|
183
+ results << { "ISO 19115" => result }
184
+ end
185
+ # fetch other documets the same way
186
+
187
+ # wait until documets fetching
188
+ while x = results.pop
189
+ # do thatever you need with result x
190
+ end
191
+ ----
192
+
193
+ ==== Fetch by URN
194
+
195
+ This functionality works only for IEC documents.
196
+
197
+ [source,ruby]
198
+ ----
199
+ x = db.fetch "urn:iec:std:iec:60050-102:2007:::"
200
+ [relaton-iec] ("IEC 60050-102") fetching...
201
+ [relaton-iec] ("IEC 60050-102") found IEC 60050-102:2007
202
+ => #<RelatonIec::IecBibliographicItem:0x007fbd6c3790e8
203
+ ...
126
204
  ----
127
205
 
128
206
  === Fetch combined documents
@@ -177,6 +255,82 @@ bib.relation[1].bibitem.docidentifier[0].id
177
255
  [source,ruby]
178
256
  ----
179
257
  bib = db.fetch "ISO 19115-1, Amd 1"
258
+ => ["Chinese Standard", "GB/T 1.1"]
259
+ [relaton-iso] ("ISO 19115-1") fetching...
260
+ [relaton-iso] ("ISO 19115-1") found ISO 19115-1:2014
261
+ [relaton-iso] ("ISO 19115-1/Amd 1") fetching...
262
+ [relaton-iso] ("ISO 19115-1/Amd 1") found ISO 19115-1:2014/Amd 1:2018
263
+ => #<RelatonIsoBib::IsoBibliographicItem:0x007fb09b36d1b8
264
+ ...
265
+ ----
266
+
267
+ ==== Fetch all documents from cache
268
+
269
+ `Relaton::Db#fetch_all(text = nil, edition: nil, year: nil)` - fetches all document from local cache
270
+
271
+ * `text` - (String) filter entries by a text (optional)
272
+ * `edition` - (String) filter entries by an edition (optional)
273
+ * `year` - (Integer) filter entries by a year (optional)
274
+
275
+ [source,ruby]
276
+ ----
277
+ # query for all entries in a cahche
278
+
279
+ items = db.fetch_all
280
+ => [#<RelatonIec::IecBibliographicItem:0x007facda8fdc28
281
+ ...
282
+
283
+ items.size
284
+ => 6
285
+
286
+ # query for all entries in a cahche for a certain string
287
+
288
+ items = db.fetch_all("mathematical terminology")
289
+ => [#<RelatonIec::IecBibliographicItem:0x007ffeae5bd240
290
+ ...
291
+
292
+ items.size
293
+ => 1
294
+
295
+ items[0].docidentifier[0].id
296
+ => "IEC 60050-102:2007"
297
+
298
+ # query for all entries in a cahche for a certain string and edition
299
+
300
+ items = db.fetch_all("system", edition: "2")
301
+ => [#<RelatonIsoBib::IsoBibliographicItem:0x007ffebe2d1be8
302
+ ...
303
+
304
+ items.size
305
+ => 1
306
+
307
+ items[0].docidentifier[0].id
308
+ => "ISO 19011:2011"
309
+
310
+ # query for all entries in a cahche for a certain string and year
311
+
312
+ items = db.fetch_all("system", year: 2018)
313
+ => [#<RelatonIsoBib::IsoBibliographicItem:0x007ffeae645fa0
314
+ ...
315
+
316
+ items.size
317
+ => 1
318
+
319
+ items[0].docidentifier[0].id
320
+ => "ISO 19011 (all parts)"
321
+ ----
322
+
323
+ === Static DB
324
+
325
+ This gem has a static DB which is distributed with it. Now the static contains documents:
326
+ ----
327
+ ISO/IEC DIR 1 IEC SUP
328
+ ISO/IEC DIR 1 ISO SUP
329
+ ISO/IEC DIR 1
330
+ ISO/IEC DIR 2 IEC
331
+ ISO/IEC DIR 2 ISO
332
+ ISO/IEC DIR IEC SUP
333
+ ISO/IEC DIR 1 ISO SUP
180
334
  ----
181
335
 
182
336
  === Get document type
@@ -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.&#13;
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
- require_relative "relaton/util"
2
- require_relative "relaton/config"
1
+ require "relaton/util"
2
+ require "relaton/config"
3
3
 
4
- require_relative "relaton/db"
5
- require_relative "relaton/db_cache"
6
- require_relative "relaton/version"
7
- require_relative "relaton/registry"
8
- require_relative "relaton/processor"
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"
@@ -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
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
@@ -12,54 +12,105 @@ module Relaton
12
12
  @registry = Relaton::Registry.instance
13
13
  @db = open_cache_biblio(global_cache, type: :global)
14
14
  @local_db = open_cache_biblio(local_cache, type: :local)
15
- @db_name = global_cache
16
- @local_db_name = local_cache
17
- static_db_name = File.expand_path "../relaton/static_cache", __dir__
18
- @static_db = open_cache_biblio static_db_name
15
+ @static_db = open_cache_biblio File.expand_path("../relaton/static_cache", __dir__)
16
+ @queues = {}
19
17
  end
20
18
 
19
+ # Move global and/or local caches to anothe dirs
20
+ # @param new_global_dir [String, nil]
21
+ # @param new_local_dir [String, nil]
22
+ def mv(new_global_dir, new_local_dir)
23
+ @db.mv new_global_dir
24
+ @local_db.mv new_local_dir
25
+ end
26
+
27
+ # Clear global and local databases
28
+ def clear
29
+ @db.clear
30
+ @local_db.clear
31
+ end
32
+
33
+ ##
21
34
  # The class of reference requested is determined by the prefix of the code:
22
35
  # GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for iecbib,
36
+ #
23
37
  # @param code [String] the ISO standard Code to look up (e.g. "ISO 9000")
24
38
  # @param year [String] the year the standard was published (optional)
25
- # @param opts [Hash] options; restricted to :all_parts if all-parts reference is required
26
- # @return [NilClass, RelatonIsoBib::IsoBibliographicItem,
39
+ #
40
+ # @param opts [Hash] options
41
+ # @option opts [Boolean] :all_parts If all-parts reference is required
42
+ # @option opts [Boolean] :keep_year If undated reference should return actual reference with year
43
+ # @option opts [Integer] :retries (1) Number of network retries
44
+ #
45
+ # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
27
46
  # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
28
- # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem]
47
+ # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
48
+ # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
49
+ # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
50
+ # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
51
+ # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
52
+ # RelatonW3c::W3cBibliographicItem
53
+ ##
29
54
  def fetch(code, year = nil, opts = {})
30
55
  stdclass = standard_class(code) || return
31
- cd = combine_doc code, year, opts, stdclass
32
- return cd if cd
56
+ processor = @registry.processors[stdclass]
57
+ ref = processor.respond_to?(:urn_to_code) ? processor.urn_to_code(code)&.first : code
58
+ ref ||= code
59
+ result = combine_doc ref, year, opts, stdclass
60
+ result ||= check_bibliocache(ref, year, opts, stdclass)
61
+ result
62
+ end
33
63
 
34
- check_bibliocache(code, year, opts, stdclass)
64
+ # @see Relaton::Db#fetch
65
+ def fetch_db(code, year = nil, opts = {})
66
+ opts[:fetch_db] = true
67
+ fetch code, year, opts
35
68
  end
36
69
 
37
- def combine_doc(code, year, opts, stdclass)
38
- if (refs = code.split " + ").size > 1
39
- reltype = "derivedFrom"
40
- reldesc = nil
41
- elsif (refs = code.split ", ").size > 1
42
- reltype = "complements"
43
- reldesc = "amendment"
44
- else return
45
- end
70
+ # fetch all standards from DB
71
+ # @param test [String, nil]
72
+ # @param edition [String], nil
73
+ # @param year [Integer, nil]
74
+ # @return [Array]
75
+ def fetch_all(text = nil, edition: nil, year: nil)
76
+ result = @static_db.all { |file, yml| search_yml file, yml, text, edition, year }.compact
77
+ db = @db || @local_db
78
+ result += db.all { |file, xml| search_xml file, xml, text, edition, year }.compact if db
79
+ result
80
+ end
46
81
 
47
- doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
48
- ref = refs[0]
49
- updates = check_bibliocache(ref, year, opts, stdclass)
50
- doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates")
51
- refs[1..-1].each_with_object(doc) do |c, d|
52
- bib = check_bibliocache("#{ref}/#{c}", year, opts, stdclass)
53
- d.relation << RelatonBib::DocumentRelation.new(
54
- type: reltype, description: reldesc, bibitem: bib
55
- )
82
+ # Fetch asynchronously
83
+ def fetch_async(code, year = nil, opts = {}, &_block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
84
+ stdclass = standard_class code
85
+ if stdclass
86
+ unless @queues[stdclass]
87
+ processor = @registry.processors[stdclass]
88
+ wp = WorkersPool.new(processor.threads) { |args| yield fetch *args }
89
+ @queues[stdclass] = { queue: Queue.new, workers_pool: wp }
90
+ Thread.new { process_queue @queues[stdclass] }
91
+ end
92
+ @queues[stdclass][:queue] << [code, year, opts]
93
+ else yield nil
56
94
  end
57
95
  end
58
96
 
59
97
  # @param code [String]
60
98
  # @param year [String, NilClass]
61
99
  # @param stdclass [Symbol, NilClass]
100
+ #
62
101
  # @param opts [Hash]
102
+ # @option opts [Boolean] :all_parts If all-parts reference is required
103
+ # @option opts [Boolean] :keep_year If undated reference should return actual reference with year
104
+ # @option opts [Integer] :retries (1) Number of network retries
105
+ #
106
+ # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
107
+ # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
108
+ # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
109
+ # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
110
+ # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
111
+ # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
112
+ # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
113
+ # RelatonW3c::W3cBibliographicItem
63
114
  def fetch_std(code, year = nil, stdclass = nil, opts = {})
64
115
  std = nil
65
116
  @registry.processors.each do |name, processor|
@@ -110,11 +161,94 @@ module Relaton
110
161
 
111
162
  private
112
163
 
164
+ # @param file [String] file path
165
+ # @param yml [String] content in YAML format
166
+ # @param text [String, nil] text to serach
167
+ # @param edition [String, nil] edition to filter
168
+ # @param year [Integer, nil] year to filter
169
+ # @return [BibliographicItem, nil]
170
+ def search_yml(file, yml, text, edition, year)
171
+ item = search_edition_year(file, yml, edition, year)
172
+ return unless item
173
+
174
+ item if match_xml_text(item.to_xml(bibdata: true), text)
175
+ end
176
+
177
+ # @param file [String] file path
178
+ # @param xml [String] content in XML format
179
+ # @param text [String, nil] text to serach
180
+ # @param edition [String, nil] edition to filter
181
+ # @param year [Integer, nil] year to filter
182
+ # @return [BibliographicItem, nil]
183
+ def search_xml(file, xml, text, edition, year)
184
+ return unless text.nil? || match_xml_text(xml, text)
185
+
186
+ search_edition_year(file, xml, edition, year)
187
+ end
188
+
189
+ # @param file [String] file path
190
+ # @param content [String] content in XML or YAmL format
191
+ # @param edition [String, nil] edition to filter
192
+ # @param year [Integer, nil] year to filter
193
+ # @return [BibliographicItem, nil]
194
+ def search_edition_year(file, content, edition, year) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
195
+ processor = @registry.processors[standard_class(file.split("/")[-2])]
196
+ item = file.match?(/xml$/) ? processor.from_xml(content) : processor.hash_to_bib(YAML.safe_load(content))
197
+ item if (edition.nil? || item.edition == edition) &&
198
+ (year.nil? || item.date.detect { |d| d.type == "published" && d.on(:year) == year })
199
+ end
200
+
201
+ # @param xml [String] content in XML format
202
+ # @param text [String, nil] text to serach
203
+ # @return [Boolean]
204
+ def match_xml_text(xml, text)
205
+ %r{((?<attr>=((?<apstr>')|"))|>).*?#{text}.*?(?(<attr>)(?(<apstr>)'|")|<)}mi.match?(xml)
206
+ end
207
+
208
+ # @param code [String]
209
+ # @param year [String, nil]
210
+ # @param stdslass [String]
211
+ #
212
+ # @param opts [Hash] options
213
+ # @option opts [Boolean] :all_parts If all-parts reference is required
214
+ # @option opts [Boolean] :keep_year If undated reference should return actual reference with year
215
+ # @option opts [Integer] :retries (1) Number of network retries
216
+ #
217
+ # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
218
+ # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
219
+ # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
220
+ # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
221
+ # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
222
+ # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
223
+ # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
224
+ # RelatonW3c::W3cBibliographicItem
225
+ def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
226
+ if (refs = code.split " + ").size > 1
227
+ reltype = "derivedFrom"
228
+ reldesc = nil
229
+ elsif (refs = code.split ", ").size > 1
230
+ reltype = "complements"
231
+ reldesc = RelatonBib::FormattedString.new content: "amendment"
232
+ else return
233
+ end
234
+
235
+ doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
236
+ ref = refs[0]
237
+ updates = check_bibliocache(ref, year, opts, stdclass)
238
+ doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates") if updates
239
+ refs[1..-1].each_with_object(doc) do |c, d|
240
+ bib = check_bibliocache("#{ref}/#{c}", year, opts, stdclass)
241
+ if bib
242
+ d.relation << RelatonBib::DocumentRelation.new(type: reltype, description: reldesc, bibitem: bib)
243
+ end
244
+ end
245
+ end
246
+
113
247
  # @param code [String] code of standard
114
248
  # @return [Symbol] standard class name
115
249
  def standard_class(code)
116
250
  @registry.processors.each do |name, processor|
117
- return name if /^#{processor.prefix}/.match(code) ||
251
+ return name if /^(urn:)?#{processor.prefix}/i.match?(code) ||
118
252
  processor.defaultprefix.match(code)
119
253
  end
120
254
  allowed = @registry.processors.reduce([]) do |m, (_k, v)|
@@ -130,7 +264,12 @@ module Relaton
130
264
  # Fofmat ID
131
265
  # @param code [String]
132
266
  # @param year [String]
267
+ #
133
268
  # @param opts [Hash]
269
+ # @option opts [Boolean] :all_parts If all-parts reference is required
270
+ # @option opts [Boolean] :keep_year If undated reference should return actual reference with year
271
+ # @option opts [Integer] :retries (1) Number of network retries
272
+ #
134
273
  # @param stdClass [Symbol]
135
274
  # @return [Array<String>] docid and code
136
275
  def std_id(code, year, opts, stdclass)
@@ -153,22 +292,35 @@ module Relaton
153
292
 
154
293
  # @param entry [String] XML string
155
294
  # @param stdclass [Symbol]
156
- # @param id [String] docid
157
- # @return [NilClass, RelatonIsoBib::IsoBibliographicItem,
295
+ # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
158
296
  # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
159
- # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem]
160
- def bib_retval(entry, stdclass, _id)
161
- entry.match?(/^not_found/) ? nil : @registry.processors[stdclass].from_xml(entry)
297
+ # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
298
+ # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
299
+ # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
300
+ # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
301
+ # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
302
+ # RelatonW3c::W3cBibliographicItem
303
+ def bib_retval(entry, stdclass)
304
+ entry.nil? || entry.match?(/^not_found/) ? nil : @registry.processors[stdclass].from_xml(entry)
162
305
  end
163
306
 
164
307
  # @param code [String]
165
308
  # @param year [String]
309
+ #
166
310
  # @param opts [Hash]
311
+ # @option opts [Boolean] :all_parts If all-parts reference is required
312
+ # @option opts [Boolean] :keep_year If undated reference should return actual reference with year
313
+ # @option opts [Integer] :retries (1) Number of network retries
314
+ #
167
315
  # @param stdclass [Symbol]
168
- # @return [NilClass, RelatonIsoBib::IsoBibliographicItem,
316
+ # @return [nil, RelatonBib::BibliographicItem, RelatonIsoBib::IsoBibliographicItem,
169
317
  # RelatonItu::ItuBibliographicItem, RelatonIetf::IetfBibliographicItem,
318
+ # RelatonIec::IecBibliographicItem, RelatonIeee::IeeeBibliographicItem,
170
319
  # RelatonNist::NistBibliongraphicItem, RelatonGb::GbbibliographicItem,
171
320
  # RelatonOgc::OgcBibliographicItem, RelatonCalconnect::CcBibliographicItem]
321
+ # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
322
+ # RelatonOmg::OmgBibliographicItem RelatinUn::UnBibliographicItem,
323
+ # RelatonW3c::W3cBibliographicItem
172
324
  def check_bibliocache(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
173
325
  id, searchcode = std_id(code, year, opts, stdclass)
174
326
  yaml = @static_db[id]
@@ -177,31 +329,41 @@ module Relaton
177
329
  db = @local_db || @db
178
330
  altdb = @local_db && @db ? @db : nil
179
331
  if db.nil?
332
+ return if opts[:fetch_db]
333
+
180
334
  bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
181
- return bib_retval(bibentry, stdclass, id)
335
+ return bib_retval(bibentry, stdclass)
182
336
  end
183
337
 
184
338
  db.delete(id) unless db.valid_entry?(id, year)
185
339
  if altdb
186
- # db[id] ||= altdb[id]
187
- db.clone_entry id, altdb
340
+ return bib_retval(altdb[id], stdclass) if opts[:fetch_db]
341
+
342
+ db.clone_entry id, altdb if altdb.valid_entry? id, year
188
343
  db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
189
344
  altdb.clone_entry(id, db) if !altdb.valid_entry?(id, year)
190
345
  else
346
+ return bib_retval(db[id], stdclass) if opts[:fetch_db]
347
+
191
348
  db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
192
349
  end
193
- bib_retval(db[id], stdclass, id)
350
+ bib_retval(db[id], stdclass)
194
351
  end
195
352
 
196
353
  # @param code [String]
197
354
  # @param year [String]
355
+ #
198
356
  # @param opts [Hash]
357
+ # @option opts [Boolean] :all_parts If all-parts reference is required
358
+ # @option opts [Boolean] :keep_year If undated reference should return actual reference with year
359
+ # @option opts [Integer] :retries (1) Number of network retries
360
+ #
199
361
  # @param stdclass [Symbol]
200
362
  # @param db [Relaton::DbCache,`NilClass]
201
363
  # @param id [String] docid
202
364
  # @return [String]
203
365
  def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
204
- bib = @registry.processors[stdclass].get(code, year, opts)
366
+ bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
205
367
  bib_id = bib&.docidentifier&.first&.id
206
368
 
207
369
  # when docid doesn't match bib's id then return a reference to bib's id
@@ -209,11 +371,19 @@ module Relaton
209
371
  bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
210
372
  args[:db][bid] ||= bib_entry bib
211
373
  "redirection #{bid}"
212
- else
213
- bib_entry bib
374
+ else bib_entry bib
214
375
  end
215
376
  end
216
377
 
378
+ # @raise [RelatonBib::RequestError]
379
+ def net_retry(code, year, opts, stdclass, retries)
380
+ @registry.processors[stdclass].get(code, year, opts)
381
+ rescue RelatonBib::RequestError => e
382
+ raise e unless retries > 1
383
+
384
+ net_retry(code, year, opts, stdclass, retries - 1)
385
+ end
386
+
217
387
  # @param bib [RelatonGb::GbBibliongraphicItem, RelatonIsoBib::IsoBibliographicItem,
218
388
  # RelatonIetf::IetfBibliographicItem, RelatonItu::ItuBibliographicItem,
219
389
  # RelatonNist::NistBibliongraphicItem, RelatonOgc::OgcBibliographicItem]
@@ -226,21 +396,32 @@ module Relaton
226
396
  end
227
397
  end
228
398
 
229
- # @param dir [String] DB directory
399
+ # @param dir [String, nil] DB directory
230
400
  # @param type [Symbol]
231
401
  # @return [Relaton::DbCache, NilClass]
232
402
  def open_cache_biblio(dir, type: :static)
233
403
  return nil if dir.nil?
234
404
 
235
405
  db = DbCache.new dir, type == :static ? "yml" : "xml"
406
+ return db if type == :static
236
407
 
237
408
  Dir["#{dir}/*/"].each do |fdir|
238
- next if type == :static || db.check_version?(fdir)
409
+ next if db.check_version?(fdir)
239
410
 
240
411
  FileUtils.rm_rf(Dir.glob(fdir + "/*"), secure: true)
412
+ db.set_version fdir
241
413
  warn "[relaton] cache #{fdir}: version is obsolete and cache is cleared."
242
414
  end
243
415
  db
244
416
  end
417
+
418
+ # @param qwp [Hash]
419
+ # @option qwp [Queue] :queue The queue of references to fetch
420
+ # @option qwp [Relaton::WorkersPool] :workers_pool The pool of workers
421
+ def process_queue(qwp)
422
+ while args = qwp[:queue].pop
423
+ qwp[:workers_pool] << args
424
+ end
425
+ end
245
426
  end
246
427
  end