relaton 1.7.2 → 1.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +46 -0
  3. data/docs/README.adoc +160 -2
  4. data/globalcache/iec/iec_60050_102_2007.xml +58 -0
  5. data/globalcache/iec/version +1 -0
  6. data/lib/relaton.rb +8 -7
  7. data/lib/relaton/config.rb +5 -2
  8. data/lib/relaton/db.rb +291 -63
  9. data/lib/relaton/db_cache.rb +25 -3
  10. data/lib/relaton/processor.rb +11 -0
  11. data/lib/relaton/registry.rb +1 -1
  12. data/lib/relaton/util.rb +1 -1
  13. data/lib/relaton/version.rb +1 -1
  14. data/lib/relaton/workers_pool.rb +23 -0
  15. data/relaton.gemspec +6 -5
  16. data/spec/relaton/config_spec.rb +1 -1
  17. data/spec/relaton/db_spec.rb +145 -0
  18. data/spec/relaton/processor_spec.rb +4 -0
  19. data/spec/relaton/regirtry_spec.rb +51 -45
  20. data/spec/relaton_spec.rb +37 -19
  21. data/spec/vcr_cassetes/19133_2005.yml +20 -20
  22. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +10 -10
  23. data/spec/vcr_cassetes/cie_001_1980.yml +120 -0
  24. data/spec/vcr_cassetes/ecma_6.yml +132 -446
  25. data/spec/vcr_cassetes/fisp_140.yml +4 -4
  26. data/spec/vcr_cassetes/gb_t_20223_2006.yml +11 -11
  27. data/spec/vcr_cassetes/iec_60050_102_2007.yml +285 -0
  28. data/spec/vcr_cassetes/iec_combined_included.yml +78 -423
  29. data/spec/vcr_cassetes/ieee_528_2019.yml +20 -20
  30. data/spec/vcr_cassetes/iho_b_11.yml +15 -15
  31. data/spec/vcr_cassetes/iso_111111119115_1.yml +5 -5
  32. data/spec/vcr_cassetes/iso_19115.yml +21 -21
  33. data/spec/vcr_cassetes/iso_19115_1.yml +21 -21
  34. data/spec/vcr_cassetes/iso_19115_1_2.yml +42 -42
  35. data/spec/vcr_cassetes/iso_awi_24229.yml +21 -21
  36. data/spec/vcr_cassetes/iso_combined_applied.yml +42 -42
  37. data/spec/vcr_cassetes/iso_combined_included.yml +40 -40
  38. data/spec/vcr_cassetes/itu_combined_included.yml +165 -147
  39. data/spec/vcr_cassetes/ogc_19_025r1.yml +13044 -18
  40. data/spec/vcr_cassetes/ogm_ami4ccm_1_0.yml +7 -7
  41. data/spec/vcr_cassetes/rfc_8341.yml +47 -15
  42. data/spec/vcr_cassetes/rfc_unsuccess.yml +70 -0
  43. data/spec/vcr_cassetes/sp_800_38b.yml +4 -4
  44. data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +29 -29
  45. data/spec/vcr_cassetes/w3c_json_ld11.yml +12 -12
  46. metadata +29 -39
  47. data/.github/workflows/macos.yml +0 -34
  48. data/.github/workflows/ubuntu.yml +0 -32
  49. data/.github/workflows/windows.yml +0 -35
@@ -1,4 +1,5 @@
1
1
  require "fileutils"
2
+ require "timeout"
2
3
 
3
4
  module Relaton
4
5
  class DbCache
@@ -14,6 +15,26 @@ module Relaton
14
15
  # set_version # unless File.exist? file_version
15
16
  end
16
17
 
18
+ # Move caches to anothe dir
19
+ # @param new_dir [String, nil]
20
+ # @return [String, nil]
21
+ def mv(new_dir)
22
+ return unless new_dir && @ext == "xml"
23
+
24
+ if File.exist? new_dir
25
+ warn "[relaton] WARNING: target directory exists \"#{new_dir}\""
26
+ return
27
+ end
28
+
29
+ FileUtils.mv dir, new_dir
30
+ @dir = new_dir
31
+ end
32
+
33
+ # Clear database
34
+ def clear
35
+ FileUtils.rm_rf Dir.glob "#{dir}/*" if @ext == "xml" # unless it's static DB
36
+ end
37
+
17
38
  # Save item
18
39
  # @param key [String]
19
40
  # @param value [String] Bibitem xml serialization
@@ -76,8 +97,9 @@ module Relaton
76
97
  # Returns all items
77
98
  # @return [Array<String>]
78
99
  def all
