relaton 1.11.4 → 1.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/relaton/db.rb +61 -31
  3. data/lib/relaton/db_cache.rb +7 -1
  4. data/lib/relaton/version.rb +1 -1
  5. data/relaton.gemspec +21 -21
  6. data/spec/relaton/db_spec.rb +51 -1
  7. data/spec/spec_helper.rb +1 -0
  8. data/spec/vcr_cassetes/3gpp_tr_00_01u_umts_3_0_0.yml +7 -7
  9. data/spec/vcr_cassetes/async_fetch.yml +1402 -1402
  10. data/spec/vcr_cassetes/bipm_i18n_async_fetch.yml +51 -259
  11. data/spec/vcr_cassetes/bsi_bs_en_iso_8848.yml +11 -11
  12. data/spec/vcr_cassetes/cc_dir_10005_2019.yml +10 -10
  13. data/spec/vcr_cassetes/cie_001_1980.yml +10 -9
  14. data/spec/vcr_cassetes/ecma_6.yml +47 -15
  15. data/spec/vcr_cassetes/en_10160_1999.yml +27 -27
  16. data/spec/vcr_cassetes/fisp_140.yml +6 -6
  17. data/spec/vcr_cassetes/gb_t_20223_2006.yml +6 -6
  18. data/spec/vcr_cassetes/iana_service_names_port_numbers.yml +10 -13
  19. data/spec/vcr_cassetes/iec_60050_102_2007.yml +28 -28
  20. data/spec/vcr_cassetes/iec_combined_included.yml +88 -88
  21. data/spec/vcr_cassetes/ieee_528_2019.yml +823 -1133
  22. data/spec/vcr_cassetes/iho_b_11.yml +7 -7
  23. data/spec/vcr_cassetes/iso_111111119115_1.yml +2 -2
  24. data/spec/vcr_cassetes/iso_19115_1.yml +16 -16
  25. data/spec/vcr_cassetes/iso_19115_1_2.yml +29 -29
  26. data/spec/vcr_cassetes/iso_19115_all_parts.yml +15 -15
  27. data/spec/vcr_cassetes/iso_19133_2005.yml +15 -15
  28. data/spec/vcr_cassetes/iso_combined_applied.yml +30 -30
  29. data/spec/vcr_cassetes/iso_combined_included.yml +31 -31
  30. data/spec/vcr_cassetes/iso_dis_14093.yml +14 -14
  31. data/spec/vcr_cassetes/itu_combined_included.yml +168 -168
  32. data/spec/vcr_cassetes/oasis_amqp_core_types_v1_0_pt1.yml +9 -9
  33. data/spec/vcr_cassetes/ogc_19_025r1.yml +7 -7
  34. data/spec/vcr_cassetes/omg_ami4ccm_1_0.yml +4 -4
  35. data/spec/vcr_cassetes/rfc_8341.yml +10 -10
  36. data/spec/vcr_cassetes/sp_800_38b.yml +6 -6
  37. data/spec/vcr_cassetes/threads_from_env.yml +56 -56
  38. data/spec/vcr_cassetes/un_rtade_cefact_2004_32.yml +31 -29
  39. data/spec/vcr_cassetes/w3c_json_ld11.yml +20 -20
  40. metadata +44 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd53313a7d35f6ed1adf7669962afc84282d15d232247d3facec910aaba05270
4
- data.tar.gz: 304a0e1c5a44731f0a4f9a30c063df920deb8694aca702044fd1ab03a10fe5e8
3
+ metadata.gz: 8299cf7ea6a28e344f438461d16233fe9acd733bc00441583ce9768c702b15fa
4
+ data.tar.gz: 28d87384bb3b763981ae98902b144236254b7cce20c3d608ef746be679b0661a
5
5
  SHA512:
