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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.rubocop.yml +1 -1
  4. data/lib/relaton.rb +1 -0
  5. data/lib/relaton/config.rb +4 -3
  6. data/lib/relaton/db.rb +110 -53
  7. data/lib/relaton/db_cache.rb +55 -99
  8. data/lib/relaton/registry.rb +2 -1
  9. data/lib/relaton/util.rb +2 -0
  10. data/lib/relaton/version.rb +1 -1
  11. data/relaton.gemspec +22 -19
  12. data/spec/relaton/db_cache_spec.rb +2 -2
  13. data/spec/relaton/db_spec.rb +17 -0
  14. data/spec/relaton/regirtry_spec.rb +9 -1
  15. data/spec/relaton_spec.rb +48 -7
  16. data/spec/spec_helper.rb +4 -0
  17. data/spec/vcr_cassetes/19133_2005.yml +17 -17
  18. data/spec/vcr_cassetes/api_relaton_org.yml +51 -0
  19. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +182 -0
  20. data/spec/vcr_cassetes/async_fetch.yml +2046 -1615
  21. data/spec/vcr_cassetes/bsi_bs_en_iso_8848.yml +17 -17
  22. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +16 -16
  23. data/spec/vcr_cassetes/cen_en_10160_1999.yml +249 -0
  24. data/spec/vcr_cassetes/cie_001_1980.yml +7 -7
  25. data/spec/vcr_cassetes/ecma_6.yml +7 -7
  26. data/spec/vcr_cassetes/fisp_140.yml +8 -10
  27. data/spec/vcr_cassetes/gb_t_20223_2006.yml +11 -11
  28. data/spec/vcr_cassetes/iec_60050_102_2007.yml +28 -28
  29. data/spec/vcr_cassetes/iec_combined_included.yml +85 -85
  30. data/spec/vcr_cassetes/ieee_528_2019.yml +37 -37
  31. data/spec/vcr_cassetes/iho_b_11.yml +7 -7
  32. data/spec/vcr_cassetes/iso_111111119115_1.yml +4 -4
  33. data/spec/vcr_cassetes/iso_19115.yml +17 -17
  34. data/spec/vcr_cassetes/iso_19115_1.yml +17 -17
  35. data/spec/vcr_cassetes/iso_19115_1_2.yml +36 -36
  36. data/spec/vcr_cassetes/iso_awi_14093.yml +182 -0
  37. data/spec/vcr_cassetes/iso_combined_applied.yml +36 -36
  38. data/spec/vcr_cassetes/iso_combined_included.yml +35 -35
  39. data/spec/vcr_cassetes/itu_combined_included.yml +741 -669
  40. data/spec/vcr_cassetes/ogc_19_025r1.yml +1247 -1163
  41. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +43 -0
  42. data/spec/vcr_cassetes/rfc_8341.yml +7 -7
  43. data/spec/vcr_cassetes/sp_800_38b.yml +8 -10
  44. data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +29 -29
  45. data/spec/vcr_cassetes/w3c_json_ld11.yml +17 -17
  46. metadata +91 -46
  47. data/spec/vcr_cassetes/iso_awi_24229.yml +0 -182
  48. 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: d0ff67d3ebeb9332a6aa18ad88e8b585478c29adb27ccda935ab9b8af4b34e2b
4
- data.tar.gz: 9aefca4601eb5bd7c4491dafc41fcee87cbb7e5d7508ee05086cfa39122bfbef
3
+ metadata.gz: e0872533d5f93e35d777c6a84a4f38a5698b64cc00d9d103b77f7e10fc34738b
4
+ data.tar.gz: 3f1cc128d958996cd8ea6eb31bacc530bba464a8d8b5cb855cd4e204214ef7d1
5
5
  SHA512:
6
- metadata.gz: b69bf1fbbbc4258bd22304dda3d54b23bc8a8e2361aeff2f26487518236e6b46690d0a793dd076489749ae0dcd93a6c3da7bc1969d3e877149ad9722b9ed0e9e
7
- data.tar.gz: '0682111008bcb648773cd0e90bb4f5a789007b5d5deca6aa2c5aa245b1f677a136eff936c6256b8e6bf76bcf4cb65f8371ba0cb5fe0c9ffe908e7d4640031342'
6
+ metadata.gz: 1862b4eb76509da3ae2ac959d1ffd7bf6e785bc45033c5123236f5c3f9dc5cafc42940a7cba78222960a59ad542fb0786f2a0be8e5da926bbb4b3aa886278a5e
7
+ data.tar.gz: b21c4797a9003696de1e5d79f017d19c417a9db72e549eeaab7edaa935e26ce9f1b009fdea83bf8896100ed30c63d5b7df730fbeaacedfc91243468cbc54a39b
@@ -16,7 +16,7 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
- ruby: [ '2.7', '2.6', '2.5', '2.4' ]
19
+ ruby: [ '2.7', '2.6', '2.5' ]
20
20
  os: [ ubuntu-latest, windows-latest, macos-latest ]
21
21
  experimental: [ false ]
22
22
  include:
data/.rubocop.yml CHANGED
@@ -5,6 +5,6 @@
5
5
  inherit_from:
6
6
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
7
7
  AllCops:
8
- TargetRubyVersion: 2.4
8
+ TargetRubyVersion: 2.5
9
9
  Rails:
10
10
  Enabled: false
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"
@@ -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 = false
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("../relaton/static_cache",
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
- @db&.mv new_dir
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
- if db
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 *args }
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 do
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 YAmL format
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
- ref = refs[0]
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(ref + divider + c, year, opts, stdclass)
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([]) do |m, (_k, v)|
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
- if entry.nil? || entry.match?(/^not_found/) then nil
335
- else @registry.processors[stdclass].from_xml(entry)
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
- if bib.respond_to? :to_xml
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
@@ -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 @dir
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" # unless it's static DB
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}/#{prefix(key)}"
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? /^not_found/
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
- block_given? ? yield(f, content) : content
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(file)
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 [TrueClass, FalseClass]
104
+ # @return [Boolean]
117
105
  def check_version?(fdir)
118
- version_dir = fdir + "/version"
119
- return false unless File.exist? version_dir
106
+ version_file = "#{fdir}/version"
107
+ return false unless File.exist? version_file
120
108
 
121
- v = File.read version_dir, encoding: "utf-8"
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
- private
168
-
169
- # Check if a file content is redirection
170
- #
171
- # @prarm value [String] file content
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
- # Return item's file name
179
- # @param key [String]
142
+ private
143
+
144
+ # @param value [String]
180
145
  # @return [String]
181
- def filename(key)
182
- prefcode = key.downcase.match /^(?<prefix>[^\(]+)\((?<code>[^\)]+)/
183
- fn = if prefcode
184
- "#{prefcode[:prefix]}/#{prefcode[:code].gsub(/[-:\s\/\()]/, '_').squeeze('_')}"
185
- else
186
- key.gsub(/[-:\s]/, "_")
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
- # Return item's subdir
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 prefix(key)
211
- key.downcase.match(/^[^\(]+(?=\()/).to_s
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