79
- Dir.glob("#{@dir}/**/*.xml").sort.map do |f|
80
- File.read(f, encoding: "utf-8")
100
+ Dir.glob("#{@dir}/**/*.{xml,yml,yaml}").sort.map do |f|
101
+ content = File.read(f, encoding: "utf-8")
102
+ block_given? ? yield(f, content) : content
81
103
  end
82
104
  end
83
105
 
@@ -193,7 +215,7 @@ module Relaton
193
215
  # @content [String]
194
216
  def file_safe_write(file, content)
195
217
  File.open file, File::RDWR | File::CREAT, encoding: "UTF-8" do |f|
196
- Timeout.timeout(1) { f.flock File::LOCK_EX }
218
+ Timeout.timeout(10) { f.flock File::LOCK_EX }
197
219
  f.write content
198
220
  end
199
221
  end
@@ -20,5 +20,16 @@ module Relaton
20
20
  def hash_to_bib(_hash)
21
21
  raise "This is an abstract class!"
22
22
  end
23
+
24
+ def grammar_hash
25
+ raise "This is an abstract class!"
26
+ end
27
+
28
+ # Retuns default number of workers. Should be overraded by childred classes if need.
29
+ #
30
+ # @return [Integer] nuber of wokrers
31
+ def threads
32
+ 10
33
+ end
23
34
  end
24
35
  end
@@ -8,7 +8,7 @@ module Relaton
8
8
  SUPPORTED_GEMS = %w[
9
9
  relaton_gb relaton_iec relaton_ietf relaton_iso relaton_itu relaton_nist
10
10
  relaton_ogc relaton_calconnect relaton_omg relaton_un relaton_w3c
11
- relaton_ieee relaton_iho relaton_bipm relaton_ecma
11
+ relaton_ieee relaton_iho relaton_bipm relaton_ecma relaton_cie
12
12
  ].freeze
13
13
 
14
14
  include Singleton
data/lib/relaton/util.rb CHANGED
@@ -4,7 +4,7 @@ module Relaton
4
4
  log_types = Relaton.configuration.logs.map(&:to_s) || []
5
5
 
6
6
  if log_types.include?(type.to_s)
7
- puts(message)
7
+ warn(message)
8
8
  end
9
9
  end
10
10
  end
@@ -1,3 +1,3 @@
1
1
  module Relaton
2
- VERSION = "1.7.2".freeze
2
+ VERSION = "1.7.7".freeze
3
3
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ # Workers poll.
5
+ class WorkersPool
6
+ def initialize(workers = 2, &_block)
7
+ num_workers = workers < 2 ? 2 : workers
8
+ @queue = SizedQueue.new(num_workers * 2)
9
+ @threads = Array.new num_workers do
10
+ Thread.new do
11
+ while item = @queue.pop
12
+ yield(item)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def <<(item)
19
+ @queue << item
20
+ self
21
+ end
22
+ end
23
+ end
data/relaton.gemspec CHANGED
@@ -32,9 +32,10 @@ Gem::Specification.new do |spec|
32
32
  # spec.add_dependency "algoliasearch"
33
33
  spec.add_dependency "relaton-bipm", "~> 1.7.0"
34
34
  spec.add_dependency "relaton-calconnect", "~> 1.7.0"
35
- spec.add_dependency "relaton-ecma", "1.7.pre1"
35
+ spec.add_dependency "relaton-cie", "~> 1.7.pre1"
36
+ spec.add_dependency "relaton-ecma", "~> 1.7.pre1"
36
37
  spec.add_dependency "relaton-gb", "~> 1.7.0"
37
- spec.add_dependency "relaton-iec", ">= 1.7.3"
38
+ spec.add_dependency "relaton-iec", ">= 1.7.6"
38
39
  spec.add_dependency "relaton-ieee", "~> 1.7.0"
39
40
  spec.add_dependency "relaton-ietf", "~> 1.7.0"
40
41
  spec.add_dependency "relaton-iho", "~> 1.7.0"
@@ -47,15 +48,15 @@ Gem::Specification.new do |spec|
47
48
  spec.add_dependency "relaton-w3c", "~> 1.7.0"
48
49
 
49
50
  spec.add_development_dependency "byebug", "~> 11.0"
50
- spec.add_development_dependency "debase"
51
+ # spec.add_development_dependency "debase"
51
52
  spec.add_development_dependency "equivalent-xml", "~> 0.6"
52
53
  spec.add_development_dependency "guard", "~> 2.14"
53
54
  spec.add_development_dependency "guard-rspec", "~> 4.7"
54
55
  spec.add_development_dependency "pry-byebug", "~> 3.9.0"
