relaton 1.7.8 → 1.8.pre4
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 +1 -1
- data/.rubocop.yml +1 -1
- data/lib/relaton.rb +1 -0
- data/lib/relaton/config.rb +4 -3
- data/lib/relaton/db.rb +110 -53
- data/lib/relaton/db_cache.rb +55 -99
- data/lib/relaton/registry.rb +2 -1
- data/lib/relaton/util.rb +2 -0
- data/lib/relaton/version.rb +1 -1
- data/relaton.gemspec +22 -19
- data/spec/relaton/db_cache_spec.rb +2 -2
- data/spec/relaton/db_spec.rb +17 -0
- data/spec/relaton/regirtry_spec.rb +9 -1
- data/spec/relaton_spec.rb +48 -7
- data/spec/spec_helper.rb +4 -0
- data/spec/vcr_cassetes/19133_2005.yml +17 -17
- 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 +2046 -1615
- data/spec/vcr_cassetes/bsi_bs_en_iso_8848.yml +17 -17
- data/spec/vcr_cassetes/cc_dir_10005_2019.yml +16 -16
- 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 +11 -11
- data/spec/vcr_cassetes/iec_60050_102_2007.yml +28 -28
- data/spec/vcr_cassetes/iec_combined_included.yml +85 -85
- data/spec/vcr_cassetes/ieee_528_2019.yml +37 -37
- data/spec/vcr_cassetes/iho_b_11.yml +7 -7
- data/spec/vcr_cassetes/iso_111111119115_1.yml +4 -4
- data/spec/vcr_cassetes/iso_19115.yml +17 -17
- data/spec/vcr_cassetes/iso_19115_1.yml +17 -17
- data/spec/vcr_cassetes/iso_19115_1_2.yml +36 -36
- data/spec/vcr_cassetes/iso_awi_14093.yml +182 -0
- data/spec/vcr_cassetes/iso_combined_applied.yml +36 -36
- data/spec/vcr_cassetes/iso_combined_included.yml +35 -35
- data/spec/vcr_cassetes/itu_combined_included.yml +741 -669
- data/spec/vcr_cassetes/ogc_19_025r1.yml +1247 -1163
- 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 +29 -29
- data/spec/vcr_cassetes/w3c_json_ld11.yml +17 -17
- metadata +91 -46
- data/spec/vcr_cassetes/iso_awi_24229.yml +0 -182
- data/spec/vcr_cassetes/ogm_ami4ccm_1_0.yml +0 -43
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e0872533d5f93e35d777c6a84a4f38a5698b64cc00d9d103b77f7e10fc34738b
|
|
4
|
+
data.tar.gz: 3f1cc128d958996cd8ea6eb31bacc530bba464a8d8b5cb855cd4e204214ef7d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1862b4eb76509da3ae2ac959d1ffd7bf6e785bc45033c5123236f5c3f9dc5cafc42940a7cba78222960a59ad542fb0786f2a0be8e5da926bbb4b3aa886278a5e
|
|
7
|
+
data.tar.gz: b21c4797a9003696de1e5d79f017d19c417a9db72e549eeaab7edaa935e26ce9f1b009fdea83bf8896100ed30c63d5b7df730fbeaacedfc91243468cbc54a39b
|
data/.github/workflows/rake.yml
CHANGED
data/.rubocop.yml
CHANGED
data/lib/relaton.rb
CHANGED
data/lib/relaton/config.rb
CHANGED
|
@@ -12,13 +12,14 @@ 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
|
|
16
16
|
|
|
17
17
|
def initialize
|
|
18
|
-
@logs = %i(info error)
|
|
18
|
+
@logs = %i(info error) # allowed values: :info, :warning, :error, :debug
|
|
19
19
|
|
|
20
20
|
# @TODO change to true when we start using api.relaton.org
|
|
21
|
-
@use_api =
|
|
21
|
+
@use_api = true
|
|
22
|
+
@api_host = "https://api.relaton.org/api/v1"
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
data/lib/relaton/db.rb
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
require "yaml"
|
|
2
|
-
require_relative "registry"
|
|
3
|
-
require_relative "db_cache"
|
|
4
|
-
|
|
5
1
|
module Relaton
|
|
6
|
-
class RelatonError < StandardError; end
|
|
7
|
-
|
|
8
2
|
class Db
|
|
9
3
|
# @param global_cache [String] directory of global DB
|
|
10
4
|
# @param local_cache [String] directory of local DB
|
|
11
5
|
def initialize(global_cache, local_cache)
|
|
12
6
|
@registry = Relaton::Registry.instance
|
|
13
7
|
gpath = global_cache && File.expand_path(global_cache)
|
|
14
|
-
@db = open_cache_biblio(gpath, type: :global)
|
|
15
8
|
lpath = local_cache && File.expand_path(local_cache)
|
|
9
|
+
@db = open_cache_biblio(gpath, type: :global)
|
|
16
10
|
@local_db = open_cache_biblio(lpath, type: :local)
|
|
17
|
-
@static_db = open_cache_biblio File.expand_path
|
|
18
|
-
__dir__)
|
|
11
|
+
@static_db = open_cache_biblio File.expand_path "../relaton/static_cache", __dir__
|
|
19
12
|
@queues = {}
|
|
20
13
|
end
|
|
21
14
|
|
|
@@ -25,10 +18,8 @@ module Relaton
|
|
|
25
18
|
# @return [String, nil]
|
|
26
19
|
def mv(new_dir, type: :global)
|
|
27
20
|
case type
|
|
28
|
-
when :global
|
|
29
|
-
|
|
30
|
-
when :local
|
|
31
|
-
@local_db&.mv new_dir
|
|
21
|
+
when :global then @db&.mv new_dir
|
|
22
|
+
when :local then @local_db&.mv new_dir
|
|
32
23
|
end
|
|
33
24
|
end
|
|
34
25
|
|
|
@@ -89,22 +80,18 @@ module Relaton
|
|
|
89
80
|
result = @static_db.all do |file, yml|
|
|
90
81
|
search_yml file, yml, text, edition, year
|
|
91
82
|
end.compact
|
|
92
|
-
db = @db || @local_db
|
|
93
|
-
|
|
94
|
-
result += db.all do |file, xml|
|
|
95
|
-
search_xml file, xml, text, edition, year
|
|
96
|
-
end.compact
|
|
83
|
+
if (db = @db || @local_db)
|
|
84
|
+
result += db.all { |f, x| search_xml f, x, text, edition, year }.compact
|
|
97
85
|
end
|
|
98
86
|
result
|
|
99
87
|
end
|
|
100
88
|
|
|
101
89
|
# Fetch asynchronously
|
|
102
90
|
def fetch_async(code, year = nil, opts = {}, &_block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
103
|
-
stdclass = standard_class code
|
|
104
|
-
if stdclass
|
|
91
|
+
if (stdclass = standard_class code)
|
|
105
92
|
unless @queues[stdclass]
|
|
106
93
|
processor = @registry.processors[stdclass]
|
|
107
|
-
wp = WorkersPool.new(processor.threads) { |args| yield fetch
|
|
94
|
+
wp = WorkersPool.new(processor.threads) { |args| yield fetch(*args) }
|
|
108
95
|
@queues[stdclass] = { queue: Queue.new, workers_pool: wp }
|
|
109
96
|
Thread.new { process_queue @queues[stdclass] }
|
|
110
97
|
end
|
|
@@ -173,14 +160,43 @@ module Relaton
|
|
|
173
160
|
def to_xml
|
|
174
161
|
db = @local_db || @db || return
|
|
175
162
|
Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
|
176
|
-
xml.documents
|
|
177
|
-
xml.parent.add_child db.all.join(" ")
|
|
178
|
-
end
|
|
163
|
+
xml.documents { xml.parent.add_child db.all.join(" ") }
|
|
179
164
|
end.to_xml
|
|
180
165
|
end
|
|
181
166
|
|
|
182
167
|
private
|
|
183
168
|
|
|
169
|
+
#
|
|
170
|
+
# @param code [String]
|
|
171
|
+
# @param year [String]
|
|
172
|
+
#
|
|
173
|
+
# @param opts [Hash]
|
|
174
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
175
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
176
|
+
# actual reference with year
|
|
177
|
+
#
|
|
178
|
+
# @param stdclass [Symbol]
|
|
179
|
+
def fetch_api(code, year, opts, stdclass)
|
|
180
|
+
return unless Relaton.configuration.use_api
|
|
181
|
+
|
|
182
|
+
url = "#{Relaton.configuration.api_host}/document?#{params(code, year, opts)}"
|
|
183
|
+
rsp = Net::HTTP.get_response URI(url)
|
|
184
|
+
@registry.processors[stdclass].from_xml rsp.body if rsp.code == "200"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
#
|
|
188
|
+
# Make string of parametrs
|
|
189
|
+
#
|
|
190
|
+
# @param [String] code
|
|
191
|
+
# @param [String] year
|
|
192
|
+
# @param [Hash] opts
|
|
193
|
+
#
|
|
194
|
+
# @return [String]
|
|
195
|
+
#
|
|
196
|
+
def params(code, year, opts)
|
|
197
|
+
opts.merge(code: code, year: year).map { |k, v| "#{k}=#{v}" }.join "&"
|
|
198
|
+
end
|
|
199
|
+
|
|
184
200
|
# @param file [String] file path
|
|
185
201
|
# @param yml [String] content in YAML format
|
|
186
202
|
# @param text [String, nil] text to serach
|
|
@@ -207,7 +223,7 @@ module Relaton
|
|
|
207
223
|
end
|
|
208
224
|
|
|
209
225
|
# @param file [String] file path
|
|
210
|
-
# @param content [String] content in XML or
|
|
226
|
+
# @param content [String] content in XML or YAML format
|
|
211
227
|
# @param edition [String, nil] edition to filter
|
|
212
228
|
# @param year [Integer, nil] year to filter
|
|
213
229
|
# @return [BibliographicItem, nil]
|
|
@@ -220,9 +236,14 @@ module Relaton
|
|
|
220
236
|
item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s })
|
|
221
237
|
end
|
|
222
238
|
|
|
239
|
+
#
|
|
240
|
+
# Look up text in the XML elements attributes and content
|
|
241
|
+
#
|
|
223
242
|
# @param xml [String] content in XML format
|
|
224
243
|
# @param text [String, nil] text to serach
|
|
244
|
+
#
|
|
225
245
|
# @return [Boolean]
|
|
246
|
+
#
|
|
226
247
|
def match_xml_text(xml, text)
|
|
227
248
|
%r{((?<attr>=((?<apstr>')|"))|>).*?#{text}.*?(?(<attr>)(?(<apstr>)'|")|<)}mi.match?(xml)
|
|
228
249
|
end
|
|
@@ -256,19 +277,15 @@ module Relaton
|
|
|
256
277
|
end
|
|
257
278
|
|
|
258
279
|
doc = @registry.processors[stdclass].hash_to_bib docid: { id: code }
|
|
259
|
-
|
|
260
|
-
updates = check_bibliocache(ref, year, opts, stdclass)
|
|
280
|
+
updates = check_bibliocache(refs[0], year, opts, stdclass)
|
|
261
281
|
if updates
|
|
262
|
-
doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates,
|
|
263
|
-
type: "updates")
|
|
282
|
+
doc.relation << RelatonBib::DocumentRelation.new(bibitem: updates, type: "updates")
|
|
264
283
|
end
|
|
265
284
|
divider = stdclass == :relaton_itu ? " " : "/"
|
|
266
285
|
refs[1..-1].each_with_object(doc) do |c, d|
|
|
267
|
-
bib = check_bibliocache(
|
|
286
|
+
bib = check_bibliocache(refs[0] + divider + c, year, opts, stdclass)
|
|
268
287
|
if bib
|
|
269
|
-
d.relation << RelatonBib::DocumentRelation.new(
|
|
270
|
-
type: reltype, description: reldesc, bibitem: bib
|
|
271
|
-
)
|
|
288
|
+
d.relation << RelatonBib::DocumentRelation.new(type: reltype, description: reldesc, bibitem: bib)
|
|
272
289
|
end
|
|
273
290
|
end
|
|
274
291
|
end
|
|
@@ -280,9 +297,7 @@ module Relaton
|
|
|
280
297
|
return name if /^(urn:)?#{processor.prefix}/i.match?(code) ||
|
|
281
298
|
processor.defaultprefix.match(code)
|
|
282
299
|
end
|
|
283
|
-
allowed = @registry.processors.reduce([])
|
|
284
|
-
m << v.prefix
|
|
285
|
-
end
|
|
300
|
+
allowed = @registry.processors.reduce([]) { |m, (_k, v)| m << v.prefix }
|
|
286
301
|
Util.log <<~WARN, :info
|
|
287
302
|
[relaton] #{code} does not have a recognised prefix: #{allowed.join(', ')}.
|
|
288
303
|
See https://github.com/relaton/relaton/ for instructions on prefixing and wrapping document identifiers to disambiguate them.
|
|
@@ -331,8 +346,8 @@ module Relaton
|
|
|
331
346
|
# RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
|
|
332
347
|
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
333
348
|
def bib_retval(entry, stdclass)
|
|
334
|
-
|
|
335
|
-
|
|
349
|
+
unless entry.nil? || entry.match?(/^not_found/)
|
|
350
|
+
@registry.processors[stdclass].from_xml(entry)
|
|
336
351
|
end
|
|
337
352
|
end
|
|
338
353
|
|
|
@@ -356,8 +371,7 @@ module Relaton
|
|
|
356
371
|
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
357
372
|
def check_bibliocache(code, year, opts, stdclass) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
358
373
|
id, searchcode = std_id(code, year, opts, stdclass)
|
|
359
|
-
yaml = @static_db[id]
|
|
360
|
-
if yaml
|
|
374
|
+
if (yaml = @static_db[id])
|
|
361
375
|
return @registry.processors[stdclass].hash_to_bib YAML.safe_load(yaml)
|
|
362
376
|
end
|
|
363
377
|
|
|
@@ -366,8 +380,7 @@ module Relaton
|
|
|
366
380
|
if db.nil?
|
|
367
381
|
return if opts[:fetch_db]
|
|
368
382
|
|
|
369
|
-
bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db,
|
|
370
|
-
id: id)
|
|
383
|
+
bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
|
|
371
384
|
return bib_retval(bibentry, stdclass)
|
|
372
385
|
end
|
|
373
386
|
|
|
@@ -376,18 +389,17 @@ module Relaton
|
|
|
376
389
|
return bib_retval(altdb[id], stdclass) if opts[:fetch_db]
|
|
377
390
|
|
|
378
391
|
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)
|
|
392
|
+
db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
|
|
381
393
|
altdb.clone_entry(id, db) if !altdb.valid_entry?(id, year)
|
|
382
394
|
else
|
|
383
395
|
return bib_retval(db[id], stdclass) if opts[:fetch_db]
|
|
384
396
|
|
|
385
|
-
db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db,
|
|
386
|
-
id: id)
|
|
397
|
+
db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
|
|
387
398
|
end
|
|
388
399
|
bib_retval(db[id], stdclass)
|
|
389
400
|
end
|
|
390
401
|
|
|
402
|
+
#
|
|
391
403
|
# @param code [String]
|
|
392
404
|
# @param year [String]
|
|
393
405
|
#
|
|
@@ -400,7 +412,9 @@ module Relaton
|
|
|
400
412
|
# @param stdclass [Symbol]
|
|
401
413
|
# @param db [Relaton::DbCache,`NilClass]
|
|
402
414
|
# @param id [String] docid
|
|
415
|
+
#
|
|
403
416
|
# @return [String]
|
|
417
|
+
#
|
|
404
418
|
def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
405
419
|
bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
|
|
406
420
|
bib_id = bib&.docidentifier&.first&.id
|
|
@@ -415,8 +429,27 @@ module Relaton
|
|
|
415
429
|
end
|
|
416
430
|
end
|
|
417
431
|
|
|
432
|
+
#
|
|
433
|
+
# @param code [String]
|
|
434
|
+
# @param year [String]
|
|
435
|
+
#
|
|
436
|
+
# @param opts [Hash]
|
|
437
|
+
# @option opts [Boolean] :all_parts If all-parts reference is required
|
|
438
|
+
# @option opts [Boolean] :keep_year If undated reference should return
|
|
439
|
+
# actual reference with year
|
|
440
|
+
#
|
|
441
|
+
# @param stdclass [Symbol]
|
|
442
|
+
# @param retries [Integer] remain Number of network retries
|
|
443
|
+
#
|
|
418
444
|
# @raise [RelatonBib::RequestError]
|
|
445
|
+
# @return [RelatonBib::BibliographicItem]
|
|
446
|
+
#
|
|
419
447
|
def net_retry(code, year, opts, stdclass, retries)
|
|
448
|
+
doc = fetch_api code, year, opts, stdclass
|
|
449
|
+
return doc if doc
|
|
450
|
+
|
|
451
|
+
@registry.processors[stdclass].get(code, year, opts)
|
|
452
|
+
rescue Errno::ECONNREFUSED
|
|
420
453
|
@registry.processors[stdclass].get(code, year, opts)
|
|
421
454
|
rescue RelatonBib::RequestError => e
|
|
422
455
|
raise e unless retries > 1
|
|
@@ -434,11 +467,7 @@ module Relaton
|
|
|
434
467
|
# RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
|
|
435
468
|
# @return [String] XML or "not_found mm-dd-yyyy"
|
|
436
469
|
def bib_entry(bib)
|
|
437
|
-
|
|
438
|
-
bib.to_xml(bibdata: true)
|
|
439
|
-
else
|
|
440
|
-
"not_found #{Date.today}"
|
|
441
|
-
end
|
|
470
|
+
bib.respond_to?(:to_xml) ? bib.to_xml(bibdata: true) : "not_found #{Date.today}"
|
|
442
471
|
end
|
|
443
472
|
|
|
444
473
|
# @param dir [String, nil] DB directory
|
|
@@ -456,8 +485,7 @@ module Relaton
|
|
|
456
485
|
FileUtils.rm_rf(fdir, secure: true)
|
|
457
486
|
Util.log(
|
|
458
487
|
"[relaton] WARNING: cache #{fdir}: version is obsolete and cache is "\
|
|
459
|
-
"cleared.",
|
|
460
|
-
:warning
|
|
488
|
+
"cleared.", :warning
|
|
461
489
|
)
|
|
462
490
|
end
|
|
463
491
|
db
|
|
@@ -469,5 +497,34 @@ module Relaton
|
|
|
469
497
|
def process_queue(qwp)
|
|
470
498
|
while args = qwp[:queue].pop; qwp[:workers_pool] << args end
|
|
471
499
|
end
|
|
500
|
+
|
|
501
|
+
class << self
|
|
502
|
+
# Initialse and return relaton instance, with local and global cache names
|
|
503
|
+
# local_cache: local cache name; none created if nil; "relaton" created
|
|
504
|
+
# if empty global_cache: boolean to create global_cache
|
|
505
|
+
# flush_caches: flush caches
|
|
506
|
+
def init_bib_caches(**opts) # rubocop:disable Metrics/CyclomaticComplexity
|
|
507
|
+
globalname = global_bibliocache_name if opts[:global_cache]
|
|
508
|
+
localname = local_bibliocache_name(opts[:local_cache])
|
|
509
|
+
flush_caches globalname, localname if opts[:flush_caches]
|
|
510
|
+
Relaton::Db.new(globalname, localname)
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
private
|
|
514
|
+
|
|
515
|
+
def flush_caches(gcache, lcache)
|
|
516
|
+
FileUtils.rm_rf gcache unless gcache.nil?
|
|
517
|
+
FileUtils.rm_rf lcache unless lcache.nil?
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
def global_bibliocache_name
|
|
521
|
+
"#{Dir.home}/.relaton/cache"
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
def local_bibliocache_name(cachename)
|
|
525
|
+
cachename = "relaton" if cachename.empty?
|
|
526
|
+
"#{cachename}/cache"
|
|
527
|
+
end
|
|
528
|
+
end
|
|
472
529
|
end
|
|
473
530
|
end
|
data/lib/relaton/db_cache.rb
CHANGED
|
@@ -10,9 +10,7 @@ module Relaton
|
|
|
10
10
|
def initialize(dir, ext = "xml")
|
|
11
11
|
@dir = dir
|
|
12
12
|
@ext = ext
|
|
13
|
-
FileUtils::mkdir_p
|
|
14
|
-
# file_version = "#{@dir}/version"
|
|
15
|
-
# set_version # unless File.exist? file_version
|
|
13
|
+
FileUtils::mkdir_p dir
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
# Move caches to anothe dir
|
|
@@ -32,7 +30,7 @@ module Relaton
|
|
|
32
30
|
|
|
33
31
|
# Clear database
|
|
34
32
|
def clear
|
|
35
|
-
FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" #
|
|
33
|
+
FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" # if it isn't a static DB
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
# Save item
|
|
@@ -43,23 +41,13 @@ module Relaton
|
|
|
43
41
|
delete key
|
|
44
42
|
return
|
|
45
43
|
end
|
|
46
|
-
|
|
47
|
-
prefix_dir = "#{@dir}/#{
|
|
44
|
+
/^(?<pref>[^(]+)(?=\()/ =~ key.downcase
|
|
45
|
+
prefix_dir = "#{@dir}/#{pref}"
|
|
48
46
|
FileUtils::mkdir_p prefix_dir unless Dir.exist? prefix_dir
|
|
49
47
|
set_version prefix_dir
|
|
50
48
|
file_safe_write "#{filename(key)}.#{ext(value)}", value
|
|
51
49
|
end
|
|
52
50
|
|
|
53
|
-
# @param value [String]
|
|
54
|
-
# @return [String]
|
|
55
|
-
def ext(value)
|
|
56
|
-
case value
|
|
57
|
-
when /^not_found/ then "notfound"
|
|
58
|
-
when /^redirection/ then "redirect"
|
|
59
|
-
else @ext
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
51
|
# Read item
|
|
64
52
|
# @param key [String]
|
|
65
53
|
# @return [String]
|
|
@@ -86,7 +74,7 @@ module Relaton
|
|
|
86
74
|
value = self[key]
|
|
87
75
|
return unless value
|
|
88
76
|
|
|
89
|
-
if value.match?
|
|
77
|
+
if value.match?(/^not_found/)
|
|
90
78
|
value.match(/\d{4}-\d{2}-\d{2}/).to_s
|
|
91
79
|
else
|
|
92
80
|
doc = Nokogiri::XML value
|
|
@@ -96,10 +84,10 @@ module Relaton
|
|
|
96
84
|
|
|
97
85
|
# Returns all items
|
|
98
86
|
# @return [Array<String>]
|
|
99
|
-
def all
|
|
87
|
+
def all(&block)
|
|
100
88
|
Dir.glob("#{@dir}/**/*.{xml,yml,yaml}").sort.map do |f|
|
|
101
89
|
content = File.read(f, encoding: "utf-8")
|
|
102
|
-
|
|
90
|
+
block ? yield(f, content) : content
|
|
103
91
|
end
|
|
104
92
|
end
|
|
105
93
|
|
|
@@ -107,30 +95,19 @@ module Relaton
|
|
|
107
95
|
# @param key [String]
|
|
108
96
|
def delete(key)
|
|
109
97
|
file = filename key
|
|
110
|
-
f = search_ext
|
|
98
|
+
f = search_ext file
|
|
111
99
|
File.delete f if f
|
|
112
100
|
end
|
|
113
101
|
|
|
114
102
|
# Check if version of the DB match to the gem grammar hash.
|
|
115
103
|
# @param fdir [String] dir pathe to flover cache
|
|
116
|
-
# @return [
|
|
104
|
+
# @return [Boolean]
|
|
117
105
|
def check_version?(fdir)
|
|
118
|
-
|
|
119
|
-
return false unless File.exist?
|
|
106
|
+
version_file = "#{fdir}/version"
|
|
107
|
+
return false unless File.exist? version_file
|
|
120
108
|
|
|
121
|
-
v = File.read
|
|
122
|
-
v.strip == grammar_hash(fdir)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# Set version of the DB to the gem grammar hash.
|
|
126
|
-
# @param fdir [String] dir pathe to flover cache
|
|
127
|
-
# @return [Relaton::DbCache]
|
|
128
|
-
def set_version(fdir)
|
|
129
|
-
file_version = "#{fdir}/version"
|
|
130
|
-
unless File.exist? file_version
|
|
131
|
-
file_safe_write file_version, grammar_hash(fdir)
|
|
132
|
-
end
|
|
133
|
-
self
|
|
109
|
+
v = File.read version_file, encoding: "utf-8"
|
|
110
|
+
v.strip == self.class.grammar_hash(fdir)
|
|
134
111
|
end
|
|
135
112
|
|
|
136
113
|
# if cached reference is undated, expire it after 60 days
|
|
@@ -144,15 +121,6 @@ module Relaton
|
|
|
144
121
|
year || Date.today - date < 60
|
|
145
122
|
end
|
|
146
123
|
|
|
147
|
-
protected
|
|
148
|
-
|
|
149
|
-
# @param fdir [String] dir pathe to flover cache
|
|
150
|
-
# @return [String]
|
|
151
|
-
def grammar_hash(fdir)
|
|
152
|
-
type = fdir.split("/").last
|
|
153
|
-
Relaton::Registry.instance.by_type(type)&.grammar_hash
|
|
154
|
-
end
|
|
155
|
-
|
|
156
124
|
# Reads file by a key
|
|
157
125
|
#
|
|
158
126
|
# @param key [String]
|
|
@@ -164,28 +132,23 @@ module Relaton
|
|
|
164
132
|
File.read(f, encoding: "utf-8")
|
|
165
133
|
end
|
|
166
134
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
# @return [String, NilClass] redirection code or nil
|
|
173
|
-
def redirect?(value)
|
|
174
|
-
%r{redirection\s(?<code>.*)} =~ value
|
|
175
|
-
code
|
|
135
|
+
# @param fdir [String] dir pathe to flover cache
|
|
136
|
+
# @return [String]
|
|
137
|
+
def self.grammar_hash(fdir)
|
|
138
|
+
type = fdir.split("/").last
|
|
139
|
+
Relaton::Registry.instance.by_type(type)&.grammar_hash
|
|
176
140
|
end
|
|
177
141
|
|
|
178
|
-
|
|
179
|
-
|
|
142
|
+
private
|
|
143
|
+
|
|
144
|
+
# @param value [String]
|
|
180
145
|
# @return [String]
|
|
181
|
-
def
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
end
|
|
188
|
-
"#{@dir}/#{fn.sub(/(,|_$)/, '')}"
|
|
146
|
+
def ext(value)
|
|
147
|
+
case value
|
|
148
|
+
when /^not_found/ then "notfound"
|
|
149
|
+
when /^redirection/ then "redirect"
|
|
150
|
+
else @ext
|
|
151
|
+
end
|
|
189
152
|
end
|
|
190
153
|
|
|
191
154
|
#
|
|
@@ -204,11 +167,36 @@ module Relaton
|
|
|
204
167
|
end
|
|
205
168
|
end
|
|
206
169
|
|
|
207
|
-
#
|
|
170
|
+
# Set version of the DB to the gem grammar hash.
|
|
171
|
+
# @param fdir [String] dir pathe to flover cache
|
|
172
|
+
def set_version(fdir)
|
|
173
|
+
file_version = "#{fdir}/version"
|
|
174
|
+
unless File.exist? file_version
|
|
175
|
+
file_safe_write file_version, self.class.grammar_hash(fdir)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Return item's file name
|
|
208
180
|
# @param key [String]
|
|
209
181
|
# @return [String]
|
|
210
|
-
def
|
|
211
|
-
key.downcase.match(/^[
|
|
182
|
+
def filename(key)
|
|
183
|
+
prefcode = key.downcase.match(/^(?<prefix>[^(]+)\((?<code>[^)]+)/)
|
|
184
|
+
fn = if prefcode
|
|
185
|
+
"#{prefcode[:prefix]}/#{prefcode[:code].gsub(/[-:\s\/()]/, '_')
|
|
186
|
+
.squeeze('_')}"
|
|
187
|
+
else
|
|
188
|
+
key.gsub(/[-:\s]/, "_")
|
|
189
|
+
end
|
|
190
|
+
"#{@dir}/#{fn.sub(/(,|_$)/, '')}"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Check if a file content is redirection
|
|
194
|
+
#
|
|
195
|
+
# @prarm value [String] file content
|
|
196
|
+
# @return [String, NilClass] redirection code or nil
|
|
197
|
+
def redirect?(value)
|
|
198
|
+
%r{redirection\s(?<code>.*)} =~ value
|
|
199
|
+
code
|
|
212
200
|
end
|
|
213
201
|
|
|
214
202
|
# @param file [String]
|
|
@@ -219,37 +207,5 @@ module Relaton
|
|
|
219
207
|
f.write content
|
|
220
208
|
end
|
|
221
209
|
end
|
|
222
|
-
|
|
223
|
-
class << self
|
|
224
|
-
private
|
|
225
|
-
|
|
226
|
-
def global_bibliocache_name
|
|
227
|
-
"#{Dir.home}/.relaton/cache"
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
def local_bibliocache_name(cachename)
|
|
231
|
-
return nil if cachename.nil?
|
|
232
|
-
|
|
233
|
-
cachename = "relaton" if cachename.empty?
|
|
234
|
-
"#{cachename}/cache"
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
public
|
|
238
|
-
|
|
239
|
-
# Initialse and return relaton instance, with local and global cache names
|
|
240
|
-
# local_cache: local cache name; none created if nil; "relaton" created
|
|
241
|
-
# if empty global_cache: boolean to create global_cache
|
|
242
|
-
# flush_caches: flush caches
|
|
243
|
-
def init_bib_caches(opts) # rubocop:disable Metrics/CyclomaticComplexity
|
|
244
|
-
globalname = global_bibliocache_name if opts[:global_cache]
|
|
245
|
-
localname = local_bibliocache_name(opts[:local_cache])
|
|
246
|
-
localname = "relaton" if localname&.empty?
|
|
247
|
-
if opts[:flush_caches]
|
|
248
|
-
FileUtils.rm_rf globalname unless globalname.nil?
|
|
249
|
-
FileUtils.rm_rf localname unless localname.nil?
|
|
250
|
-
end
|
|
251
|
-
Relaton::Db.new(globalname, localname)
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
210
|
end
|
|
255
211
|
end
|