relaton 1.7.9 → 1.8.pre2

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 +1 -1
  3. data/.rubocop.yml +1 -1
  4. data/lib/relaton.rb +3 -0
  5. data/lib/relaton/config.rb +4 -2
  6. data/lib/relaton/db.rb +106 -52
  7. data/lib/relaton/db_cache.rb +38 -125
  8. data/lib/relaton/registry.rb +1 -0
  9. data/lib/relaton/storage.rb +186 -0
  10. data/lib/relaton/version.rb +1 -1
  11. data/relaton.gemspec +23 -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/storage_spec.rb +130 -0
  16. data/spec/relaton_spec.rb +48 -7
  17. data/spec/spec_helper.rb +4 -0
  18. data/spec/vcr_cassetes/19133_2005.yml +17 -17
  19. data/spec/vcr_cassetes/api_relaton_org.yml +33 -0
  20. data/spec/vcr_cassetes/api_relaton_org_unavailable.yml +182 -0
  21. data/spec/vcr_cassetes/async_fetch.yml +2037 -1606
  22. data/spec/vcr_cassetes/bsi_bs_en_iso_8848.yml +17 -17
  23. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +10 -10
  24. data/spec/vcr_cassetes/cen_en_10160_1999.yml +249 -0
  25. data/spec/vcr_cassetes/cie_001_1980.yml +7 -7
  26. data/spec/vcr_cassetes/ecma_6.yml +7 -7
  27. data/spec/vcr_cassetes/fisp_140.yml +4 -4
  28. data/spec/vcr_cassetes/gb_t_20223_2006.yml +9 -9
  29. data/spec/vcr_cassetes/iec_60050_102_2007.yml +23 -23
  30. data/spec/vcr_cassetes/iec_combined_included.yml +81 -79
  31. data/spec/vcr_cassetes/ieee_528_2019.yml +38 -38
  32. data/spec/vcr_cassetes/iho_b_11.yml +7 -7
  33. data/spec/vcr_cassetes/iso_111111119115_1.yml +3 -3
  34. data/spec/vcr_cassetes/iso_19115.yml +19 -19
  35. data/spec/vcr_cassetes/iso_19115_1.yml +18 -18
  36. data/spec/vcr_cassetes/iso_19115_1_2.yml +35 -35
  37. data/spec/vcr_cassetes/iso_awi_14093.yml +182 -0
  38. data/spec/vcr_cassetes/iso_combined_applied.yml +38 -38
  39. data/spec/vcr_cassetes/iso_combined_included.yml +34 -34
  40. data/spec/vcr_cassetes/itu_combined_included.yml +456 -459
  41. data/spec/vcr_cassetes/ogc_19_025r1.yml +1222 -1163
  42. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +43 -0
  43. data/spec/vcr_cassetes/rfc_8341.yml +7 -7
  44. data/spec/vcr_cassetes/sp_800_38b.yml +4 -4
  45. data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +29 -29
  46. data/spec/vcr_cassetes/w3c_json_ld11.yml +17 -17
  47. metadata +107 -46
  48. data/spec/vcr_cassetes/iso_awi_24229.yml +0 -182
  49. data/spec/vcr_cassetes/ogm_ami4ccm_1_0.yml +0 -43
@@ -9,6 +9,7 @@ module Relaton
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
11
  relaton_ieee relaton_iho relaton_bipm relaton_ecma relaton_cie relaton_bsi
12
+ relaton_cen
12
13
  ].freeze
13
14
 
14
15
  include Singleton