55
- spec.add_development_dependency "rake", "~> 10.0"
56
+ spec.add_development_dependency "rake", "~> 13.0"
56
57
  spec.add_development_dependency "rspec", "~> 3.6"
57
58
  spec.add_development_dependency "rubocop", "= 0.54.0"
58
- spec.add_development_dependency "ruby-debug-ide"
59
+ # spec.add_development_dependency "ruby-debug-ide"
59
60
  spec.add_development_dependency "simplecov", "~> 0.15"
60
61
  spec.add_development_dependency "timecop", "~> 0.9"
61
62
  spec.add_development_dependency "vcr", "~> 5"
@@ -17,6 +17,6 @@ RSpec.describe Relaton::Config do
17
17
  end
18
18
 
19
19
  def restore_to_default_config
20
- Relaton.configuration.logs = %i(warning error)
20
+ Relaton.configuration.logs = %i(info error)
21
21
  end
22
22
  end
@@ -1,6 +1,121 @@
1
1
  RSpec.describe Relaton::Db do
2
2
  before(:each) { FileUtils.rm_rf %w[testcache testcache2] }
3
3
 
4
+ context "modifing database" do
5
+ let(:db) { Relaton::Db.new "testcache", "testcache2" }
6
+
7
+ before(:each) do
8
+ db.save_entry "ISO(ISO 123)", "<bibitem id='ISO123></bibitem>"
9
+ end
10
+
11
+ context "move to new dir" do
12
+ let(:db) { Relaton::Db.new "global_cache", "local_cache" }
13
+
14
+ after(:each) do
15
+ FileUtils.rm_rf "global_cache"
16
+ FileUtils.rm_rf "local_cache"
17
+ end
18
+
19
+ it "global cache" do
20
+ expect(File.exist?("global_cache")).to be true
21
+ expect(db.mv("testcache")).to eq "testcache"
22
+ expect(File.exist?("testcache")).to be true
23
+ expect(File.exist?("global_cache")).to be false
24
+ end
25
+
26
+ it "local cache" do
27
+ expect(File.exist?("local_cache")).to be true
28
+ expect(db.mv("testcache2", type: :local)).to eq "testcache2"
29
+ expect(File.exist?("testcache2")).to be true
30
+ expect(File.exist?("local_cache")).to be false
31
+ end
32
+ end
33
+
34
+ it "warn if moving in existed dir" do
35
+ expect(File).to receive(:exist?).with("new_cache_dir")
36
+ .and_return true
37
+ expect do
38
+ expect(db.mv("new_cache_dir")).to be_nil
39
+ end.to output(/\[relaton\] WARNING: target directory exists/).to_stderr
40
+ end
41
+
42
+ it "clear" do
43
+ expect(File.exist?("testcache/iso")).to be true
44
+ expect(File.exist?("testcache2/iso")).to be true
45
+ db.clear
46
+ expect(File.exist?("testcache/iso")).to be false
47
+ expect(File.exist?("testcache2/iso")).to be false
48
+ end
49
+ end
50
+
51
+ context "query in local DB" do
52
+ let(:db) { Relaton::Db.new "testcache", "testcache2" }
53
+
54
+ before(:each) do
55
+ db.save_entry "ISO(ISO 123)", <<~DOC
56
+ <bibitem id='ISO123'>
57
+ <title>The first test</title><edition>2</edition><date type="published"><on>2011-10-12</on></date>
58
+ </bibitem>
59
+ DOC
60
+ db.save_entry "IEC(IEC 123)", <<~DOC
61
+ <bibitem id="IEC123">
62
+ <title>The second test</title><edition>1</edition><date type="published"><on>2015-12</on></date>
63
+ </bibitem>
64
+ DOC
65
+ end
66
+
67
+ after(:each) { db.clear }
68
+
69
+ it "one document" do
70
+ item = db.fetch_db "ISO((ISO 124)"
71
+ expect(item).to be_nil
72
+ item = db.fetch_db "ISO(ISO 123)"
73
+ expect(item).to be_instance_of RelatonIsoBib::IsoBibliographicItem
74
+ end
75
+
76
+ it "all documents" do
77
+ items = db.fetch_all
78
+ expect(items.size).to be 9
79
+ expect(items[7]).to be_instance_of RelatonIec::IecBibliographicItem
80
+ expect(items[8]).to be_instance_of RelatonIsoBib::IsoBibliographicItem
81
+ end
82
+
83
+ context "search for text" do
84
+ it do
85
+ items = db.fetch_all "test"
86
+ expect(items.size).to eq 2
87
+ items = db.fetch_all "first"
88
+ expect(items.size).to eq 1
89
+ expect(items[0].id).to eq "ISO123"
90
+ end
91
+
92
+ it "in attributes" do
93
+ items = db.fetch_all "123"
94
+ expect(items.size).to eq 2
95
+ items = db.fetch_all "ISO"
96
+ expect(items.size).to eq 8
97
+ expect(items[7].id).to eq "ISO123"
98
+ end
99
+
100
+ it "and fail" do
101
+ items = db.fetch_all "bibitem"
102
+ expect(items.size).to eq 0
103
+ end
104
+
105
+ it "and edition" do
106
+ items = db.fetch_all "123", edition: "2"
107
+ expect(items.size).to eq 1
108
+ expect(items[0].id).to eq "ISO123"
109
+ end
110
+
111
+ it "and year" do
112
+ items = db.fetch_all "123", year: 2015
113
+ expect(items.size).to eq 1
114
+ expect(items[0].id).to eq "IEC123"
115
+ end
116
+ end
117
+ end
118
+
4
119
  it "returns docid type" do