6
- metadata.gz: 4cfb3d708769580fccb31ef09a408265a4b828e70082c7f44a2fe485c2982437cf4f8b8369ada51e7e2d9d3e05c05eada5eaca8126506ea5b9224b7575727501
7
- data.tar.gz: 2255f0695f06f0714e55b03d9a9ad7c2b7567d417ff184e598c462e299aeed145fb6fb143fc9e83aedf7223479addd9542a6ea3d16b17298f55621676100010f
6
+ metadata.gz: 5720aed26b5585b6673d92fd8c99fbae0883689c254344d5dbad5549a157388bd6422a2550942eb58a8d32f1c2d0aeafd6485de55274c0c02271ec5f87661405
7
+ data.tar.gz: 45fca34e30fe15699b9b3933f4060c877d54947ae31c5bc70ff05812b654c0876175eedda1d71ef16755a4db02a797c30199cd2128d081ae46b186a4939964f5
data/lib/relaton/db.rb CHANGED
@@ -95,9 +95,18 @@ module Relaton
95
95
  result
96
96
  end
97
97
 
98
+ #
98
99
  # Fetch asynchronously
99
- def fetch_async(code, year = nil, opts = {}, &block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
100
- stdclass = @registry.class_by_ref code
100
+ #
101
+ # @param [String] ref reference
102
+ # @param [String] year document yer
103
+ # @param [Hash] opts options
104
+ #
105
+ # @return [RelatonBib::BibliographicItem, RelatonBib::RequestError, nil] bibitem if document is found,
106
+ # request error if server doesn't answer, nil if document not found
107
+ #
108
+ def fetch_async(ref, year = nil, opts = {}, &block) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
109
+ stdclass = @registry.class_by_ref ref
101
110
  if stdclass
102
111
  unless @queues[stdclass]
103
112
  processor = @registry.processors[stdclass]
@@ -106,11 +115,14 @@ module Relaton
106
115
  args[3].call fetch(*args[0..2])
107
116
  rescue RelatonBib::RequestError => e
108
117
  args[3].call e
118
+ rescue StandardError => e
119
+ Util.log "[relaton] ERROR: #{args[0]} -- #{e.message}", :error
120
+ args[3].call nil
109
121
  end
110
122
  @queues[stdclass] = { queue: Queue.new, workers_pool: wp }
111
123
  Thread.new { process_queue @queues[stdclass] }
112
124
  end
113
- @queues[stdclass][:queue] << [code, year, opts, block]
125
+ @queues[stdclass][:queue] << [ref, year, opts, block]
114
126
  else yield nil
115
127
  end
116
128
  end
@@ -196,7 +208,7 @@ module Relaton
196
208
  end
197
209
 
198
210
  # @param file [String] file path
199
- # @param content [String] content in XML or YAmL format
211
+ # @param content [String] content in XML or YAML format
200
212
  # @param edition [String, nil] edition to filter
201
213
  # @param year [Integer, nil] year to filter
202
214
  # @return [BibliographicItem, nil]
@@ -205,7 +217,7 @@ module Relaton
205
217
  item = if file.match?(/xml$/) then processor.from_xml(content)
206
218
  else processor.hash_to_bib(YAML.safe_load(content))
207
219
  end
208
- item if (edition.nil? || item.edition == edition) && (year.nil? ||
220
+ item if (edition.nil? || item.edition.content == edition) && (year.nil? ||
209
221
  item.date.detect { |d| d.type == "published" && d.on(:year).to_s == year.to_s })
210
222
  end
211
223
 
@@ -293,8 +305,10 @@ module Relaton
293
305
  [prefix, code]
294
306
  end
295
307
 
308
+ #
296
309
  # @param entry [String] XML string
297
310
  # @param stdclass [Symbol]
311
+ #
298
312
  # @return [nil, RelatonBib::BibliographicItem,
299
313
  # RelatonIsoBib::IsoBibliographicItem, RelatonItu::ItuBibliographicItem,
300
314
  # RelatonIetf::IetfBibliographicItem, RelatonIec::IecBibliographicItem,
@@ -304,9 +318,7 @@ module Relaton
304
318
  # RelatonBipm::BipmBibliographicItem, RelatonIho::IhoBibliographicItem,
305
319
  # RelatonOmg::OmgBibliographicItem, RelatonW3c::W3cBibliographicItem]
306
320
  def bib_retval(entry, stdclass)
307
- if entry.nil? || entry.match?(/^not_found/) then nil
308
- else @registry.processors[stdclass].from_xml(entry)
309
- end
321
+ @registry.processors[stdclass].from_xml(entry) if entry
310
322
  end
311
323
 
312
324
  # @param code [String]
@@ -334,8 +346,7 @@ module Relaton
334
346
  if db.nil?
335
347
  return if opts[:fetch_db]
336
348
 
337
- bibentry = new_bib_entry(searchcode, year, opts, stdclass, db: db,
338
- id: id)
349
+ bibentry = new_bib_entry(searchcode, year, opts, stdclass)
339
350
  return bib_retval(bibentry, stdclass)
340
351
  end
341
352
 
@@ -348,45 +359,58 @@ module Relaton
348
359
  @semaphore.synchronize do
349
360
  db.clone_entry id, altdb if altdb.valid_entry? id, year
350
361
  end
351
- entry = new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id) unless db[id]
362
+ new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
352
363
  @semaphore.synchronize do
353
- db[id] ||= entry
354
364
  altdb.clone_entry(id, db) if !altdb.valid_entry?(id, year)
355
365
  end
356
366
  else
357
367
  return bib_retval(db[id], stdclass) if opts[:fetch_db]
358
368
 
359
- db[id] ||= new_bib_entry(searchcode, year, opts, stdclass, db: db,
360
- id: id)
369
+ new_bib_entry(searchcode, year, opts, stdclass, db: db, id: id)
361
370
  end
362
371
  bib_retval(db[id], stdclass)
363
372
  end
364
373
 
374
+ #
375
+ # Create new bibliographic entry if it doesn't exist in database
376
+ #
365
377
  # @param code [String]
366
378
  # @param year [String]
367
379
  #
368
380
  # @param opts [Hash]
369
- # @option opts [Boolean] :all_parts If all-parts reference is required
370
- # @option opts [Boolean] :keep_year If undated reference should return
371
- # actual reference with year
381
+ # @option opts [Boolean, nil] :all_parts If true then all-parts reference is
382
+ # requested
383
+ # @option opts [Boolean, nil] :keep_year If true then undated reference
384
+ # should return actual reference with year
372
385
  # @option opts [Integer] :retries (1) Number of network retries
373
386
  #
374
387
  # @param stdclass [Symbol]
375
- # @param db [Relaton::DbCache,`NilClass]
376
- # @param id [String] docid
377
- # @return [String]
378
- def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
388
+ # @param db [Relaton::DbCache,`nil]
389
+ # @param id [String, nil] docid
390
+ #
391
+ # @return [String] bibliographic entry
392
+ # XML or "redirection ID" or "not_found YYYY-MM-DD" string
393
+ #
394
+ def new_bib_entry(code, year, opts, stdclass, **args) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
395
+ entry = @semaphore.synchronize { args[:db] && args[:db][args[:id]] }
396
+ if entry
397
+ Util.log "[relaton] (#{code}) not found." if entry&.match?(/^not_found/)
398
+ return entry
399
+ end
400
+
379
401
  bib = net_retry(code, year, opts, stdclass, opts.fetch(:retries, 1))
380
402
  bib_id = bib&.docidentifier&.first&.id
381
403
 
382
404
  # when docid doesn't match bib's id then return a reference to bib's id
383
- if args[:db] && args[:id] &&
384
- bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}}
385
- bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
386
- @semaphore.synchronize { args[:db][bid] ||= bib_entry bib }
387
- "redirection #{bid}"
388
- else bib_entry bib
389
- end
405
+ entry = if args[:db] && args[:id] && bib_id && args[:id] !~ %r{#{Regexp.quote("(#{bib_id})")}}
406
+ bid = std_id(bib.docidentifier.first.id, nil, {}, stdclass).first
407
+ @semaphore.synchronize { args[:db][bid] ||= bib_entry bib }
408
+ "redirection #{bid}"
409
+ else bib_entry bib
410
+ end
411
+ return entry if args[:db].nil? || args[:id].nil?
412
+
413
+ @semaphore.synchronize { args[:db][args[:id]] ||= entry }
390
414
  end
391
415
 
392
416
  # @raise [RelatonBib::RequestError]
@@ -442,10 +466,16 @@ module Relaton
442
466
  end
443
467
 
444
468
  class << self
469
+ #
445
470
  # Initialse and return relaton instance, with local and global cache names
446
- # local_cache: local cache name; none created if nil; "relaton" created
447
- # if empty global_cache: boolean to create global_cache
448
- # flush_caches: flush caches
471
+ #
472
+ # @param local_cache [String, nil] local cache name;
473
+ # "relaton" created if empty or nil
474
+ # @param global_cache [Boolean, nil] create global_cache if true
475
+ # @param flush_caches [Boolean, nil] flush caches if true
476
+ #
477
+ # @return [Relaton::Db] relaton DB instance
478
+ #
449
479
  def init_bib_caches(**opts) # rubocop:disable Metrics/CyclomaticComplexity
450
480
  globalname = global_bibliocache_name if opts[:global_cache]
451
481
  localname = local_bibliocache_name(opts[:local_cache])
@@ -45,7 +45,7 @@ module Relaton
45
45
  end
46
46
 
47
47
  prefix_dir = "#{@dir}/#{prefix(key)}"
48
- FileUtils::mkdir_p prefix_dir unless Dir.exist? prefix_dir
48
+ FileUtils::mkdir_p prefix_dir
49
49
  set_version prefix_dir
50
50
  file_safe_write "#{filename(key)}.#{ext(value)}", value
51
51
  end
@@ -72,6 +72,12 @@ module Relaton
72
72
  end
73
73
  end
74
74
 
75
+ #
76
+ # Save entry from cache of `db` to this cache.
77
+ #
78
+ # @param [String] key key of the entry
79
+ # @param [Relaton::Db] db database
80
+ #
75
81
  def clone_entry(key, db)
76
82
  self[key] ||= db.get(key)
77
83
  if (code = redirect? get(key))
@@ -1,3 +1,3 @@
1
1
  module Relaton
2
- VERSION = "1.11.4".freeze
2
+ VERSION = "1.12.1".freeze
3
3
  end
data/relaton.gemspec CHANGED
@@ -29,27 +29,27 @@ Gem::Specification.new do |spec|
29
29
  # spec.test_files = `git ls-files -- {spec}/*`.split("\n")
30
30
  spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
31
31
 
32
- spec.add_dependency "relaton-3gpp", "~> 1.11.0"
33
- spec.add_dependency "relaton-bipm", "~> 1.11.0"
34
- spec.add_dependency "relaton-bsi", "~> 1.11.0"
35
- spec.add_dependency "relaton-calconnect", "~> 1.11.0"
36
- spec.add_dependency "relaton-cen", "~> 1.11.0"
37
- spec.add_dependency "relaton-cie", "~> 1.11.0"
38
- spec.add_dependency "relaton-ecma", "~> 1.11.0"
39
- spec.add_dependency "relaton-gb", "~> 1.11.0"
40
- spec.add_dependency "relaton-iana", "~> 1.11.0"
41
- spec.add_dependency "relaton-iec", "~> 1.11.0"
42
- spec.add_dependency "relaton-ieee", "~> 1.11.0"
43
- spec.add_dependency "relaton-ietf", "~> 1.11.0"
44
- spec.add_dependency "relaton-iho", "~> 1.11.0"
45
- spec.add_dependency "relaton-iso", "~> 1.11.0"
46
- spec.add_dependency "relaton-itu", "~> 1.11.0"
47
- spec.add_dependency "relaton-nist", "~> 1.11.0"
48
- spec.add_dependency "relaton-oasis", "~> 1.11.0"
49
- spec.add_dependency "relaton-ogc", "~> 1.11.0"
50
- spec.add_dependency "relaton-omg", "~> 1.11.0"
51
- spec.add_dependency "relaton-un", "~> 1.11.0"
52
- spec.add_dependency "relaton-w3c", "~> 1.11.0"
32
+ spec.add_dependency "relaton-3gpp", "~> 1.12.0"
33
+ spec.add_dependency "relaton-bipm", "~> 1.12.0"
34
+ spec.add_dependency "relaton-bsi", "~> 1.12.0"
35
+ spec.add_dependency "relaton-calconnect", "~> 1.12.0"
36
+ spec.add_dependency "relaton-cen", "~> 1.12.0"
37
+ spec.add_dependency "relaton-cie", "~> 1.12.0"
38
+ spec.add_dependency "relaton-ecma", "~> 1.12.0"
39
+ spec.add_dependency "relaton-gb", "~> 1.12.0"
40
+ spec.add_dependency "relaton-iana", "~> 1.12.0"
41
+ spec.add_dependency "relaton-iec", "~> 1.12.0"
42
+ spec.add_dependency "relaton-ieee", "~> 1.12.0"
43
+ spec.add_dependency "relaton-ietf", "~> 1.12.0"
44
+ spec.add_dependency "relaton-iho", "~> 1.12.0"
45
+ spec.add_dependency "relaton-iso", "~> 1.12.0"
46
+ spec.add_dependency "relaton-itu", "~> 1.12.0"
47
+ spec.add_dependency "relaton-nist", "~> 1.12.0"
48
+ spec.add_dependency "relaton-oasis", "~> 1.12.0"
49
+ spec.add_dependency "relaton-ogc", "~> 1.12.0"
50
+ spec.add_dependency "relaton-omg", "~> 1.12.0"
51
+ spec.add_dependency "relaton-un", "~> 1.12.0"
52
+ spec.add_dependency "relaton-w3c", "~> 1.12.0"
53
53
 
54
54
  spec.add_development_dependency "byebug", "~> 11.0"
55
55
  spec.add_development_dependency "equivalent-xml", "~> 0.6"
@@ -1,6 +1,40 @@
1
1
  RSpec.describe Relaton::Db do
2
2
  before(:each) { FileUtils.rm_rf %w[testcache testcache2] }
3
3
 
4
+ context "instance methods" do
5
+ subject { Relaton::Db.new nil, nil }
6
+
7
+ context "#search_edition_year" do
8
+ it "create bibitem from YAML content" do
9
+ h = { "docid" => [{ "id" => "ISO 123", type: "ISO", "primary" => true }] }
10
+ expect(YAML).to receive(:safe_load).with(:content).and_return h
11
+ item = subject.send :search_edition_year, "iso/item.yaml", :content, nil, nil
12
+ expect(item).to be_instance_of RelatonIsoBib::IsoBibliographicItem
13
+ end
14
+ end
15
+
16
+ context "#new_bib_entry" do
17
+ it "warn if cached entry is not_found" do
18
+ id = "ISO(ISO 123)"
19
+ db = double "db"
20
+ expect(db).to receive(:[]).with(id).and_return "not_found"
21
+ expect do
22
+ entry = subject.send :new_bib_entry, "ISO 123", nil, {}, :relaton_iso, db: db, id: id
23
+ expect(entry).to eq "not_found"
24
+ end.to output("[relaton] (ISO 123) not found.\n").to_stderr
25
+ end
26
+ end
27
+ end
28
+
29
+ context "class methods" do
30
+ it "::init_bib_caches" do
31
+ expect(FileUtils).to receive(:rm_rf).with(/\/\.relaton\/cache$/)
32
+ expect(FileUtils).to receive(:rm_rf).with(/testcache\/cache$/)
33
+ expect(Relaton::Db).to receive(:new).with(/\/\.relaton\/cache$/, /testcache\/cache$/)
34
+ Relaton::Db.init_bib_caches(global_cache: true, local_cache: "testcache", flush_caches: true)
35
+ end
36
+ end
37
+
4
38
  context "modifing database" do
5
39
  let(:db) { Relaton::Db.new "testcache", "testcache2" }
6
40
 
@@ -178,7 +212,7 @@ RSpec.describe Relaton::Db do
178
212
  refs = ["CGPM Resolution 1889-00", "CGPM Résolution 1889-00",
179
213
  "CGPM Réunion 9", "CGPM Meeting 9"]
180
214
  results = []
181
- VCR.use_cassette "bipm_i18n_async_fetch" do
215
+ VCR.use_cassette "bipm_i18n_async_fetch", match_requests_on: %i[method uri body] do
182
216
  refs.each do |ref|
183
217
  db.fetch_async(ref) { |r| queue << [r, ref] }
184
218
  end
@@ -198,6 +232,22 @@ RSpec.describe Relaton::Db do
198
232
  expect(result).to be_nil
199
233
  end
200
234
 
235
+ it "handle HTTP request error" do
236
+ expect(db).to receive(:fetch).and_raise RelatonBib::RequestError
237
+ db.fetch_async("ISO REF") { |r| queue << r }
238
+ result = Timeout.timeout(5) { queue.pop }
239
+ expect(result).to be_instance_of RelatonBib::RequestError
240
+ end
241
+
242
+ it "handle other errors" do
243
+ expect(db).to receive(:fetch).and_raise Errno::EACCES
244
+ expect do
245
+ db.fetch_async("ISO REF") { |r| queue << r }
246
+ result = Timeout.timeout(5) { queue.pop }
247
+ expect(result).to be_nil
248
+ end.to output("[relaton] ERROR: ISO REF -- Permission denied\n").to_stderr
249
+ end
250
+
201
251
  it "use threads number from RELATON_FETCH_PARALLEL" do
202
252
  expect(ENV).to receive(:[]).with("RELATON_FETCH_PARALLEL").and_return(1)
203
253
  allow(ENV).to receive(:[]).and_call_original
data/spec/spec_helper.rb CHANGED
@@ -13,6 +13,7 @@ VCR.configure do |c|
13
13
  clean_outdated_http_interactions: true,
14
14
  re_record_interval: 7 * 24 * 3600,
15
15
  record: :once,
16
+ allow_playback_repeats: true,
16
17
  }