@@ -0,0 +1,186 @@
1
+ require "aws-sdk-s3"
2
+
3
+ module Relaton
4
+ #
5
+ # Man
6
+ #
7
+ class Storage
8
+ include Singleton
9
+
10
+ def initialize
11
+ if Relaton.configuration.api_mode
12
+ @s3 = Aws::S3::Client.new
13
+ end
14
+ end
15
+
16
+ #
17
+ # Save file to storage
18
+ #
19
+ # @param dir [String]
20
+ # @param key [String]
21
+ # @param value [String]
22
+ #
23
+ def save(dir, key, value)
24
+ set_version dir
25
+ if Relaton.configuration.api_mode then s3_write key, value
26
+ else file_safe_write key, value
27
+ end
28
+ end
29
+
30
+ #
31
+ # Returns all items
32
+ #
33
+ # @param dir [String]
34
+ #
35
+ # @return [Array<String>]
36
+ #
37
+ def all(dir, &block)
38
+ return all_s3 dir, &block if Relaton.configuration.api_mode
39
+
40
+ Dir.glob("#{dir}/**/*.{xml,yml,yaml}").sort.map do |f|
41
+ content = File.read(f, encoding: "utf-8")
42
+ block ? yield(f, content) : content
43
+ end
44
+ end
45
+
46
+ # Delete item
47
+ # @param key [String] path to file without extension
48
+ def delete(key)
49
+ f = search_ext(key)
50
+ if Relaton.configuration.api_mode && f
51
+ @s3.delete_object bucket: ENV["AWS_BUCKET"], key: f
52
+ elsif f then File.delete f
53
+ end
54
+ end
55
+
56
+ # Check if version of the DB match to the gem grammar hash.
57
+ # @param fdir [String] dir pathe to flavor cache
58
+ # @return [Boolean]
59
+ def check_version?(fdir)
60
+ file_version = "#{fdir}/version"
61
+ if Relaton.configuration.api_mode
62
+ check_version_s3? file_version, fdir
63
+ else
64
+ return false unless File.exist? fdir
65
+
66
+ v = File.read file_version, encoding: "utf-8"
67
+ v.strip == grammar_hash(fdir)
68
+ end
69
+ end
70
+
71
+ # Reads file by a key
72
+ #
73
+ # @param key [String]
74
+ # @return [String, NilClass]
75
+ def get(key, static: false)
76
+ return unless (f = search_ext(key, static: static))
77
+
78
+ if Relaton.configuration.api_mode && !static
79
+ s3_read f
80
+ else
81
+ File.read(f, encoding: "utf-8")
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ # Check if version of the DB match to the gem grammar hash.
88
+ # @param file_version [String] dir pathe to flover cache
89
+ # @param dir [String] fdir pathe to flavor cache
90
+ # @return [Boolean]
91
+ def check_version_s3?(file_version, fdir)
92
+ s3_read(file_version) == grammar_hash(fdir)
93
+ rescue Aws::S3::Errors::NoSuchKey
94
+ false
95
+ end
96
+
97
+ #
98
+ # Read file form AWS S#
99
+ #
100
+ # @param [String] key file name
101
+ #
102
+ # @return [String] content
103
+ #
104
+ def s3_read(key)
105
+ obj = @s3.get_object bucket: ENV["AWS_BUCKET"], key: key
106
+ obj.body.read
107
+ end
108
+
109
+ #
110
+ # Write file to AWS S3
111
+ #
112
+ # @param [String] key
113
+ # @param [String] value
114
+ #
115
+ def s3_write(key, value)
116
+ @s3.put_object(bucket: ENV["AWS_BUCKET"], key: key, body: value,
117
+ content_type: "text/plain; charset=utf-8")
118
+ end
119
+
120
+ #
121
+ # Returns all items
122
+ #
123
+ # @param dir [String]
124
+ #
125
+ # @return [Array<String>]
126
+ #
127
+ def all_s3(dir)
128
+ list = @s3.list_objects_v2 bucket: ENV["AWS_BUCKET"], prefix: dir
129
+ list.contents.select { |i| i.key.match?(/\.xml$/) }.sort_by(&:key).map do |item|
130
+ content = s3_read item.key
131
+ block_given? ? yield(item.key, content) : content
132
+ end
133
+ end
134
+
135
+ #
136
+ # Checks if there is file with xml or txt extension and return filename with
137
+ # the extension.
138
+ #
139
+ # @param file [String]
140
+ # @return [String, NilClass]
141
+ def search_ext(file, static: false)
142
+ if Relaton.configuration.api_mode && !static
143
+ fs = @s3.list_objects_v2 bucket: ENV["AWS_BUCKET"], prefix: "#{file}."
144
+ fs.contents.first&.key
145
+ else
146
+ Dir["#{file}.*"].first
147
+ end
148
+ end
149
+
150
+ # Set version of the DB to the gem grammar hash.
151
+ # @param fdir [String] dir pathe to flover cache
152
+ def set_version(fdir)
153
+ file_version = "#{fdir}/version"
154
+ return set_version_s3 file_version, fdir if Relaton.configuration.api_mode
155
+
156
+ FileUtils::mkdir_p fdir unless Dir.exist?(fdir)
157
+ unless File.exist? file_version
158
+ file_safe_write file_version, grammar_hash(fdir)
159
+ end
160
+ end
161
+
162
+ # Set version of the DB to the gem grammar hash.
163
+ # @param fdir [String] dir pathe to flover cache
164
+ def set_version_s3(fver, dir)
165
+ @s3.head_object bucket: ENV["AWS_BUCKET"], key: fver
166
+ rescue Aws::S3::Errors::NotFound
167
+ s3_write fver, grammar_hash(dir)
168
+ end
169
+
170
+ # @param file [String]
171
+ # @content [String]
172
+ def file_safe_write(file, content)
173
+ File.open file, File::RDWR | File::CREAT, encoding: "UTF-8" do |f|
174
+ Timeout.timeout(10) { f.flock File::LOCK_EX }
175
+ f.write content
176
+ end
177
+ end
178
+
179
+ # @param fdir [String] dir pathe to flover cache
180
+ # @return [String]
181
+ def grammar_hash(fdir)
182
+ type = fdir.split("/").last
183
+ Relaton::Registry.instance.by_type(type)&.grammar_hash
184
+ end
185
+ end
186
+ end
@@ -1,3 +1,3 @@
1
1
  module Relaton