5
120
  db = Relaton::Db.new "testcache", "testcache2"
6
121
  expect(db.docid_type("CN(GB/T 1.1)")).to eq ["Chinese Standard", "GB/T 1.1"]
@@ -30,6 +145,36 @@ RSpec.describe Relaton::Db do
30
145
  end
31
146
  end
32
147
 
148
+ it "fetch document with net retries" do
149
+ db = Relaton::Db.new nil, nil
150
+ expect(db.instance_variable_get(:@registry).processors[:relaton_ietf]).to receive(:get)
151
+ .and_raise(RelatonBib::RequestError).exactly(3).times
152
+ expect { db.fetch "RFC 8341", nil, retries: 3 }.to raise_error RelatonBib::RequestError
153
+ end
154
+
155
+ context "async fetch" do
156
+ let(:db) { Relaton::Db.new nil, nil }
157
+ let(:queue) { Queue.new }
158
+
159
+ it "success" do
160
+ result = nil
161
+ VCR.use_cassette "rfc_8341" do
162
+ db.fetch_async("RFC 8341") { |r| queue << r }
163
+ Timeout.timeout(5) { result = queue.pop }
164
+ end
165
+ expect(result).to be_instance_of RelatonIetf::IetfBibliographicItem
166
+ end
167
+
168
+ it "prefix not found" do
169
+ result = ""
170
+ VCR.use_cassette "rfc_unsuccess" do
171
+ db.fetch_async("ABC 123456") { |r| queue << r }
172
+ Timeout.timeout(5) { result = queue.pop }
173
+ end
174
+ expect(result).to be_nil
175
+ end
176
+ end
177
+
33
178
  context "fetch documents form static cache" do
34
179
  let(:db) { Relaton::Db.new nil, nil }
35
180
 
@@ -23,5 +23,9 @@ RSpec.describe Relaton::Processor do
23
23
  it "hash_to_bib method should be implemented" do
24
24
  expect { subject.hash_to_bib({}) }.to raise_error StandardError
25
25
  end
26
+
27
+ it "grammar_hash method should be implemented" do
28
+ expect { subject.grammar_hash }.to raise_error StandardError
29
+ end
26
30
  end
27
31
  end
@@ -3,7 +3,7 @@ RSpec.describe Relaton::Registry do
3
3
  stub_const "Relaton::Registry::SUPPORTED_GEMS", ["not_supported_gem"]
4
4
  expect { Relaton::Registry.clone.instance }.to output(
5
5
  /backend not_supported_gem not present/
6
- ).to_stdout
6
+ ).to_stderr
7
7
  end
8
8
 
9
9
  it "finds ISO processor" do
@@ -15,63 +15,69 @@ RSpec.describe Relaton::Registry do
15
15
  expect(Relaton::Registry.instance.supported_processors).to include :relaton_iso
16
16
  end
17
17
 
18
- it "finds processor by type" do
19
- expect(Relaton::Registry.instance.by_type("CN")).to be_instance_of RelatonGb::Processor
20
- end
18
+ context "finds processor by type" do
19
+ it "CN" do
20
+ expect(Relaton::Registry.instance.by_type("CN")).to be_instance_of RelatonGb::Processor
21
+ end
21
22
 
22
- it "finds processor by type" do
23
- expect(Relaton::Registry.instance.by_type("IEC")).to be_instance_of RelatonIec::Processor
24
- end
23
+ it "IEC" do
24
+ expect(Relaton::Registry.instance.by_type("IEC")).to be_instance_of RelatonIec::Processor
25
+ end
25
26
 