17
18
  c.hook_into :webmock
18
19
  end
@@ -41,29 +41,29 @@ http_interactions:
41
41
  X-Xss-Protection:
42
42
  - 1; mode=block
43
43
  X-Github-Request-Id:
44
- - 7178:6974:A78BC:C192B:62AAF846
44
+ - 7D28:10C50:1BF854C:1DDFC0B:62BDDA6B
45
45
  Accept-Ranges:
46
46
  - bytes
47
47
  Date:
48
- - Thu, 16 Jun 2022 09:30:46 GMT
48
+ - Thu, 30 Jun 2022 17:16:27 GMT
49
49
  Via:
50
50
  - 1.1 varnish
51
51
  X-Served-By:
52
- - cache-vie6334-VIE
52
+ - cache-vie6348-VIE
53
53
  X-Cache:
54
54
  - MISS
55
55
  X-Cache-Hits:
56
56
  - '0'
57
57
  X-Timer:
58
- - S1655371847.568153,VS0,VE230
58
+ - S1656609387.047148,VS0,VE235
59
59
  Vary:
60
60
  - Authorization,Accept-Encoding,Origin
61
61
  Access-Control-Allow-Origin:
62
62
  - "*"
63
63
  X-Fastly-Request-Id:
64
- - da76509a3e570d0b83c3692633c0dfea81acef96
64
+ - 93a267346ed97c52087b05f16495084f70b848e8
65
65
  Expires:
66
- - Thu, 16 Jun 2022 09:35:46 GMT
66
+ - Thu, 30 Jun 2022 17:21:27 GMT
67
67
  Source-Age:
68
68
  - '0'
69
69
  body:
@@ -143,5 +143,5 @@ http_interactions:
143
143
  freeze_stage3_meeting: SMG-28
144
144
  close_meeting: SP-28
145
145
  project_end: '1999-02-12'
146
- recorded_at: Thu, 16 Jun 2022 09:30:46 GMT
146
+ recorded_at: Thu, 30 Jun 2022 17:16:27 GMT
147
147
  recorded_with: VCR 6.1.0