2
- VERSION = "1.7.9".freeze
2
+ VERSION = "1.8.pre2".freeze
3
3
  end
data/relaton.gemspec CHANGED
@@ -27,26 +27,28 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ["lib"]
28
28
  spec.files = `git ls-files`.split("\n")
29
29
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
30
- spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
30
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
31
31
 
32
32
  # spec.add_dependency "algoliasearch"
33
- spec.add_dependency "relaton-bipm", "~> 1.7.0"
34
- spec.add_dependency "relaton-bsi", "~> 1.7.pre"
35
- spec.add_dependency "relaton-calconnect", "~> 1.7.0"
36
- spec.add_dependency "relaton-cie", "~> 1.7.pre1"
37
- spec.add_dependency "relaton-ecma", "~> 1.7.pre1"
38
- spec.add_dependency "relaton-gb", "~> 1.7.0"
39
- spec.add_dependency "relaton-iec", ">= 1.7.6"
40
- spec.add_dependency "relaton-ieee", "~> 1.7.0"
41
- spec.add_dependency "relaton-ietf", "~> 1.7.0"
42
- spec.add_dependency "relaton-iho", "~> 1.7.0"
43
- spec.add_dependency "relaton-iso", ">= 1.7.1"
44
- spec.add_dependency "relaton-itu", ">= 1.7.2"
45
- spec.add_dependency "relaton-nist", ">= 1.7.1"
46
- spec.add_dependency "relaton-ogc", "~> 1.7.0"
47
- spec.add_dependency "relaton-omg", "~> 1.7.0"
48
- spec.add_dependency "relaton-un", "~> 1.7.0"
49
- spec.add_dependency "relaton-w3c", "~> 1.7.0"
33
+ spec.add_dependency "aws-sdk-s3", "~> 1.96.0"
34
+ spec.add_dependency "relaton-bipm", "~> 1.8.0"
35
+ spec.add_dependency "relaton-bsi", "~> 1.8.0"
36
+ spec.add_dependency "relaton-calconnect", "~> 1.8.0"
37
+ spec.add_dependency "relaton-cen", "~> 1.8.pre1"
38
+ spec.add_dependency "relaton-cie", "~> 1.8.0"
39
+ spec.add_dependency "relaton-ecma", "~> 1.8.0"
40
+ spec.add_dependency "relaton-gb", "~> 1.8.0"
41
+ spec.add_dependency "relaton-iec", ">= 1.8.0"
42
+ spec.add_dependency "relaton-ieee", "~> 1.8.0"
43
+ spec.add_dependency "relaton-ietf", "~> 1.8.0"
44
+ spec.add_dependency "relaton-iho", "~> 1.8.0"
45
+ spec.add_dependency "relaton-iso", ">= 1.8.0"
46
+ spec.add_dependency "relaton-itu", ">= 1.8.0"
47
+ spec.add_dependency "relaton-nist", ">= 1.8.0"
48
+ spec.add_dependency "relaton-ogc", "~> 1.8.0"
49
+ spec.add_dependency "relaton-omg", "~> 1.8.0"
50
+ spec.add_dependency "relaton-un", "~> 1.8.0"
51
+ spec.add_dependency "relaton-w3c", "~> 1.8.0"
50
52
 
