relaton 1.7.6 → 1.8.pre3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +1 -1
- data/.rubocop.yml +1 -1
- data/docs/README.adoc +20 -11
- data/lib/relaton.rb +1 -0
- data/lib/relaton/config.rb +7 -3
- data/lib/relaton/db.rb +213 -101
- data/lib/relaton/db_cache.rb +44 -125
- data/lib/relaton/registry.rb +3 -2
- data/lib/relaton/storage.rb +186 -0
- data/lib/relaton/util.rb +3 -1
- data/lib/relaton/version.rb +1 -1
- data/lib/relaton/workers_pool.rb +1 -3
- data/relaton.gemspec +24 -19
- data/spec/relaton/config_spec.rb +1 -1
- data/spec/relaton/db_cache_spec.rb +2 -2
- data/spec/relaton/db_spec.rb +65 -16
- data/spec/relaton/regirtry_spec.rb +10 -2
- data/spec/relaton/storage_spec.rb +130 -0
- data/spec/relaton_spec.rb +61 -13
- data/spec/spec_helper.rb +4 -0
- data/spec/vcr_cassetes/19133_2005.yml +22 -22
- data/spec/vcr_cassetes/api_relaton_org.yml +51 -0
- data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +182 -0
- data/spec/vcr_cassetes/async_fetch.yml +4854 -0
- data/spec/vcr_cassetes/bsi_bs_en_iso_8848.yml +159 -0
- data/spec/vcr_cassetes/cc_dir_10005_2019.yml +12 -12
- data/spec/vcr_cassetes/cen_en_10160_1999.yml +249 -0
- data/spec/vcr_cassetes/cie_001_1980.yml +7 -7
- data/spec/vcr_cassetes/ecma_6.yml +7 -7
- data/spec/vcr_cassetes/fisp_140.yml +8 -10
- data/spec/vcr_cassetes/gb_t_20223_2006.yml +9 -9
- data/spec/vcr_cassetes/iec_60050_102_2007.yml +35 -33
- data/spec/vcr_cassetes/iec_combined_included.yml +87 -89
- data/spec/vcr_cassetes/ieee_528_2019.yml +20 -18
- data/spec/vcr_cassetes/iho_b_11.yml +7 -7
- data/spec/vcr_cassetes/iso_111111119115_1.yml +5 -5
- data/spec/vcr_cassetes/iso_19115.yml +22 -22
- data/spec/vcr_cassetes/iso_19115_1.yml +21 -21
- data/spec/vcr_cassetes/iso_19115_1_2.yml +41 -41
- data/spec/vcr_cassetes/iso_awi_14093.yml +182 -0
- data/spec/vcr_cassetes/iso_combined_applied.yml +42 -42
- data/spec/vcr_cassetes/iso_combined_included.yml +43 -43
- data/spec/vcr_cassetes/itu_combined_included.yml +813 -681
- data/spec/vcr_cassetes/ogc_19_025r1.yml +1350 -1158
- data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +43 -0
- data/spec/vcr_cassetes/rfc_8341.yml +7 -7
- data/spec/vcr_cassetes/sp_800_38b.yml +8 -10
- data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +34 -34
- data/spec/vcr_cassetes/w3c_json_ld11.yml +17 -17
- metadata +122 -47
- data/localcache/iec/iec_60050_102_2007.xml +0 -58
- data/localcache/iec/version +0 -1
- data/spec/vcr_cassetes/iso_awi_24229.yml +0 -182
- data/spec/vcr_cassetes/ogm_ami4ccm_1_0.yml +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d954779afa85cdbe30b00b6780f4fe2ea261839da0f82855dca6e63fe8be77d
|
4
|
+
data.tar.gz: e7549980e5771e74412291428b8010ad4d6a7720526b98169b97dac82539e909
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 466c2e7c24c972df07bf9548b0dac26ec0eb2c03d7c8716abba50cc7a95f83dd58c903b3b99a99fbddcb3afa1d68518c93082acee68034ec3d3230e10d4f0b25
|
7
|
+
data.tar.gz: 3f4fb6fd8750375862ae109d8d50654372fa3d8e1b6b8eb966e827a026cd4c99f1790a68068c6785a93c6a2c459b6c1506a1768aef881025fa12914cffd0708b
|
data/.github/workflows/rake.yml
CHANGED
data/.rubocop.yml
CHANGED
data/docs/README.adoc
CHANGED
@@ -106,14 +106,18 @@ db = Relaton::Db.new("globalcache", "localcache")
|
|
106
106
|
|
107
107
|
==== Move DB
|
108
108
|
|
109
|
-
`Relaton::Db#mv(
|
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
110
|
|
111
|
-
* `
|
112
|
-
* `
|
111
|
+
* `new_dir` - (String) new cache location
|
112
|
+
* `type` - (Symbol) type of cache DB. Allowed values are: `:global`, `:local`. Default is `:global`.
|
113
113
|
|
114
114
|
[source,ruby]
|
115
115
|
----
|
116
|
-
db.mv("
|
116
|
+
db.mv("new_global_dir")
|
117
|
+
=> "new_global_dir"
|
118
|
+
|
119
|
+
db.mv("new_local_dir", type: :local)
|
120
|
+
=> "new_local_dir"
|
117
121
|
----
|
118
122
|
|
119
123
|
==== Clear DB
|
@@ -178,14 +182,19 @@ x = db.fetch_db("ISO 5749")
|
|
178
182
|
# prepare queue for results
|
179
183
|
results = Queue.new
|
180
184
|
|
181
|
-
# fetch
|
182
|
-
|
183
|
-
|
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
|
184
193
|
end
|
185
|
-
# fetch other documets the same way
|
186
194
|
|
187
195
|
# wait until documets fetching
|
188
|
-
|
196
|
+
refs.size.times do
|
197
|
+
ref, doc = results.pop
|
189
198
|
# do thatever you need with result x
|
190
199
|
end
|
191
200
|
----
|
@@ -330,7 +339,7 @@ ISO/IEC DIR 1
|
|
330
339
|
ISO/IEC DIR 2 IEC
|
331
340
|
ISO/IEC DIR 2 ISO
|
332
341
|
ISO/IEC DIR IEC SUP
|
333
|
-
ISO/IEC DIR 1
|
342
|
+
ISO/IEC DIR 1 JTC SUP
|
334
343
|
----
|
335
344
|
|
336
345
|
=== Get document type
|
@@ -368,7 +377,7 @@ x.to_xml bibdata: true
|
|
368
377
|
db.load_entry("ISO(ISO 19011)")
|
369
378
|
=> "<bibdata type="standard">
|
370
379
|
...
|
371
|
-
|
380
|
+
</bibdata>"
|
372
381
|
----
|
373
382
|
|
374
383
|
=== Entry manipulation
|
data/lib/relaton.rb
CHANGED
data/lib/relaton/config.rb
CHANGED
@@ -12,11 +12,15 @@ module Relaton
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class Configuration
|
15
|
-
attr_accessor :logs, :use_api
|
15
|
+
attr_accessor :logs, :use_api, :api_host, :api_mode
|
16
16
|
|
17
17
|
def initialize
|
18
|
-
@logs = %i(warning error
|
19
|
-
|
18
|
+
@logs = %i(info error) # allowed values: :info, :warning, :error, :debug
|
19
|
+
|
20
|
+
# @TODO change to true when we start using api.relaton.org
|
21
|
+
@use_api = true
|
22
|
+
@api_mode = false
|
23
|
+
@api_host = "https://api.relaton.org/api/v1"
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
data/lib/relaton/db.rb
CHANGED
@@ -1,60 +1,71 @@
|
|
1
|
-
require "yaml"
|
2
|
-
require_relative "registry"
|
3
|
-
require_relative "db_cache"
|
4
|
-
|
5
1
|
module Relaton
|
6
|
-
class RelatonError < StandardError; end
|
2
|
+
# class RelatonError < StandardError; end
|
7
3
|
|
8
4
|
class Db
|
9
5
|
# @param global_cache [String] directory of global DB
|
10
6
|
# @param local_cache [String] directory of local DB
|
11
|
-
def initialize(global_cache, local_cache)
|
7
|
+
def initialize(global_cache, local_cache) # rubocop:disable Metrics/MethodLength
|
12
8
|
@registry = Relaton::Registry.instance
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
if Relaton.configuration.api_mode
|
10
|
+
gpath = global_cache
|
11
|
+
lpath = local_cache
|
12
|
+
else
|
13
|
+
gpath = global_cache && File.expand_path(global_cache)
|
14
|
+
lpath = local_cache && File.expand_path(local_cache)
|
15
|
+
end
|
16
|
+
@db = open_cache_biblio(gpath, type: :global)
|
17
|
+
@local_db = open_cache_biblio(lpath, type: :local)
|
18
|
+
@static_db = open_cache_biblio File.expand_path "../relaton/static_cache", __dir__
|
16
19
|
@queues = {}
|
17
20
|
end
|
18
21
|
|
19
|
-
# Move global
|
20
|
-
# @param
|
21
|
-
# @param
|
22
|
-
|
23
|
-
|
24
|
-
|
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 then @db&.mv new_dir
|
29
|
+
when :local then @local_db&.mv new_dir
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
# Clear global and local databases
|
28
34
|
def clear
|
29
|
-
@db
|
30
|
-
@local_db
|
35
|
+
@db&.clear
|
36
|
+
@local_db&.clear
|
31
37
|
end
|
32
38
|
|
33
39
|
##
|
34
40
|
# The class of reference requested is determined by the prefix of the code:
|
35
|
-
# GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for
|
41
|
+
# GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for
|
42
|
+
# iecbib,
|
36
43
|
#
|
37
44
|
# @param code [String] the ISO standard Code to look up (e.g. "ISO 9000")
|
38
45
|
# @param year [String] the year the standard was published (optional)
|
39
46
|
#
|
40
47
|
# @param opts [Hash] options
|
41
48
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
42
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
49
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
50
|
+
# actual reference with year
|
43
51
|
# @option opts [Integer] :retries (1) Number of network retries
|
44
52
|
#
|
45
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# RelatonOgc::OgcBibliographicItem,
|
53
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
54
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
55
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
56
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
57
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
58
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
50
59
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
51
|
-
# RelatonOmg::OmgBibliographicItem
|
52
|
-
# RelatonW3c::W3cBibliographicItem
|
60
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
53
61
|
##
|
54
62
|
def fetch(code, year = nil, opts = {})
|
55
63
|
stdclass = standard_class(code) || return
|
56
64
|
processor = @registry.processors[stdclass]
|
57
|
-
ref = processor.respond_to?(:urn_to_code)
|
65
|
+
ref = if processor.respond_to?(:urn_to_code)
|
66
|
+
processor.urn_to_code(code)&.first
|
67
|
+
else code
|
68
|
+
end
|
58
69
|
ref ||= code
|
59
70
|
result = combine_doc ref, year, opts, stdclass
|
60
71
|
result ||= check_bibliocache(ref, year, opts, stdclass)
|
@@ -73,19 +84,21 @@ module Relaton
|
|
73
84
|
# @param year [Integer, nil]
|
74
85
|
# @return [Array]
|
75
86
|
def fetch_all(text = nil, edition: nil, year: nil)
|
76
|
-
result = @static_db.all
|
77
|
-
|
78
|
-
|
87
|
+
result = @static_db.all do |file, yml|
|
88
|
+
search_yml file, yml, text, edition, year
|
89
|
+
end.compact
|
90
|
+
if (db = @db || @local_db)
|
91
|
+
result += db.all { |f, x| search_xml f, x, text, edition, year }.compact
|
92
|
+
end
|
79
93
|
result
|
80
94
|
end
|
81
95
|
|
82
96
|
# Fetch asynchronously
|
83
97
|
def fetch_async(code, year = nil, opts = {}, &_block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
84
|
-
stdclass = standard_class code
|
85
|
-
if stdclass
|
98
|
+
if (stdclass = standard_class code)
|
86
99
|
unless @queues[stdclass]
|
87
100
|
processor = @registry.processors[stdclass]
|
88
|
-
wp = WorkersPool.new(processor.threads) { |args| yield fetch
|
101
|
+
wp = WorkersPool.new(processor.threads) { |args| yield fetch(*args) }
|
89
102
|
@queues[stdclass] = { queue: Queue.new, workers_pool: wp }
|
90
103
|
Thread.new { process_queue @queues[stdclass] }
|
91
104
|
end
|
@@ -100,17 +113,18 @@ module Relaton
|
|
100
113
|
#
|
101
114
|
# @param opts [Hash]
|
102
115
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
103
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
116
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
117
|
+
# actual reference with year
|
104
118
|
# @option opts [Integer] :retries (1) Number of network retries
|
105
119
|
#
|
106
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
# RelatonOgc::OgcBibliographicItem,
|
120
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
121
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
122
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
123
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
124
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
125
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
111
126
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
112
|
-
# RelatonOmg::OmgBibliographicItem
|
113
|
-
# RelatonW3c::W3cBibliographicItem
|
127
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
114
128
|
def fetch_std(code, year = nil, stdclass = nil, opts = {})
|
115
129
|
std = nil
|
116
130
|
@registry.processors.each do |name, processor|
|
@@ -153,14 +167,43 @@ module Relaton
|
|
153
167
|
def to_xml
|
154
168
|
db = @local_db || @db || return
|
155
169
|
Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
156
|
-
xml.documents
|
157
|
-
xml.parent.add_child db.all.join(" ")
|
158
|
-
end
|
170
|
+
xml.documents { xml.parent.add_child db.all.join(" ") }
|
159
171
|
end.to_xml
|
160
172
|
end
|
161
173
|
|
162
174
|
private
|
163
175
|
|
176
|
+
#
|
177
|
+
# @param code [String]
|
178
|
+
# @param year [String]
|
179
|
+
#
|
180
|
+
# @param opts [Hash]
|
181
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
182
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
183
|
+
# actual reference with year
|
184
|
+
#
|
185
|
+
# @param stdclass [Symbol]
|
186
|
+
def fetch_api(code, year, opts, stdclass)
|
187
|
+
return unless Relaton.configuration.use_api
|
188
|
+
|
189
|
+
url = "#{Relaton.configuration.api_host}/document?#{params(code, year, opts)}"
|
190
|
+
rsp = Net::HTTP.get_response URI(url)
|
191
|
+
@registry.processors[stdclass].from_xml rsp.body if rsp.code == "200"
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Make string of parametrs
|
196
|
+
#
|
197
|
+
# @param [String] code
|
198
|
+
# @param [String] year
|
199
|
+
# @param [Hash] opts
|
200
|
+
#
|
201
|
+
# @return [String]
|
202
|
+
#
|
203
|
+
def params(code, year, opts)
|
204
|
+
opts.merge(code: code, year: year).map { |k, v| "#{k}=#{v}" }.join "&"
|
205
|
+
end
|
206
|
+
|
164
207
|
# @param file [String] file path
|
165
208
|
# @param yml [String] content in YAML format
|
166
209
|
# @param text [String, nil] text to serach
|
@@ -187,20 +230,27 @@ module Relaton
|
|
187
230
|
end
|
188
231
|
|
189
232
|
# @param file [String] file path
|
190
|
-
# @param content [String] content in XML or
|
233
|
+
# @param content [String] content in XML or YAML format
|
191
234
|
# @param edition [String, nil] edition to filter
|
192
235
|
# @param year [Integer, nil] year to filter
|
193
236
|
# @return [BibliographicItem, nil]
|
194
237
|
def search_edition_year(file, content, edition, year) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
195
238
|
processor = @registry.processors[standard_class(file.split("/")[-2])]
|
196
|
-
item = file.match?(/xml$/)
|
197
|
-
|
198
|
-
|
239
|
+
item = if file.match?(/xml$/) then processor.from_xml(content)
|
240
|
+
else processor.hash_to_bib(YAML.safe_load(content))
|
241
|
+
end
|
242
|
+
item if (edition.nil? || item.edition == edition) && (year.nil? ||
|
243
|
+
item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s })
|
199
244
|
end
|
200
245
|
|
246
|
+
#
|
247
|
+
# Look up text in the XML elements attributes and content
|
248
|
+
#
|
201
249
|
# @param xml [String] content in XML format
|
202
250
|
# @param text [String, nil] text to serach
|
251
|
+
#
|
203
252
|
# @return [Boolean]
|
253
|
+
#
|
204
254
|
def match_xml_text(xml, text)
|
205
255
|
%r{((?<attr>=((?<apstr>')|"))|>).*?#{text}.*?(?(<attr>)(?(<apstr>)'|")|<)}mi.match?(xml)
|
206
256
|
end
|
@@ -211,18 +261,19 @@ module Relaton
|
|
211
261
|
#
|
212
262
|
# @param opts [Hash] options
|
213
263
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
214
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
264
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
265
|
+
# actual reference with year
|
215
266
|
# @option opts [Integer] :retries (1) Number of network retries
|
216
267
|
#
|
217
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
# RelatonOgc::OgcBibliographicItem,
|
268
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
269
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
270
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
271
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
272
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
273
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
222
274
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
223
|
-
# RelatonOmg::OmgBibliographicItem
|
224
|
-
#
|
225
|
-
def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
275
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
276
|
+
def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
226
277
|
if (refs = code.split " + ").size > 1
|
227
278
|
reltype = "derivedFrom"
|
228
279
|
reldesc = nil
|
@@ -233,11 +284,13 @@ module Relaton
|
|
233
284
|
end
|
234
285
|
|
235
286
|
doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
|
236
|
-
|
237
|
-
updates
|
238
|
-
|
287
|
+
updates = check_bibliocache(refs[0], year, opts, stdclass)
|
288
|
+
if updates
|
289
|
+
doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates")
|
290
|
+
end
|
291
|
+
divider = stdclass == :relaton_itu ? " " : "/"
|
239
292
|
refs[1..-1].each_with_object(doc) do |c, d|
|
240
|
-
bib = check_bibliocache(
|
293
|
+
bib = check_bibliocache(refs[0] + divider + c, year, opts, stdclass)
|
241
294
|
if bib
|
242
295
|
d.relation << RelatonBib::DocumentRelation.new(type: reltype, description: reldesc, bibitem: bib)
|
243
296
|
end
|
@@ -251,11 +304,9 @@ module Relaton
|
|
251
304
|
return name if /^(urn:)?#{processor.prefix}/i.match?(code) ||
|
252
305
|
processor.defaultprefix.match(code)
|
253
306
|
end
|
254
|
-
allowed = @registry.processors.reduce([])
|
255
|
-
|
256
|
-
|
257
|
-
warn <<~WARN
|
258
|
-
#{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
307
|
+
allowed = @registry.processors.reduce([]) { |m, (_k, v)| m << v.prefix }
|
308
|
+
Util.log <<~WARN, :info
|
309
|
+
[relaton] #{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
259
310
|
See https://github.com/relaton/relaton/ for instructions on prefixing and wrapping document identifiers to disambiguate them.
|
260
311
|
WARN
|
261
312
|
end
|
@@ -267,7 +318,8 @@ module Relaton
|
|
267
318
|
#
|
268
319
|
# @param opts [Hash]
|
269
320
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
270
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
321
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
322
|
+
# actual reference with year
|
271
323
|
# @option opts [Integer] :retries (1) Number of network retries
|
272
324
|
#
|
273
325
|
# @param stdClass [Symbol]
|
@@ -292,16 +344,18 @@ module Relaton
|
|
292
344
|
|
293
345
|
# @param entry [String] XML string
|
294
346
|
# @param stdclass [Symbol]
|
295
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
296
|
-
#
|
297
|
-
#
|
298
|
-
#
|
299
|
-
# RelatonOgc::OgcBibliographicItem,
|
347
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
348
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
349
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
350
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
351
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
352
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
300
353
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
301
|
-
# RelatonOmg::OmgBibliographicItem
|
302
|
-
# RelatonW3c::W3cBibliographicItem
|
354
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
303
355
|
def bib_retval(entry, stdclass)
|
304
|
-
entry.nil? || entry.match?(/^not_found/)
|
356
|
+
unless entry.nil? || entry.match?(/^not_found/)
|
357
|
+
@registry.processors[stdclass].from_xml(entry)
|
358
|
+
end
|
305
359
|
end
|
306
360
|
|
307
361
|
# @param code [String]
|
@@ -309,22 +363,24 @@ module Relaton
|
|
309
363
|
#
|
310
364
|
# @param opts [Hash]
|
311
365
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
312
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
366
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
367
|
+
# actual reference with year
|
313
368
|
# @option opts [Integer] :retries (1) Number of network retries
|
314
369
|
#
|
315
370
|
# @param stdclass [Symbol]
|
316
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
317
|
-
#
|
318
|
-
#
|
319
|
-
#
|
320
|
-
# RelatonOgc::OgcBibliographicItem,
|
371
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
372
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
373
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
374
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
375
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
376
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
321
377
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
322
|
-
# RelatonOmg::OmgBibliographicItem
|
323
|
-
# RelatonW3c::W3cBibliographicItem
|
378
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
324
379
|
def check_bibliocache(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
325
380
|
id, searchcode = std_id(code, year, opts, stdclass)
|
326
|
-
yaml = @static_db[id]
|
327
|
-
|
381
|
+
if (yaml = @static_db[id])
|
382
|
+
return @registry.processors[stdclass].hash_to_bib YAML.safe_load(yaml)
|
383
|
+
end
|
328
384
|
|
329
385
|
db = @local_db || @db
|
330
386
|
altdb = @local_db && @db ? @db : nil
|
@@ -350,24 +406,29 @@ module Relaton
|
|
350
406
|
bib_retval(db[id], stdclass)
|
351
407
|
end
|
352
408
|
|
409
|
+
#
|
353
410
|
# @param code [String]
|
354
411
|
# @param year [String]
|
355
412
|
#
|
356
413
|
# @param opts [Hash]
|
357
414
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
358
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
415
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
416
|
+
# actual reference with year
|
359
417
|
# @option opts [Integer] :retries (1) Number of network retries
|
360
418
|
#
|
361
419
|
# @param stdclass [Symbol]
|
362
420
|
# @param db [Relaton::DbCache,`NilClass]
|
363
421
|
# @param id [String] docid
|
422
|
+
#
|
364
423
|
# @return [String]
|
424
|
+
#
|
365
425
|
def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
366
426
|
bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
|
367
427
|
bib_id = bib&.docidentifier&.first&.id
|
368
428
|
|
369
429
|
# when docid doesn't match bib's id then return a reference to bib's id
|
370
|
-
if args[:db] && args[:id] &&
|
430
|
+
if args[:db] && args[:id] &&
|
431
|
+
bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}}
|
371
432
|
bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
|
372
433
|
args[:db][bid] ||= bib_entry bib
|
373
434
|
"redirection #{bid}"
|
@@ -375,8 +436,27 @@ module Relaton
|
|
375
436
|
end
|
376
437
|
end
|
377
438
|
|
439
|
+
#
|
440
|
+
# @param code [String]
|
441
|
+
# @param year [String]
|
442
|
+
#
|
443
|
+
# @param opts [Hash]
|
444
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
445
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
446
|
+
# actual reference with year
|
447
|
+
#
|
448
|
+
# @param stdclass [Symbol]
|
449
|
+
# @param retries [Integer] remain Number of network retries
|
450
|
+
#
|
378
451
|
# @raise [RelatonBib::RequestError]
|
452
|
+
# @return [RelatonBib::BibliographicItem]
|
453
|
+
#
|
379
454
|
def net_retry(code, year, opts, stdclass, retries)
|
455
|
+
doc = fetch_api code, year, opts, stdclass
|
456
|
+
return doc if doc
|
457
|
+
|
458
|
+
@registry.processors[stdclass].get(code, year, opts)
|
459
|
+
rescue Errno::ECONNREFUSED
|
380
460
|
@registry.processors[stdclass].get(code, year, opts)
|
381
461
|
rescue RelatonBib::RequestError => e
|
382
462
|
raise e unless retries > 1
|
@@ -384,22 +464,23 @@ module Relaton
|
|
384
464
|
net_retry(code, year, opts, stdclass, retries - 1)
|
385
465
|
end
|
386
466
|
|
387
|
-
# @param bib [
|
388
|
-
#
|
389
|
-
#
|
467
|
+
# @param bib [RelatonBib::BibliographicItem,
|
468
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
469
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
470
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
471
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
472
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
473
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
474
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
390
475
|
# @return [String] XML or "not_found mm-dd-yyyy"
|
391
476
|
def bib_entry(bib)
|
392
|
-
|
393
|
-
bib.to_xml(bibdata: true)
|
394
|
-
else
|
395
|
-
"not_found #{Date.today}"
|
396
|
-
end
|
477
|
+
bib.respond_to?(:to_xml) ? bib.to_xml(bibdata: true) : "not_found #{Date.today}"
|
397
478
|
end
|
398
479
|
|
399
480
|
# @param dir [String, nil] DB directory
|
400
481
|
# @param type [Symbol]
|
401
482
|
# @return [Relaton::DbCache, NilClass]
|
402
|
-
def open_cache_biblio(dir, type: :static)
|
483
|
+
def open_cache_biblio(dir, type: :static) # rubocop:disable Metrics/MethodLength
|
403
484
|
return nil if dir.nil?
|
404
485
|
|
405
486
|
db = DbCache.new dir, type == :static ? "yml" : "xml"
|
@@ -408,9 +489,11 @@ module Relaton
|
|
408
489
|
Dir["#{dir}/*/"].each do |fdir|
|
409
490
|
next if db.check_version?(fdir)
|
410
491
|
|
411
|
-
FileUtils.rm_rf(
|
412
|
-
|
413
|
-
|
492
|
+
FileUtils.rm_rf(fdir, secure: true)
|
493
|
+
Util.log(
|
494
|
+
"[relaton] WARNING: cache #{fdir}: version is obsolete and cache is "\
|
495
|
+
"cleared.", :warning
|
496
|
+
)
|
414
497
|
end
|
415
498
|
db
|
416
499
|
end
|
@@ -419,8 +502,37 @@ module Relaton
|
|
419
502
|
# @option qwp [Queue] :queue The queue of references to fetch
|
420
503
|
# @option qwp [Relaton::WorkersPool] :workers_pool The pool of workers
|
421
504
|
def process_queue(qwp)
|
422
|
-
while args = qwp[:queue].pop
|
423
|
-
|
505
|
+
while args = qwp[:queue].pop; qwp[:workers_pool] << args end
|
506
|
+
end
|
507
|
+
|
508
|
+
class << self
|
509
|
+
# Initialse and return relaton instance, with local and global cache names
|
510
|
+
# local_cache: local cache name; none created if nil; "relaton" created
|
511
|
+
# if empty global_cache: boolean to create global_cache
|
512
|
+
# flush_caches: flush caches
|
513
|
+
def init_bib_caches(**opts) # rubocop:disable Metrics/CyclomaticComplexity
|
514
|
+
globalname = global_bibliocache_name if opts[:global_cache]
|
515
|
+
localname = local_bibliocache_name(opts[:local_cache])
|
516
|
+
flush_caches globalname, localname if opts[:flush_caches]
|
517
|
+
Relaton::Db.new(globalname, localname)
|
518
|
+
end
|
519
|
+
|
520
|
+
private
|
521
|
+
|
522
|
+
def flush_caches(gcache, lcache)
|
523
|
+
FileUtils.rm_rf gcache unless gcache.nil?
|
524
|
+
FileUtils.rm_rf lcache unless lcache.nil?
|
525
|
+
end
|
526
|
+
|
527
|
+
def global_bibliocache_name
|
528
|
+
Relaton.configuration.api_mode ? "cache" : "#{Dir.home}/.relaton/cache"
|
529
|
+
end
|
530
|
+
|
531
|
+
def local_bibliocache_name(cachename)
|
532
|
+
return nil if Relaton.configuration.api_mode || cachename.nil?
|
533
|
+
|
534
|
+
cachename = "relaton" if cachename.empty?
|
535
|
+
"#{cachename}/cache"
|
424
536
|
end
|
425
537
|
end
|
426
538
|
end
|