relaton 1.7.5 → 1.8.pre2
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 +3 -0
- data/lib/relaton/config.rb +7 -3
- data/lib/relaton/db.rb +199 -99
- 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 +23 -23
- data/spec/vcr_cassetes/api_relaton_org.yml +33 -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 +10 -10
- 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 +133 -68
- data/spec/vcr_cassetes/fisp_140.yml +4 -4
- data/spec/vcr_cassetes/gb_t_20223_2006.yml +9 -9
- data/spec/vcr_cassetes/iec_60050_102_2007.yml +30 -28
- data/spec/vcr_cassetes/iec_combined_included.yml +81 -85
- data/spec/vcr_cassetes/ieee_528_2019.yml +19 -17
- 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 +23 -23
- data/spec/vcr_cassetes/iso_19115_1.yml +20 -20
- data/spec/vcr_cassetes/iso_19115_1_2.yml +42 -42
- 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 +45 -45
- data/spec/vcr_cassetes/itu_combined_included.yml +813 -681
- data/spec/vcr_cassetes/ogc_19_025r1.yml +1325 -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 +4 -4
- data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +34 -34
- data/spec/vcr_cassetes/w3c_json_ld11.yml +17 -17
- metadata +126 -51
- 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: 7613bdf8be768f76e3e24d8727210075cd8ad8d4e24924ec5d19d28473cd933f
|
4
|
+
data.tar.gz: 1332d1463afd07385d3aacb917a2f621b572e802b25ec64d5d5f87781b6c6ef6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd636d5da683476ff6abf8a0c686bd9b7112cbbbda7c19f96249b75a6ecb8a4cb4c5764eeead68e949003b8f460574b50fabbcbe2f838ff9f104cb52adda45ba
|
7
|
+
data.tar.gz: 75ec0ed77c187b48baef584702b10cd5add0938325a19a40eac6e0217c86b7f769f30ad2561c612ab4fd2c0905c03e8c94797c92ce28a034215cf88bfc8d5f09
|
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
@@ -1,5 +1,6 @@
|
|
1
1
|
require "relaton/util"
|
2
2
|
require "relaton/config"
|
3
|
+
require "yaml"
|
3
4
|
|
4
5
|
require "relaton/workers_pool"
|
5
6
|
require "relaton/db"
|
@@ -7,3 +8,5 @@ require "relaton/db_cache"
|
|
7
8
|
require "relaton/version"
|
8
9
|
require "relaton/registry"
|
9
10
|
require "relaton/processor"
|
11
|
+
require "relaton/registry"
|
12
|
+
require "relaton/db_cache"
|
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 = nil # "http://0.0.0.0:9292"
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
data/lib/relaton/db.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require "yaml"
|
2
|
-
require_relative "registry"
|
3
|
-
require_relative "db_cache"
|
4
|
-
|
5
1
|
module Relaton
|
6
2
|
class RelatonError < StandardError; end
|
7
3
|
|
@@ -10,51 +6,66 @@ module Relaton
|
|
10
6
|
# @param local_cache [String] directory of local DB
|
11
7
|
def initialize(global_cache, local_cache)
|
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,31 @@ 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
|
+
params = opts.merge(code: code, year: year).map { |k, v| "#{k}=#{v}" }.join "&"
|
190
|
+
url = "#{Relaton.configuration.api_host}/api/v1/fetch?#{params}"
|
191
|
+
rsp = Net::HTTP.get_response URI(url)
|
192
|
+
@registry.processors[stdclass].from_xml rsp.body if rsp.code == "200"
|
193
|
+
end
|
194
|
+
|
164
195
|
# @param file [String] file path
|
165
196
|
# @param yml [String] content in YAML format
|
166
197
|
# @param text [String, nil] text to serach
|
@@ -187,20 +218,27 @@ module Relaton
|
|
187
218
|
end
|
188
219
|
|
189
220
|
# @param file [String] file path
|
190
|
-
# @param content [String] content in XML or
|
221
|
+
# @param content [String] content in XML or YAML format
|
191
222
|
# @param edition [String, nil] edition to filter
|
192
223
|
# @param year [Integer, nil] year to filter
|
193
224
|
# @return [BibliographicItem, nil]
|
194
225
|
def search_edition_year(file, content, edition, year) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
195
226
|
processor = @registry.processors[standard_class(file.split("/")[-2])]
|
196
|
-
item = file.match?(/xml$/)
|
197
|
-
|
198
|
-
|
227
|
+
item = if file.match?(/xml$/) then processor.from_xml(content)
|
228
|
+
else processor.hash_to_bib(YAML.safe_load(content))
|
229
|
+
end
|
230
|
+
item if (edition.nil? || item.edition == edition) && (year.nil? ||
|
231
|
+
item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s })
|
199
232
|
end
|
200
233
|
|
234
|
+
#
|
235
|
+
# Look up text in the XML elements attributes and content
|
236
|
+
#
|
201
237
|
# @param xml [String] content in XML format
|
202
238
|
# @param text [String, nil] text to serach
|
239
|
+
#
|
203
240
|
# @return [Boolean]
|
241
|
+
#
|
204
242
|
def match_xml_text(xml, text)
|
205
243
|
%r{((?<attr>=((?<apstr>')|"))|>).*?#{text}.*?(?(<attr>)(?(<apstr>)'|")|<)}mi.match?(xml)
|
206
244
|
end
|
@@ -211,18 +249,19 @@ module Relaton
|
|
211
249
|
#
|
212
250
|
# @param opts [Hash] options
|
213
251
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
214
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
252
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
253
|
+
# actual reference with year
|
215
254
|
# @option opts [Integer] :retries (1) Number of network retries
|
216
255
|
#
|
217
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
# RelatonOgc::OgcBibliographicItem,
|
256
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
257
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
258
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
259
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
260
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
261
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
222
262
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
223
|
-
# RelatonOmg::OmgBibliographicItem
|
224
|
-
#
|
225
|
-
def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
263
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
264
|
+
def combine_doc(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
226
265
|
if (refs = code.split " + ").size > 1
|
227
266
|
reltype = "derivedFrom"
|
228
267
|
reldesc = nil
|
@@ -233,11 +272,13 @@ module Relaton
|
|
233
272
|
end
|
234
273
|
|
235
274
|
doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
|
236
|
-
|
237
|
-
updates
|
238
|
-
|
275
|
+
updates = check_bibliocache(refs[0], year, opts, stdclass)
|
276
|
+
if updates
|
277
|
+
doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates")
|
278
|
+
end
|
279
|
+
divider = stdclass == :relaton_itu ? " " : "/"
|
239
280
|
refs[1..-1].each_with_object(doc) do |c, d|
|
240
|
-
bib = check_bibliocache(
|
281
|
+
bib = check_bibliocache(refs[0] + divider + c, year, opts, stdclass)
|
241
282
|
if bib
|
242
283
|
d.relation << RelatonBib::DocumentRelation.new(type: reltype, description: reldesc, bibitem: bib)
|
243
284
|
end
|
@@ -251,11 +292,9 @@ module Relaton
|
|
251
292
|
return name if /^(urn:)?#{processor.prefix}/i.match?(code) ||
|
252
293
|
processor.defaultprefix.match(code)
|
253
294
|
end
|
254
|
-
allowed = @registry.processors.reduce([])
|
255
|
-
|
256
|
-
|
257
|
-
warn <<~WARN
|
258
|
-
#{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
295
|
+
allowed = @registry.processors.reduce([]) { |m, (_k, v)| m << v.prefix }
|
296
|
+
Util.log <<~WARN, :info
|
297
|
+
[relaton] #{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
259
298
|
See https://github.com/relaton/relaton/ for instructions on prefixing and wrapping document identifiers to disambiguate them.
|
260
299
|
WARN
|
261
300
|
end
|
@@ -267,7 +306,8 @@ module Relaton
|
|
267
306
|
#
|
268
307
|
# @param opts [Hash]
|
269
308
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
270
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
309
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
310
|
+
# actual reference with year
|
271
311
|
# @option opts [Integer] :retries (1) Number of network retries
|
272
312
|
#
|
273
313
|
# @param stdClass [Symbol]
|
@@ -292,16 +332,18 @@ module Relaton
|
|
292
332
|
|
293
333
|
# @param entry [String] XML string
|
294
334
|
# @param stdclass [Symbol]
|
295
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
296
|
-
#
|
297
|
-
#
|
298
|
-
#
|
299
|
-
# RelatonOgc::OgcBibliographicItem,
|
335
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
336
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
337
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
338
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
339
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
340
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
300
341
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
301
|
-
# RelatonOmg::OmgBibliographicItem
|
302
|
-
# RelatonW3c::W3cBibliographicItem
|
342
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
303
343
|
def bib_retval(entry, stdclass)
|
304
|
-
entry.nil? || entry.match?(/^not_found/)
|
344
|
+
unless entry.nil? || entry.match?(/^not_found/)
|
345
|
+
@registry.processors[stdclass].from_xml(entry)
|
346
|
+
end
|
305
347
|
end
|
306
348
|
|
307
349
|
# @param code [String]
|
@@ -309,22 +351,24 @@ module Relaton
|
|
309
351
|
#
|
310
352
|
# @param opts [Hash]
|
311
353
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
312
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
354
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
355
|
+
# actual reference with year
|
313
356
|
# @option opts [Integer] :retries (1) Number of network retries
|
314
357
|
#
|
315
358
|
# @param stdclass [Symbol]
|
316
|
-
# @return [nil, RelatonBib::BibliographicItem,
|
317
|
-
#
|
318
|
-
#
|
319
|
-
#
|
320
|
-
# RelatonOgc::OgcBibliographicItem,
|
359
|
+
# @return [nil, RelatonBib::BibliographicItem,
|
360
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
361
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
362
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
363
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
364
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
321
365
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
322
|
-
# RelatonOmg::OmgBibliographicItem
|
323
|
-
# RelatonW3c::W3cBibliographicItem
|
366
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
324
367
|
def check_bibliocache(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
325
368
|
id, searchcode = std_id(code, year, opts, stdclass)
|
326
|
-
yaml = @static_db[id]
|
327
|
-
|
369
|
+
if (yaml = @static_db[id])
|
370
|
+
return @registry.processors[stdclass].hash_to_bib YAML.safe_load(yaml)
|
371
|
+
end
|
328
372
|
|
329
373
|
db = @local_db || @db
|
330
374
|
altdb = @local_db && @db ? @db : nil
|
@@ -350,24 +394,29 @@ module Relaton
|
|
350
394
|
bib_retval(db[id], stdclass)
|
351
395
|
end
|
352
396
|
|
397
|
+
#
|
353
398
|
# @param code [String]
|
354
399
|
# @param year [String]
|
355
400
|
#
|
356
401
|
# @param opts [Hash]
|
357
402
|
# @option opts [Boolean] :all_parts If all-parts reference is required
|
358
|
-
# @option opts [Boolean] :keep_year If undated reference should return
|
403
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
404
|
+
# actual reference with year
|
359
405
|
# @option opts [Integer] :retries (1) Number of network retries
|
360
406
|
#
|
361
407
|
# @param stdclass [Symbol]
|
362
408
|
# @param db [Relaton::DbCache,`NilClass]
|
363
409
|
# @param id [String] docid
|
410
|
+
#
|
364
411
|
# @return [String]
|
412
|
+
#
|
365
413
|
def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
366
414
|
bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
|
367
415
|
bib_id = bib&.docidentifier&.first&.id
|
368
416
|
|
369
417
|
# when docid doesn't match bib's id then return a reference to bib's id
|
370
|
-
if args[:db] && args[:id] &&
|
418
|
+
if args[:db] && args[:id] &&
|
419
|
+
bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}}
|
371
420
|
bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
|
372
421
|
args[:db][bid] ||= bib_entry bib
|
373
422
|
"redirection #{bid}"
|
@@ -375,8 +424,27 @@ module Relaton
|
|
375
424
|
end
|
376
425
|
end
|
377
426
|
|
427
|
+
#
|
428
|
+
# @param code [String]
|
429
|
+
# @param year [String]
|
430
|
+
#
|
431
|
+
# @param opts [Hash]
|
432
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
433
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
434
|
+
# actual reference with year
|
435
|
+
#
|
436
|
+
# @param stdclass [Symbol]
|
437
|
+
# @param retries [Integer] remain Number of network retries
|
438
|
+
#
|
378
439
|
# @raise [RelatonBib::RequestError]
|
440
|
+
# @return [RelatonBib::BibliographicItem]
|
441
|
+
#
|
379
442
|
def net_retry(code, year, opts, stdclass, retries)
|
443
|
+
doc = fetch_api code, year, opts, stdclass
|
444
|
+
return doc if doc
|
445
|
+
|
446
|
+
@registry.processors[stdclass].get(code, year, opts)
|
447
|
+
rescue Errno::ECONNREFUSED
|
380
448
|
@registry.processors[stdclass].get(code, year, opts)
|
381
449
|
rescue RelatonBib::RequestError => e
|
382
450
|
raise e unless retries > 1
|
@@ -384,22 +452,23 @@ module Relaton
|
|
384
452
|
net_retry(code, year, opts, stdclass, retries - 1)
|
385
453
|
end
|
386
454
|
|
387
|
-
# @param bib [
|
388
|
-
#
|
389
|
-
#
|
455
|
+
# @param bib [RelatonBib::BibliographicItem,
|
456
|
+
# RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
|
457
|
+
# RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
|
458
|
+
# RelatonIeee::IeeeBibliographicItem, RelatonNist::NistBibliongraphicItem,
|
459
|
+
# RelatonGb::GbbibliographicItem, RelatonOgc::OgcBibliographicItem,
|
460
|
+
# RelatonCalconnect::CcBibliographicItem, RelatinUn::UnBibliographicItem,
|
461
|
+
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
462
|
+
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
390
463
|
# @return [String] XML or "not_found mm-dd-yyyy"
|
391
464
|
def bib_entry(bib)
|
392
|
-
|
393
|
-
bib.to_xml(bibdata: true)
|
394
|
-
else
|
395
|
-
"not_found #{Date.today}"
|
396
|
-
end
|
465
|
+
bib.respond_to?(:to_xml) ? bib.to_xml(bibdata: true) : "not_found #{Date.today}"
|
397
466
|
end
|
398
467
|
|
399
468
|
# @param dir [String, nil] DB directory
|
400
469
|
# @param type [Symbol]
|
401
470
|
# @return [Relaton::DbCache, NilClass]
|
402
|
-
def open_cache_biblio(dir, type: :static)
|
471
|
+
def open_cache_biblio(dir, type: :static) # rubocop:disable Metrics/MethodLength
|
403
472
|
return nil if dir.nil?
|
404
473
|
|
405
474
|
db = DbCache.new dir, type == :static ? "yml" : "xml"
|
@@ -408,9 +477,11 @@ module Relaton
|
|
408
477
|
Dir["#{dir}/*/"].each do |fdir|
|
409
478
|
next if db.check_version?(fdir)
|
410
479
|
|
411
|
-
FileUtils.rm_rf(
|
412
|
-
|
413
|
-
|
480
|
+
FileUtils.rm_rf(fdir, secure: true)
|
481
|
+
Util.log(
|
482
|
+
"[relaton] WARNING: cache #{fdir}: version is obsolete and cache is "\
|
483
|
+
"cleared.", :warning
|
484
|
+
)
|
414
485
|
end
|
415
486
|
db
|
416
487
|
end
|
@@ -419,8 +490,37 @@ module Relaton
|
|
419
490
|
# @option qwp [Queue] :queue The queue of references to fetch
|
420
491
|
# @option qwp [Relaton::WorkersPool] :workers_pool The pool of workers
|
421
492
|
def process_queue(qwp)
|
422
|
-
while args = qwp[:queue].pop
|
423
|
-
|
493
|
+
while args = qwp[:queue].pop; qwp[:workers_pool] << args end
|
494
|
+
end
|
495
|
+
|
496
|
+
class << self
|
497
|
+
# Initialse and return relaton instance, with local and global cache names
|
498
|
+
# local_cache: local cache name; none created if nil; "relaton" created
|
499
|
+
# if empty global_cache: boolean to create global_cache
|
500
|
+
# flush_caches: flush caches
|
501
|
+
def init_bib_caches(**opts) # rubocop:disable Metrics/CyclomaticComplexity
|
502
|
+
globalname = global_bibliocache_name if opts[:global_cache]
|
503
|
+
localname = local_bibliocache_name(opts[:local_cache])
|
504
|
+
flush_caches globalname, localname if opts[:flush_caches]
|
505
|
+
Relaton::Db.new(globalname, localname)
|
506
|
+
end
|
507
|
+
|
508
|
+
private
|
509
|
+
|
510
|
+
def flush_caches(gcache, lcache)
|
511
|
+
FileUtils.rm_rf gcache unless gcache.nil?
|
512
|
+
FileUtils.rm_rf lcache unless lcache.nil?
|
513
|
+
end
|
514
|
+
|
515
|
+
def global_bibliocache_name
|
516
|
+
Relaton.configuration.api_mode ? "cache" : "#{Dir.home}/.relaton/cache"
|
517
|
+
end
|
518
|
+
|
519
|
+
def local_bibliocache_name(cachename)
|
520
|
+
return nil if Relaton.configuration.api_mode || cachename.nil?
|
521
|
+
|
522
|
+
cachename = "relaton" if cachename.empty?
|
523
|
+
"#{cachename}/cache"
|
424
524
|
end
|
425
525
|
end
|
426
526
|
end
|