51
53
  spec.add_development_dependency "byebug", "~> 11.0"
52
54
  # spec.add_development_dependency "debase"
@@ -56,7 +58,9 @@ Gem::Specification.new do |spec|
56
58
  spec.add_development_dependency "pry-byebug", "~> 3.9.0"
57
59
  spec.add_development_dependency "rake", "~> 13.0"
58
60
  spec.add_development_dependency "rspec", "~> 3.6"
59
- spec.add_development_dependency "rubocop", "= 0.54.0"
61
+ spec.add_development_dependency "rubocop", "~> 1.17.0"
62
+ spec.add_development_dependency "rubocop-performance", "~> 1.11.0"
63
+ spec.add_development_dependency "rubocop-rails", "~> 2.10.0"
60
64
  # spec.add_development_dependency "ruby-debug-ide"
61
65
  spec.add_development_dependency "simplecov", "~> 0.15"
62
66
  spec.add_development_dependency "timecop", "~> 0.9"
@@ -6,8 +6,8 @@ RSpec.describe Relaton::DbCache do
6
6
  cache_path = File.expand_path("~/.relaton/cache")
7
7
  FileUtils.mv cache_path, "relaton1/cache", force: true
8
8
  FileUtils.rm_rf %w(relaton)
9
- Relaton::DbCache.init_bib_caches(
10
- global_cache: true, local_cache: "", flush_caches: true
9
+ Relaton::Db.init_bib_caches(
10
+ global_cache: true, local_cache: "", flush_caches: true,
11
11
  )
12
12
  expect(File.exist?(cache_path)).to be true
13
13
  expect(File.exist?("relaton")).to be true
@@ -1,6 +1,23 @@
1
1
  RSpec.describe Relaton::Db do
2
2
  before(:each) { FileUtils.rm_rf %w[testcache testcache2] }
3
3
 
4
+ context "initialization in API mode" do
5
+ before(:each) { Relaton.configure { |c| c.api_mode = true } }
6
+ after(:each) { Relaton.configure { |c| c.api_mode = false } }
7
+
8
+ it do
9
+ db = Relaton::Db.new "cache", nil
10
+ cache = db.instance_variable_get :@db
11
+ expect(cache.dir).to eq "cache"
12
+ end
13
+
14
+ it "with default cache directory" do
15
+ db = Relaton::Db.init_bib_caches global_cache: true
16
+ cache = db.instance_variable_get :@db
17
+ expect(cache.dir).to eq "cache"
18
+ end
19
+ end
20
+
4
21
  context "modifing database" do
5
22
  let(:db) { Relaton::Db.new "testcache", "testcache2" }
6
23
 
@@ -2,7 +2,7 @@ RSpec.describe Relaton::Registry do
2
2
  it "outputs backend not present" do
3
3
  stub_const "Relaton::Registry::SUPPORTED_GEMS", ["not_supported_gem"]
4
4
  expect { Relaton::Registry.clone.instance }.to output(
5
- /backend not_supported_gem not present/
5
+ /backend not_supported_gem not present/,
6
6
  ).to_stderr
7
7
  end
8
8
 
@@ -79,5 +79,13 @@ RSpec.describe Relaton::Registry do
79
79
  it "CIE" do
80
80
  expect(Relaton::Registry.instance.by_type("CIE")).to be_instance_of RelatonCie::Processor
81
81
  end
82
+
83
+ it "BSI" do
84
+ expect(Relaton::Registry.instance.by_type("BSI")).to be_instance_of RelatonBsi::Processor
85
+ end
86
+
87
+ it "CEN" do
88
+ expect(Relaton::Registry.instance.by_type("CEN")).to be_instance_of RelatonCen::Processor
89
+ end
82
90
  end
83
91
  end
@@ -0,0 +1,130 @@
1
+ RSpec.describe Relaton::Storage do
2
+ context "API mode" do
3
+ before(:each) do
4
+ Relaton.configure do |config|
5
+ config.api_mode = true
6
+ end
7
+ Singleton.__init__ Relaton::Storage
8
+ end
9
+
10
+ after(:each) do
11
+ Relaton.configure do |config|
12
+ config.api_mode = false
13
+ end
14
+ Singleton.__init__ Relaton::Storage
15
+ end
16
+
17
+ let(:storage) { Relaton::Storage.instance }
18
+ let(:bucket) { "test-bucket" }
19
+
20
+ it "save document to S3" do
21
+ dir = "cahche/iso"
22
+ # file = "doc.xml"
23
+ body = "<doc>Test doc</doc>"
24
+ key = File.join dir, "doc.xml"
25
+ client = double "AwsClient"
26
+ expect(ENV).to receive(:[]).with("AWS_BUCKET").and_return(bucket).twice
27
+ expect(client).to receive(:head_object).with(bucket: bucket, key: "cahche/iso/version")
28
+ expect(client).to receive(:put_object).with(
29
+ bucket: bucket, key: key, body: body,
30
+ content_type: "text/plain; charset=utf-8"
31
+ )
32
+ expect(Aws::S3::Client).to receive(:new).and_return client
33
+ storage.save dir, key, body
34
+ end
35
+
36
+ it "read document from S3" do
37
+ dir = "cahche/iso"
38
+ # file = "doc.xml"
39
+ body = "<doc>Test doc</doc>"
40
+ key = File.join dir, "doc"
41
+ client = double "AwsClient"
42
+ item = double "Item", key: "#{key}.xml"
43
+ list = double "List", contents: [item]
44
+ obj_body = double "Body", read: body
45
+ obj = double "Object", body: obj_body
46
+ expect(ENV).to receive(:[]).with("AWS_BUCKET").and_return(bucket).twice
47
+ expect(client).to receive(:list_objects_v2).with(bucket: bucket, prefix: "#{key}.").and_return list
48
+ expect(client).to receive(:get_object).with(bucket: bucket, key: "#{key}.xml").and_return obj
49
+ expect(Aws::S3::Client).to receive(:new).and_return client
50
+ expect(storage.get(key)).to eq body
51
+ end
52
+
53
+ it "delete document from S3" do
54
+ key = "cache/iso/doc"
55
+ client = double "AwsClient"
56
+ item = double "Item", key: "#{key}.xml"
57
+ list = double "List", contents: [item]
58
+ expect(ENV).to receive(:[]).with("AWS_BUCKET").and_return(bucket).twice
59
+ expect(client).to receive(:list_objects_v2).with(bucket: bucket, prefix: "#{key}.").and_return list
60
+ expect(client).to receive(:delete_object).with(bucket: bucket, key: "#{key}.xml")
61
+ expect(Aws::S3::Client).to receive(:new).and_return client
62
+ storage.delete key
63
+ end
64
+
65
+ it "return all the documents from S3" do
66
+ dir = "cahche/iso"
67
+ # file = "doc.xml"
68
+ body = "<doc>Test doc</doc>"
69
+ key = File.join dir, "doc.xml"
70
+ client = double "AwsClient"
71
+ expect(ENV).to receive(:[]).with("AWS_BUCKET").and_return(bucket).twice
72
+ item = double "Item", key: key
73
+ list = double "List", contents: [item]
74
+ obj_body = double "Body", read: body
75
+ obj = double "Object", body: obj_body
76
+ expect(client).to receive(:list_objects_v2).with(bucket: bucket, prefix: dir).and_return list
77
+ expect(client).to receive(:get_object).with(bucket: bucket, key: key).and_return obj
78
+ expect(Aws::S3::Client).to receive(:new).and_return client
79
+ contents = storage.all dir
80
+ expect(contents).to eq [body]
81
+ end
82
+
83
+ it "set version" do
84
+ dir = "cahche/iso"
85
+ key = File.join dir, "version"
86
+ hash = Relaton::Registry.instance.by_type("iso").grammar_hash
87
+ client = double "AwsClient"
88
+ expect(ENV).to receive(:[]).with("AWS_BUCKET").and_return(bucket).twice
89
+ # expect(ENV).to receive(:[]).and_call_original
90
+ error = Aws::S3::Errors::NotFound.new Seahorse::Client::RequestContext.new, ""
91
+ expect(client).to receive(:head_object).with(bucket: bucket, key: key)
92
+ .and_raise error
93
+ expect(client).to receive(:put_object).with(
94
+ bucket: bucket, key: key, body: hash,
95
+ content_type: "text/plain; charset=utf-8"
96
+ )
97
+ expect(Aws::S3::Client).to receive(:new).and_return client
98
+ storage.send :set_version, dir
99
+ end
100
+
101
+ context "check version" do
102
+ it "valid" do
103
+ dir = "cahche/iso"
104
+ key = File.join dir, "version"
105
+ hash = Relaton::Registry.instance.by_type("iso").grammar_hash
106
+ client = double "AwsClient"
107
+ obj_body = double "Body", read: hash
108
+ obj = double "Object", body: obj_body
109
+ expect(client).to receive(:get_object).with(bucket: bucket, key: key).and_return obj
110
+ expect(Aws::S3::Client).to receive(:new).and_return client
111
+ expect(ENV).to receive(:[]).with("AWS_BUCKET").and_return(bucket)
112
+ expect(storage.check_version?(dir)).to be true
113
+ end
114
+
115
+ it "version file doesn't exist" do
116
+ dir = "cahche/iso"
117
+ key = File.join dir, "version"
118
+ # hash = "invalid"
119
+ client = double "AwsClient"
120
+ # obj_body = double "Body", read: hash
121
+ # obj = double "Object", body: obj_body
122
+ error = Aws::S3::Errors::NoSuchKey.new Seahorse::Client::RequestContext.new, ""
123
+ expect(client).to receive(:get_object).with(bucket: bucket, key: key).and_raise error
124
+ expect(Aws::S3::Client).to receive(:new).and_return client
125
+ expect(ENV).to receive(:[]).with("AWS_BUCKET").and_return(bucket)
126
+ expect(storage.check_version?(dir)).to be false
127
+ end
128
+ end
129
+ end
130
+ end