26
- it "finds processor by type" do
27
- expect(Relaton::Registry.instance.by_type("IETF")).to be_instance_of RelatonIetf::Processor
28
- end
27
+ it "IETF" do
28
+ expect(Relaton::Registry.instance.by_type("IETF")).to be_instance_of RelatonIetf::Processor
29
+ end
29
30
 
30
- it "finds processor by type" do
31
- expect(Relaton::Registry.instance.by_type("ISO")).to be_instance_of RelatonIso::Processor
32
- end
31
+ it "ISO" do
32
+ expect(Relaton::Registry.instance.by_type("ISO")).to be_instance_of RelatonIso::Processor
33
+ end
33
34
 
34
- it "finds processor by type" do
35
- expect(Relaton::Registry.instance.by_type("ITU")).to be_instance_of RelatonItu::Processor
36
- end
35
+ it "ITU" do
36
+ expect(Relaton::Registry.instance.by_type("ITU")).to be_instance_of RelatonItu::Processor
37
+ end
37
38
 
38
- it "finds processor by type" do
39
- expect(Relaton::Registry.instance.by_type("NIST")).to be_instance_of RelatonNist::Processor
40
- end
39
+ it "NIST" do
40
+ expect(Relaton::Registry.instance.by_type("NIST")).to be_instance_of RelatonNist::Processor
41
+ end
41
42
 
42
- it "finds processor by type" do
43
- expect(Relaton::Registry.instance.by_type("OGC")).to be_instance_of RelatonOgc::Processor
44
- end
43
+ it "OGC" do
44
+ expect(Relaton::Registry.instance.by_type("OGC")).to be_instance_of RelatonOgc::Processor
45
+ end
45
46
 
46
- it "finds processor by type" do
47
- expect(Relaton::Registry.instance.by_type("CC")).to be_instance_of RelatonCalconnect::Processor
48
- end
47
+ it "CC" do
48
+ expect(Relaton::Registry.instance.by_type("CC")).to be_instance_of RelatonCalconnect::Processor
49
+ end
49
50
 
50
- it "finds processor by type" do
51
- expect(Relaton::Registry.instance.by_type("OMG")).to be_instance_of RelatonOmg::Processor
52
- end
51
+ it "OMG" do
52
+ expect(Relaton::Registry.instance.by_type("OMG")).to be_instance_of RelatonOmg::Processor
53
+ end
53
54
 
54
- it "finds processor by type" do
55
- expect(Relaton::Registry.instance.by_type("UN")).to be_instance_of RelatonUn::Processor
56
- end
55
+ it "UN" do
56
+ expect(Relaton::Registry.instance.by_type("UN")).to be_instance_of RelatonUn::Processor
57
+ end
57
58
 
58
- it "finds processor by type" do
59
- expect(Relaton::Registry.instance.by_type("W3C")).to be_instance_of RelatonW3c::Processor
60
- end
59
+ it "W3C" do
60
+ expect(Relaton::Registry.instance.by_type("W3C")).to be_instance_of RelatonW3c::Processor
61
+ end
61
62
 
62
- it "finds processor by type" do
63
- expect(Relaton::Registry.instance.by_type("IEEE")).to be_instance_of RelatonIeee::Processor
64
- end
63
+ it "IEEE" do
64
+ expect(Relaton::Registry.instance.by_type("IEEE")).to be_instance_of RelatonIeee::Processor
65
+ end
65
66
 
66
- it "finds processor by type" do
67
- expect(Relaton::Registry.instance.by_type("IHO")).to be_instance_of RelatonIho::Processor
68
- end
67
+ it "IHO" do
68
+ expect(Relaton::Registry.instance.by_type("IHO")).to be_instance_of RelatonIho::Processor
69
+ end
69
70
 
70
- it "finds processor by type" do
71
- expect(Relaton::Registry.instance.by_type("BIPM")).to be_instance_of RelatonBipm::Processor
72
- end
71
+ it "BIPM" do
72
+ expect(Relaton::Registry.instance.by_type("BIPM")).to be_instance_of RelatonBipm::Processor
73
+ end
74
+
75
+ it "ECMA" do
76
+ expect(Relaton::Registry.instance.by_type("ECMA")).to be_instance_of RelatonEcma::Processor
77
+ end
73
78
 
74
- it "finds processor by type" do
75
- expect(Relaton::Registry.instance.by_type("ECMA")).to be_instance_of RelatonEcma::Processor
79
+ it "CIE" do
80
+ expect(Relaton::Registry.instance.by_type("CIE")).to be_instance_of RelatonCie::Processor
81
+ end
76
82
  end
77
83
  end